How to keep Browserify bundle size sensible when using requires for thirdparty stuff (via grunt if it matters)

本秂侑毒 提交于 2019-12-03 15:58:41

If you create an external bundle containing all your app's dependencies (B + C) and declare those modules as external when bundling your app's own code (A), then things should work as you expect.

I don't know the grunt-browserify config incantations for doing this, but the following show how you'd use browserify directly in some example gulp tasks, so the bundle creation should be reusable:

var browserify = require('browserify')
var gulp = require('gulp')
var source = require('vinyl-source-stream')

gulp.task('js-deps', function() {
  var b = browserify()
  b.require('react')
  b.require('react-router-component')
  b.transform('envify')

  return b.bundle()
    .pipe(source('deps.js'))
    .pipe(gulp.dest('./build'))
})

gulp.task('bundle-js', function() {
  var b = browserify('./lib/app.js')
  b.external('react')
  b.external('react-router-component')

  return b.bundle()
    .pipe(source('app.js'))
    .pipe(gulp.dest('./build'))
})

Someone else already mentioned the external option which should be the actual solution. Now, do consider these pieces of advice as well. You might know most if not all of it already but some of it might help. This won't turn the 600k file into 1k but might be significant nonetheless.

Begin by checking out the advanced options in https://github.com/substack/node-browserify#usage and more specifically the --no-bundle-external option. If the external option does work with require('b') but still includes the external libraries, this is your best bet;

Also look at the options about the global variables as well. When I started out with browserify I had a single function compile into a huge library as it contained all the stubs for the NodeJS native modules. The aforementioned options were key in solving this issue. It was in a Grunt-task but if I recall correctly it wasn't with the grunt-browserify task, it still might be relevant.

Do set the build environment before running browserify:app if you haven't already done that. There are libraries which depend on these variables for their production compilation (I think React is one of them).

    grunt.loadNpmTasks('grunt-env');

    // initConfig task
    env: {
      dist: {
        NODE_ENV : 'production',
      },
      dev: {
        NODE_ENV: 'development',
      } 
    }

    grunt.registerTask("build_dist", ['env:dist', 'browserify:app']

Try running Uglify with specifically these options as well;

    // initConfig task options
    options: {
      compress:{
        dead_code     : true,  // discard unreachable code
        drop_debugger : true,  // discard “debugger” statements
        global_defs   : {      // global definitions
          "DEBUG": false,      // matters for some libraries
        },
      }
    }

You can optimize a lot more but this should get you started.

B is included separately and assumed to be global, I've got this working just fine by doing a dirty bit of a replace in my build step that swaps out require("B") with global.B.

If you're swapping to global.B after the compilation your package will have all of require('b')'s dependencies as well. This hack is (probably) better:

This is not acceptable but I don't know how to get it any smaller as I don't know what the heck its pulling in (or more importantly what I can exclude to make it still work)

Go look inside the source code of the generated library, you should be able to identify the different modules and their filepath.

I've put together a working example for how to split code into multiple bundles using Browserify: https://github.com/aldendaniels/browserify-bundle-splitting

With this approach you can load all your vendor code via Browserify (no global shimming needed), but still have your own code bundled separately.

Since the generated bundles are truly independent, you can easily have different settings for the generated bundles. For example, you might want to disable source maps for 3rd party code, but use source maps for your own code.

You can see which files are taking up space in the bundle by running this command: browserify --list test/browser/browserify-test-uncompiled.js | xargs ls -la | sort

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