Skip to content

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、图片、字体等),然后遍历这个图结构,打包一个个模块

image-20240222113352344

安装

依赖包:

  • node
  • webpack
  • webpack-cli: 从webpack4开始必须安装。用于识别命令行

安装: npm i webpack webpack-cli -D(局部安装(开发环境))

打包类型

打包类型:

  • JS
    • ES6转ES5
  • CSS
    • CSS
    • Less
    • Sass
  • 资源
    • img
    • font
    • HTML
    • .vue
    • .jsx

基本打包

1、初始化项目配置

sh
npm init -y

2、安装webpack

sh
npm i webpack webpack-cli -D

3、打包文件

sh
npx webpack

npm命令打包

1、在package.json的scripts中设置脚本

sh
"build": "webpack --config wk.config.js"

2、运行npm run build打包

命令参数

sh
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支持

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

context

作用: 基础目录,绝对路径,用于从配置中解析入口点(entry point)和 加载器(loader)。默认:项目根目录

entry

作用: 入口

注意: 入口文件路径是相对context(默认是项目根目录)计算的

output

作用: 输出

参数:

  • path:输出目录(必须是绝对路径),如path: path.resolve(__dirname, './build')
  • filename:输出文件名,如'filename: bundle.js'
  • chunkFilename:用于指定分包打包文件的名称,可以和占位符配合使用
  • cleanboolean | {dry, keep},在生成文件之前清空 output 目录,替代 CleanWebpackPlugin插件,如clean: true
    • dryboolean,打印而不是删除应该移除的静态资源
    • keepreg | string | (filename)=>boolean ,保留指定的静态资源
  • publicPathstring | function,指定在浏览器中引用打包后的资源时的公共路径。
    • 用处:
      • 处理静态资源文件(如图片、字体、样式表等)在 HTML 中的引用路径。如publicPath: /mr-trip/
      • 指定静态资源文件在 CDN 上的路径。如:https://www.xxx.com/cdn/

注意: 配置文件中的path必须是一个绝对路径,如:path.resolve(__dirname, './build')

module

作用: 模块

配置:

  • rules[{test, use, loader, type, exclude, include, parser, generator, enforce},...],规则集合
    • testreg,匹配文件资源
    • use[{loader, options, query},...],设置对匹配到的资源使用的loader及配置
      • loaderstring,使用的loader。示例:use: [{loader: 'css-loader'}],简写:use: ['css-loader']
      • optionsobject,loader的配置项。示例:use: [{loader: 'css-loader', options: {importLoaders: 1}}]
      • query:``,已被options替代
      • 注意: use中多个loader的使用顺序是从后往前
    • loaderRule.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
        • maxSizenumber默认:8096,指定打包成base64的图片最大值(单位:byte)。和type: asset配合使用
    • generator{filename},重命名打包后的资源文件
      • filename:``,重命名打包后的资源文件,可以和占位符配合使用
    • 其他
    • excludeReg,排除所有符合条件的模块,不能和 resource 选项共存
    • includeReg,引入符合以下任何条件的模块,不能和 resource 选项共存
    • enforcepre | post | normal | inline,用于控制 loader 执行顺序的选项。
      • pre:指定该 loader 在所有其他 loader 之前执行。常用于进行某些预处理,例如代码风格检查。
      • post:指定该 loader 在所有其他 loader 之后执行。常用于进行某些后处理,例如添加某些特性或优化。
      • normal默认,loader 将按照 Webpack 的默认顺序执行。
      • inline:在行内设置的 loader。如:import 'loader1!loader2!./test.js'

详细:Loader

resolve

作用: 配置模块如何解析

配置:

  • modulesstring[],告诉 webpack 解析模块时应该搜索的目录,默认值:['node_modules']
  • alias{},创建 import 或 require 的别名,来确保模块引入变得更简单,如:resolve.alias.'@': path.resolve(__dirname, './src')
  • extensionsstring[],webpack会尝试按顺序解析这些后缀名。默认值:['.js', '.json', '.wasm']
    • 常用值:['.js', '.json', '.vue', '.jsx', '.ts', 'tsx']
    • 注意: 如果有多个文件有相同的名字,但后缀名不同,webpack 会解析列在数组首位的后缀的文件 并跳过其余的后缀。
  • mainFilesstring[],解析目录时要使用的文件名。默认值:['index']

resolveLoader

作用: 这组选项与上面的 resolve 对象的属性集合相同, 但仅用于解析 webpack 的 loader 包

