背景
在项目中用webpack打包时,通常会将自己写的业务逻辑代码和第三方库的js文件一起打包成一个js文件,这样的话这个文件就会很大,对项目的运行速率影响很大。而且,我们在打包时每次都会将第三方库文件重新打包一次,但是往往这样是没有必要的,因为第三方往往是不会发生很大改变的,只是可能会需要升级一下。所以在这里,将第三方库文件和自己写的js文件分开打包还是很有必要的,这里总结一下目前用得最多的两种方法。
利用react官网的脚手架创建一个例子
按照下面几个步骤就可以创建一个小demo
- npm add create-react-app
- create-react-app myapp
- cd myapp
- npm start
运行完这几步后,恭喜你成功创建了一个react小例子,接下来需要做的就是如何使用webpack来打包这个demo。
在myapp下创建webpack.base.config.js文件
在文件中写基本的配置如下:
const path = require('path')
const webpack = require('webpack')
function resolve(relatedPath) {
return path.join(__dirname, relatedPath)
}
module.exports = {
entry: {
index: resolve('../myapp/src/index.js')
},
output: {
path: resolve('../myapp/dist'),
filename: '[name].[hash:4].js',
chunkFilename: 'chunks/[name].[hash:4].js',
},
resolveLoader: {
moduleExtensions: ['-loader']
},
module: {
rules: [
{
test: /\.js[x]?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react', 'es2015', 'stage-0']
}
},
{
test: /\.css/,
loader: 'css'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url',
options: {
limit: 8192,
name: 'img/[name].[hash:4].[ext]'
}
},
{
test: /\.html$/, //静态资源
loader: 'html',
}
],
}
}
package.json文件的配置内容如下:
"dependencies": {
"react": "^16.5.0",
"react-dom": "^16.5.0",
"webpack": "~3.10.0"
},
"devDependencies": {
"babel-core": "~6.26.0",
"babel-eslint": "~8.2.1",
"babel-loader": "~7.1.2",
"babel-plugin-import": "^1.8.0",
"babel-plugin-transform-decorators-legacy": "~1.3.4",
"babel-plugin-transform-runtime": "~6.23.0",
"babel-preset-env": "^1.6.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"css-loader": "~0.28.9",
"url-loader": "~0.6.2"
}
使用npm install或yarn install就可以将需要的工具都加载好
修改package.json中scripts中的内容
在上面的package.json文件中将build的内容改成
"build": "webpack --config webpack.base.config.js"
然后npm build和yarn build均可,这样就使用webpack打包了react官网的例子
分析
首先看一下这个小demo的文件目录
自己的业务逻辑是src中的文件,而第三方库是在node_modules中,我们就需要将这两个分开打包,因为node-modules相对于自己的js文件是很大的,下面介绍一下两种分开打包的方法。
使用CommonsChunkPlugin
这个方法会使我们的第三方库文件在打包的时候和自己的业务逻辑分开,也很简单,主要是路径要写对,就像下面这样在你的配置文件中添加即可
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendors',
filename: '[name].[hash:4].js'//生成的vendors文件就是以这样的形式命名
}),
]
在webpack.base.config.js的入口文件中增加
vendors: ['react', "react-dom"]//指的是想将什么第三方文件库进行分开打包
这样就可以实现分开打包的功能了,是不是很简单,当然简单一点,必然也是有缺点的,至于缺点是啥,就接着往下看咯!
使用DllPlugin
这个插件比CommonsChunkPlugin更复杂一些,当然也好一些,而且要配合.DllReferencePlugin使用,使用DllPlugin需要单独创建一个配置文件,我们叫它webpack.dll.config.js文件,在这个文件中我们需要放置这些内容:
const webpack = require('webpack')
const path = require('path')
function resolve(relatedPath) {
return path.join(__dirname, relatedPath)
}
module.exports = {
entry: {
vendors: ['react', "react-dom"]//需要打包的第三方库文件
},
output: {
filename: '[name].[chunkhash:4].js',//生成的文件名
path: resolve('../myapp/dist'),//生成的文件存放的路径
library: '[name]_[chunkhash:4]'//决定了manifest中的格式
},
plugins: [
new webpack.DllPlugin({
path: resolve('../myapp/dist/manifest.json'),
name: '[name]_[chunkhash:4]',//生成的第三方库文件, 要和上面的library一致
context:__dirname
}),
],
}
在webpack.dll.config.js放置这些过后还要在webpack.base.config.js中放置它的搭档插件
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,//上下文关系
manifest: require('./dist/manifest.json')//生成的索引表
}),
],
完成这两步后要给package.json文件中scripts中的内容添加一条
"webpack": "webpack --config webpack.dll.config.js"
然后运行yarn webpack,再运行yarn build就可以看到生成如下的文件目录
生成了三个文件,自己写的代码打包后的是index.js,第三方是vendors.js,而manifest则是这两个的桥梁,是用来联系index.js和vendors.js的。
点开文件夹你会发现js文件会变小很多,而vendors.js会大很多,这样就是分离成功了。
总结
这两个插件都可以实分开打包的功能,前者较后者比较简单,后者比前者更高效,高效体现在后者是在编译的过程就将两者分开了,即可以只编译自己写的代码,也可以调用vendors.js中的第三方库;而前者是在打包的时候将两者分开,这样看的话还是后者更加高效。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。