Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Gulp to build requireJS project - gulp-requirejs

Tags:

I am trying to use gulp-requirejs to build a demo project. I expect result to be a single file with all js dependencies and template included. Here is my gulpfile.js

var gulp = require('gulp'); var rjs = require('gulp-requirejs'); var paths = {   scripts: ['app/**/*.js'],   images: 'app/img/**/*' };  gulp.task('requirejsBuild', function() {     rjs({         name: 'main',         baseUrl: './app',         out: 'result.js'     })     .pipe(gulp.dest('app/dist'));  });  // The default task (called when you run `gulp` from cli) gulp.task('default', ['requirejsBuild']); 

The above build file works with no error, but the result.js only contains the content of main.js and config.js. All the view files, jquery, underscore, backbone is not included.

How can I configure gulp-requirejs to put every js template into one js file? If it is not the right way to go, can you please suggest other method?

Edit

config.js

require.config({     paths: {         "almond": "/bower_components/almond/almond",         "underscore": "/bower_components/lodash/dist/lodash.underscore",         "jquery": "/bower_components/jquery/dist/jquery",         "backbone": "/bower_components/backbone/backbone",         "text":"/bower_components/requirejs-text/text",         "book": "./model-book"     } }); 

main.js

// Break out the application running from the configuration definition to // assist with testing. require(["config"], function() {     // Kick off the application.     require(["app", "router"], function(app, Router) {         // Define your master router on the application namespace and trigger all         // navigation from this instance.         app.router = new Router();          // Trigger the initial route and enable HTML5 History API support, set the         // root folder to '/' by default.  Change in app.js.         Backbone.history.start({ pushState: false, root: '/' });     }); }); 

The output is just a combination this two files, which is not what I expected.

like image 459
Nicolas S.Xu Avatar asked Jun 01 '14 09:06

Nicolas S.Xu


2 Answers

gulp-requirejs has been blacklisted by the gulp folks. They see the RequireJS optimizer as its own build system, incompatible with gulp. I don't know much about that, but I did find an alternative in amd-optimize that worked for me.

npm install amd-optimize --save-dev 

Then in your gulpfile:

var amdOptimize = require('amd-optimize'); var concat = require('gulp-concat');  gulp.task('bundle', function () {     return gulp.src('**/*.js')         .pipe(amdOptimize('main'))         .pipe(concat('main-bundle.js'))         .pipe(gulp.dest('dist')); }); 

The output of amdOptimize is a stream which contains the dependencies of the primary module (main in the above example) in an order that resolves correctly when loaded. These files are then concatenated together via concat into a single file main-bundle.js before being written into the dist folder.

You could also minify this file and perform other transformations as needed.


As an aside, in my case I was compiling TypeScript into AMD modules for bundling. Thinking this through further I realized that when bundling everything I don't need the asynchronous loading provided by AMD/RequireJS. I am going to experiment with having TypeScript compile CommonJS modules instead, then bundling them using webpack or browserify, both of which seem to have good support within gulp.

like image 134
Drew Noakes Avatar answered Oct 04 '22 21:10

Drew Noakes


UPDATE

My previous answer always reported taskReady even if requirejs reported an error. I reconsidered this approach and added error logging. Also I try to fail the build completely as described here gulp-jshint: How to fail the build? because a silent fail really eats your time. See updated code below.

Drew's comment about blacklist was very helpfull and gulp folks suggest using requirejs directly. So I post my direct requirejs solution:

var DIST = './dist'; var requirejs = require('requirejs'); var requirejsConfig = require('./requireConfig.js').RJSConfig;  gulp.task('requirejs', function (taskReady) {     requirejsConfig.name = 'index';     requirejsConfig.out = DIST + 'app.js';     requirejsConfig.optimize = 'uglify';     requirejs.optimize(requirejsConfig, function () {         taskReady();     }, function (error) {         console.error('requirejs task failed', JSON.stringify(error))         process.exit(1);     }); }); 

The file at ./dist/app.js is built and uglified. And this way gulp will know when require has finished building. So the task can be used as a dependency.

like image 39
Olga Avatar answered Oct 04 '22 21:10

Olga