How to include node_modules in a separate browserify vendor bundle

﹥>﹥吖頭↗ 提交于 2019-12-03 10:48:44

问题


I am trying to convert an AngularJS app to use browserify. I have installed all my bower packages in node_modules using napa. Now I want to browserify them into a separate vendor bundle and declare them as 'external' dependencies. I would like to give them aliases, so that I can "require('angular')" instead of "require('angular/angular')", as it seems you can do with externals.

The examples I have seen (e.g. http://benclinkinbeard.com/posts/external-bundles-for-faster-browserify-builds/) all assume that I have downloaed the vendor files into a 'lib' directory. I want to just bundle my vendor files from node_modules. It seems like it should be easy but I can't see how to do it.


回答1:


I was just trying to do the same thing. I think you need to use --require for the vendor bundle and --export for the application's so that the dependencies don't get bundled twice.

This worked for me using browserify's api and gulp (lodash and pixijs being my node_modules):

var gulp = require('gulp');
var browserify = require('browserify');
var handleErrors = require('../util/handleErrors');
var source = require('vinyl-source-stream');


gulp.task('libs', function () {
  return browserify()
    .require('lodash')
    .require('pixi.js')
    .bundle()
    .on('error', handleErrors)
    .pipe(source('libs.js'))
    .pipe(gulp.dest('./build/'));
});

gulp.task('scripts', function () {
  return browserify('./src/main.js')
    .external('lodash')
    .external('pixi.js')
    .bundle()
    .on('error', handleErrors)
    .pipe(source('main.js'))
    .pipe(gulp.dest('./build/'));
});

gulp.task('watch', function(){
  gulp.watch('src/**', ['scripts']);
});

gulp.task('default', ['libs', 'scripts', 'watch']);

Of course, this solution is a pain to maintain... So I patched browserify to accept arrays in require and external and then you can do this which I think it's a lot better:

var gulp         = require('gulp');
var browserify   = require('browserify');
var handleErrors = require('../util/handleErrors');
var source       = require('vinyl-source-stream');

var packageJson = require('../../package.json');
var dependencies = Object.keys(packageJson && packageJson.dependencies || {});


gulp.task('libs', function () {
  return browserify()
    .require(dependencies)
    .bundle()
    .on('error', handleErrors)
    .pipe(source('libs.js'))
    .pipe(gulp.dest('./build/'));
});

gulp.task('scripts', function () {
  return browserify('./src/main.js')
    .external(dependencies)
    .bundle()
    .on('error', handleErrors)
    .pipe(source('main.js'))
    .pipe(gulp.dest('./build/'));
});

gulp.task('watch', function(){
  gulp.watch('package.json', ['libs']);
  gulp.watch('src/**', ['scripts']);
});

gulp.task('default', ['libs', 'scripts', 'watch']);

That's the best I could come up with... Please, let me know if you find a better way.




回答2:


I also face this issue. Because it was huge file when all vendor library in same file. So browser always stuck with downloading more than 10MB file. File minification also was not solution because it was take more time to compile and that was not helpful for development.

I have kept vendor.js and app.js for separate node modules and application scripts. It's like this.

Sample vendor.js (src/app/vendor.js)

/**
 * Node modules
 */
require('angular');
require('angular-cookies');
require('angular-ui-router');
require('angular-aria');
require('angular-animate');
....

Sample app.js (src/app/app.js)

/**
 * App Common Modules
 */
require('./modules/about/about.routing.js');
require('./modules/home/home.routing.js');

/**
 * Services
 */
require('./shared/services/order.js');
require('./shared/services/product.js');


/**
 * Directives
 */
require('./shared/directives/dropzone.js');
require('./shared/directives/tab-change.js');


angular
    .module('myApp', [
        //------------- Node modules ------------//
        'ui.router',
        'ngMaterial',


        //------------- App Common modules ------------//

        //About
        'cloudDecor.routing.about',
        'cloudDecor.controller.about',


        //Home
        'cloudDecor.routing.home',
        'cloudDecor.controller.home',


        //------------- Services --------------//

        'cloudDecor.service.order',


        //------------- Directives ------------//
        'cloudDecor.directive.dropzone',
        'cloudDecor.directive.tab-change'

    ]);

gulpfile.js

var gulp = require('gulp'),   
    browserify = require('browserify'),
    uglify = require('gulp-uglify'),
    buffer = require('vinyl-buffer');


//App js
gulp.task('app_js', function() {
    // Grabs the app.js file
    browserify({
            entries: ['./src/app/app.js'],
            debug: true
        })
        .bundle()
        .pipe(source('main.js'))
        .pipe(buffer())
        .pipe(gulp.dest('./build/'));
});

//Vendor js
gulp.task('vendor_js', function() {
    // Grabs the app.js file
    browserify({
        entries: ['./src/app/vendor.js']
    })
    .bundle()
    .pipe(source('vendor.min.js'))
    .pipe(buffer())
    .pipe(uglify({ mangle: false }))
    .pipe(gulp.dest('./build/'));
});

gulp.task('default', ['app_js', 'vendor_js']);

Make sure include vendor.js before use main.js in index.html

<html>
<body>

<!--Vendor js, See src/vendor.js-->
<script type="text/javascript" src="vendor.min.js"></script>

<!--App scripts, See src/app.js-->
<script type="text/javascript" src="main.js"></script>
</body>
</html>



回答3:


This solution looks great:

var packageJSON = require('./package.json');
var dependencies = Object.keys(packageJSON && packageJSON.dependencies || {});

gulp.task('vendor', function() {
   return browserify()
    .require(dependencies)
    .bundle()
    .pipe(source('vendor.bundle.js'))
    .pipe(gulp.dest(__dirname + '/public/scripts'));
});


来源:https://stackoverflow.com/questions/22330103/how-to-include-node-modules-in-a-separate-browserify-vendor-bundle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!