module.exports = {
//...
module: {
noParse: /jquery|lodash/, //不去解析jquery | lodash 中的依赖库
}
};
复制代码
若是js中引入jquery, webpack会去解析jq中是否有依赖库,配置noParse
后打包时候忽略解析配置的库,提升打包效率。javascript
module:{
rules:[
{
test:/\.js$/,
exclude:/node_modules/, // 解析不包含的目录,二者写其一便可
include:path.resolve('src'), // 即系包含的目录,二者写其一便可
use:{
loader:'babel-loader',
options:{
presets:[
'@babel/preset-env',
'@babel/preset-react'
...
复制代码
exclude
排除目录不进行解析。html
IgnorePlugin
是 webpack
内置插件,能够忽略第三方包不进行打包java
举例:node
moment包react
好比引入第三方依赖库moment
, 该库主要是对时间进行格式化,而且支持多个国家语言。jquery
moment打包问题webpack
import moment from 'moment'
//设置语言
moment.locale('zh-cn');
let r = moment().endOf('day').fromNow();
console.log(r);
复制代码
虽然只设置了一种语言,可是在打包的时候,moment
会将全部语言引入。这样就致使包很大,打包速度又慢 。 咱们须要把其余不须要的与语言包剔除 而moment
的包含./locale/
该字段路径的文件目录就是各国语言的目录,好比./locale/zh-cn
就是中文语言web
IgnorePlugin使用npm
let Webpack = require('webpack');
plugins:[
new Webpack.IgnorePlugin(/\.\/locale/,/moment/)
]
复制代码
若是在moment
中引入了./locale
目录的内容,会忽略掉 传递给IgnorePlugin
的第一个参数resourceRegExp
参数并不针对导入或必需的已解析文件名或绝对模块名进行测试,而是针对在导入发生的源代码中传递给require或import的字符串进行测试。例如,若是您试图排除node_modules/moment/locale/*.js
,这是行不通的 使用第二个contextRegExp
参数选择导入发生的特定目录。下面的代码将致使这些locale文件被忽略json
问题存在与解决
若是上述方法忽略了./locale/
的目录,那么全部语音都会被忽略,若是须要引入中文,须要手动配置
import moment from 'moment'
//手动引入所须要的语言包
import 'moment/locale/zh-cn';
moment.locale('zh-cn');
let r = moment().endOf('day').fromNow();
console.log(r);
复制代码
场景举例: 当打包一个react项目的时候,项目中引入reacr
和react-dom
两个包,而这两个库很大且基本不会变,每次项目打包都会对打包,浪费时间和性能。
处理方法: 将react和react-dom单独打包好,而后动态连接引入便可。若是第二次打包,那么发现react和react-dom已经被打包好了,那么直接找到打包好的文件,不须要再次打包。
实现
src 下 index.js 文件引入 react
和react-dom
import React from 'react'
import {render} from 'react-dom'
render('<h1>jsx</h1>')
复制代码
src 下建立 test.js
文件
module.exports = 'joker';
复制代码
建立webpack.config.react.js
对react
包单独打包
let path = require('path');
let webpack = require('webpack');
module.exports = {
mode:'development',
entry:{
react:['react','react-dom']
},
output:{
filename:'_dll_[name].js',//产生的文件名_dll_react.js
path:path.resolve(__dirname,'dist'),
library:'_dll_[name]',//_dll_react //
// libraryTarget:'var',
},
plugins:[
new webpack.DllPlugin({
name:'_dll_[name]',//这个name要与output中的library同名
path:path.resolve(__dirname,'dist','manifest.json')
})
]
}
复制代码
打包出一个_dll_react.js
和一个是清单manifest.json
而后在index.html去引用这个打包后的文件
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="/_dll_react.js"></script>
</body>
</html>
复制代码
可是如今,咱们引用react
或react-dom
的时候,咱们须要判断是否在清单里,这时候,咱们就须要在咱们正式的webpack.config.js里进行配置, 须要使用到webpack内置插件webpack.DllReferencePlugin
let path = require('path');
let webpack = require('webpack');
let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devServer:{
port:3000,
open:true,
contentBase:'./dist'
},
mode:'development',
entry:'./src/index.js',
output:{
filename:'bundle.js',
path:path.resolve(__dirname,'./dist')
},
module:{
rules:[
{
test:/\.js$/,
use:{
loader:'babel-loader',
options:{
presets:[
'@babel/preset-env',
'@babel/preset-react'
]
}
}
}
]
},
plugins:[
new webpack.DllReferencePlugin({
manifest:path.resolve(__dirname,'dist','manifest.json')
}),
new HtmlWebpackPlugin({
template:'./src/index.html',
filename:'index.html'
})
]
}
复制代码
场景举例: 当多页应用重复使用部分公用代码时,每次单页都会重复加载这些公用代码会形成一下问题: 相同资源,重复加载,增长用户流量和服务器成本
处理方法: 那么,若是将这些公共代码抽取出来,并让浏览器缓存起来,用户在请求资源的时候,能够直接读取缓存中的这些代码,这样就能解决以上问题。
如何抽取公共代码: 如今存在以下文件结构
other.js
↑
-------------
↑ ↑
a.js b.js
↓ ↓
-------------
↓
index.js
复制代码
如上图,index.js
和other.js
都依赖了a.js
和 b.js
,那么只须要将 a.js
和b.js
抽离出来并打包成common.js
,而后让index.js
和other.js
直接引用common.js
便可.
1.webpack.config.js配置 使用optimization的splitChunks属性
module.exports = {
optimization:{
splitChunks:{//分割代码块,若是只有一个入口,就不须要分割了,只有多页,才须要把公共的抽离出来
cacheGroups:{//缓存组
common:{//公共的模块
chunks:'initial',//刚开始就要抽离
minSize:0,//大小大于0字节的时候须要抽离出来
minChunks:2,//重复2次使用的时候须要抽离出来
}
}
}
},
...
}
复制代码
npm run build获得的文件为:
dist
|
----- common~index~other.js
|
----- index.js
|
----- other.js
|
----- index.html
复制代码
这样,index.js
和other.js
都引用了抽离出来的公共代码common~index~other.js
如何抽离第三方库 假设在上面的基础上,index.js 和 other.js都引用了jquery库,那么这样来配置抽离第三方库 vendor属性的配置,是用于抽取第三方库的(详看代码和注释)
module.exports = {
optimization:{
splitChunks:{ //分割代码块,若是只有一个入口,就不须要分割了,只有多页,才须要把公共的抽离出来
cacheGroups:{ //缓存组
common:{ //公共的模块
chunks:'initial',
minSize:0,
minChunks:2,
},
vendor:{ test:/node_modules/,//把这个目录下符合下面几个条件的库抽离出来
chunks:'initial',//刚开始就要抽离
minSize:0,//大小大于0字节的时候须要抽离出来
minChunks:2,//重复2次使用的时候须要抽离出来
}
}
}
},
...
}
复制代码
可是这样会存在问题——代码从上到下执行,会先执行common,而后执行vendor,而在执行common的时候,就把jquery抽离出来打包到跟a.js和b.js里面去了,后面的vendor就没有什么效果了。这并非个好方案,咱们最好是可以将库单独抽离出来,因而,能够这么操做: 在vendor添加权重属性:priority,将权重提升,使得先去抽离第三方库,再去抽离a.js和b.js
module.exports = {
optimization:{
splitChunks:{//分割代码块,若是只有一个入口,就不须要分割了,只有多页,才须要把公共的抽离出来
cacheGroups:{//缓存组
common:{//公共的模块
chunks:'initial',
minSize:0,
minChunks:2,
},
vendor:{
priority:1,//添加权重
test:/node_modules/,//把这个目录下符合下面几个条件的库抽离出来
chunks:'initial',//刚开始就要抽离
minSize:0,//大小大于0字节的时候须要抽离出来
minChunks:2,//重复2次使用的时候须要抽离出来
}
}
}
},
...
}
复制代码
打包结果为
common~index~other.js 579 bytes
index.html 388 bytes
index.js 7.38 KiB
other.js 7.38 KiB
vendor~index~other.js 306 KiB
复制代码