目录
1. 简介
Webpack 是 前端资源打包工具,它会根据模块之间的依赖关系进行静态分析,将模块按照指定的规则生成对应的静态资源。
webpack会从入口文件开始打包,先形成依赖关系图,根据依赖图把不同的资源引进来形成一个chunk代码块, 然后根据chunk根据不同的资源进行处理,比如: less => css, 这个处理过程就是 打包,打包之后输出去,输出去的文件 就是 bundle。
Webpack 处理是会构建出一个依赖图,该依赖图映射项目所需的每个模块,并将多种静态资源 js、css、less 转换成一个静态文件bundle.js,减少了页面的请求。
从 v4.0.0 开始,webpack 可以不用再引入一个配置文件来打包项目,然而,但它仍然有着 高度可配置性
1. Entry 入口
入口指示Webpack 以哪个文件为起点开始打包,分析构建内部 依赖图(dependency graph) 。默认是 './src/index.js', 可以通过配置指定 entry 属性,指定一个或多个 入口起点。
webpack.config.js
module.exports = {
entry: './src/index.js'
}
2. Output
输出指示Webpack打包后的资源bundle 输出到哪里去,以及如何命名。
3. Loader
Loader 让 Webpack 能够去处理那些非 JavaScript 文件(Webpack 自身只理解JavaScript),把文件转成 webpack可以识别的 js 文件。
4. Plugins
插件(plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等。
5. Model
通过选择 development
, production
或 none
之中的一个,来设置 mode
参数,你可以启用 webpack 内置在相应环境下的优化。其默认值为 production
。
2. webpack 体验
1. 新建文件夹, npm init
2. 引入 webpack webpack-cli, 先 -g 全局引入(这样可以直接用 webpack-cli 的命令),再 -D 引入
npm webpack webpack-cli -g
npm webpack webpack-cli -D
3. 新建代码文件夹 src, 打包输出的文件夹 build
新建 index.js 入口文件
function add(x, y) {
return x+y;
}
console.log(add(1,2));
/**
* index,js: webpack 入口起点文件
* 1. 运行指令
* 开发环境: webpack ./src/index.js -o ./build/built.js --mode=development
* webpack会以 ./src/index.js 为入口文件开始打包,打包输出到 ./build/built/main.js
* 整体打包环境,是开发环境
*
* 生产环境:webpack ./src/index.js -o ./build/built.js --mode=production
* webpack会以 ./src/index.js 为入口文件开始打包,打包输出到 ./build/built/main.js
* 整体打包环境,是生产环境
*/
1. 开发环境控制台 输入 指令:
webpack ./src/index.js -o ./build/built.js --mode=development
会生成built.js/main.js, main.js里面是 打包的内容
main.js 文件 eval 函数 包含了 index.js 的所有内容,包括注释。
2. 生产环境控制台 输入 指令:
webpack ./src/index.js -o ./build/built.js --mode=production
文件 main.js 里面 是 webpack帮你压缩好的 代码了,我的是 webpack5, 好家伙,直接剩下一个运行语句
3.node 运行这个文件,输出 3
node .\build\built.js\main.js
结论:
1. webpack 能处理 js/json文件,不能处理css/img等其他资源
2. 生产环境和开发环境将 ES6 模块化编译成浏览器能识别的模块化
3. 生产环境比开发环境多一个压缩 js 代码。
3. webpack 打包样式资源
src 文件夹 下建 index.js(入口文件), index.css 样式文件, index.less 样式
build 文件夹,建 index.html
根目录新建一个 webpack.config.js 文件
初始配置模板:
/**
* webpack.config.js webpack的配置文件
*
* 作用: 指示webpack 干哪些活( 当运行 webpack 指令时,会加载里面的配置)
*
* 所有构建工具都是基于 node.js 平台运行的 —— 模块化默认采用 common.js
*/
// resolve 用来拼接绝对路径的方法
const { resolve } = require('path');
module.exports = {
// 入口
entry: './src/index.js',
// 输出
output: {
// 输出文件名
filename: 'built.js',
// 输出路径,绝对路径
// __dirname nodejs的变量,代表当前文件的目录绝对路径
path: resolve(__dirname, 'build')
},
// loader 的配置
module: {
rules: [
// 详细 loader 配置
// 不同文件必须配置不同loader 配置
{
// test 匹配哪些文件
test: /\.css$/,
//使用哪些 loader 进行处理
use: [
// use 数组中 loader 执行顺序: 从右到左,从下到上,依次执行
// 创建style 标签,将 js 中的样式资源插入进去,添加到 head 中生效
'style-loader',
// 将css文件变成commonjs模块加载 js 到中,里面内容是样式字符串
'css-loader'
]
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
// 将less文件编译成 css文件
'less-loader'
]
}
]
},
// plugins 的配置
plugins: [
// 详细 plugins 的配置
],
// 模式
mode: 'development', // 或 'production'
}
注意:__dirname 是两个 _ , 写少一个 bug找半天
控制台输入 webpack 即可 运行打包,并且 index.css的样式 生效于 index.html中
4. 打包 html资源
/**
* loader : 1.下载 2. 使用(配置loader)
* plugins: 1. 下载 2. 引入 3. 使用
*/
plugins 引入 html-webpack-plugins
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: []
},
plugins: [
// html-webpack-plugin
// 功能: 默认会创建一个空的 html,自动引入打包输出的所有资源(JS/CSS)
// 需要有结构的html文件
new HtmlWebpackPlugin({
// 复制 ./src/index.html 文件, 并自动引入打包输出的所有资源(JS/CSS)
template: './src/index.html'
})
],
mode: 'development'
}
5. 打包图片资源
webpack5 自带图片处理,可以直接使用 assets Module, webpack4 的话 就要 加上 url-loader, 有的还需要 加 file-loader.
在index.less 文件中 引入 图片
body,html {
margin: 0;
padding:0;
}
.one {
height: 100px;
width: 200px;
background-image: url('./1.jpg');
background-repeat: no-repeat;
background-size: 100% 100%;
}
.tow {
height: 200px;
width: 200px;
background-image: url('./2.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
.three {
height: 300px;
width: 300px;
background-image: url('./3.jpg');
background-repeat: no-repeat;
background-size: 100% 100%;
}
index.html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>打包图片资源</title>
</head>
<body>
<div id="app">
<div class="one"></div>
<div class="tow"></div>
<div class="three"></div>
<img src="./1.jpg" alt="图片">
</div>
</body>
</html>
url-loader: webpack5的 不用 加该loader, webpack5会自动处理.
{
// 处理图片资源
test: /\.(jpg|png|gif)$/,
// 下载url-loader file-loader
loader: 'url-loader',
options: {
// 图片大小小于 300kb, 就会被 base64处理
// 优点:减少请求数量(减轻服务器压力)
// 优点: 图片体积会更大(文件请求速度更慢)
limit: 200 * 1024,
// 问题: 因为url-loader默认使用 es6 模块化解析,而 html-loader 引入图片是 commonjs
// 解析时会出现问题: [object Module]
// 解决: 关闭 url-loader 的 es6 模块化, 使用 commonjs 解析
esModule: false,
// 给图片进行重命名(没必要)
// [hash:10] 取图片的hash 的前 10位
// [ext] 取文件原来扩展名
// name: '[hash:10].[ext]'
}
}
html-loader: 处理html文件的img 图片(负责引入img,从而被 url-loader 进行处理)
{
test: /\.html$/,
// 处理html文件的img 图片(负责引入img,从而被 url-loader 进行处理)
loader: 'html-loader'
}
6. 打包其他资源
同样 webpack 5 会自动处理或用 asset Module 处理,不需要另外加 url-loader
以 引入 iconfont 字体库 为例
webpack5:
module.exports = {
........
..........
............
{
// 处理图片资源 webpack5图片新打包方法
test: /\.(jpg|png|gif)$/,
// webpack5中使用assets-module(url-loader已废弃)
type: 'asset/resource',
parser: {
dataUrlCondition: {
maxSize: 10 * 1024
}
},
generator: {
filename: 'img/[name].[hash:6][ext]',
publicPath: './'
}
},
...
...
}
index.js 引入 iconfont.css
webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin")
const { resolve } = require('path')
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build'),
},
module: {
rules:[
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
}
webpack4: 需要加上 url-loader
// 打包其他资源( 除了 html/css/js 资源以外的资源
{
// 排除css/js/html资源
exclude: /\.(css|js|html)$/,
loader: 'url-loader',
options: {
type: 'javascript/auto',
esModule: false,
}
}
7. devserve 热更新
下载 webpack-dev-server
// 开发服务器 devServer: 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~)
// 特点: 只会在内存中编译打包,不会有任何输出
// 启动 devServer 指令:
webpack4: npx webpack-dev-server
webpack5: npx webpack server
const HtmlWebpackPlugin = require("html-webpack-plugin")
const { resolve } = require('path')
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build'),
},
module: {
rules:[
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development',
// 开发服务器 devServer: 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~)
// 特点: 只会在内存中编译打包,不会有任何输出
// 启动 devServer 指令为: npx webpack-dev-server
devServer: {
static: {
directory: resolve(__dirname, 'public')
},
// 启动gzip压缩
compress: true,
port: 9000,
// 启动后打开默认浏览器
open: true
}
}
8. 提取 css 成单独文件
下载 mini-css-extract-plugin
配置loader 和 plugin
loader:
module: {
rules: [
{
test: /\.css$/,
MiniCssExtractPlugin.loader,
'css-loader',
]
}
plugin:
plugins: [
new MiniCssExtractPlugin({
filename: 'css/built.css',
})
]
结果:
9. css兼容性处理
/** postcss-loader
* css 兼容性处理: postcss ---> postcss-loader postcss-preset-env
* 帮助 postcss 找到 package.json 中 browserslist 里面的配置,通过配置加载指定的css兼容性样式
*/
1. 设置 nodejs 环境变量
webpack.config.js 加上
process.env.NODE_ENV = 'development';
loader 中配置:webpack5
{
test: /\.css$/,
use: [
// 创建style标签,插入
// 'style-loader',
// 取代 style-loader, 提取js中的 css成单独文件
MiniCssExtractPlugin.loader,
// 将css文件 整合到js文件中
'css-loader',
// 使用默认配置
// 'postcss-loader'
// 需修改 postcss loader 配置
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
['postcss-preset-env',{}]
]
}
}
}
]
},
package.json 加上browserslist 配置
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
10. css 压缩
webpack4 用插件: optimize-css-assets-webpack-plugin
webpack5 用插件:css-minimizer-webpack-plugin
添加配置
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...`
// 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
// `...`,
new CssMinimizerPlugin(),
],
minimize:true,
},
webpack.config.js
const { resolve } = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
// 设置 nodejs 环境变量
process.env.NODE_ENV = 'development';
module.exports = {
entry: './src/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
// 取代 style-loader, 提取js中的 css成单独文件
MiniCssExtractPlugin.loader,
// 将css文件 整合到js文件中
'css-loader',
// 需修改 postcss loader 配置
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
['postcss-preset-env',{}]
]
}
}
}
]
},
{
test: /\.html$/,
loader: 'html-loader'
}
]
},
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...`
// 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
new CssMinimizerPlugin(),
],
minimize:true,
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/built.css', // 输出的内容重命名
}),
],
mode: 'development',
devServer: {
static: {
directory: resolve(__dirname, 'public')
},
// 启动 gzip压缩
compress: true,
port: 3000,
open: true,
}
}
11. js语法检查
webpack5 插件: eslint-webpack-plugin
webpack4 : eslint-loader (webpack5 已弃用)
webpack5
const ESLintWebpackPlugin = require('eslint-webpack-plugin');
............
...............
....................................
plugins: [
new ESLintWebpackPlugin({
fix: true,
}),
],
package.json 还需要加上 eslint 配置
"eslintConfig": {
"env": {
"browser": true
}
},
12. js 兼容性处理
如果代码没有做兼容性处理, 代码 根本无法在 IE浏览器正常运行,IE 不认识 ES6 、以及ES6以上的语法;
/**
* js兼容性处理: babel-loader @babel/core @babel/preset-env
* 1. 基本js 兼容处理 => @babel/preset-env
* 问题: 只能转换基本语法, 如 promise 高级语法不能转换
* 2. 全部js 兼容性处理 => @babel/polyfill, 直接在文件中 引入 即可使用
* 问题: 只要解决部分兼容性问题,不需要全部兼容性的代码全部引入,体积太大
* 3. 需要做兼容性处理: 按需引入 => core.js
*/
结合: babel-loader @babel/core 和 core.js 即可 解决 js兼容性问题
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 预设: 指示babel 做什么样的兼容性处理, 智能按需引入polyfill
presets: [['@babel/preset-env',{
// 按需加载
useBuiltIns: 'usage',
// 指定 core-js版本
corejs: {
version: 3
},
// 指定兼容哪个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}]]
},
}
]
}
13. js、html 压缩
// 生产环境下会自动压缩代码
mode: 'production',
html 压缩,直接配置 HtmlWebpackPlugin
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
// 压缩 html代码
minify: {
// 移除空格
collapseWhitespace: true,
// 移除空格
removeComments: true
}
})
]
14 生产环境基本配置
webpack.config.js
const { resolve } = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
process.env.NODE_ENV = 'production'
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins:[
[
'postcss-preset-env',
{
}
]
]
}
}
}
]
module.exports = {
entry: './src/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [...commonCssLoader]
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader']
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: { version: 3},
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
},
{
// 处理图片资源 webpack5图片新打包方法
test: /\.(jpg|png|gif)$/,
// webpack5中使用assets-module(url-loader已废弃)
type: 'asset/resource',
parser: {
dataUrlCondition: {
maxSize: 10 * 1024
}
},
generator: {
filename: 'img/[name].[hash:6][ext]',
publicPath: './'
}
},
{
test: /\.(eot|ttf|otf|woff2?)$/,
type: 'asset',
generator: {
filename: 'fonts/[name].[hash:8][ext]'
}
},
{
test: /\.html/,
loader: 'html-loader'
},
{
exclude: /\.(js|css|less|html|jpg|png|gif|eot|ttf|otf|woff2)$/,
loader: 'file-loader',
options: {
outputPath: 'media'
}
}
]
},
optimization: {
minimizer: [
new CssMinimizerWebpackPlugin()
],
minimize: true,
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true,
}
}),
// 提取css成单独文件
new MiniCssExtractPlugin({
filename: 'css/built.css'
}),
],
mode: 'production',
devServer: {
static: {
directory: resolve(__dirname, 'public')
},
compress: true,
port: 3000,
open: true,
// 当修改了 webpack配置,想要 新配置生效,必须要重新打包
hot: true,
}
}
15. 性能优化
webpack优化
开发环境性能优化
优化打包构建速度
* HMR
优化代码调试
*source-map
生产环境性能优化
优化打包构建速度
* oneOf
* babel缓存
* 多进程打包
*extrernals
*dll
优化代码运行速度
*文件资源缓存 (hash - chunkhash - contenthash)
hash 每次打包都会成功一个 hash 值
chunkhash 同一个chunkhash 共用一个 chunkhash 值
contenthash 一个内容文件一个 contenthash, 内容不变,contenthash不变
* tree shaking
*code split
*l懒加载/ 预加载
*pwa
16. HMR
HMR: hot module replacement 热模块替换 / 模块热替换
作用: 一个模块发生变化,只会重新打包这一模块(而不会打包所有模块)
极大提高构建速度
直接在 devServer配置 加上 hot: true
devServer: {
static: {
directory: resolve(__dirname, 'public')
},
compress: true,
port: 3000,
open: true,
// 当修改了 webpack配置,想要 新配置生效,必须要重新打包
hot: true,
}
样式文件:可以使用HMP 功能, 因为 style-loader 内部实现了
js文件:默认不能使用HMP功能
html文件:默认不能使用 HMP功能, 同时会导致问题,html 文件不能热更新了(不需要做HMP功能)
解决: 修改entry 入口,将html 文件引入
entry: ['./src/index.js', './src/index.html'],
17. source-map
source-map: 能提供 源代码 到 构建后代码的 映射 关系,通过映射追踪可以定位到具体代码出错的位置。
在webpack.config.js 中配置 devtool: 'source-map' 即可开启
可选值:[inline-|hidden-|eval_][nosources-][cheap-[module-]]source-map
module.exports = {
devtool: 'source-map',
}
开发环境下: 速度快,调试更友好
速度快(eval > inline > cheap....)
eval-cheap-source-map
eval-source-map
调试更友好
source-map
cheap-module-source-map
cheap-source-map
生产环境:源码要不要隐藏?调试要不要友好
内联会让代码体积变大,所以生产环境下不用内联
nosources-source-map 全部隐藏
hidden-source-map 只隐藏源代码,会提示构建后代码错误信息
--》source-map / cheap-module-source-map
18. oneOf
把loader 放到 oneOf下,oneOf 下的loader 只会匹配一个
// 注意: 不能有两个匹配处理同一种类型的文件,如有两个loader处理同一种类型文件( 如下两个loader 都处理 js 文件,把有限的一种 放在 oneOf外面),只需要把 有限处理的loader 放到 oneOf上面即可,
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
exforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true
}
},
{
oneOf: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: { version: 3},
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
},
]
}
],
},
19. 缓存
1. babel 缓存
cacheDirectory: true
--> 让第二次打包构建速度更快
在webpack中使用babel-loader是去为了兼容我们的js代码,将更高级的语法转译成浏览器所能识别语法,但是这个过程编译过程会很慢。
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: { version: 3},
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
],
// 开启babel缓存
// 第二次构建时,会读取之前的缓存
cacheDirectory: true
}
},
2. 文件资源缓存
hash: 每次webpack 构建时会生成一个唯一的 hash 值;
问题: 因为js 和 css 同时使用一个 hash 值。如果重新打包,会导致所有缓存失效(可能只改一个文件)。
chunkhash: 根据 chunk 生成的 hash 值。如果打包来源同一个 chunk,那hash值一样。
问题: js 和 css 的hash 值还是一样的,因为 css 是在 js 中被引入的,所有属于同一个 chunk.
contenthash: 根据文件的内容生成 hash 值。不同文件hash 值不同。 推荐使用。
输出js文件:取 contenthash 值 10位
output: {
filename: 'js/built.[contenthash:10].js',
path: resolve(__dirname, 'build')
},
提取的 css文件:取 contenthash 值 10位
plugins: [
// 提取css成单独文件
new MiniCssExtractPlugin({
filename: 'css/built.[contenthash:10].css'
}),
],
20. tree shaking
去掉没有用代码
前提: 1. 必须使用ES6模块化 2. 开启 production 环境
作用: 减少代码体积
在package.json 中配置
"sideEffect": false 所有代码都没有副作用,都可以进行tree shaking
问题: 可能会把css / @babel/polyfill 文件干掉
"sideEffects": ["*.css", "*.less"]
21. 代码分隔 code split
1. 多入口文件
有几个入口,就会生成 几个js文件
// 多入口
entry: {
main: './src/index.js',
test: './src/test.js'
},
2. module.exports中 配置 optimization
/**
* 1. 可以将 node_modules中代码单独打包成一个 chunk 最终输出
* 2. 自动分析多入口 chunk 中, 有没有公共的文件,如果有会打包成单独一个 chunk
*/
optimization: {
splitChunks: {
chunks: 'all',
},
// 将当前模块记录其他模块的hash 单独打包为一个文件 runtime
// 解决: 修改 test.js文件 导致 indexjs 文件的 contenthash 变化
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`
}
},
3. 通过js 代码单独打包
通过 js 代码,让某个文件被单独打包成一个 chunk
import 动态导入语法: 能将某个文件单独打包
import('./test.js')
.then(({ mul, count}) => {
// 文件加载成功
console.log(mul(2, 5))
console.log(count([1,2,3,4,5]))
}).catch(() => {
// 文件加载失败
})
22. 懒加载 lazy loading
懒加载: 当文件需要使用时才加载
预加载 prefetch:会在使用前,提前加载 js 文件。(等其他资源加载完毕,浏览器空闲了,载加载资源)慎用预加载,会有兼容性问题。
点击按钮的时候,在 import 文件
document.getElementById('bnt').onclick = function () {
import(/*webpackChunkName: 'test'*/'./test.js')
.then(({ mul, count}) => {
console.log(mul(2, 5))
console.log(count([1,2,3,4,5]))
}).catch(() => {
})
}
23. PWA渐进式网络应用程序
官网上截取:
添加 workbox-webpack-plugin 插件,然后调整 webpack.config.js
文件:
npm install workbox-webpack-plugin --save-dev
webpack.config.js
plugins: [
new WorkboxPlugin.GenerateSW({
// 这些选项帮助快速启用 ServiceWorkers
// 不允许遗留任何“旧的” ServiceWorkers
clientsClaim: true,
skipWaiting: true,
}),
],
注册 Service Worker
接下来我们注册 Service Worker,使其出场并开始表演。通过添加以下注册代码来完成此操作:
index.js
+ if ('serviceWorker' in navigator) {
+ window.addEventListener('load', () => {
+ navigator.serviceWorker.register('/service-worker.js').then(registration => {
+ console.log('SW registered: ', registration);
+ }).catch(registrationError => {
+ console.log('SW registration failed: ', registrationError);
+ });
+ });
+ }
注意 package.json 如果项目加上了Eslint 检查,需要加上 支持全局变量
"eslintConfig": {
"env": {
"browser": true
}
},
24. 多进程打包
thread-loaderhttps://webpack.docschina.org/loaders/thread-loader/#root
25. externals 外部扩展
externals 排除某些文件的打包, 例如 ’jQuery'
官网截取:
externals
string
object
function
RegExp
[string, object, function, RegExp]
防止将某些 import
的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)。
例如,从 CDN 引入 jQuery,而不是把它打包:
index.html
<script
src="https://code.jquery.com/jquery-3.1.0.js"
integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
crossorigin="anonymous"
></script>
webpack.config.js
module.exports = {
//...
externals: {
jquery: 'jQuery',
},
};
26 DllPlugin
DllPlugin 用法https://webpack.docschina.org/plugins/dll-plugin#usage