常用配置:

  • modulesstring[],告诉 webpack 解析模块时应该搜索的目录,默认值:['node_modules']
  • alias{},创建 import 或 require 的别名,来确保模块引入变得更简单。如:resolve.alias.'@': path.resolve(__dirname, './src')
  • extensionsstring[],webpack会尝试按顺序解析这些后缀名。默认值:['.js', '.json', '.wasm']
    • 常用值:['.js', '.json', '.vue', '.jsx', '.ts', 'tsx']
    • 注意: 如果有多个文件有相同的名字,但后缀名不同,webpack 会解析列在数组首位的后缀的文件 并跳过其余的后缀。
  • mainFilesstring[],解析目录时要使用的文件名。默认值:['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}),用于自动加载模块而不必在每个模块中显式地 importrequire 它们
    • keystring,希望在全局作用域中提供的变量名称。
    • valuestring | [moduel, variable],要加载的模块
      • modulestring,要加载的模块(通常是 npm 包)。
      • variablestring,可选,指定模块中的具体变量。如果你要加载整个模块,可以省略这个选项。
  • new MiniCssExtractPlugin()({filename, chunkFilename}),用于将 CSS 提取到单独的文件中,而不是将其嵌入到 JavaScript 文件中。
    • filenamestring,指定生成的 CSS 文件名。可以使用占位符 [name][id][contenthash] 等。
    • chunkFilenamestring,指定异步加载的 CSS 文件名。
    • 注意: 确保项目中没有同时使用 style-loaderMiniCssExtractPlugin.loader,否则可能会出现冲突。
  • new PurgeCSSPlugin()({paths, safelist?}),检查项目中实际使用的 CSS,并删除未使用的样式。
    • pathsarray,指定要扫描的文件路径。可以使用 glob 模块来匹配路径,确保所有使用 CSS 的文件都被检查。
    • safelist?array,指定一个列表,保留某些类名,即使它们没有被使用。
  • 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,指定要排除的文件路径
  • :``,

image-20240222152908812

mode

作用: 开发模式

值:

  • none:不使用任何优化选项
  • development:开发环境。会将DefinePluginprocess.env.NODE_ENV的值设为development。打包后的变量名为有效名
  • production:(默认),生产环境。会将DefinePluginprocess.env.NODE_ENV的值设为production。打包后的变量名为丑化名

设置为development

image-20240222155835544

设置为production

image-20240222155838654

devServer

作用: 本地服务器,可用于热更新

配置:

  • hotboolean,(默认true),开启HMR热更新
  • host:``,配置主机
    • 'localhost':(默认),会被解析成127.0.0.1
    • '127.0.0.1':回环地址,发出去的包,会被自己接收
    • '0.0.0.0':任何人都可以访问
  • portnumber,(默认8080),配置端口
  • openboolean,(默认false),浏览器自动打开项目
  • 性能优化
  • compressboolean,(默认true),启用压缩,如:Content-Encoding: gzip
  • 跨域代理
  • proxy{'/api': { target, pathRewrite, changeOrigin }},设置服务器代理
    • targetstring,存储资源的真实地址。
    • pathRewrite{},重写路径,可以去除url中的/api。如pathRewrite: { '^/api': '' }
    • changeOriginboolean,(默认false),默认情况下,代理时会保留主机头的来源,可以将 changeOrigin 设置为 true 以覆盖此行为。

devtool

作用: 控制是否生成,以及如何生成 source-map

常见devtool选项:

  • 不生成source-map文件:

  • false:``,不使用source-map,也就是没有任何和source-map相关的内容。

  • none:``,

  • eval:``,

  • development环境:

  • eval:``,(development模式下的默认值),不生成source-map。

    • 但是它会在eval执行的代码中,添加//# sourceURL=
    • 它会被浏览器在执行时解析,并且在调试面板中生成对应的一些文件目录,方便我们调试代码。但不是很准确
  • 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},用于对代码进行分割和提取公共模块。可以将一些通用的模块抽离出来成为单独的文件,以减小打包文件的体积,提高加载速度。

    • chunksall | async | initial | ()=>{},指定哪些 chunk 参与分割

      • 'all':(),加载所有 chunk。
      • 'async':(默认),按需加载异步的 chunk。
      • 'initial':(),仅对入口点的代码进行分割。
      • ()=>{}:(),提供一个函数去做更多的控制。这个函数的返回值将决定是否包含每一个 chunk。
    • minSizenumber,指定分割后的 chunk 的最小大小,单位为 bytes。

    • maxSizenumber,指定分割后的 chunk 的最大大小,单位为 bytes。如果为 0,则表示没有限制。

    • cacheGroups{key: {test, priority, filename, reuseExistingChunk}, key: {}...},缓存组,用于配置不同类型的模块如何被分割。

      • testreg | function | string,用于匹配符合条件的模块。
      • prioritynumber默认:-20,决定模块被打包到哪个 cache group 的优先级,数值越大优先级越高。
      • filenamestring | (pathData, assetInfo) => string,给生成的文件分配名称。
      • reuseExistingChunkboolean默认:true,是否重用已经存在的 chunk。
  • chunkIdsfalse | 'natural' | 'named' | 'deterministic' | 'size' | 'total-size'

    ​ 告知 webpack 当选择模块 id 时需要使用哪种算法。

    • false:(默认),没有任何内置的算法。但自定义的算法会由插件提供。

    • named:(开发模式默认值),对调试更友好的可读的 id。(完整的名子)

    • deterministic:(生产模式默认),在不同的编译中不变的短数字 id。有益于长期缓存。(数字不会变化)

      • 在 webpack4 中是没有这个值的,那个时候如果使用 natural,那么在一些编译发生变化时,就会有问题
    • natural:(),按使用顺序的数字 id。(数字会变化)

    • size:(),专注于让初始下载包大小更小的数字 id。

    • total-size:(),专注于让总下载包大小更小的数字 id。

  • runtimeChunktrue | 'multiple' | 'single' | {name},配置 runtime 相关的代码是否抽取到一个单独的 chunk 中,目前已经不再单独打包

    • true | multiple:(),针对每个入口打包一个 runtime 文件
    • single:(),打包一个 runtime 文件
    • {name}:(推荐),name 属性决定 runtimeChunk 的名称
  • minimizeboolean,告知webpack使用 TerserPlugin 或其它在 optimization.minimizer 定义的插件压缩 bundle。

  • minimizer[new TerserPlugin()?, new CssMinimizer()?, '...'?]

    ​ 允许你通过提供一个或多个定制过的 TerserPlugin 实例,覆盖默认压缩工具(minimizer)。

    • new TerserPlugin()?( {extractComments?, parallel?, terserOptions?} )

      ​ 用于对JS代码简化的插件

      • 依赖包:terser-webpack-plugin (内置插件)
      • extractCommentsboolean,(D: true),将注释抽取到一个单独的文件中。
        • 注意: 开发中,不希望保留这个注释时,可以设为 false
      • parallelboolean,(D: true),使用多进程并发运行提高构建的速度
        • 注意: 并发运行的默认数量: os.cpus().length - 1
      • terserOptions{compress, mangle, toplevel, keep_classnames, keep_fnames},设置terser配置
        • compress{arrows, arguments, dead_code, unused},设置压缩相关的选项
          • arrowsboolean,(),将class或者object中的函数转换成箭头函数
          • argumentsboolean,(),将函数中使用的arguments[index]转成对应的形参名称
          • dead_codeboolean,(D: true),移除不可达的代码(tree shaking)
          • unusedboolean,(D: true),移除未使用过的函数(tree shaking)
        • mangleboolean,设置丑化相关的选项,可以直接设置为 true
        • toplevelboolean,顶层变量是否进行转换
        • keep_classnamesboolean,保留类的名称
        • keep_fnamesboolean,保留函数的名称
    • new CssMinimizer()?( {parallel?, minimizerOptions?} ),压缩和优化 CSS 代码的插件

      • 依赖包:css-minimizer-webpack-plugin (内置插件)
      • parallel?boolean,(D: true),是否开启多进程并行压缩
      • minimizerOptions?{preset},传递给 CssMinimizer压缩器的选项,如指定压缩规则、是否启用并行压缩等
    • '...'?,可以使用 '...' 来访问默认值

  • usedExportsboolean默认:true,帮助 Webpack 识别和剔除未使用的导出

