I am trying to learn how to use browserify so I can compile all my dependencies to one file. All the dependencies are being pulled in with NPM through updating a package.json. For example, I want to create a file with browserify that consists of the compiled javascript from this json file.
"dependencies": {
"highcharts": "0.0.11",
"bootstrap": "3.1.0"
}
I would like to do this on the fly and have it automatically pull from this json file.
You need to require the dependencies in whatever module you need them. For example, if one of your dependencies is Lodash, you'll require it where you use it:
var lodash = require('lodash');
module.exports = function() {
// do something with lodash in here if you want
};
The purpose of using something like browserify, webpack, etc., is that you specifically don't compile everything into a "global dependency bundle", as this subverts the modularization that those libraries (browserify, webpack) are meant to impose.
Related
How do I configure Syncfusion JavaScript for use with Aurelia via Aurelia CLI?
Here is how Syncfusion JavaScript configured when used with jspm (via http://aurelia-ui-toolkits.github.io/demo-syncfusion/#/installation):
Open config.js and add a couple of path mappings:
paths: {
"*": "src/*",
"github:*": "jspm_packages/github/*",
"npm:*": "jspm_packages/npm/*",
"common/ej.*": "jspm_packages/github/syncfusion/JavaScript-Widgets#14.1.0.41/scripts/ej/common/ej.*.js", <----
"datavisualization/ej.*": "jspm_packages/github/syncfusion/JavaScript-Widgets#14.1.0.41/scripts/ej/datavisualization/ej.*.js", <----
"ej.*": "jspm_packages/github/syncfusion/JavaScript-Widgets#14.1.0.41/scripts/ej/web/ej.*.js", <----
"syncfusion-javascript/*": "jspm_packages/github/syncfusion/JavaScript-Widgets#14.1.0.41/*" <----
},
"map": {
"aurelia-bootstrapper": "npm:aurelia-bootstrapper#1.0.0-beta.1",
"aurelia-fetch-client": "npm:aurelia-fetch-client#1.0.0-beta.1",
"aurelia-framework": "npm:aurelia-framework#1.0.0-beta.1.0.2",
"jquery": "npm:jquery#2.2.3", <----
"jquery.min": "npm:jquery#2.2.3", <----
"jquery-easing": "npm:jquery.easing#1.3.2", <----
"jquery-validation": "npm:jquery-validation#1.15.0", <----
"jquery-validation-unobtrusive": "npm:jquery-validation-unobtrusive#3.2.6", <----
"jsrender": "npm:jsrender#0.9.75", <----
}
Check out the Aurelia CLI documentation on how to add libraries to your project.
Your basic steps will probably be to install the package via npm:
npm install syncfusion-javascript --save
That will add the package to your project.json file and have it downloaded.
Next you're going to want to configure your aurelia.json file. Because SyncFusion is not modular, and is really just a library of files, there is no way to just reference a package and have it bundled. What you'll have to do is create a package for each of the packages you're using.
Or, alternate solution, create your own javascript "main" file that references all the modules in the package you want, and set that as the "main" in the package description
{
"name": "syncfusion-javascript",
"path": "../node_modules/syncfusion-javascript",
"main": "syncFusionCustomMain"
}
Your syncFusionCustomMain.js file would import the files from the node_modules folder, and then export the functions to be referenced appropriately.
Sorry this is kind of bad news for you. This package is just not loader friendly, and as of right now, the CLI doesn't have support for just defining paths (since everything gets bundled, it needs to have everything be explicit at compile time).
I've created a simple JavaScript application using AngularJS.
I'm using npm and Bower to manage my dependencies, Gulp to automatise my tasks and I want to use the CommonJS' module.exports/require() to tie everything up together: I decided to go for Browserify to bundle this all up.
There's my very empty and clean project on Github, if you wanna take a look.
In order to be able to require('angular'), I configured Browserify to shim that AngularJS into the available modules, using browserify-shim. Pretty straightforward, here's the relevant part of my package.json:
"browser": {
"angular": "./bower_components/angular/angular.min.js"
},
"browserify": {
"transform": [
"browserify-shim"
]
},
"browserify-shim": {
"angular": {
"exports": "angular"
}
}
It's pretty neat, my main JS file now looks like this:
'use strict';
var angular = require('angular');
angular.module('MyApp', [])
.controller('View1Ctrl', ['$scope', require('./view1/view1.js')])
.controller('View2Ctrl', ['$scope', require('./view2/view2.js')]);
And that works.
Now, I'm trying to get into some more advanced stuff, using external libraries available through Bower. They get installed under bower_components and look -well- just like my project, they've got a package.json, a bower.json and all.
Take for example ng-dialog, which also require('angular'). Once retrieved via bower install ng-dialog --save, I do two things:
Link their dist's JS file to a keyword (let's say ng-dialog) in my package.json
require('ng-dialog') in main main JS file in order to have my Angular module depend on theirs.
Here's the updated relevant part of my package.json (note that ng-dialog does not need to be shimmed):
"browser": {
"angular": "./bower_components/angular/angular.min.js",
"ng-dialog": "./bower_components/ng-dialog/js/ngDialog.min.js"
},
"browserify": {
"transform": [
"browserify-shim"
]
},
"browserify-shim": {
"angular": {
"exports": "angular"
}
}
... and my updated app.js file:
'use strict';
var angular = require('angular');
require('ng-dialog');
angular.module('MyApp', ['ngDialog'])
.controller('View1Ctrl', ['$scope', require('./view1/view1.js')])
.controller('View2Ctrl', ['$scope', require('./view2/view2.js')]);
I get the following error while Browserify-ing this up:
Error: Cannot find module 'angular' from 'C:\...\bower_components\ng-dialog\js'
After a good half hour of tweaking around, it turned out that SIMPLY deleting the package.json file from bower_components/ng-dialog makes it all go smoothly.
What is going on and how the hell should I bundle that ngDialog.min.js?
As stated in the Browserify Handbook
The module system that browserify uses is the same as node, so packages published to npm that were originally intended for use in node but not browsers will work just fine in the browser too.
Increasingly, people are publishing modules to npm which are intentionally designed to work in both node and in the browser using browserify and many packages on npm are intended for use in just the browser. npm is for all javascript, front or backend alike.
Therefore use the npm distribution of Angular and ngDialog packages rather than the bower ones
npm install angular ng-dialog --save
This will do away with the need to do the whole configuration in package.json and simply calling require() in the project will make browserify work.
When we require any node module in the project, browserify bundles the file present in the main field of the package.json of that respective node module. Currently as ngDialog's main field references the ngDialog.js file , therefore you will need to change it to ngDialog.min.js so that browserify bundles that file. (This isn't a major issue as you compress your browserify bundle using gulp-uglify)
I have forked your code and done the necessary changes in it - Check them here https://github.com/pra85/angular-seed
I'm trying to build a standalone JS lib that uses backbone/jquery. Here's a sample repo that represents the lib I'm trying to build.
I have a few goals for this lib:
Don't expose ANY globals (ie wrap everything properly so nothing leaks)
Don't be affected by any other package tools like requireJS
This lib could be loaded into any other website and I don't want any conflicts with JS that might be there (which is beyond my control) such as requireJS
So, my understanding is that I can use browserify-shim to properly shim these modules such that they can be used as expected with require in browserify. I'm pretty sure the shim is supposed to undef defines and require when it wraps these modules, which would achieve goal #2. Goal #1 would hopefully then be achieved just by using browserify as expected.
I can't really seem to get this to work and I"m not sure if it's just my misunderstanding of browserify-shim. I seem to have the same problem whether or not I run browserify from the command line: browserify src/main.js -o build/main.js or using the gulp build.
Basically, it's as if browserify-shim isn't even running. If you open up the index.html, you can see that the requirejs code I've loaded in is definitely affecting my lib as Backbone is just an empty object, then requirejs crashes.
You can see my package.json here in the repo, and it looks roughly like this:
{
...
"browserify-shim": {
"./node_modules/jquery/dist/jquery.js": "$",
"./node_modules/underscore.js": "_",
"./node_modules/backbone.js": {
"exports": "Backbone",
"depends": [
"./node_modules/underscore.js",
"./node_modules/jquery/dist/jquery.js"
]
}
},
"devDependencies": {
"browserify": "^4.1.11",
"browserify-shim": "^3.6.0",
"gulp": "^3.8.1",
"vinyl-source-stream": "^0.1.1"
},
"dependencies": {
"backbone": "^1.1.2",
"jquery": "^1.11.0",
"underscore": "^1.6.0"
}
}
Not sure what I'm missing here, but I'm having no luck. I was wondering if anyone can help or at least corroborate that what I'm trying to achieve is correct and possible with browserify-shim.
Thanks.
edit
To illustrate that it's definitely not shimming the modules, I've created a build/main.js and a build/main-shimmed.js that are exactly the same. The main.js I ran with no shim config and the shimmed one had the above config. I'm clearly missing something here.
Browserify and Browserify-shim are working in this case, and your main.js is calling the right require.
The problem you are running into is the that libraries you are bundling are also attempting to wire up the AMD style configuration. Your "crossing the streams", beware of Gozer.
Either get versions without the AMD configuration loaders, or comment them out.
I want to use gulp to build bundles of JavaScript files.
For example I have the following structure in my project:
/vendor/vendor1/vendor1.js
/vendor/vendor2/vendor2.js
/js/includes/include1.js
/js/includes/include2.js
/js/bundle1.js
/js/bundle2.js
There are vendor includes (1-2), local includes (3-4), and bundle files (5-6).
Vendor includes are just third-party JavaScript libraries installed with bower or composer. They can be CommonJS, AMD or just a plain-old jQuery plugins.
I want to specify dependencies inside of a bundle files like this:
/js/bundle1.js
(function() {
// Vendor includes.
include('vendor1');
include('vendor2');
// Local includes.
include('includes/include1.js');
include('includes/include2.js');
// Some code here.
})();
I want gulp to process this source file and create a final distribution file (bundle) ensuring that all dependencies (includes) are merged together in a single file. So I can include foo.js from my HTML and all dependencies will be available to it.
I want to have a clear and robust system to manage all dependencies inside of a project and build distribution files.
How can I achieve this?
What format should I use for my own scripts (AMD, CommonJS, other)?
How do I specify dependencies in my source bundle files?
How do I build distribution?
Your question is posed as if there's a single answer, but there isn't. The problem you're trying to solve is one that many people have solved in many different ways, and you've identified two of the major options: AMD and CommonJS. There are other ways, but given that you might be new to Javascript dependency management as well as gulp, I'd recommend going with something that's relatively straightforward (even though this subject is inherently not straightforward).
I think the easiest route for you might be:
use CommonJS to express the dependencies
use browserify to resolve them into bundles
in browserify, use the "UMD" method so that you get a single bundle that will work for apps that use either AMD or CommonJS or are not using either of these dependency management systems
The statement in gulp to run browserify as such might look something like:
var browserify = require('gulp-browserify');
gulp.src('bundles/bundle1.js', {read: false})
.pipe(browserify({
'standalone': true
})
.pipe(rename('bundle1Output.js'))
.pipe(gulp.dest('dist'));
That should give you a dist/bundle1Output.js file.
There is a gulp plugin for this:
https://www.npmjs.com/package/gulp-include
It should do what you want, except that in your bundle file instead of this:
(function() {
// Vendor includes.
include('vendor1');
include('vendor2');
// Local includes.
include('includes/include1.js');
include('includes/include2.js');
// Some code here.
})();
You would have to write:
//=require vendor1/**/*.js
//=require vendor2/**/*.js
//=require includes/include1.js
//=require includes/include2.js
// Some code here
I would like to use the the node-bencoding package with my current RequireJS project setup, but I have been unable to get it configured.
I have followed these instructions and have ran:
npm install requirejs
npm install node-bencoding
Then in my app.js file I had changed it:
var requirejs = require('requirejs');
// Place third party dependencies in the lib folder
//
// Configure loading modules from the lib directory,
// except 'app' ones,
requirejs.config({
nodeRequire: require,
"baseUrl": "assets/js/lib",
"paths": {
"app": "../app",
"jquery": "https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min",
"angularjs": "https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min"
},
});
However when I load the page I get the error:
Error: Module name "requirejs" has not been loaded yet for context: _. Use require([]) http://requirejs.org/docs/errors.html#notloaded
I'm not exactly sure where I should have my node_modules directory. My directory structure is as follows: all my JS files are contained within src/assets/js - there is assets/js/app and assets/js/lib as is the RequireJS convention. Currently I have put my node_modules directory in src/.
Looks like you are trying to use it in a browser. And your application is not server side JavaScript, so RequireJS usage sample in a Node does not apply. In this case you would like to use node only to optimize your scripts.
I recently blogged about Understanding AMD & RequireJS, it might be useful.