迎接2026,重新认识Webpack5

文章目录

    • 概要
    • 主要内容
      • [1. 安装nvm、node.js](#1. 安装nvm、node.js)
      • [2. 初始化项目、安装并配置Webpack5](#2. 初始化项目、安装并配置Webpack5)
      • [3. Loader 和 Plugin](#3. Loader 和 Plugin)
      • [4. 减小打包体积](#4. 减小打包体积)
      • [5. 提高打包速度](#5. 提高打包速度)
      • [6. 优化 LCP/FCP](#6. 优化 LCP/FCP)
      • [7. Web Vitals 优化](#7. Web Vitals 优化)
      • [8. DDL 预加载](#8. DDL 预加载)
        • [8.1 创建 DLL 配置文件](#8.1 创建 DLL 配置文件)
        • [8.2 总配置方案](#8.2 总配置方案)
        • [8.3 配置 package.json 脚本](#8.3 配置 package.json 脚本)
    • 小结

概要

时光飞逝,前端技术更是日新月异。转眼间,我们已站在2025年的尾巴上,即将迈入2026年。在这个框架林立、工具纷繁的时代,你是否曾感到一丝焦虑:那些被视为"基石"的技术,真的掌握了吗?

Webpack5,作为现代前端工程化的奠基者与核心,曾一度是面试和开发的"必问题"。尽管如今有Vite等后起之秀凭借其极速的热更新吸引了大量目光,但Webpack凭借其无与伦比的生态、成熟的解决方案和极其灵活的模块打包能力,依然是众多大型项目的首选,其底层思想更是理解前端构建的关键。

前面都是废话,Webpack5是一个现代化的前端构建工具,用于打包JavaScript、CSS、图像等资源。它通过模块化处理依赖关系,提升开发效率和性能。三十年河东三十年河西,今时不同往日,虽然Webpack已经没有了往日的荣光,但是当年这么多用 Webpack 创建的项目都还需要维护,因此还是值得前端开发者去学习的。

主要内容

1. 安装nvm、node.js

Webpack5依赖Node.js环境,首先确保已安装 Node.js(建议版本14+)。

但我不推荐你直接安装 Node.js,而是推荐你先安装 nvm-windows,然后再通过 nvm 来安装和管理 Node.js 版本。

  • 安装最新的长期支持版本:

    bash 复制代码
    # 安装最新的 LTS 版本
    nvm install lts
    
    # 使用刚刚安装的 LTS 版本
    nvm use lts
    
    # 设置该版本为默认版本(可选)
    nvm on
    
    # 验证安装是否成功
    node --version
    npm --version
  • 不同项目使用不同版本(切换版本):

    bash 复制代码
    # 查看所有可安装的远程版本
    nvm list available
    
    # 安装特定版本,如 18.20.2
    nvm install 18.20.2
    
    # 查看本地已安装的所有版本
    nvm list
    
    # 切换到版本 18.20.2
    nvm use 18.20.2

这样做主要有以下几个无法替代的巨大优势:

  1. 轻松切换 Node.js 版本:不同的项目可能需要不同版本的 Node.js。使用 nvm,你可以在一台电脑上同时安装多个版本(如最新的 20.x、稳定的 18.x LTS),并可以随时在命令行中一键切换,非常灵活。
  2. 避免权限问题:在 Windows 上直接安装 Node.js 可能会遇到全局包安装需要管理员权限的问题。通过 nvm 安装的 Node.js 会存在于你的用户目录下,彻底避免这类烦人的权限错误。
  3. 简单的安装/卸载:使用 nvm install <version>nvm uninstall <version> 来安装或卸载 Node.js 版本比手动清理要简单干净得多。

2. 初始化项目、安装并配置Webpack5

  • 初始化Node.js项目:在命令行中创建项目文件夹并初始化package.json文件。

    bash 复制代码
    mkdir my-webpack-project  # 创建项目文件夹
    cd my-webpack-project     # 进入文件夹
    npm init -y               # 初始化项目,使用默认配置
  • 安装Webpack5:推荐局部安装(仅当前项目使用),避免全局冲突。

    bash 复制代码
    npm install webpack webpack-cli --save-dev  # 安装最新版Webpack和CLI工具
    npm install webpack-dev-server --save-dev  # 安装开发服务器(devServer)实现热更新和本地调试
  • 安装后,Webpack5命令可通过npx webpack执行。安装Webpack-cli后,可使用webpack-cli init交互式初始化项目配置。

    bash 复制代码
    # 查看Webpack版本
    webpack -v
    
    # 指定入口文件打包,例如webpack src/index.js dist/bundle.js
    webpack <entry> [<entry>] <output>
    
    # 使用自定义配置文件打包
    webpack --config webpack.conf.js
  • Webpack5的核心是配置文件webpack.config.js

    • 定义入口、输出、加载器等。

      js 复制代码
      // webpack.config.js
      const path = require('path');
      
      module.exports = {
        entry: './src/index.js',     // 入口文件
        output: {
          filename: 'bundle.js',      // 输出文件名
          path: path.resolve(__dirname, 'dist') // 输出目录
        },
        mode: 'development',          // 开发模式(简化调试)
      };
    • 定义热更新和本地调试。

      js 复制代码
      module.exports = {
        // ...其他配置
        devServer: {
          static: './dist',   // 静态文件目录
          hot: true,          // 热更新
          port: 8080          // 端口
        }
      };
    • 安装配置Loader和Plugin。

      • Loader处理非JS资源(如CSS),例如安装css-loader和style-loader。
      • Plugin优化构建,如HtmlWebpackPlugin生成HTML文件。

3. Loader 和 Plugin

  • Webpack 5 的常用 Loader 和 Plugin 分类及代表工具:

    类型 名称 作用描述
    Loader babel-loader 转换 ES6+/TypeScript 代码为浏览器兼容JS
    css-loader 解析CSS 中的 @import 和 url() 依赖
    style-loader 将 CSS 注入 DOM(通过 <style> 标签)
    sass-loader 编译 SCSS/Sass 为 CSS
    postcss-loader 使用 PostCSS 处理 CSS(自动添加前缀等)
    file-loader 处理图片/字体等资源文件(Webpack 5 可用资源模块替代)
    Plugin HtmlWebpackPlugin 自动生成 HTML 并注入打包后的资源链接
    MiniCssExtractPlugin 将 CSS 提取为独立文件(替代 style-loader)
    CleanWebpackPlugin 构建前清理输出目录
    CompressionPlugin 生成 Gzip/Brotli 压缩文件
    BundleAnalyzerPlugin 可视化分析包体积
  • Loader:文件加载时转换器

    • babel-loader:转换 ES6+/TypeScript 代码为浏览器兼容 JS

    • css-loader:解析 CSS 中的 @importurl() 依赖

    • style-loader:将 CSS 注入 DOM(通过 <style> 标签)

    • sass-loader:编译 SCSS/Sass 为 CSS

    • postcss-loader:使用 PostCSS 处理 CSS(自动添加前缀等)

    • file-loader:处理图片/字体等资源文件(Webpack 5 可用资源模块替代)

    • 安装

      bash 复制代码
      npm i -D babel-loader @babel/core @babel/preset-env
      npm i -D css-loader
      npm i -D style-loader
      npm i -D sass-loader sass
      npm i -D postcss-loader postcss
      npm i -D file-loader
    • 配置

      js 复制代码
      /**
       * CSS处理链:sass-loader(先编译Sass) -> postcss-loader(处理CSS) -> css-loader(解析CSS) -> style-loader(注入CSS)
       */
      module.exports = {
        module: {
          rules: [
            // Babel for JavaScript
            {
              test: /\.js$/,
              exclude: /node_modules/,
              use: 'babel-loader'
            },
            // CSS with PostCSS
            {
              test: /\.css$/,
              use: ['style-loader', 'css-loader', 'postcss-loader']
            },
            // Sass with PostCSS
            {
              test: /\.scss$/,
              use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader']
            },
            // File loader for images
            {
              test: /\.(png|jpe?g|gif|svg)$/,
              use: {
                loader: 'file-loader',
                options: { outputPath: 'assets/' }
              }
            }
          ]
        }
      };
  • Plugin:扩展 Webpack 功能的钩子,用于优化资源

    • HtmlWebpackPlugin:自动生成 HTML 并注入打包后的资源链接

    • MiniCssExtractPlugin:将 CSS 提取为独立文件(替代 style-loader)

    • CleanWebpackPlugin:构建前清理输出目录

    • CompressionPlugin:生成 Gzip/Brotli 压缩文件

    • BundleAnalyzerPlugin:可视化分析包体积

    • 安装

      bash 复制代码
      npm i -D html-webpack-plugin
      npm i -D mini-css-extract-plugin
      npm i -D clean-webpack-plugin
      npm i -D compression-webpack-plugin
      npm i -D webpack-bundle-analyzer
    • 配置

      js 复制代码
      /**
       * HtmlWebpackPlugin: 生成HTML文件,并自动注入打包后的资源
       * MiniCssExtractPlugin: 将CSS提取为单独的文件
       * CleanWebpackPlugin: 在每次构建前清理输出目录
       * CompressionPlugin: 为资源提供gzip等压缩版本
       * BundleAnalyzerPlugin: 生成打包分析报告,帮助优化体积
       */
      const path = require('path');
      const { CleanWebpackPlugin } = require('clean-webpack-plugin');
      const HtmlWebpackPlugin = require('html-webpack-plugin');
      const MiniCssExtractPlugin = require('mini-css-extract-plugin');
      const CompressionPlugin = require('compression-webpack-plugin');
      const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
      
      module.exports = {
        entry: './src/index.js',
        output: {
          path: path.resolve(__dirname, 'dist'),
          filename: 'js/[name].[contenthash:8].js'
        },
        module: {
          rules: [
            {
              test: /\.css$/,
              use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
            }
          ]
        },
        plugins: [
          new CleanWebpackPlugin(),
          new HtmlWebpackPlugin({
            template: './public/index.html'
          }),
          new MiniCssExtractPlugin({
            filename: 'css/[name].[contenthash:8].css'
          }),
          new CompressionPlugin(),
          new BundleAnalyzerPlugin({ analyzerMode: 'disabled' }) // 按需启用
        ]
      };
  • Loader vs Plugin 核心区别:

    • Loader:文件加载时转换器(如转译 JSX、编译 SCSS)
    • Plugin:扩展 Webpack 功能的钩子(如优化资源、生成HTML)

4. 减小打包体积

  • 关键优化:

    • Tree Shaking:生产模式自动启用(需 ES6 模块语法)
    • 资源压缩:图片使用 image-webpack-loader 进一步压缩
    • 按需加载:使用 import() 动态导入路由组件
  • 插件:

    • 压缩JavaScript:terser-webpack-plugin
    • 压缩CSS:css-minimizer-webpack-plugin
    • 压缩图片:image-minimizer-webpack-plugin
    bash 复制代码
    npm i -D terser-webpack-plugin 
    npm i -D css-minimizer-webpack-plugin 
    npm i -D image-minimizer-webpack-plugin  
  • 配置:

    js 复制代码
    const TerserPlugin = require("terser-webpack-plugin");
    const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
    const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin"); // 引入图片压缩插件
    
    module.exports = {
      optimization: {
        minimize: true,
        minimizer: [
          // 1. JS 压缩器
          new TerserPlugin({
            parallel: true,
            terserOptions: {
              compress: { drop_console: true },
            },
          }),
    
          // 2. CSS 压缩器
          new CssMinimizerPlugin(),
    
          // 3. 图片压缩插件
          new ImageMinimizerPlugin({
            minimizer: {
              implementation: ImageMinimizerPlugin.imageminMinify,
              options: {
                plugins: [
                  ["imagemin-mozjpeg", { quality: 80 }], // 压缩 JPEG
                  ["imagemin-pngquant", { quality: [0.6, 0.8] }], // 压缩 PNG
                  ["imagemin-gifsicle", { interlaced: true }], // 压缩 GIF
                  ["imagemin-svgo", { plugins: [{ removeViewBox: false }] }], // 压缩 SVG
                ],
              },
            },
            // 生成 webp 格式的选项(可选)
            generator: [
              {
                preset: "webp",
                implementation: ImageMinimizerPlugin.imageminGenerate,
                options: { plugins: ["imagemin-webp"] },
              },
            ],
          }),
        ],
        // 4. 代码分割配置(保持原样)
        splitChunks: {
          chunks: "all",
          cacheGroups: {
            vendor: {
              test: /[\\/]node_modules[\\/]/,
              name: "vendors",
            },
          },
        },
      },
      module: {
        rules: [
          // 5. 资源模块配置(图片处理)
          {
            test: /\.(png|jpe?g|gif|svg)$/i,
            type: "asset/resource",
            generator: {
              filename: "images/[hash][ext][query]", // 输出路径
            },
          },
        ],
      },
    };

5. 提高打包速度

  • 提速技巧:
    • 限制 Loader 范围:通过 include/exclude 减少处理文件
    • 多进程构建:使用 thread-loader(CPU密集型操作),需要在 babel-loader 之前!
    • DLL 预构建:对稳定库(如 React)提前打包
js 复制代码
const os = require("os");

module.exports = {
  // Webpack 5 持久化缓存配置
  cache: {
    type: "filesystem",
    buildDependencies: {
      config: [__filename], // 配置文件变更时刷新缓存
    },
  },

  resolve: {
    extensions: [".js", ".jsx", ".json"], // 文件扩展名
    alias: {
      "@": path.resolve(__dirname, "src"), // 路径别名
    },
  },

  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "thread-loader", // 添加 thread-loader
            options: {
              workers: os.cpus().length - 1, // 根据 CPU 核心数自动设置
              workerParallelJobs: 50,
              poolTimeout: 2000,
            },
          },
          {
            loader: "babel-loader",
            options: {
              cacheDirectory: true, // 启用 Babel 缓存[^1]
              presets: ["@babel/preset-env"],
            },
          },
        ],
      },
    ],
  },
};

6. 优化 LCP/FCP

  • 概念
    • LCP(最大内容渲染):首屏主要内容加载时间
    • FCP(首次内容渲染):首次任意内容渲染时间
  • LCP/FCP 专项优化:
    • 关键 CSS 内联:使用 critters-webpack-plugin 首屏 CSS 内联
    • 资源预加载:对关键字体/图片添加 <link rel="preload">
    • 延迟非关键 JS:通过 async/defer 延迟第三方脚本
    • CDN 加速:将静态资源上传至 CDN
    • 优化图片格式:使用 WebP 格式(通过 image-minimizer-webpack-plugin)
js 复制代码
// 优化配置
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      minify: true, // 压缩 HTML
      preload: '**/*.css' // 预加载关键 CSS
    }),
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css'
    })
  ],
  module: {
    rules: [{
      test: /\.css$/,
      use: [
        MiniCssExtractPlugin.loader, // 提取 CSS 文件
        'css-loader'
      ]
    }]
  }
};

