Webpack 2021-8-30
Tree Shaking
tree shaking:去除无用代码
前提:1.必须使用es6模块化
2.开启production环境
作用:减少代码体积
在package.json中配置
“sideEffects”:false 所有代码都没有副作用(都可以进行tree shaking)
问题:可能会把css/@babel/polyfill(副作用)文件干掉
“sideEffects”:["*.css"]
code split 代码分隔
webpack.config.js
//单入口
//entry:'./src/js/index.js'
entry: {
//多入口:有一个入口,最终输出就有一个bundle
index:'./src/js/index.js',
test:'./src/js/test.js'
},
/*
* 1.可以将node_modules中代码单独打包成一个chunk最终输出
* 2.自动分析多入口chunk中,有没有公共的文件,如果有会打包成单独一个chunk
* */
optimization:{
splitChunks:{
chunks:'all'
}
},
test.js
export function mul(x,y) {
return x+y
}
export function count(x,y) {
return x-y
}
index.js
/*
* 通过js代码,让某个文件被单独打包成一个chunk
* import动态导入语法:能将某个文件单独打包
* */
import(/*webpackChunkName:'test'*/'./test')
.then(({mul,count})=>{
//文件加载成功~
//eslint-disable-next-line
console.log(mul(2,5))
})
.catch(()=>{
//eslint-disable-next-line
console.log('文件加载失败')
})
console.log(count(1,2,3,4))
懒加载和预加载
index.js
console.log('index.js文件被加载了~')
document.getElementById('btn').onclick = function () {
//懒加载~:当文件需要使用时才加载~
//预加载 prefetch:会在使用之前,提前加载js文件
//正常加载可以认为是并行加载(同一时间加载多个文件、
//预加载:prefetch:等其他资源加载完毕,浏览器空闲了,再偷偷加载资源
import(/*webpackChunkName:'test',webpackPrefetch:true */'./test').then(({mul})=>{
console.log(mul(4,5))
})
}
PWA
离线访问功能
npm i workbox-webpack-plugin --s
webpack.config.js
const WorkboxWebpackPlugin = require('workbox-webpack-plugin')
plugins: [
new WorkboxWebpackPlugin.GenerateSW({
/*
* 1.帮助serviceworker快速启动
* 2.删除旧的serviceworker
*
* 生成一个serviceworker配置文件
* */
clientClaim:true,
skipWaiting:true
})
],
index.js
import {mul} from './test'
import '../css/index.css'
function sum(...args) {
return args.reduce((p, c) => p + c, 0)
}
//eslint-disable-next-line
console.log(mul(2, 3))
//eslint-disable-next-line
console.log(sum(1, 2, 3, 4))
/*
* 1.eslint不认识window、navigator全局变量
* 解决:需要修改package.json中eslintConfig配置
* "env":{
* "browser":true // 支持浏览器端全局变量
* }
*
* 2.sw代码必须运行在服务器上
* --> nodejs
* -->
* npm i serve -g
* serve -s build 启动服务器,将build目录下所有资源作为静态资源暴露出去
* */
//注册serviceworker
//处理兼容性问题
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker
.register('/service-worker.js')
.then(()=>{
console.log('sw注册成功了')
})
.catch(()=>{
console.log('sw注册失败了')
})
})
}
多进程打包
npm i thread-loader -s
{
test: /\.js$/,
exclude: /node_modules/,
use: [
/*
* 开启多进程打包
* 进程启动大概为600ms,进程通信也有开销。
* 只有工作消耗时间比较长,才需要多进程打包
* */
{
loader:'thread-loader',
options: {
workers:2//进程2个
}
},
{
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: {version: 3},
target: {
chrome: '60',
firefox: '50'
}
}
]
],
//开启babel缓存
//第二次构建时,会读取之前的缓存
cacheDirectory: true
}
}
],
//优先执行
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true
}
},
externals
webpack.config.js
const {resolve} = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/built.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'production',
externals:{
//拒绝jQuery被打包进来
jquery:'jQuery'
}
}
built.js
import $ from 'jquery'console.log($)
index.html
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><h1 id="title">hello html</h1><script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script><script type="text/javascript" src="js/built.js"></script></body></html>
dll
webpack.config.js
/** 使用dll技术,对某些库(第三方库:jquery,react,vue...)进行单独打包* 当你运行webpack时,默认查找webpack.config.js 配置文件* 需求:需要运行webpack.dll.js 文件* --> webpack --config webpack.dll.js* */const {resolve} = require('path')const HtmlWebpackPlugin = require('html-webpack-plugin')const webpack = require('webpack')const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin')module.exports = { entry: { //最终打包生成的[name] --> jquery //['jquery'] --> 要打包的库时jquery jquery: ['jquery'] }, output: { filename: '[name].js', path: resolve(__dirname, 'dll'), library: '[name]_[hash]',//打包的库里面向外暴露出去的内容叫什么名字 }, plugins: [ //打包生成一个manifest.json --> 提供和jquery映射 new webpack.DllPlugin({ name: '[name]_[hash]', //映射库的暴露的内容名称 path: resolve(__dirname, 'dll/manifest.json') // 输出文件路径 }), //告诉webpack哪些库不参与打包,同时使用时的名称也得变 new webpack.DllReferencePlugin({ manifest: resolve(__dirname, 'dll/manifest.json') }), //将某个文件打包输出出去,并在html中自动引入该资源 new AddAssetHtmlWebpackPlugin({ filepath:resolve(__dirname,'dll/jquery.js') }) ], mode: 'production'}
webpack性能优化
开发环境性能优化
生产环境性能优化
开发环境性能优化
优化打包构建速度
HMR
优化代码调试
source-map
生产环境性能优化
优化打包构建速度
oneOf
babel缓存
externals
dll
优化代码运行的性能
缓存(hash-chunkhash-contenthash)
tree shaking
code split
懒加载/预加载
pwa