前言
Webpack学习笔记
下载依赖
1
| npm install -D webpack webpack-cli
|
执行打包
- 如果项目根目录存在
webpack.config.js文件,则读取自定义配置,否则使用默认配置
--stats detailed:展示详细打包信息
--watch:观察者模式,实时侦测文件变化并自动重新打包
--env <key>、--env <key>=<value>:指定环境变量
-c <file>、--config <file>:指定配置文件,缺省值为./webpack.config.js
--entry <file>.js:指定入口文件,缺省值为./src/index.js
--ouput-filename <file_name>.js:指定打包后的文件名,缺省值为main.js
--output-path <dir_name>:指定打包后的文件所在目录,缺省值为./dist
配置文件
mode:打包环境
none:不指定打包环境
development:开发环境
production:生产环境
entry:指定入口文件
output:指定出口配置
filename:指定打包后的文件名
path:指定打包后的文件所在目录,必须是绝对路径
clean:是否清理上一次打包的文件
publicPath:指定打包后的资源的URL前缀
devtool:SourceMap配置,在生产环境下不要生成SourceMap
module:解析文件的模块配置
plugins:插件配置
optimization:代码优化配置
performance:性能配置
webpack.config.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const path = require("path");
module.exports = { mode: "none", entry: "index.js", output: { filename: "main.js", path: path.resolve(__dirname, "dist"), clean: true, publicPath: "http://127.0.0.1:80/", }, devtool: "inline-source-map", resolve: {}, module: {}, plugins: [], optimization: {}, performance: {} }
|
输出配置
输出为单个JS文件
webpack.config.js1 2 3 4 5
| module.exports = { output: { filename: "main.js", } }
|
输出为多个JS文件
webpack.config.js1 2 3 4 5 6
| module.exports = { output: { filename: "[name].js", path: path.resolve(__dirname, "dist"), } }
|
解析器配置
手动指定导入的文件所使用的解析器
1
| import "<loader_name>!<file>";
|
通过配置文件配置解析器
test:使用正则表达式匹配需要解析的文件名
use:指定解析器
"":只有一个解析器,并且无其他配置,则可以直接指定解析器名
["", ""]:有多个解析器,但无其他配置,则可以直接指定多个解析器名,多个解析器调用顺序为从后往前
[{}, {}]:有多个解析器,且有其他配置,则可以指定多个解析器配置,多个解析器调用顺序为从后往前
type:指定资源类型
asset/resource:直接打包文件,并得到文件的URL,通过内置的file-loader实现
asset/inline:得到文件的的Base64编码值,通过内置的url-loader实现
asset/source:得到文件的原始内容,通过内置的raw-loader实现
asset:缺省值,根据parser.dataUrlCondition.maxSize配置的文件大小(单位字节),小于等于则切换为asset/inline,大于则切换为asset/resource
generator:指定打包后的文件配置
filename:指定打包后的文件路径及文件名
[path]:原始文件路径
[name]:原始文件名,不包含扩展名
[hash]:原始文件哈希值(包含文件内容及文件元数据)
[hash:<num>]:截取指定长度的文件哈希值
[contenthash]:原始文件内容哈希值
[ext]:原始文件扩展名
[query]:原始文件查询字符串
webpack.config.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| module.exports = { module: { rules: [ { test: /<file_name>/, use: "<loader_name>", type: "asset", parser: { dataUrlCondition: { maxSize: 10*1024 } }, generator: { filename: "[path][name][hash][contenthash][ext][query]" }, } ] } }
|
解析规则配置
mainFiles:导入时自动匹配主文件名
extensions:导入时自动匹配扩展名
webpack.config.js1 2 3 4 5 6 7 8 9
| module.exports = { resolve: { mainFiles: ["index"] extensions: [".wasm", ".mjs", ".js", ".json"], alias: { "@src": path.resolve(__dirname, "src") } } }
|
插件配置
全局变量插件
修改配置文件
webpack.config.js1 2 3 4 5 6 7 8 9
| const { DefinePlugin } = require("webpack");
module.exports = { plugins: [ new DefinePlugin({ "key": JSON.stringify("value") }) ] }
|
使用全局变量
内置全局变量
1
| console.log(process.env.NODE_ENV);
|
代码分离
准备多个JS文件
1 2 3
| + src - index.js - another.js
|
方案一:修改入口节点
修改配置文件
entry:指定多个入口节点
output.filename:指定输出文件名
webpack.config.js1 2 3 4 5 6 7 8 9
| module.exports = { entry: { index: "./src/index.js", another: "./src/another.js", }, output: { filename: "[name].bundle.js", } }
|
方案二:抽离公共JS文件为trunk
修改配置文件
- 公共模块会被打包为
shared.bundle.js
webpack.config.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| module.exports = { entry: { index: { import: "./src/index.js", dependOn: "shared", }, another: { import: "./src/another.js", dependOn: "shared", }, shared: "公共模块名", }, output: { filename: "[name].bundle.js", } }
|
方案三:通过插件抽离公共JS文件为chunk
- 通过内置的插件
split-chunks-plugin实现插件抽离公共JS文件为chunk
修改配置文件
webpack.config.js1 2 3 4 5 6 7 8 9 10 11 12 13 14
| module.exports = { entry: { index: "./src/index.js", another: "./src/another.js", }, output: { filename: "[name].bundle.js", }, optimization: { splitChunks: { chunks: "all", } } }
|
方案四:动态导入
- 根据使用
import()函数导入的JS文件,作为公共JS文件
- 动态导入可以和静态导入组合使用
- 通过动态导入的方式打包的公共JS文件,会自动进行懒加载,只有在被调用的时候,浏览器才会下载对应的JS文件
在JS文件中导入JS文件
another.js1 2 3 4 5
| function getComment() { return import("公共模块名").then(({公共模块内的函数名}) => { 公共模块内的函数名(); }); }
|
index.js
- 公共JS文件会被打包为
目录民_文件名_js.bundle.js文件
通过魔法注释定义公共模块打包后的文件名
another.js1 2 3 4 5
| function getComment() { return import("公共模块名").then(({公共模块内的函数名}) => { 公共模块内的函数名(); }); }
|
- 公共JS文件会被打包为
自定义文件名.bundle.js文件
懒加载和预加载
懒加载
- 在访问HTML时,先不加载这个资源,如果这个资源被调用,才会自动加载这个资源
- 传送门
预获取
- 打包后的HTML中会引入
<link rel="prefetch" as="script" href="">标签
- 在访问这个HTML时,先不加载这个资源,只有在网络空闲时,才会自动加载这个资源
通过魔法注释定义模块预获取
webpackPrefetch: true:定义模块预获取
another.js1 2 3 4 5
| function getComment() { return import("模块名").then(({模块内的函数名}) => { 模块内的函数名(); }); }
|
预加载
通过魔法注释定义模块预加载
webpackPreload: true:定义模块预加载
another.js1 2 3 4 5
| function getComment() { return import("模块名").then(({模块内的函数名}) => { 模块内的函数名(); }); }
|
环境变量
修改配置文件
webpack.config.js1 2 3 4 5
| module.exports = (env) => { return { ... } }
|
执行打包时指定环境变量
- 执行打包时指定环境变量,通过环境变量添加了部分配置
1
| webpack --env <key>=<value>
|
利用环境变量来确定打包环境
修改配置文件
- 如果传递了环境变量
production,则以生产环境打包,否则以开发环境打包
webpack.config.js1 2 3 4 5
| module.exports = (env) => { return { mode: env.production ? "production" : "development", } }
|
打包时指定环境变量
1
| webpack --env production
|
多环境配置
拆分多个配置文件
准备多个配置文件
1 2 3 4
| + config - webpack.config.dev.js - webpack.config.prod.js - index.js
|
修改配置文件
webpack.config.dev.js1 2 3
| module.exports = { path: path.resolve(__dirname, "../dist") }
|
执行打包时指定配置文件
-c <file>、--config <file>:指定配置文件
1
| npx webpack --config ./config/webpack.config.dev.js
|
抽离公共配置文件
准备多个配置文件
1 2 3 4 5
| + config - webpack.config.common.js - webpack.config.dev.js - webpack.config.prod.js - index.js
|
修改配置文件
- 将公共配置抽离到
webpack.config.common.js公共配置文件中
webpack.config.dev.js1 2 3
| module.exports = { path: path.resolve(__dirname, "../dist"), }
|
webpack.config.dev.js1 2 3
| module.exports = { mode: "development", }
|
webpack.config.prod.js1 2 3
| module.exports = { mode: "production", }
|
合并配置文件
准备多个配置文件
1 2 3 4 5 6
| + config - webpack.config.js - webpack.config.common.js - webpack.config.dev.js - webpack.config.prod.js - index.js
|
下载依赖
1
| npm install -D webpack-merge
|
修改配置文件
webpack.config.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const { merge } = require("webpack-merge");
const commonConfig = require("./webpack.config.common"); const devConfig = require("./webpack.config.dev"); const prodConfig = require("./webpack.config.prod");
module.exports = (env) => { switch (true) { case env.development: return merge(commonConfig, devConfig); break; case env.production: return merge(commonConfig, prodConfig); break; default: return new Error("No matching configuration was found!"); } }
|
执行打包时指定环境
1
| webpack --config ./config/webpack.config.js --env production
|
完成
参考文献
哔哩哔哩——微笑专业教前端