如何在使用第三方需要的东西时保持Browserify捆绑包大小合理(如果重要的话,通过grunt)

时间:2015-01-13 12:28:32

标签: reactjs browserify commonjs grunt-browserify

我正在尝试捆绑我自己的代码(A),后者又使用2个第三方组件(B和C),其中C也需要B.据我所知,所有内容都是使用CommonJS节点样式模块编写的。< / p>

捆绑时单独出现在60K。

B是单独包含的,并假设是全局的,我已经通过在我的构建步骤中执行一个替换的脏点来完成此工作,这需要(“B”)与global.B

交换 C是什么导致了我的问题,它的意思是“只有8K”大小但是当我尝试用A捆绑它时我的捆绑跳跃到600K +,因为我认为它依赖于大量的依赖?

这是不可接受的,但我不知道如何让它变得更小,因为我不知道它的吸引力是什么(或者更重要的是我可以排除使它仍然有效)。我可以尝试使用驱逐的二进制印章,但我不知道这是否是一种安全的方式,甚至是明智的做法。

如何捆绑C并且我的捆绑包只有68.5K(代码块的总大小为60k + 8.5k),当然还可以使用?

我是节点和浏览器的新手,但是我已经花了一个多星期的时间来讨论这个问题,公平地说我在举手之前给了它一个很好的刺。

如果重要,请提供其他信息:

  • 它需要运行服务器端和客户端
  • B实际上是ReactJS
  • C实际上是React Router Component
  • 通过ReactJS.net使用windows和c#...嘿......等等......回来...... 风滚草

4 个答案:

答案 0 :(得分:5)

如果您创建一个包含 all 您的应用程序依赖项(B + C)的外部包,并在捆绑您的应用程序自己的代码(A)时将这些模块声明为外部,那么事情应该按预期工作。

我不知道用于执行此操作的grunt-browserify配置咒语,但以下显示了如何在一些示例gulp任务中直接使用browserify,因此捆绑创建应该是可重用的:

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'))
})

答案 1 :(得分:2)

其他人已经提到了应该是实际解决方案的外部选项。现在,也要考虑这些建议。你可能已经知道了大部分内容,但有些可能会有所帮助。这不会使600k文件变成1k,但可能仍然很重要。

首先查看https://github.com/substack/node-browserify#usage中的高级选项,更具体地说是--no-bundle-external选项。如果外部选项适用于require(&#39; b&#39;)但仍然包含外部库,那么这是您最好的选择;

另请参阅有关全局变量的选项。当我开始使用browserify时,我有一个函数编译成一个巨大的库,因为它包含NodeJS本机模块的所有存根。上述选项是解决此问题的关键。这是一个Grunt任务,但如果我没记错,它不适用于grunt-browserify任务,它仍然可能是相关的。

在运行browserify之前设置构建环境:app,如果您还没有这样做的话。有些库依赖于这些变量进行生产编译(我认为React就是其中之一)。

    grunt.loadNpmTasks('grunt-env');

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

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

尝试使用特定的这些选项运行Uglify;

    // 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
        },
      }
    }

你可以进行更多优化,但这应该可以让你开始。

  

B是单独包含的,并假设是全局的,我已经通过在我的构建步骤中执行一个替换的脏点来完成这项工作,这需要(&#34; B&#34;) global.B。

如果您在编译后交换到global.B,那么您的软件包将具有所有必需(&#39; b&#39;)依赖项。这个黑客(可能)更好:

  

这是不可接受的,但我不知道如何让它变得更小,因为我不知道它的吸引力是什么(或者更重要的是我可以排除以使它仍然有效)< / p>

查看生成的库的源代码,您应该能够识别不同的模块及其文件路径。

答案 2 :(得分:1)

我已经汇总了一个工作示例,了解如何使用Browserify将代码拆分为多个包:https://github.com/aldendaniels/browserify-bundle-splitting

使用这种方法,您可以通过Browserify加载所有供应商代码(无需全局填充),但仍然可以单独捆绑您自己的代码。

由于生成的捆绑包是真正独立的,因此您可以轻松地为生成的捆绑包设置不同的设置。例如,您可能希望禁用第三方代码的源映射,但使用源映射作为您自己的代码。

答案 3 :(得分:0)

您可以通过运行此命令来查看捆绑包中占用空间的文件:browserify --list test/browser/browserify-test-uncompiled.js | xargs ls -la | sort