目录
1、noParse
2、IgnorePlugin
3、DllPlugin 动态链接库
4、happypack 多线程打包
5、splitChunks 抽离公共
6、动态加载、懒加载
像jquery这样的第三方插件,没有依赖其他模块的模块,可以设置免编译,
设置方法:webpack.config.js module下设置
module.exports = {
...
module:{
noParse:/jquery/
}
}
这个是webpack内置插件,不需要安装。
作用是:忽略第三方包指定目录,让这些指定目录不要被打包进去。
比如 moment 包,针对时间格式化的包,并且支持多个国家的语言,而我们只需要中文的依赖包,不需要将所有国家的语言包都打进去,就需要这样设置:
let Webpack = require('webpack');
plugins:[
new Webpack.IgnorePlugin(/\.\/locale/,/moment/),//moment这个库中,如果引用了./locale/目录的内容,就忽略掉,不会打包进去
]
但是这样的问题是,中文包也没有了,就需要我们手动引入啦
import moment from 'moment'
//设置语言
//手动引入所需要的语言包
import 'moment/locale/zh-cn';
moment.locale('zh-cn');
let r = moment().endOf('day').fromNow();
console.log(r);
把第三方库抽离出来,不用每次打包都打,比如 react、react-dom,我们可以把这俩个独立打包,开发的时候,引用打包好的文件。
步骤:
1)新建 webpack.config.react.js 文件,配置单独打包
let path = require('path')
let webpack = require('webpack')
module.exports = {
mode:'development',
entry:{
react:['react','react-dom'],
},
output:{
filename:"_dll_[name].js", //产生的文件名
path:path.resolve(__dirname,'dist'),
library:"_dll_[name]", //把结果返回到这样一个变量上 _dll_react
// libraryTarget:"var" // common var this...
},
plugins:[
new webpack.DllPlugin({ // name == library
name:"_dll_[name]",
path:path.resolve(__dirname,'dist','manifest.json')
})
]
}
2) 运行我们刚刚写的配置文件
npx webpack --config webpack.config.react.js
这样,在dist文件夹中,会打包出2个文件,分别是:_dll_react.js 和 manifest.json
3) webpack.config.js 中,引用打包好的 dll 文件
module.exports = {
...
plugins:[
new webpack.DllReferencePlugin({
manifest:path.resolve(__dirname,'dist','manifest.json')
})
]
}
index.html 模板页面中,手动引入
多线程打包,更适合大型项目
安装插件
yarn add happypack -D
配置 js 多线程打包
const HappyPack = require('happypack');
module.exports = {
...
module: {
rules: [
test: /\.js$/,
// use: ['babel-loader?cacheDirectory'] 之前是使用这种方式直接使用 loader
// 现在用下面的方式替换成 happypack/loader,并使用 id 指定创建的 HappyPack 插件
use: ['happypack/loader?id=js'],
exclude: /node_modules/
]
},
,
plugins: [
...,
new HappyPack({
id: 'js', // id 标识符,要和 rules 中指定的 id 对应起来
// 需要使用的 loader,用法和 rules 中 Loader 配置一样
// 可以直接是字符串,也可以是对象形式
use:[
{
loader:'babel-loader',
options:{
presets:[
'@babel/preset-env',
'@babel/preset-react'
]
}
}
]
})
]
}
同样,也可以配置css 多线程打包
module: {
rules: [
test: /\.css$/,
use: ['happypack/loader?id=css'],
exclude: /node_modules/
]
},
plugins: [
...,
new HappyPack({
id: 'css',
use:[
'style-loader','css-loader'
]
})
]
多页多入口应用,引用了公共代码,可以用splitChunks做抽离公共代码
操作:
module.exports = {
optimization:{
splitChunks:{ //分割代码块
cacheGroups:{ //缓存组
common:{ // 公共的模块
chunks:'initial', // 入口
minSize:0,//要抽离的代码的大小
minChunks:2, // 被几个模块共用 才抽离
},
vendor:{ // 抽离第三方模块
priority:1, // 优先级 先抽离第三方 再抽离其他
test:/node_modules/,
chunks:'initial', // 入口
minSize:0,//要抽离的代码的大小
minChunks:2, // 被几个模块共用 才抽离
}
}
}
}
}
es6 语法 ,用import动态加载文件,实现的原理是jsonp,vue的路由懒加载也是一样的道理
let play = document.getElementById('play');
play.addEventListener('click',()=>{
import(/* webpackChunkName:'video',webpackPrefetch:true */'./video.js').then(data=>{
console.log(data.default)
})
})
document.body.appendChild(button)
在此说明一下 preload 和 prefetch 的区别
preload :预加载,需要提前加载,会影响性能;
prefetch:预获取,会在浏览器空闲的时候获取,不影响性能
不支持的话,可能需要安装一个插件:
yarn add @babel/plugin-syntax-dynamic-import -D
然后,需要webpack.config.js 中配置一下
module.exports = {
...
module: {
rules: [
test: /\.js$/,
use:[
{
loader:'babel-loader',
options:{
presets:[
'@babel/preset-env',
'@babel/preset-react'
],
plugins:[
'@babel/plugin-syntax-dynamic-import'
]
}
}
],
exclude: /node_modules/
]
}
}