S09-01 Webpack5-基础
[TOC]
基础
入门
概述
痛点: 目前前端开发已经变得越来越复杂了:
- 模块化开发
- 使用高级特性:ES6+、TS、Less、Sass
- 热更新
- 代码压缩、合并、优化
作用: webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具
应用: 脚手架依赖于webpack
官网: https://webpack.docschina.org/
打包工具:
- Webpack
- Gulp
- Rollup
- Vite
脚手架:
- Vue:Vue-CLI
- React:create-react-app
- Angular:Angular-CLI
依赖图:
webpack会从入口文件开始,生成一个依赖关系图,它包含应用程序中所需的所有模块(包括js、css、图片、字体等),然后遍历这个图结构,打包一个个模块
安装
依赖包:
- node
- webpack
- webpack-cli: 从webpack4开始必须安装。用于识别命令行
安装: npm i webpack webpack-cli -D
(局部安装(开发环境))
打包类型
打包类型:
- JS
- ES6转ES5
- CSS
- CSS
- Less
- Sass
- 资源
- img
- font
- HTML
- .vue
- .jsx
基本打包
1、初始化项目配置
npm init -y
2、安装webpack
npm i webpack webpack-cli -D
3、打包文件
npx webpack
npm命令打包
1、在package.json
的scripts中设置脚本
"build": "webpack --config wk.config.js"
2、运行npm run build
打包
命令参数
npx webpack [命令参数]
打包命令参数:
- --entry <path>:指定打包入口,示例:
--entry ./src/main.js
- --output-filename <file>:指定打包输出文件,示例:
--output-filename bundle.js
- --output-path <dir>:指定打包输出目录,示例:
--output-path ./build
- --config <配置文件>:指定配置文件,示例:
--config wk.config.js
类型支持
在webpack.config.js
配置文件中添加以下注释,可以为编写配置提供TS支持
+ /**
+ * @type {import('webpack').Configuration}
+ */
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './build'),
filename: 'bundle.js',
clean: true
},
mode: 'production',
module: {
rules: [
// {
// test: /\.css$/,
// use: ['style-loader', 'css-loader']
// }
]
},
resolve: {
extensions: ['.js', '.json', '.ts', '.jsx', '.vue'],
alias: {
'@': path.resolve(__dirname, './src')
}
}
}
webpack.config.js
target
在webpack.config.js
中,target: 'node'
用于指示webpack构建一个针对Node.js环境的模块。这意味着:
- 输出格式:生成的代码会适合在Node.js运行,而不是浏览器。这包括使用CommonJS模块格式。
- 内置模块:Webpack会自动处理Node.js内置模块(如
fs
、path
等),不会打包这些模块,而是将它们视为外部依赖。 - Polyfill:在Node.js环境下,不会自动添加浏览器特有的polyfills(如
window
、document
等)。 - 优化:Webpack会针对Node.js进行一些特定的优化,确保生成的代码能高效运行。
context
作用: 基础目录,绝对路径,用于从配置中解析入口点(entry point)和 加载器(loader)。默认:项目根目录
entry
作用: 入口
注意: 入口文件路径是相对context(默认是项目根目录)计算的
output
作用: 输出
参数:
- path:输出目录(必须是绝对路径),如
path: path.resolve(__dirname, './build')
- filename:输出文件名,如
'filename: bundle.js'
- chunkFilename:用于指定分包打包文件的名称,可以和占位符配合使用
- clean:
boolean | {dry, keep}
,在生成文件之前清空 output 目录,替代 CleanWebpackPlugin插件,如clean: true
- dry:
boolean
,打印而不是删除应该移除的静态资源 - keep:
reg | string | (filename)=>boolean
,保留指定的静态资源
- dry:
- publicPath:
string | function
,指定在浏览器中引用打包后的资源时的公共路径。- 用处:
- 处理静态资源文件(如图片、字体、样式表等)在 HTML 中的引用路径。如
publicPath: /mr-trip/
- 指定静态资源文件在 CDN 上的路径。如:
https://www.xxx.com/cdn/
- 处理静态资源文件(如图片、字体、样式表等)在 HTML 中的引用路径。如
- 用处:
注意: 配置文件中的path必须是一个绝对路径,如:path.resolve(__dirname, './build')
module
作用: 模块
配置:
- rules:
[{test, use, loader, type, exclude, include, parser, generator, enforce},...]
,规则集合- test:
reg
,匹配文件资源 - use:
[{loader, options, query},...]
,设置对匹配到的资源使用的loader及配置- loader:
string
,使用的loader。示例:use: [{loader: 'css-loader'}]
,简写:use: ['css-loader']
- options:
object
,loader的配置项。示例:use: [{loader: 'css-loader', options: {importLoaders: 1}}]
, - query:``,已被options替代
- 注意: use中多个loader的使用顺序是从后往前的
- loader:
- loader:
,
Rule.use[{loader}]
的简写 - 打包图片
- type:
'asset' | 'asset/source' | 'asset/resourse' | 'asset/inline'
,设置类型。用于打包图片asset
:在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用url-loader
,并且配置资源体积限制实现。配置资源体积限制:parser.dataUrlConddition.maxSize: 64 *1024
asset/resourse
:发送一个单独的文件并导出 URL。之前通过使用file-loader
实现。asset/inline
:导出一个资源的 data URI。之前通过使用url-loader
实现asset/source
:导出资源的源代码。之前通过使用raw-loader
实现
- parser:
{dataUrlCondition}
,解析选项对象,用于打包图片type: 'asset'
时的配置项- dataUrlCondition:
{maxSize}
,maxSize大小以内的图片会被打包成base64- maxSize:
number
,默认:8096
,指定打包成base64的图片最大值(单位:byte)。和type: asset
配合使用
- maxSize:
- dataUrlCondition:
- generator:
{filename}
,重命名打包后的资源文件- filename:``,重命名打包后的资源文件,可以和占位符配合使用
- 其他
- exclude:
Reg
,排除所有符合条件的模块,不能和 resource 选项共存 - include:
Reg
,引入符合以下任何条件的模块,不能和 resource 选项共存 - enforce:
pre | post | normal | inline
,用于控制 loader 执行顺序的选项。pre
:指定该 loader 在所有其他 loader 之前执行。常用于进行某些预处理,例如代码风格检查。post
:指定该 loader 在所有其他 loader 之后执行。常用于进行某些后处理,例如添加某些特性或优化。normal
:默认
,loader 将按照 Webpack 的默认顺序执行。inline
:在行内设置的 loader。如:import 'loader1!loader2!./test.js'
- test:
详细:Loader
resolve
作用: 配置模块如何解析
配置:
- modules:
string[]
,告诉 webpack 解析模块时应该搜索的目录,默认值:['node_modules']
- alias:
{}
,创建 import 或 require 的别名,来确保模块引入变得更简单,如:resolve.alias.'@': path.resolve(__dirname, './src')
- extensions:
string[]
,webpack会尝试按顺序解析这些后缀名。默认值:['.js', '.json', '.wasm']
- 常用值:
['.js', '.json', '.vue', '.jsx', '.ts', 'tsx']
- 注意: 如果有多个文件有相同的名字,但后缀名不同,webpack 会解析列在数组首位的后缀的文件 并跳过其余的后缀。
- 常用值:
- mainFiles:
string[]
,解析目录时要使用的文件名。默认值:['index']
resolveLoader
作用: 这组选项与上面的 resolve 对象的属性集合相同, 但仅用于解析 webpack 的 loader 包。
常用配置:
- modules:
string[]
,告诉 webpack 解析模块时应该搜索的目录,默认值:['node_modules']
- alias:
{}
,创建 import 或 require 的别名,来确保模块引入变得更简单。如:resolve.alias.'@': path.resolve(__dirname, './src')
- extensions:
string[]
,webpack会尝试按顺序解析这些后缀名。默认值:['.js', '.json', '.wasm']
- 常用值:
['.js', '.json', '.vue', '.jsx', '.ts', 'tsx']
- 注意: 如果有多个文件有相同的名字,但后缀名不同,webpack 会解析列在数组首位的后缀的文件 并跳过其余的后缀。
- 常用值:
- mainFiles:
string[]
,解析目录时要使用的文件名。默认值:['index']
plugins
作用: 插件
常用插件:
- new CleanWebpackPlugin():
()
,清理Webpack输出目录的插件- 注意: 可以通过设置
output.clean
代替该插件
- 注意: 可以通过设置
- new HtmlWebpackPlugin():
( {title?, template?, inject?, cache?, minify?} )
,快速创建 HTML 模板用于打包- 基本选项
- title?:
string
,默认:'Webpack App'
,指定生成的 HTML 文件的标题 - template?:
string
,默认:''
,指定用作模板的 HTML 文件路径 - HTML压缩
- inject?:
true | false | 'body' | 'head'
,默认:true
,指定打包的 bundle 文件插入的位置【 - cache?:
boolean
,默认:true
,控制是否应该缓存生成的结果以提高构建性能【 - minify?:
boolean | object
,默认:生产:true, 其他:false
,是否压缩 HTML 文件。会用到 html-minifier-terser 插件【- object选项
collapseWhitespace
: 去除空格removeComments
: 删除注释removeEmptyAttributes
: 删除空属性removeRedundantAttributes
: 删除多余的属性removeScriptTypeAttributes
: 删除 script 标签的 type 属性removeStyleLinkTypeAttributes
: 删除 style 和 link 标签的 type 属性useShortDoctype
: 使用短的 doctype 声明minifyJS
: 压缩内嵌的 JavaScript 代码minifyCSS
: 压缩内嵌的 CSS 代码
- new DefinePlugin():
( {BASE_URL,...} )
,允许创建一些在编译时可配置的全局常量- 默认注入变量:
process.env.NODE_ENV
,判断当前环境是开发还是生产环境 - 注意: 配置options中的值部分双引号内的代码,并不是一个字符串,而是会被当做js代码执行一遍
- 注意: 该全局常量可以在项目的任意地方使用
- 默认注入变量:
- new ProvidePlugin():
({key: value})
,用于自动加载模块而不必在每个模块中显式地import
或require
它们- key:
string
,希望在全局作用域中提供的变量名称。 - value:
string | [moduel, variable]
,要加载的模块- module:
string
,要加载的模块(通常是 npm 包)。 - variable:
string
,可选,指定模块中的具体变量。如果你要加载整个模块,可以省略这个选项。
- module:
- key:
- new MiniCssExtractPlugin():
({filename, chunkFilename})
,用于将 CSS 提取到单独的文件中,而不是将其嵌入到 JavaScript 文件中。- filename:
string
,指定生成的 CSS 文件名。可以使用占位符[name]
、[id]
、[contenthash]
等。 - chunkFilename:
string
,指定异步加载的 CSS 文件名。 - 注意: 确保项目中没有同时使用
style-loader
和MiniCssExtractPlugin.loader
,否则可能会出现冲突。
- filename:
- new PurgeCSSPlugin():
({paths, safelist?})
,检查项目中实际使用的 CSS,并删除未使用的样式。- paths:
array
,指定要扫描的文件路径。可以使用glob
模块来匹配路径,确保所有使用 CSS 的文件都被检查。 - safelist?:
array
,指定一个列表,保留某些类名,即使它们没有被使用。
- paths:
- new webpack.optimize.ModuleConcatenationPlugin():
()
,作用域提升。将多个模块的代码合并成一个函数,这样可以减少函数调用的开销,提高执行效率。 - new CompressionPlugin():,文件压缩插件
( {test?, minRatio?, algorithm?, threshold?, include?, exclude?} )
- test?:
reg | string | array
,默认:所有文件
,匹配哪些文件需要压缩 - minRatio?:
number
,默认:0.8
,至少得压缩比例 - algorithm?:
'gzip' | 'brotli'
,默认:'gzip'
,采用的压缩算法 - threshold?:
number
,默认:0
,设置文件从多大开始压缩 - include?:
reg | string | array
,默认:所有文件
,指定要包含的文件路径 - exclude?:
reg | string | array
,默认:null
,指定要排除的文件路径
- :``,
mode
作用: 开发模式
值:
none
:不使用任何优化选项development
:开发环境。会将DefinePlugin
中process.env.NODE_ENV
的值设为development
。打包后的变量名为有效名production
:(默认),生产环境。会将DefinePlugin
中process.env.NODE_ENV
的值设为production
。打包后的变量名为丑化名
设置为development
:
设置为production
:
devServer
作用: 本地服务器,可用于热更新
配置:
- hot:
boolean
,(默认true),开启HMR热更新 - host:``,配置主机
'localhost'
:(默认),会被解析成127.0.0.1
'127.0.0.1'
:回环地址,发出去的包,会被自己接收'0.0.0.0'
:任何人都可以访问
- port:
number
,(默认8080),配置端口 - open:
boolean
,(默认false),浏览器自动打开项目 - 性能优化
- compress:
boolean
,(默认true),启用压缩,如:Content-Encoding: gzip
- 跨域代理
- proxy:
{'/api': { target, pathRewrite, changeOrigin }}
,设置服务器代理- target:
string
,存储资源的真实地址。 - pathRewrite:
{}
,重写路径,可以去除url中的/api
。如pathRewrite: { '^/api': '' }
- changeOrigin:
boolean
,(默认false),默认情况下,代理时会保留主机头的来源,可以将 changeOrigin 设置为 true 以覆盖此行为。
- target:
devtool
作用: 控制是否生成,以及如何生成 source-map
常见devtool选项:
不生成source-map文件:
false:``,不使用source-map,也就是没有任何和source-map相关的内容。
none:``,
eval:``,
development环境:
eval:``,(development模式下的默认值),不生成source-map。
- 但是它会在eval执行的代码中,添加
//# sourceURL=
- 它会被浏览器在执行时解析,并且在调试面板中生成对应的一些文件目录,方便我们调试代码。但不是很准确
- 但是它会在eval执行的代码中,添加
cheap-source-map: ``,会生成sourcemap,但是会更加高效一些(cheap低开销),因为它没有生成列映射
cheap-module-source-map: ``,会生成sourcemap,类似于cheap-source-map,但是对源自loader(如babel-loader)的sourcemap处理会更好。
production环境:
none:``,(production模式下的默认值),什么值都不要写,不生成source-map。
source-map: ``,生成独立的source-map文件,最完整的映射关系,但会增加打包后文件的大小,不适合生产环境使用。
eval-source-map: ``,会生成sourcemap,但是source-map是以DataUrl添加到eval函数的后面
inline-source-map: ``,会生成sourcemap,但是source-map是以DataUrl添加到bundle文件的后面
hidden-source-map: ,会生成sourcemap,但是不会对source-map文件进行引用。
- 相当于删除了打包文件中对sourcemap的引用注释。
- 需要手动添加:
//# sourceMappingURL=bundle.js.map
nosources-source-map: ``,会生成sourcemap,但是生成的sourcemap只有错误信息的提示,不会生成源代码文件
optimization
作用: 优化配置
常见配置:
splitChunks:
{chunks,minSize,maxSize,cacheGroups}
,用于对代码进行分割和提取公共模块。可以将一些通用的模块抽离出来成为单独的文件,以减小打包文件的体积,提高加载速度。chunks:
all | async | initial | ()=>{}
,指定哪些 chunk 参与分割'all'
:(),加载所有 chunk。'async'
:(默认),按需加载异步的 chunk。'initial'
:(),仅对入口点的代码进行分割。()=>{}
:(),提供一个函数去做更多的控制。这个函数的返回值将决定是否包含每一个 chunk。
minSize:
number
,指定分割后的 chunk 的最小大小,单位为 bytes。maxSize:
number
,指定分割后的 chunk 的最大大小,单位为 bytes。如果为 0,则表示没有限制。cacheGroups:
{key: {test, priority, filename, reuseExistingChunk}, key: {}...}
,缓存组,用于配置不同类型的模块如何被分割。- test:
reg | function | string
,用于匹配符合条件的模块。 - priority:
number
,默认:-20
,决定模块被打包到哪个 cache group 的优先级,数值越大优先级越高。 - filename:
string | (pathData, assetInfo) => string
,给生成的文件分配名称。 - reuseExistingChunk:
boolean
,默认:true
,是否重用已经存在的 chunk。
- test:
chunkIds:
false | 'natural' | 'named' | 'deterministic' | 'size' | 'total-size'
, 告知 webpack 当选择模块 id 时需要使用哪种算法。
false
:(默认),没有任何内置的算法。但自定义的算法会由插件提供。named
:(开发模式默认值),对调试更友好的可读的 id。(完整的名子)deterministic
:(生产模式默认),在不同的编译中不变的短数字 id。有益于长期缓存。(数字不会变化)- 在 webpack4 中是没有这个值的,那个时候如果使用 natural,那么在一些编译发生变化时,就会有问题
natural
:(),按使用顺序的数字 id。(数字会变化)size
:(),专注于让初始下载包大小更小的数字 id。total-size
:(),专注于让总下载包大小更小的数字 id。
runtimeChunk:
true | 'multiple' | 'single' | {name}
,配置 runtime 相关的代码是否抽取到一个单独的 chunk 中,目前已经不再单独打包true | multiple
:(),针对每个入口打包一个 runtime 文件single
:(),打包一个 runtime 文件{name}
:(推荐),name 属性决定 runtimeChunk 的名称
minimize:
boolean
,告知webpack使用 TerserPlugin 或其它在 optimization.minimizer 定义的插件压缩 bundle。minimizer:
[new TerserPlugin()?, new CssMinimizer()?, '...'?]
, 允许你通过提供一个或多个定制过的 TerserPlugin 实例,覆盖默认压缩工具(minimizer)。
new TerserPlugin()?:
( {extractComments?, parallel?, terserOptions?} )
, 用于对JS代码简化的插件
- 依赖包:terser-webpack-plugin (内置插件)
- extractComments:
boolean
,(D: true),将注释抽取到一个单独的文件中。- 注意: 开发中,不希望保留这个注释时,可以设为 false
- parallel:
boolean
,(D: true),使用多进程并发运行提高构建的速度- 注意: 并发运行的默认数量:
os.cpus().length - 1
- 注意: 并发运行的默认数量:
- terserOptions:
{compress, mangle, toplevel, keep_classnames, keep_fnames}
,设置terser配置- compress:
{arrows, arguments, dead_code, unused}
,设置压缩相关的选项- arrows:
boolean
,(),将class或者object中的函数转换成箭头函数 - arguments:
boolean
,(),将函数中使用的arguments[index]转成对应的形参名称 - dead_code:
boolean
,(D: true),移除不可达的代码(tree shaking) - unused:
boolean
,(D: true),移除未使用过的函数(tree shaking)
- arrows:
- mangle:
boolean
,设置丑化相关的选项,可以直接设置为 true - toplevel:
boolean
,顶层变量是否进行转换 - keep_classnames:
boolean
,保留类的名称 - keep_fnames:
boolean
,保留函数的名称
- compress:
new CssMinimizer()?:
( {parallel?, minimizerOptions?} )
,压缩和优化 CSS 代码的插件- 依赖包:css-minimizer-webpack-plugin (内置插件)
- parallel?:
boolean
,(D: true),是否开启多进程并行压缩 - minimizerOptions?:
{preset}
,传递给 CssMinimizer压缩器的选项,如指定压缩规则、是否启用并行压缩等
'...'?:
,可以使用
'...'
来访问默认值
usedExports:
boolean
,默认:true
,帮助 Webpack 识别和剔除未使用的导出
示例:
optimization: {
splitChunks: {
chunks: 'all',
minSize: 30000,
maxSize: 0,
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
name: 'vendors',
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
name: 'common',
},
},
},
}
配置 runtime 相关的代码是否抽取到一个单独的 chunk 中:
runtime 相关的代码指的是在运行环境中,对模块进行解析、加载、模块信息相关的代码;
比如我们的 component、bar 两个通过 import 函数相关的代码加载,就是通过 runtime 代码完成的;
抽离出来后,有利于浏览器缓存的策略:
比如我们修改了业务代码(main),那么 runtime 和 component、bar 的 chunk 是不需要重新加载的;
比如我们修改了 component、bar 的代码,那么 main 中的代码是不需要重新加载的;
设置的值:
true/multiple:针对每个入口打包一个 runtime 文件;
single:打包一个 runtime 文件;
对象:name 属性决定 runtimeChunk 的名称;
externals
作用: 从输出的 bundle 中排除依赖
externals: {key: value} | string | function | reg |
,从输出的 bundle 中排除依赖
- key:
,排除的框架的名称
- value:
,从CDN地址请求下来的JS中提供的对应的名称(不能乱写)
占位符
注意: [hash]
,[contenthash]
或者 [chunkhash]
的长度可以使用 [hash:16]
(默认为 20)来指定
- 编译层面
- [fullhash]:``,compilation 完整的 hash 值
- chunk层面
- [id]:``,此 chunk 的 ID
- [name]:``,如果设置,则为此 chunk 的名称,否则使用 chunk 的 ID
- [chunkhash]:``,此 chunk 的 hash 值,包含该 chunk 的所有元素
- [contenthash]:``,此 chunk 的 hash 值,只包括该内容类型的元素(受 optimization.realContentHash 影响)
- 模块层面
- [id]:``,模块的 ID
- [hash]:``,模块的 Hash 值
- [contenthash]:``,模块内容的 Hash 值
- 文件层面
- [file]:``,filename 和路径,不含 query 或 fragment
- [query]:``,带前缀 ? 的 query
- [fragment]:``,带前缀 # 的 fragment
- [base]:``,只有 filename(包含扩展名),不含 path
- [path]:``,只有 path,不含 filename
- [name]:``,只有 filename,不含扩展名或 path
- [ext]:
,带前缀
.
的扩展名(对 output.filename 不可用) - URL层面
- [url]:``,URL
Loader
配置loader方式
方式一:内联方式
在引入的样式前加上使用的loader,使用!
分割
import "css-loader!../css/style.css"
缺点: 使用不方便
方式二:CLI方式
webpack5中不再支持
方式三:配置方式(推荐)
在webpack.config.js
的module.rules
中添加规则
打包CSS
依赖包:
- style-loader:负责把CSS插入到DOM中
- 安装:
npm i style-loader -D
- 安装:
- css-loader:负责解析css代码
- 安装:
npm i css-loader -D
- 安装:
配置:
完整use写法:
**简写一:**只有一个loader
简写二: 多个loader没有其他属性(推荐)
打包: npm run build
注意: 当前CSS是打包成内联样式、并且没有进行压缩等操作
打包Less
依赖包:
- less:编写less的插件
- 安装:
npm i less -D
- 安装:
- style-loader:负责把CSS插入到DOM中
- 安装:
npm i style-loader -D
- 安装:
- css-loader:负责解析css代码
- 安装:
npm i css-loader -D
- 安装:
- less-loader:负责解析less代码
- 安装:
npm i less-loader -D
- 安装:
配置:
打包: npm run build
postcss-loader
依赖包:
- postcss:用JS工具和插件转换CSS代码
- 安装:
npm i postcss -D
- 安装:
- postcss-loader:使用PostCSS处理CSS
- 安装:
npm i postcss-loader -D
- 安装:
依赖插件:
- autoprefixer:(废弃),为CSS添加浏览器前缀,已被
postcss-preset-env
替代- 安装:
npm i autoprefixer -D
- 安装:
- postcss-preset-env:(推荐),帮助转换现代CSS为浏览器认识的CSS。并根据浏览器或环境添加所需polyfill
- 安装:
npm i postcss-preset-env -D
- 特性:
- 包括了
autoprefixer
的功能,user-select: none;
- 通过十六进制设置rgba颜色,
background-color: #66666666
- 转化px成rem、vw
- 包括了
- 安装:
配置:
- postcssOptions:(``),postcss配置选项
- plugins:(
['postcss-preset-env',...]
),postcss插件
- plugins:(
1、基本配置
2、抽取postcss-loader的配置
2.1、在项目根目录创建postcss.config.js
文件
2.2、添加postcss配置
3、替换成postcss-preset-env
打包: npm run build
打包图片
- rules:
[{test, use, loader, type, exclude, include, parser, generator},...]
,规则集合- type:
'asset' | 'asset/source' | 'asset/resource' | 'asset/inline'
,设置类型。用于打包图片asset
:在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用url-loader
,并且配置资源体积限制实现。asset/resource
:发送一个单独的文件并导出 URL。之前通过使用file-loader
实现。asset/inline
:导出一个资源的 data URI。之前通过使用url-loader
实现asset/source
:导出资源的源代码。之前通过使用raw-loader
实现
- parser:
{dataUrlCondition}
,解析选项对象,用于打包图片type: 'asset'
时的配置项- dataUrlCondition:
{maxSize}
,maxSize大小以内的图片会被打包成base64- maxSize:
number
,默认:8096
,指定打包成base64的图片最大值(单位:byte)。和type: asset
配合使用
- maxSize:
- dataUrlCondition:
- generator:
{filename}
,重命名打包后的资源文件- filename:``,重命名打包后的资源文件,可以和占位符配合使用
- type:
在webpack中任何图片都是一个模块
依赖包:
- file-loader:(弃用),早期加载文件模块的loader
- 现在已经内置了文件loader:
type: "asset"
配置:
1、基本配置
打包方式:
**方式一:**打包图片成单独文件:asset/resource
- 缺点: 会额外多发送网络请求获取打包的图片
**方式二:**打包图片成base64编码:asset/inline
- 缺点: 会造成打包后的JS文件很大,下载消耗时间过长,阻塞其他任务
**方式三:**自动选择打包成图片还是base64编码:asset
优点: 可以解决
resource
和inline
的缺点,在二者中间寻求一个平衡小图片:进行base64编码
大图片:单独打包图片
重命名打包后的文件:
**方式一:**配置output.assetModuleFilename
- 缺点: 配置后,所有的资源文件都是这个名字
**方式二:**配置module.rules.[{generator.filename}]
基本使用
添加目录
打包: npm run build
打包ES6
概述: Babel是一个工具链,用于在旧浏览器或环境中将ES6+代码转换为向后兼容版本的JS
依赖包:
- @babel/core:``,babel核心代码
- 安装:
npm i @babel/core -D
- 安装:
- @babel/cli:``,命令行使用babel所需
- 安装:
npm i @babel/cli -D
- 安装:
- babel-loader:``,
- 安装:
npm i babel-loader -D
- 安装:
依赖插件:
- @babel/plugin-transform-arrow-functions:``,(废弃),帮助转换箭头函数的插件
- 安装:
npm i @babel/plugin-transform-arrow-functions -D
- 命令行用法:
npx babel <src> --out-dir <dist> --plugins=@babel/plugin-transform-arrow-functions
- 安装:
- @babel/plugin-transform-block-scoping:``,(废弃),帮助转换const、let
- 安装:
npm i @babel/plugin-trangform-block-scoping -D
- 命令行用法:
npx babel <src> --out-dir <dist> --plugins=@babel/plugin-trangform-block-scoping
- 安装:
- @babel/preset-env:``,(推荐),babel的预设
- 安装:
npm i @babel/preset-env -D
- 其他常见预设:
- @babel/preset-env:``,帮助转化ES6+语法
- @babel/preset-react:``,帮助转化React语法
- @babel/preset-TypeScript:``,帮助转化TS语法
- 安装:
配置:
1、基本配置
2、配置Babel插件-转化箭头函数(废弃)
3、配置Babel插件-转化变量声明关键字(废弃)
4、抽取babel配置
4.1、在项目根目录创建babel.config.js
文件
4.2、添加babel
配置
5、使用@babel/preset-env
替代
打包: npm run build
打包Vue
依赖包:
- vue:``,vue核心代码
- vue-loader:``,
- 安装:
npm i vue-loader -D
- 安装:
- VueLoaderPlugin:``,帮助处理CSS相关
- 安装:
const { VueLoaderPlugin } = require("vue-loader/dist/index")
- 安装:
配置:
1、配置vue-loader
2、配置插件VueLoaderPlugin()
打包: npm run build
Resolve
作用: 配置模块如何解析
实现思路: resolve会根据require、import语句,找到需要引入的模块代码。底层使用enhanced-resolve
来解析文件路径
解析路径分类:
- 绝对路径:不用再解析
- 相对路径:会将相对路径和上下文路径拼接,生成绝对路径
- 注意: 上下文路径:使用import、require的资源文件所处的目录
- 模块路径:在
resolve.modules
中指定的所有目录检索模块,默认值:['node_moudles']
- 注意: 可以通过
resolve.alias
设置别名的方式替代初始模块路径
- 注意: 可以通过
解析过程:
确定文件还是目录:
文件:
- 有扩展名:直接打包文件
- 没有扩展名:使用
resolve.extensions
配置作为文件扩展名解析
目录:
- 1、先根据
resolve.mainFiles
配置文件查找顺序(默认值:index) - 2、再根据
resolve.extensions
配置解析扩展名
- 1、先根据
用法:
1、设置resolve.extensions
,让webpack自动为文件添加后缀
配置
使用
2、设置resolve.mainFiles
,让webpack自动为目录添加索引文件
注意: 一般不修改默认配置
配置
使用
3、设置resolve.alias
,为某些目录配置别名
配置
使用
Plugins
loader对比插件:
- loader 用于转换特定类型的模块。
- 插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。
常用插件:
- VueLoaderPlugin: ``,打包Vue
- CleanWebpackPlugin:``,(过时),清理Webpack输出目录的插件
- HtmlWebpackPlugin:``,快速创建 HTML 模板用于打包
- DefinePlugin:``,允许创建一些在编译时可配置的全局常量
VueLoaderPlugin()
见:打包Vue
CleanWebpackPlugin
作用: 清理Webpack输出目录的插件
依赖包:
- clean-webpack-plugin:``,
- 安装:
npm i clean-webpack-plugin -D
- 安装:
配置:
注意: 可以通过设置output.clean
代替该插件
HtmlWebpackPlugin
作用: 快速创建 HTML 模板用于打包
依赖包:
- html-webpack-plugin:``,
- 安装:
npm i html-webpack-plugin -D
- 安装:
配置:
1、基本配置
2、配置title
使用
3、自定义模板文件
DefinePlugin
作用: 允许创建一些在编译时可配置的全局常量
依赖包: webpack内置插件,无需安装
配置:
注意: 配置options中的值部分双引号内的代码,并不是一个字符串,而是会被当做js代码执行一遍
注意: 该全局常量可以在项目的任意地方使用
默认注入变量:process.env.NODE_ENV
,判断当前环境是开发还是生产环境
DevServer
依赖包:
- webpack-dev-server:
- 安装:
npm i webpack-dev-server -D
- 安装:
自动编译方案:
- webpack-dev-server
- webpack watch mode
- webpack-dev-middleware
开启本地服务器:
1、设置scripts脚本
"serve": "webpack serve --config wk.config.js"
2、运行命令
npm run serve
注意: webpack-dev-server在编译之后不会写入到任何输出文件,而是将bundle文件保留在内存中
缺点:
- 局部修改后,整个页面都会被重新刷新一遍,浪费性能
- 可以通过HMR解决该问题
devServer配置: 见devServer
HMR
~~概述:~~HMR: Hot Module Replacement(热更新,模块热替换),指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个页面
优点:
- 不重新加载整个页面,可以保留某些状态不丢失
- 只更新需要变化的内容,节省开发时间
- 修改了源代码,会立即在浏览器更新
开启HMR:
1、默认已经开启了HMR,但此时依然没有实现热更新
2、还需要指定哪个模块使用热更新
框架中的HMR: 在框架中已经提供了成熟的HMR解决方案,无需手动开启
- Vue:
- vue-loader
- React
- React Hot Loader(已弃用)
- react-refresh
跨域代理
见:
区分开发环境
创建3个配置文件:
webpack.dev.config.js
:不需要cleanwebpack.prod.config.js
:不需要devServerwebpack.common.config.js
:不需要clean、devServer、mode
1、修改scripts
"build": "webpack serve --config ./config/webpack.prod.config.js"
"serve": "webpack serve --config ./config/webpack.dev.config.js"
2、抽取公共配置
3、合并公共配置和dev/prod配置
依赖包:webpack-merge
- 安装:
npm i webpack-merge -D
- 安装:
在
dev/prod
配置中执行合并
Webpack的模块化
Webpack打包的代码,允许我们使用各种各样的模块化,但是最常用的是CommonJS、ES Module。
- 那么它是如何帮助我们实现了代码中支持模块化呢?
我们来研究一下它的原理,包括如下原理:
CommonJS模块化实现原理;
ES Module实现原理;
CommonJS加载ES Module的原理;
ES Module加载CommonJS的原理;
这里不再给出代码,查看课堂代码的注释解析;