7. Web Vitals 优化

  • LCP 优化:
    • 使用 loading="eager" 优先加载 LCP 元素图片
    • 服务端渲染(SSR)或静态站点生成(SSG)
    • 移除渲染阻塞资源
  • FCP 优化:
    • 内联关键 CSS(减少网络请求)
    • 使用骨架屏(Skeleton Screen)
    • 优化 Web 字体加载(font-display: swap)
  • 验证工具:
    • ighthouse(Chrome DevTools)
    • Webpack 性能分析:webpack --profile --json > stats.json + Webpack Analyse
  • 通过以上优化,典型项目可达到:
    • 打包体积减少 40%~60%
    • 构建速度提升 50%~70%
    • LCP 时间 < 2.5s(良好标准)

8. DDL 预加载

在 Webpack 5 中配置 DLL 预构建优化大体积库,对 echarts、lodash 等大体积库的 DLL 预构建配置。DLL 预构建能够显著提升构建速度,特别是对于大型库。

  • DLL 预构建优点
    • 显著提升构建速度:大型库只需构建一次
    • 减少开发环境构建时间:开发时只构建业务代码
    • 优化生产构建:分离第三方库减少主包体积
  • 关键配置点
    • DLL 配置文件:单独配置需要预构建的库
    • DllReferencePlugin:在主配置中引用预构建的库
    • AddAssetHtmlPlugin:自动将 DLL 文件添加到 HTML 中
    • 缓存优化:与 Webpack 5 持久化缓存协同工作
  • 推荐预构建的库
    • echarts: 大型图表库
    • lodash: 实用工具库
    • moment: 日期处理库
    • react-dom: React 渲染库
    • axios: HTTP 客户端
    • antd: UI 组件库
    • three: 3D 库
