Browserify + npm & dedupe - how to produce output files - npm

I'm investigating an approach to implement npm (with dedupe) as a dependency manager (instead of bower). And now, I have npm packages like jquery-ui that use CommonJS require statements to include dependencies like jquery.
Before using npm, I used reqular jquery-ui script, without require. So now I guess I have to use Browserify to generate JavaScript that can be used inside the browser.
And now I have a questions (let's consider jquery & jquery-ui example): if I have other packages (or my own code) that uses jQuery, does it mean I always must have one output file from Browserify? For instance: jquery-ui depends on jquery, and my own code also depends on jquery. If I have two separate output builds eg:
browserify jquery-ui.js -o dist/jquery-ui.js
browserify myCode.js -o dist/myCode.js
then this approach is bad, because I'll have two jquery included twice. Do I get it correctly?
Perhaps that is the question that summarizes everything: Do I need to have one application wide "main.js" file that requires everything that is needed for my application?

Indeed. You'll have to npm dedupe pre-browserify and use multiple entry points. If you are browserifying twice, you'll package two versions of that module. You may be best off building a partitioned bundle set. In this regard, you can use one browserify command and not duplicate modules. Check out the handbook here: https://github.com/substack/browserify-handbook#partitioning

Related

SailsJS Include node_module in view

I'm using sails(http://sailsjs.com) to develop a little platform. Everything goes smoothly following the documentation. But being new to this javascript frameworks world and npm etc etc, i've been having a trouble including other node_modules and use them in the .ejs views...
I understand not all modules are to be included in the views but how can I manage to include some?
Trying to use https://www.npmjs.com/package/vue-slider-component
Thank you in advance and sorry if this error is just plain out stupid.
Your confusion is understandable. The issue is that, until relatively recently, things installed in node_modules were solely for use in the back end code; that is, your Sails.js controller actions, models, etc. After all, the node_modules folder has the word "Node" right in it, and it was created for use with NPM (the Node Package Manager) to help organize Node (i.e. server-side JavaScript) files!
While many front-end plugins were (and still are) published on Bower, newer frameworks like Angular 2 and Vue often publish their plugins to NPM because it reduces the number of moving parts for your app. The problem is, if you try to require('vue-slider-component') in your server-rendered .ejs view, the server (i.e. Sails.js) will try and load and run that code before it renders the view, where what you really want is for that plugin to run in the browser.
The long-term solution is to use something like Browserify or Webpack to compile all of your front-end JavaScript files into a "bundle". So for example if you have a file like assets/js/my-vue-app.js that includes the line:
import vueSlider from 'vue-slider-component/src/vue2-slider.vue'
then Browserify will see that line, load up that vue2-slider.vue file, add it to the top of the my-vue-app.js file, perform some other magic, combine it with your other front-end .js files and output a file like browserified.js which you would then include via <script src="/path/to/browserified.js"> in your HTML.
Since new Sails apps use Grunt to organize and inject those <script> tags into your views for you, it can be kinda confusing as to how you would get something like Browserify or Webpack to work with Sails. For Sails 1.0, there's a seed project for using Webpack instead of Grunt. For Sails v0.12.x, you'll have to Google around to find some examples of using Broswerify or Webpack with Sails.
A short-term solution, and probably not as maintainable in the long run, is to save the contents of the minified vue-js-slider component into your assets folder (e.g. as assets/js/vue-slider-component.js), add it to your HTML with <script src="/js/vue-slider-component.js"> and access it in your code as window['vue-slider-component'].

Why would one need gulp-concat, even though browserify is already being used?

I was of the understanding that Browserify could be used to bundle various JavaScript files into one. However, after looking at some examples on the internet, I found that some people use Browserify and yet they also include gulp-concat.
For example, the angularjs-gulp-example project uses both.
Why? I thought Browserify could do the concatenation as well.
Browserify is a bundler that creates JavaScript bundles from CommonJS modules. Typically, the bundle will contain all of a project's source files and all of the CommonJS/UMD dependencies. (Also, like Node, Browserify can require JSON files, so they could be in the bundle, too.)
If a project has dependencies that are not included using require and are instead indended to be used in <script> elements - the build process might opt to use a tool like gulp-concat to concatenate them to the front of the bundle.
That's likely why gulp-concat is used in the project you referenced in your question. It concatenates an Angular template cache that's generated from .html files - something Browserify doesn't deal with (unless a transform has been configured).

How to use Cycle.js without Browserify/Webpack?

Bower: I couldn't find a Bower package for #Cycle/Core, #Cycle/DOM, do these libraries exist? I'm confused at why there is an NPM package in the first place since Cycle.js is front-end based (and NPM is specialized for back-end only).
ES5: Is it possible to use Cycle.js with Gulp/Typescript/ES5 (and not use Browserify/webpack)?
npm is not specialized for back-end only. It is for everything.1
It is possible to use Cycle.js without browserify or webpack. The library comes with ES5 distribution files, found in the dist directory.
Yes, you can use Gulp, TypeScript and ES5 with Cycle.js.
Everything Frederik said, plus here is a standalone Cycle.js example on codepen. You can see the links to the JavaScript files being loaded by clicking on Settings, then JavaScript. Here they are for convenience:
https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.7/rx.all.js
https://rawgit.com/cyclejs/cycle-core/master/dist/cycle.js
https://rawgit.com/cyclejs/cycle-dom/master/dist/cycle-dom.js
Full example is on codepen
Or you can try stealjs.
At runtime it downloads your dependencies.
I use npm to get the packages, gulp to move the packages to wwwroot. TypeScript to downcompile, and systemjs to load the modules. No webpack or bower required.

browserify with noparse=true - how it works

I would like to ask what is the purpose of using browserify with noparse option set to true (or how browserify works). For instance:
if browserify does not parse files at all, does it means that it will not find require statements?
if it does not find require statements, then how to force code to load module? For instance, I have toastr & jQuery. toastr requires jQuery. But when I used browserify to create a bundle with noparse set to true, and I added to this bundle both files:
var bundler = browserify();
bundler.add('jquery.js');
bundler.add('toastr.js');
bundler.bundle();
then I get the error, that jQuery module it not found.
Normally when you bundle a file with browserify, it parses the file for require() calls so it can build a dependency graph and bundle the required files. The purpose of the noParse option is to skip that parsing when you don't need or want it. For example, if you're bundling a large library file like jQuery and you know it doesn't contain any require() calls that need to be processed, it will save time in bundling if you noParse that file. Also, it's currently difficult to require() a previously browserified bundle when making a new bundle. In that case you can sometimes resolve the issue by setting noParse for the previously browserified bundle.
if browserify does not parse files at all, does it means that it will not find require statements?
Yes.

Why is browserify pulling in a lib 2 times? - Browserify

I have an Angular app where I use browserify to manage my dependencies. I am also using momentjs to do all my time manipulation. I have several modules that I am using browserify to build, but it is pulling in momentjs more than once, even when I use the external command. Here is my code. First I have a base module that has all of my shared libs:
require('angular');
require('angular-route');
require('moment');
Here is the code I use to browserify in my gulpfile.js:
browserify().require('./js/donor/donor-libs.js')
.bundle()
.pipe(source('donor-libs.js'))
.pipe(gulp.dest('./build'));
This builds out fine and has the libs that I would expect including momentjs.
Now I go to build a module that is dependent on this module. momentjs is used in this module. Here is the code that I use to build the module:
browserify().require('./js/donor/history-module.js')
.external('./js/donor/donor-libs.js')
.bundle()
.pipe(source(filename))
.pipe(gulp.dest('./build'));
Now when I look in my build directory, I have momentjs in both the donor-libs.js and my history-module.js. Why doesn't it recognize that I have already required in momentjs in my donor-libs.js? What do I need to do to only require in 3rd party libs one time? What don't I understand about the external command?
The reason libs are being pulled in multiple times is that the external command is being used improperly. external is expecting a path or an array of paths that will externalized. external will not look through a js file and find the required files and then not pull them in other modules. The code should of looked something like this
.external('angular', 'angular-route', 'moment')
or the path to the required lib. This would of externalized these files and fixed the problem of a lib being pulled in multiple times.