Skip to content

webpack 学习

01.安装开发环境

shell
yarn init -y
yarn add webpack webpack-cli -D

02.项目目录

隐藏了 node_modules 文件夹

shell
.
├── package.json
├── src
   ├── index.js
   ├── one.js
   └── two.js
└── yarn.lock

03.打包项目

开发模式:

shell
node_modules/.bin/webpack --mode development

生产模式:

shell
node_modules/.bin/webpack --mode production

04.基本文件

javascript
const { resolve } = require('path')
module.exports = {
  // 1. entry 入口 指示webpack以哪个文件作为入口起点开始打包
  entry: './src/index.js',
  // 2. output 出口 指示webpack打包后的资源输出到哪里,以及命名
  output: {
    filename: 'main.js',
    path: resolve(__dirname, 'build'),
  },
  // 3. loader 帮webpack处理非javascript资源(css,img,font,icon等),webpack自身只能理解js和json
  module: {
    rules: [],
  },
  // 4. plugins 帮助webpack执行范围更广的任务,范围包括从打包优化压缩到重新定义环境中的变量
  plugins: [],
  /* 5. mode
    开发模式(development) 配置比较简单,能让代码本地调试运行的环境
    生产模式(production) 代码需要不断优化到性能最好,能让代码优化上线运行的环境,会自动启用一些插件,生产环境使用插件更多
  */
  mode: 'development',
}

05.多入口与多出口配置

javascript
module.exports = {
  // 1. entry 入口 指示webpack以哪个文件作为入口起点开始打包
  // 单入口
  // entry: './src/index.js',
  // 多入口
  entry: { one: './src/index.js', tow: './src/main.js' },
  // 2. output 出口 指示webpack打包后的资源输出到哪里,以及命名
  // 单出口
  // output: {
  //   filename: 'main.js',
  //   path: resolve(__dirname, 'build')
  // },
  // 多出口
  output: {
    filename: '[name].js',
    path: resolve(__dirname, 'build')
  },

06.打包和压缩 Html 资源

安装插件 html-webpack-plugin

shell
yarn add html-webpack-plugin

引入插件并配置

javascript
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  plugins: [
    // 默认会创建一个空的html文件,目的为自动引入js、css资源
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'demo.html',
      minify: {
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true,
      },
    }),
  ],
}

07.打包多个 Html 开发

javascript
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  // 多入口
  entry: {
    vendor: ['./src/js/jQ.js', './src/js/common.js'],
    index: './src/js/index.js',
    cart: './src/js/cart.js',
  },
  // 多出口
  output: {
    filename: '[name].js',
    path: resolve(__dirname, 'build'),
  },
  // 3. loader 帮webpack处理非javascript资源(css,img,font,icon等),webpack自身只能理解js和json
  module: {
    rules: [],
  },
  // 4. plugins 帮助webpack执行范围更广的任务,范围包括从打包优化压缩到重新定义环境中的变量
  plugins: [
    // 默认会创建一个空的html文件,目的为自动引入js、css资源
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
      chunks: ['index', 'vendor'],
      minify: {
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true,
      },
    }),
    new HtmlWebpackPlugin({
      template: './src/cart.html',
      filename: 'cart.html',
      chunks: ['cart', 'vendor'],
      minify: {
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true,
      },
    }),
  ],
  /* 5. mode
    开发模式(development) 配置比较简单,能让代码本地调试运行的环境
    生产模式(production) 代码需要不断优化到性能最好,能让代码优化上线运行的环境,会自动启用一些插件,生产环境使用插件更多
  */
  mode: 'development',
}

08.打包 Css 资源

安装 loader 资源

shell
yarn add css-loader style-loader -D

在 js 文件中引入 css 文件

javascript
// main.js
require('./style.css')

配置 webpack 文件

javascript
// 3. loader 帮webpack处理非javascript资源(css,img,font,icon等),webpack自身只能理解js和json
module: {
  rules: [
    {
      test: /\.css$/, // 匹配文件类型
      use: ['style-loader', 'css-loader'] // 从最后一个开始,第一个为最后一个
    }
  ]
},

09.打包 Scss 资源

安装 loader 资源

shell
yarn add node-sass sass-loader -D

配置 webpack 文件

javascript
// 3. loader 帮webpack处理非javascript资源(css,img,font,icon等),webpack自身只能理解js和json
  module: {
    rules: [
      {
        test: /\.css$/, // 匹配文件类型
        use: ['style-loader', 'css-loader'] // 从最后一个开始,第一个为最后一个
      },
      {
        test: /\.scss$/, // 注意匹配类型为scss 而不是sass
        use: ['style-loader', 'css-loader', 'sass-loader']
      }
    ]
  },

10.提取 css 文件

10.1 安装插件

shell
yarn add mini-css-extract-plugin -D

10.2 配置 webpack 文件

javascript
module: {
  rules: [
    {
      test: /\.css$/, // 匹配文件类型
      // use: ['style-loader', 'css-loader'] // 从最后一个开始,第一个为最后一个
      use: [MiniCssExtractPlugin.loader, 'css-loader'] // 从最后一个开始,第一个为最后一个
    },
    {
      test: /\.scss$/, // 注意匹配类型为scss 而不是sass
      // use: ['style-loader', 'css-loader', 'sass-loader']
      use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
    }
  ]
},
  // 4. plugins 帮助webpack执行范围更广的任务,范围包括从打包优化压缩到重新定义环境中的变量
  plugins: [
    // 默认会创建一个空的html文件,目的为自动引入js、css资源
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html'
    }),
    new MiniCssExtractPlugin()
  ],

11.设置 css 兼容性

11.1 安装插件

shell
 yarn add postcss-loader postcss-preset-env -D

11.2 配置 webpack 文件

javascript
module: {
    rules: [
      {
        test: /\.css$/, // 匹配文件类型
        // use: ['style-loader', 'css-loader'] // 从最后一个开始,第一个为最后一个
        use: [MiniCssExtractPlugin.loader, 'css-loader','postcss-loader'] // 从最后一个开始,第一个为最后一个
      },
      {
        test: /\.scss$/, // 注意匹配类型为scss 而不是sass
        // use: ['style-loader', 'css-loader', 'sass-loader']
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
      }
    ]
  },

11.3 新建 postcss.config.js 文件并配置

javascript
module.exports = {
  plugins: [require('postcss-preset-env')()],
}

11.4 示例:

源 css 文件

css
.box {
  backface-visibility: hidden;
}

打包后 css 文件:

css
.box {
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

12.压缩 css 代码

安装插件 css-minimizer-webpack-plugin

shell
yarn add css-minimizer-webpack-plugin -D

配置 webpack 文件

javascript
module.exports = {
  // 优化
  optimization: {
    // 允许你通过提供一个或多个定制过的 TerserPlugin 实例,覆盖默认压缩工具(minimizer)。
    minimizer: [new CssMinimizerPlugin()],
    // 在开发环境下启用css压缩
    minimize: true,
  },
}

13.打包图片资源

13.1 背景图片引入

在 webpack 5 之前,通常使用:

资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:

  • asset/resource 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现。

  • asset/inline 导出一个资源的 data URI。之前通过使用 url-loader 实现。

  • asset/source 导出资源的源代码。之前通过使用 raw-loader 实现。

  • asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体积限制实现。

配置 webpack 文件

javascript
module.exports = {
  output: {
    filename: 'main.js',
    path: resolve(__dirname, 'build'),
    assetModuleFilename: 'images/[hash][ext][query]',
  },
  module: {
    rules: [
      { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] },
      { test: /\.scss$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'] },
      { test: /\.(png|jpg|gif)$/i, type: 'asset/resource' },
    ],
  },
}

默认情况下,asset/resource 模块以 [hash][ext][query] 文件名发送到输出目录。

可以通过在 webpack 配置中设置 output.assetModuleFilename 来修改此模板字符串,如上图所示

⚠️注意: 现在,webpack 将按照默认条件,自动地在 resourceinline 之间进行选择:小于 8kb 的文件,将会视为 inline 模块类型,否则会被视为 resource 模块类型。 可以通过在 webpack 配置的 module rule 层级中,设置 Rule.parser.dataUrlCondition.maxSize 选项来修改此条件

javascript
module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.txt/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 4 * 1024, // 4kb
          },
        },
      },
    ],
  },
}

13.2 src 图片引入

安装 loader 资源:html-loader

shell
yarn add html-loader -D

配置 webpack 文件:

javascript
module.exports = {
  module: {
    rules: [{ test: /\.html$/, loader: 'html-loader' }],
  },
}

14.字体文件打包

下载把字体放入 font 文件夹中

shell
src
├── css
│   ├── index.scss
│   └── style.css
├── fonts
│   ├── iconfont.css
│   ├── iconfont.js
│   ├── iconfont.ttf
│   ├── iconfont.woff
│   └── iconfont.woff2
├── images
│   └── 1.png
├── index.html
└── index.js

配置入口文件

javascript
# index.js
require('@/fonts/iconfont')

配置 html 文件

html
<html lang="zh">
  <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" />
    <style>
      .icon {
        width: 2em;
        height: 2em;
        vertical-align: -0.15em;
        fill: currentColor;
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <!-- Symbol 引用 -->
    <svg class="icon" aria-hidden="true">
      <use xlink:href="#icon-VIP"></use>
    </svg>
    VIP
    <svg class="icon" aria-hidden="true">
      <use xlink:href="#icon-caiyi"></use>
    </svg>
    才艺
    <svg class="icon" aria-hidden="true">
      <use xlink:href="#icon-daka"></use>
    </svg>
    打卡
    <!-- Class 引用-->
    <!-- <i class="iconfont icon-VIP">vip</i>
    <i class="iconfont icon-caiyi">才艺</i>
    <i class="iconfont icon-daka">打卡</i> -->
  </body>
</html>

配置 webpack 文件

javascript
module.exports = {
  module: {
    rules: [{ test: /\.(woff|woff2|eot|ttf|otf)$/, type: 'asset' }],
  },
  // (可选)创建 import 或 require 的别名,来确保模块引入变得更简单。
  // 例如,一些位于 src/ 文件夹下的常用模块:
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src/'),
      images: resolve(__dirname, 'src/images/'),
    },
  },
}