8.1 创建 DLL 配置文件
js 复制代码
// webpack.dll.config.js
const path = require('path');
const { DllPlugin } = require('webpack');

module.exports = {
  mode: 'production',
  entry: {
    vendor: [
      'echarts',         // 添加需要预构建的大型库
      'lodash', 
      'moment',
      'react-dom',
      'axios'
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dll'),
    filename: '[name].dll.js',
    library: '[name]_dll' // 全局变量名,供引用
  },
  plugins: [
    new DllPlugin({
      name: '[name]_dll', // 与 output.library 保持一致
      path: path.join(__dirname, 'dll', '[name]-manifest.json')
    })
  ]
};
8.2 总配置方案
js 复制代码
// webpack.config.js
const path = require('path');
const webpack = require('webpack');
const { DllPlugin } = require('webpack');
const { DllReferencePlugin } = require('webpack');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');

// 1. 创建单独的 DLL 配置文件 (webpack.dll.config.js)
module.exports = (env, argv) => {
  const isProduction = argv.mode === 'production';
  
  return {
    // Webpack 基础配置
    cache: {
      type: 'filesystem',
      buildDependencies: {
        config: [__filename] // 配置文件变更时刷新缓存
      }
    },
    
    resolve: {
      extensions: ['.js', '.jsx', '.json'],
      alias: {
        '@': path.resolve(__dirname, 'src')
      }
    },
    
    module: {
      rules: [
        {
          test: /\.jsx?$/,
          exclude: /node_modules/,
          use: [
            {
              loader: 'babel-loader',
              options: {
                cacheDirectory: true, // Babel 缓存
                presets: ['@babel/preset-env', '@babel/preset-react']
              }
            }
          ]
        }
      ]
    },
    
    plugins: [
      // 引用预先构建的 DLL
      new DllReferencePlugin({
        context: __dirname,
        manifest: require('./dll/vendor-manifest.json')
      }),
      
      // 将 DLL 文件添加到 HTML 中
      new AddAssetHtmlPlugin({
        filepath: path.resolve(__dirname, 'dll/vendor.dll.js'),
        publicPath: '/dll', // 公共路径
        outputPath: 'dll'   // 输出目录
      }),
      
      // 其他插件...
    ],
    
    // 生产环境特定配置
    ...(isProduction ? {
      optimization: {
        minimize: true,
        splitChunks: {
          chunks: 'all',
          cacheGroups: {
            vendor: {
              test: /[\\/]node_modules[\\/]/,
              name: 'vendors',
              chunks: 'all'
            }
          }
        }
      }
    } : {})
  };
};
8.3 配置 package.json 脚本
json 复制代码
{
  "scripts": {
    "build:dll": "webpack --config webpack.dll.config.js",
    "dev": "npm run build:dll && webpack serve --mode development",
    "build": "npm run build:dll && webpack --mode production"
  }
}

小结

  • Loader vs Plugin 核心区别:

    • Loader:文件加载时转换器(如转译 JSX、编译 SCSS)
    • Plugin:扩展 Webpack 功能的钩子(如优化资源、生成 HTML)
  • 减小打包体积(压缩):

    • Tree Shaking:生产模式自动启用(需 ES6 模块语法 import { ... } from '...'
    • 资源压缩:图片使用 image-webpack-loader 进一步压缩
    • 按需加载:使用 import() 动态导入路由组件
    • JavaScript代码压缩:terser-webpack-plugin
    • CSS代码压缩:ss-minimizer-webpack-plugin
  • 提高打包速度

    • 限制 Loader 范围:通过 include/exclude 减少处理文件
    • 多进程构建:使用 thread-loader(CPU 密集型操作)
    • DLL 预构建:对稳定库(如 React)提前打包
  • LCP/FCP 专项优化

    • 关键 CSS 内联:使用 critters-webpack-plugin 首屏 CSS 内联
    • 资源预加载:对关键字体/图片添加 <link rel="preload">
    • 延迟非关键 JS:通过 async/defer 延迟第三方脚本
    • CDN 加速:将静态资源上传至 CDN
    • 优化图片格式:使用 WebP 格式(通过 image-minimizer-webpack-plugin
  • Web Vitals 优化实践

    • LCP 优化:

      • 使用 loading="eager" 优先加载 LCP 元素图片
      • 服务端渲染(SSR)或静态站点生成(SSG)
      • 移除渲染阻塞资源
    • FCP 优化:

      • 内联关键 CSS(减少网络请求)
      • 使用骨架屏(Skeleton Screen)
      • 优化 Web 字体加载(font-display: swap)
    • 验证工具:

      • ighthouse(Chrome DevTools)
      • Webpack 性能分析:webpack --profile --json > stats.json + Webpack Analyse
  • 优化 Webpack 需结合:

    • 现代工具:Webpack 5 内置资源模块/持久化缓存
    • 按需处理:Loader 范围限制/代码分割
    • 性能指标驱动:专注 LCP/FCP 等核心 Web Vitals
相关推荐
HIT_Weston2 小时前
43、【Ubuntu】【Gitlab】拉出内网 Web 服务:静态&动态服务
前端·ubuntu·gitlab
LucidX2 小时前
Web——反向代理、负载均衡与 Tomcat 实战部署
前端·tomcat·负载均衡
sen_shan3 小时前
《Vue项目开发实战》第八章:组件封装--vxeGrid
前端·javascript·vue.js
五点六六六3 小时前
双非同学校招笔记——离开字节入职小📕
前端·面试·程序员
IT_陈寒3 小时前
Redis实战:5个高频应用场景下的性能优化技巧,让你的QPS提升50%
前端·人工智能·后端
2***57423 小时前
Vue项目国际化实践
前端·javascript·vue.js
我也爱吃馄饨3 小时前
写的webpack插件如何适配CommonJs项目和EsModule项目
java·前端·webpack
全马必破三3 小时前
HTML常考知识点
前端·html
OLong3 小时前
忘掉"发请求",声明你要的数据:TanStack Query 带来的思维革命
前端