从webpack看前端工程化

492 阅读6分钟

一、什么是前端工程化

前端工程化是在前端开发过程中,通过一系列规范、工具和流程,以达到节约成本、提高效率和保障质量的目的。但工程化绝不仅 == webpack,工程化涵盖多个方面,包括开发阶段、构建阶段、测试阶段、部署和运维阶段等。

image.png

1. 开发阶段
  • 脚手架:创建前端应用的目录结构,并生成样板代码
  • 公共库:维护可复用的 UI 组件、业务模块、工具模块等公共资源
  • 包管理:引入第三方库/组件
  • 调试工具:DevTools、Mock、性能分析诊断等调试功能
2. 构建阶段
  • 打包工具 gulp、webpack、vite、rspack以及rolldown等
3. 测试阶段
  • 单元测试
  • 自动化测试
  • 性能测试
4. 部署运维阶段
  • CI/CD的发布和部署

二、webpack与前端工程化的关系

webpack 是一个现代 JavaScript 应用的静态模块打包工具。在 Webpack 的世界里,前端的每个资源都被看作一个模块,它通过分析这些模块之间的依赖关系,生成最终的打包文件。Webpack 作为一个构建工具,支持 JavaScript、CSS、图片等各种资源的模块化管理和优化。

image.png

1. 工作原理
  • 入口(Entry) :指定从哪个文件开始构建应用的依赖图。

  • 输出(Output) :指定 Webpack 将最终结果输出到哪里。

  • 加载器(Loader) :用于转换文件的内容,支持将非 JavaScript 文件(如 CSS、图片、字体)转化为模块。

  • 插件(Plugin) :通过插件在构建过程中对模块进行优化、打包、分析等操作,插件通常执行更复杂的任务。

2. 应用
  1. 模块化管理

    Webpack 的模块化能力使得前端项目中的每个资源都能作为独立模块进行管理。以 CSS 和图片为例:

    • 使用 css-loaderstyle-loader以及less-loader,开发者可以在 JavaScript 中直接引入 css、less 文件。
    • 借助 file-loaderurl-loader,图片可以被打包成 base64 字符串或复制到输出目录(webpack5 内置asset模块替代方案)。

    这种资源管理方式避免了文件引用的混乱,同时增强了模块间的解耦性。

  2. 自动化构建

    Webpack 提供了一套自动化构建工具链,极大提升了开发效率:

    • 开发环境:使用 webpack-dev-server(也可以自己起一个express服务器,配合webpack-hot-middlewarewebpack-dev-middleware实现) 启动本地服务器,配合 热模块替换(HMR) 实现实时预览。
    • 生产环境:通过 Tree Shaking、代码压缩、GZip等功能优化构建产物,确保上线代码的高效和可靠。

//devserver 配置
const DEV_SERVER_CONFIG = {
  HOST: '127.0.0.1',
  PORT: 9002,
  HMR_PATH: '__webpack_hmr', // 官方规定
  TIMEOUT: 20000,
};
//  开发环境的entry配置需要注入 hmr
Object.keys(webpackBaseConfig.entry).forEach((key) => {
  //第三方包不需要热更新
  if (!key.indexOf('vendor') != -1) {
    webpackBaseConfig.entry[key] = [
      webpackBaseConfig.entry[key],
      `webpack-hot-middleware/client?path=http://${DEV_SERVER_CONFIG.HOST}:${DEV_SERVER_CONFIG.PORT}/${DEV_SERVER_CONFIG.HMR_PATH}&timeout=${DEV_SERVER_CONFIG.TIMEOUT}&reload=true`,
    ];
  }
});
const app = express();
const compiler = webpack(webpackConfig); //初始化配置
//指定静态目录
app.use(express.static(path.resolve(__dirname, '../public/dist/dev')));
// 引入 webpack-dev-middleware 中间件 (监控文件改动)
app.use(
  devMiddleware(compiler, {
    //落地文件
    writeToDisk: (filePath) => filePath.endsWith('.tpl'),
    //资源路径
    publicPath: webpackConfig.output.publicPath,
    //headers配置
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
      'Access-Control-Allow-Headers': 'X-Request-With,content-type,Authorization',
    },
    
  }),
);
// 引入 webpack-hot-middleware 中间件(实现热更新通讯)
app.use(
  hotMiddleware(compiler, {
    //热更新的路径
    path: '/' + DEV_SERVER_CONFIG.HMR_PATH,
    log: () => {},
  }),
);

  1. 性能优化

    性能优化是前端工程化的核心目标之一。Webpack 提供了多种内置功能和插件,用于提升前端应用的性能。

    • Tree Shaking:移除未使用的代码(依赖于 ES6 模块的静态分析)。
    • 代码分割(Code Splitting) :将代码按需加载,减少初始加载时间。
    • 资源压缩:通过 TerserPluginCssMinimizerPlugin 压缩 JavaScript 和 CSS。
    • GZip:通过CompressionPlugin生成Gzip压缩文件
