简体   繁体   中英

Can I achieve this with Gulp + Browserify? Do I need Webpack instead?

I've been using Gulp for a while now. Then I was introduced to Browserify. Now Webpack is on my horizon given I'm moving towards React. I digress...

I'd like to achieve these steps:

  1. require front end dependencies, such as jQuery and Backbone, in a node application so as to have one source of truth - npm .
  2. Concatenate those dependencies (in whatever order I choose) into a dependencies.js file suitable for the browser (Browserify, right?).
  3. Concatenate the above file with my own JavaScript files (in whatever order I choose) into a all.min.js file, minified, wrapped in a self executing anonymous function - (function(){ /*all code here*/})() - so as to avoid any global variables / variables on the window object / global pollution . (<-- this one is the key).

I'd love to be able to handle this all in just Gulp as I'm used to it, but the whole global pollution thing is killing me. Take a look at the gulp file:

var gulp       = require('gulp');
var concat     = require('gulp-concat-util'); // Makes concat.header, concat.footer available.
var uglify     = require('gulp-uglify');
var browserify = require('browserify');
var source     = require('vinyl-source-stream');
var buffer     = require('vinyl-buffer');

gulp.task('browserify', function() {
  return browserify('libraries.js') // File containing a list of requires's.
    .bundle()
    .pipe(source('dependencies.js')) // Concatenated file.
    .pipe(buffer())
    .pipe(gulp.dest('./dev/dependencies')); // Destination directory.
});

gulp.task('scripts', function() {
  return gulp.src([
    'dev/dependencies/dependencies.js',
    'dev/js/models/**/*.js', // Models before views & collections.
    'dev/js/**/!(app|templates)*.js',
    'dev/js/templates.js',
    'dev/js/app.js'
  ])
    .pipe(concat('all.min.js')) // Final file.
    .pipe(concat.header('(function(){')) // Attempts to wrap in a SEAF.
    .pipe(concat.footer('\n})();'))
    .pipe(uglify())
    .pipe(gulp.dest('public'));
});

All of that code will indeed produce a single file, minified, wrapped in a SEAF, but the libraries I required (say Backbone & jQuery) are still accessible in the global scope. My life! Is this just the way it works? Those libraries are attaching themselves to window (I looked in the code) but I thought maybe some Browserify magic could deal with that. Any thoughts are appreciated!

A lot of modules will use UMD (Universal Module Definition) patterns. One of the patterns is to always declare the module as a global resource so that other libraries that do not use a module loader will have the library available globally. Having single libraries globally registered is not terribly bad as long as they do not collide. Since you are wrapping your app code in an IIFE and hopefully not adding to the window object directly the globals should be limited to just the 3rd party libraries.

I'm using webpack for processing js and css and I'm pretty happy with it.

All library dependencies are installed by npm install and saved in package.json. In the result I have bunch of minified files that contains all my app. JS modules are stored in function scopes, so, no global scope is spoiled. Easy to maintain, easy to understand and track all dependencies used in each module.

I'll give you some basic example.

File: webpack.config.js - configuration for webpack

module.exports = {

  // entrypoint for webpack to start processing
  entry: {
    bundle: './js/main.js'
  },

  output: {
    path: __dirname + '/' + 'assets',
    filename: '[name].js',
    publicPath : '/assets/',
  }
};

File: ./js/main.js - entrypoint for webpack

// This is require from node_modules
var $ = require('jquery');

// this is require for my local module
var MyModule1 = require('./modules/module1.js');

File: ./modules/module1.js - local module

var OtherLib = require('other-lib');

...

// exporting some data for others    
module.exports = {
  // export object  
};

Pros:

Cons that I faced:

  • webpack is JS preprocessor, so, if you need to have processed CSS as separate file (not in minified JS), you need to extract CSS from JS result. So, I'm using ExtractTextPlugin.
  • It quite slow while processing lots of SASS files in --watch mode.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM