Webpack 知识体系 | 青训营笔记

97 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 13 天

Webpack 简介

概念

前端资源编译及打包工具

前端工程化主要工具

工程化工具

gulp、grunt、rollup.js、browserify、webpack、vite

优势

  • 多份资源文件打包成一个 Bundle
  • 支持 Babel、Eslint、TypeScript、CoffeeScript、Less、Sass 等
  • 支持模块化处理 CSS、图片 等资源文件
  • 支持 HMR + 开发服务器
  • 支持持续监听、持续构建
  • 支持代码分离
  • 支持 Tree-shaking
  • 支持 Sourcemap

核心流程

  1. 入口处理

从 entry 文件开始,启动编译流程

  1. 依赖解析

从 entry 文件开始,根据 require 或 import 等语句找到依赖资源

  1. 资源解析

根据 module 配置,调用资源转移器,将 png、CSS 非标准 JS 资源转译为 JS 内容

  1. 资源合并打包

将转译后的资源内容打包为可直接在浏览器运行的 JS 文件

特性

  • 多个文件资源合并成一个,减少 HTTP 请求数
  • 支持模块化开发
  • 支持高级 JS 特性
  • 支持 TypeScript、CoffeeScript 方言
  • 统一图片、CSS、字体等其他资源的处理模型

Webpack 简单使用

  1. 安装相关依赖
npm i webpack webpack-cli -D
  1. 编辑配置文件
module.exports = {
  entry: 'main.js',
  mode: 'development',
  devtool: false,
  output: {
    filename: '[name].js',
    path: path.join(__dirname, './dist'),
  },
  module: {},
  plugins: {},
};
  1. 执行构建命令
npx webpack

Webpack 配置

流程类配置

  • 输入 entry、context
  • 模块解析 resolve、externals
  • 模块转译 module
  • 后处理 optimization、mode、target
  • 输出 output

工具类配置

  • 开发效率 watch、devtool、devServer
  • 性能优化 cache、performance
  • 日志 stats、infrastructureLogging

其他配置

amd、bail

配置示例

module.exports = {
  entry: 'main.js',
  output: {
    filename: '[name].js',
    path: path.join(__dirname, './dist'),
  },
  mode: 'development',
  devtool: false,
  devServer: {
    hot: true,
  },
  watch: true,
  module: {
    rules: [
      {
        test: /.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /.js$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: [
                ['@babel/preset-env'],
              ],
            },
          },
        ],
      },
      {
        test: /.less$/,
        use: ['style-loader', 'css-loader', 'less-loader'],
      },
    ],
  },
  plugins: [
    new HTMLWebpackPlugin(),
  ],
}

Webpack 使用

输入输出

module.exports = {
  entry: 'main.js',
  output: {
    filename: '[name].js',
    path: path.join(__dirname, './dist'),
  },
}

css 使用

npm i style-loader css-loader -D

module.exports = {
  modules: {
    rules: [
      {
        test: /.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
}

babel 使用

npm i @babel/core @babel/preset-env babel-loader -D

@babel/preset-env @babel/preset-react @babel/preset-typescript

module.exports = {
  modules: {
    rules: [
      {
        test: /.js$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: [
                ['@babel/preset-env'],
              ],
            },
          },
        ],
      },
    ],
  },
}

生成 HTML

npm i html-webpack-plugin -D

module.exports = {
  plugins: [
    new HTMLWebpackPlugin(),
  ],
}

HMR

即 hot module replacement

启动 npx webpack serve

module.exports = {
  devServer: {
    hot: true,
  },
  watch: true,
}

Tree-Shaking

移除未使用的代码

配置 optimization.usedExports

对部分工具库如 lodash 效果非常好

module.exports = {
  mode: 'production',
  optimization: {
    usedExports: true,
  },
}

loader

处理非 js 引用文件,转换为 js 支持识别的形式

其他一些 loader

自定义 loader

  • 链式执行
  • 支持异步执行
  • 分 normal、pitch 两种模式
module.exports = function (source) {
  console.log(source);
  return source;
}

自定义插件

class MyPlugin {
  apply (compiler) {
    compiler.hooks.thisCompilation.tap('MyPlugin', (compilation) => {})
  };
}

总结