示例:

js
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 的名称;

image-20240229141439870

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,使用!分割

js
import "css-loader!../css/style.css"

缺点: 使用不方便

方式二:CLI方式

webpack5中不再支持

方式三:配置方式(推荐

webpack.config.jsmodule.rules中添加规则

打包CSS

依赖包:

  • style-loader:负责把CSS插入到DOM中
    • 安装:npm i style-loader -D
  • css-loader:负责解析css代码
    • 安装:npm i css-loader -D

配置:

完整use写法:

image-20240621110329918

**简写一:**只有一个loader

image-20240222132054683

简写二: 多个loader没有其他属性(推荐)

image-20240222132100714

打包: 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

配置:

image-20240222132426426

打包: 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插件

1、基本配置 image-20240222132858296

2、抽取postcss-loader的配置

​ 2.1、在项目根目录创建postcss.config.js文件

​ 2.2、添加postcss配置

image-20240222132933897

3、替换成postcss-preset-envimage-20240222132939569

打包: npm run build

image-20240621110208032

打包图片

  • 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
        • maxSizenumber默认:8096,指定打包成base64的图片最大值(单位:byte)。和type: asset配合使用
    • generator{filename},重命名打包后的资源文件
      • filename:``,重命名打包后的资源文件,可以和占位符配合使用

在webpack中任何图片都是一个模块

image-20240222133021625

依赖包:

  • file-loader:(弃用),早期加载文件模块的loader
  • 现在已经内置了文件loader:type: "asset"

配置:

1、基本配置

image-20240222133309799

打包方式:

**方式一:**打包图片成单独文件:asset/resource

  • 缺点: 会额外多发送网络请求获取打包的图片

image-20240222133441737

**方式二:**打包图片成base64编码:asset/inline

  • 缺点: 会造成打包后的JS文件很大,下载消耗时间过长,阻塞其他任务

image-20240222133548179

**方式三:**自动选择打包成图片还是base64编码:asset

  • 优点: 可以解决resourceinline的缺点,在二者中间寻求一个平衡

    • 小图片:进行base64编码

    • 大图片:单独打包图片

image-20240222133647722

重命名打包后的文件:

**方式一:**配置output.assetModuleFilename

  • 缺点: 配置后,所有的资源文件都是这个名字

image-20240222133925475

**方式二:**配置module.rules.[{generator.filename}]

  • 基本使用

    image-20240222133950626

  • 添加目录

    image-20240222133958543

image-20240621114934636

打包: 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、基本配置

image-20240222134608965

2、配置Babel插件-转化箭头函数(废弃

image-20240222134616386

3、配置Babel插件-转化变量声明关键字(废弃

image-20240222134636348

4、抽取babel配置

​ 4.1、在项目根目录创建babel.config.js文件

​ 4.2、添加babel配置

image-20240222134715265

5、使用@babel/preset-env替代

image-20240222134722229

打包: 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()

image-20240808111003094

打包: 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、设置resolve.extensions,让webpack自动为文件添加后缀

  • 配置

    image-20240222135652474

  • 使用

    image-20240222135708731

2、设置resolve.mainFiles,让webpack自动为目录添加索引文件

注意: 一般不修改默认配置

  • 配置

  • 使用

3、设置resolve.alias,为某些目录配置别名

  • 配置

    image-20240222135748878

  • 使用

    image-20240222135757596

Plugins

loader对比插件:

  • loader 用于转换特定类型的模块。
  • 插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。

常用插件:

  • VueLoaderPlugin: ``,打包Vue
  • CleanWebpackPlugin:``,(过时),清理Webpack输出目录的插件
  • HtmlWebpackPlugin:``,快速创建 HTML 模板用于打包
  • DefinePlugin:``,允许创建一些在编译时可配置的全局常量

VueLoaderPlugin()

见:打包Vue

CleanWebpackPlugin

作用: 清理Webpack输出目录的插件

依赖包:

  • clean-webpack-plugin:``,
    • 安装:npm i clean-webpack-plugin -D

配置:

image-20240222140206448

注意: 可以通过设置output.clean代替该插件

HtmlWebpackPlugin

作用: 快速创建 HTML 模板用于打包

依赖包:

  • html-webpack-plugin:``,
    • 安装:npm i html-webpack-plugin -D

配置:

1、基本配置

image-20240222140333619

2、配置title

image-20240222140347539

使用

image-20240222140407932

3、自定义模板文件

image-20240222140354319

DefinePlugin

作用: 允许创建一些在编译时可配置的全局常量

依赖包: webpack内置插件,无需安装

配置:

image-20240222140440941

注意: 配置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脚本

sh
"serve": "webpack serve --config wk.config.js"

2、运行命令

sh
npm run serve

注意: webpack-dev-server在编译之后不会写入到任何输出文件,而是将bundle文件保留在内存中

缺点:

  • 局部修改后,整个页面都会被重新刷新一遍,浪费性能
  • 可以通过HMR解决该问题

devServer配置:devServer

HMR

~~概述:~~HMR: Hot Module Replacement(热更新,模块热替换),指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个页面

优点:

  • 不重新加载整个页面,可以保留某些状态不丢失
  • 只更新需要变化的内容,节省开发时间
  • 修改了源代码,会立即在浏览器更新

开启HMR:

1、默认已经开启了HMR,但此时依然没有实现热更新

2、还需要指定哪个模块使用热更新

image-20240222141035482

框架中的HMR: 在框架中已经提供了成熟的HMR解决方案,无需手动开启

  • Vue:
    • vue-loader
  • React
    • React Hot Loader已弃用
    • react-refresh

跨域代理

见:跨域代理

区分开发环境

创建3个配置文件:

  • webpack.dev.config.js:不需要clean
  • webpack.prod.config.js:不需要devServer
  • webpack.common.config.js:不需要clean、devServer、mode

1、修改scripts

js
"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配置中执行合并

    image-20240719162503510

Webpack的模块化

Webpack打包的代码,允许我们使用各种各样的模块化,但是最常用的是CommonJS、ES Module

  • 那么它是如何帮助我们实现了代码中支持模块化呢?

我们来研究一下它的原理,包括如下原理:

  • CommonJS模块化实现原理;

  • ES Module实现原理;

  • CommonJS加载ES Module的原理;

  • ES Module加载CommonJS的原理;

这里不再给出代码,查看课堂代码的注释解析;