Reactjs 当使用第三方产品时,如何保持Browserify捆绑包大小合理(如果重要,通过grunt)
我正在尝试将我自己的代码(A)捆绑起来,这又使用了两个第三方组件(B和C),其中C也需要B。据我所知,所有内容都是使用CommonJS节点样式模块编写的 当bundled以60K的价格推出时,A将独立运行 B是单独包含的,假设是全局的,我在构建步骤中做了一个肮脏的替换,将require(“B”)替换为global.B,使它工作得很好 C是什么导致了我的问题,虽然它的大小应该是“8K”,但当我尝试将它与A捆绑在一起时,我的捆绑会跳到600K+,因为我假设它有大量的依赖性 这是不可接受的,但我不知道如何让它变小,因为我不知道它到底拉了什么(或者更重要的是,我可以排除什么使它仍然工作)。我可以试着用二元切块,但我不知道这样做是安全的还是明智的 我怎样才能把C打包成68.5K(两个代码块的总大小都是60k+8.5K)的包,当然还能用 我是node和browserify的新手,但我已经花了一个多星期的时间来研究这个问题,可以说我在举手之前已经尝试过了 其他重要信息:Reactjs 当使用第三方产品时,如何保持Browserify捆绑包大小合理(如果重要,通过grunt),reactjs,browserify,commonjs,grunt-browserify,Reactjs,Browserify,Commonjs,Grunt Browserify,我正在尝试将我自己的代码(A)捆绑起来,这又使用了两个第三方组件(B和C),其中C也需要B。据我所知,所有内容都是使用CommonJS节点样式模块编写的 当bundled以60K的价格推出时,A将独立运行 B是单独包含的,假设是全局的,我在构建步骤中做了一个肮脏的替换,将require(“B”)替换为global.B,使它工作得很好 C是什么导致了我的问题,虽然它的大小应该是“8K”,但当我尝试将它与A捆绑在一起时,我的捆绑会跳到600K+,因为我假设它有大量的依赖性 这是不可接受的,但我不知道
- 它需要运行服务器端和客户端
- B实际上是JS
- C实际上是React路由器组件
- 通过ReactJS.net使用windows和c#嘿…等等…回来…风滚草
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'))
})
其他人已经提到了外部选项,它应该是实际的解决方案。现在,也要考虑这些建议。你可能已经知道了大部分(如果不是全部的话),但其中一些可能会有所帮助。这不会将600k文件转换为1k文件,但可能会非常重要 首先检查中的高级选项,更具体地说是--no bundle external选项。如果外部选项与require('b')一起工作,但仍然包括外部库,那么这是您的最佳选择 此外,还可以查看有关全局变量的选项。当我开始使用browserify时,我将一个函数编译成一个巨大的库,因为它包含NodeJS本机模块的所有存根。上述选择是解决这一问题的关键。它在Grunt任务中,但如果我没记错的话,它与Grunt browserify任务无关,它可能仍然相关 如果尚未设置生成环境,请在运行browserify:app之前设置生成环境。有些库的产品编译依赖于这些变量(我认为React就是其中之一) 试着用这些选项运行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是单独包含的,假设是全局的,我在构建步骤中做了一个肮脏的替换,将require(“B”)替换为global.B,使它工作得很好
如果您在编译后切换到global.B,那么您的包也将具有require('B')的所有依赖项。这种黑客(可能)更好:
- 去
- CTRL+F“重新映射”
- 实现它,使其指向b-singleton.js
- b-singleton.js内容:
module.exports = window.B;
查看生成的库的源代码,您应该能够识别不同的模块及其文件路径。我提供了一个工作示例,说明如何使用Browserify将代码拆分为多个捆绑包: 使用这种方法,您可以通过Browserify加载所有供应商代码(无需全局填充),但仍然可以单独绑定自己的代码
由于生成的bundle是真正独立的,因此您可以轻松地对生成的bundle进行不同的设置。例如,您可能希望禁用第三方代码的源映射,但要为自己的代码使用源代码映射。通过运行以下命令,您可以看到哪些文件占用了捆绑包中的空间:
browserify--list test/browser/browserify-test-uncompiled.js | xargs ls-la | sort
将需要您用于捆绑代码的代码/命令的更多详细信息。我将我的代码绑定到2个文件中,libraries.js和application.js,我可以将application.js文件保留为真正的自定义应用程序代码。相关问题,似乎是React路由器组件引用React内部模块的问题,导致htem被拉到我的绑定包中:我一直在玩External,我的问题仍然是捆绑包的总体大小。60万美元,我认为应该只有1/8,这让我有些头疼。拥有540K的externals和60K的my bundle仍然需要向客户端发送大量代码:(600KB听起来对未统一的React加上一些其他依赖项是合适的。作为参考,未统一的是~933KB。使用process.env.NODE_env='production'
,用于生产构建的envify转换和UglifyJS,缩小到~344KB,通过连线压缩到~120KB。我知道,但它应该已经可用了e通过单独的客户端注入服务器端。希望避免造成问题的“双重打击”。听起来像是你在追求的,但我以前没有在依赖项的依赖项上使用过它,
module.exports = window.B;