//压缩
optimization: {
    minimize: true,
    minimizer: [
      //css 压缩
      new CssMinimizerPlugin(),
      // js 压缩
      new TerserPlugin({
        cache: true, //启用缓存加快构建过程
        parallel: true, //利用多核cpu的优势加快优势速度
        terserOptions: {
          compress: {
            drop_console: true, // 删除 console.* 语句
            drop_debugger: true, // 删除 debugger 语句
          },
          format: {
            comments: false, // 移除注释
          },
        },
      }),
      // 生成 gzip 压缩文件,后续放nginx上设置gzip
      new CompressionPlugin({
        test: /\.(js|css|svg)$/, // 压缩的文件类型
        algorithm: 'gzip', // 使用 gzip 压缩算法
        threshold: 10240, // 只处理大于 10KB 的文件
        minRatio: 0.8, // 只有压缩率小于 0.8 的文件才会生成
        //是否删除原有静态资源文件,即只保留压缩后的.gz文件,建置为false,还保留源文件。以防.gz文件访问不到的时候,还可以访问源文件双重保障
        deleteOriginalAssets: false,
      }),
    ],
    runtimeChunk: true, //将运行时代码抽离到单独的文件,提升缓存利用率
  },
  //分包
  splitChunks: {
      chunks: 'all', //对同步和异步模块都进行分割
      maxAsyncRequests: 10, //每次异步加载的最大并行请求数
      maxInitialRequests: 10, //每次初始化加载的最大并行请求数
      cacheGroups: {
        vendor: {
          //第三方库
          test: /[\\/]node_modules[\\/]/, //打包node_modules下的文件
          name: 'vendor', // 模块名称
          priority: 20, //优先级 数字越大越高
          enforce: true, //强制执行 会无视规则
          reuseExistingChunk: true, //复用已有的公共chunk
        },
        common: {
          //公共模块
          name: 'common',
          minChunks: 2, //被引用2次及2次以上的模块
          minSize: 1, //最小文件分割大小1 byte
          priority: 10,
          reuseExistingChunk: true,
        },
      },
    },
  1. 多环境支持

    在实际开发中,前端项目通常需要适配多个运行环境(如开发、测试和生产环境)。Webpack 支持通过环境变量或多配置文件,灵活管理不同环境的构建需求。

  2. 面临的挑战

    随着前端生态的不断强大和技术演进,越来越多的打包的打包工具可供选择,例如vite、rspack等,但是不管有多少工具,我们要理解的是工程化的思想。

三、总结

前端工程化不仅是开发工具的选择,更是整个开发流程的优化。它通过工具链、自动化、模块化等技术手段,帮助开发团队提升开发效率、代码质量和协作能力。随着前端技术的发展,前端工程化的内涵也在不断扩展,从简单的代码打包到复杂的持续集成与自动化部署,前端工程化已经成为支撑大规模 Web 应用开发的基础。在实际项目中,开发者需要根据具体需求选择合适的工具和实践,并不断优化开发流程和技术栈.

image.png