基于 webpack5 完成工程化建设

抖音 - 哲玄《大前端全栈实践》

前言

通过最近学习,对工程化有了进一步的认识,前端工程化 不是一个具体的工具,而是一个思想和体系,可以通过:

  • 模块化/组件化来解耦复杂应用。
  • 规范化来约束开发过程。
  • 自动化来提升效率和质量。
  • 性能优化来保障用户体验。

掌握工程化思想,要比学习怎么使用构建工具来的更重要。

1.解析引擎工作流程

2. 项目Webpack架构设计

2.1 配置文件结构

bash 复制代码
app/webpack/
├── config/
│   ├── webpack.base.js    # 基础配置(公共配置)
│   ├── webpack.dev.js     # 开发环境配置
│   └── webpack.prod.js    # 生产环境配置
├── dev.js                 # 开发服务器启动脚本
└── prod.js               # 生产环境构建脚本

2.2 配置继承关系

scss 复制代码
webpack.base.js (基础配置)
    ├── webpack.dev.js (开发环境继承)
    └── webpack.prod.js (生产环境继承)

3. 核心配置详解

3.1 基础配置 (webpack.base.js)

3.1.1 多页面入口配置

javascript 复制代码
// 动态构造入口文件和HTML模板文件
const pageEntries = {};
const htmlWebpackPluginList = [];
const entryList = path.resolve(process.cwd(), "./app/pages/**/entry.*.js");

glob.sync(entryList).forEach((file) => {
  const entryName = path.basename(file, ".js");
  pageEntries[entryName] = file;
  htmlWebpackPluginList.push(
    new HtmlWebpackPlugin({
      filename: path.resolve(process.cwd(), "./app/public/dist/", `${entryName}.tpl`),
      template: path.resolve(process.cwd(), "./app/view/entry.tpl"),
      chunks: [entryName],
    })
  );
});

3.1.2 模块解析规则

javascript 复制代码
module: {
  rules: [
    {
      test: /\.vue$/,
      use: { loader: "vue-loader" }
    },
    {
      test: /\.js$/,
      include: [path.resolve(process.cwd(), "./app/pages")],
      use: { loader: "babel-loader" }
    },
    {
      test: /\.(png|jep?g|gif)(\?.+)?$/,
      use: {
        loader: "url-loader",
        options: { limit: 300, esModule: false }
      }
    }
  ]
}

3.1.3 代码分割策略

javascript 复制代码
optimization: {
  splitChunks: {
    chunks: "all",
    cacheGroups: {
      vendor: {
        test: /[\/]node_modules[\/]/,
        name: "vendor",
        priority: 20,
        enforce: true,
        reuseExistingChunk: true,
      },
      common: {
        name: "common",
        minChunks: 2,
        minSize: 1,
        priority: 10,
        reuseExistingChunk: true,
      },
    },
  },
  runtimeChunk: true,
}

分割策略:

  1. vendor:第三方库代码(node_modules)
  2. common:业务公共代码(被2个以上页面引用)
  3. runtime:webpack运行时代码
  4. entry.{page}:页面特定代码

3.2 开发环境配置 (webpack.dev.js)

3.2.1 热更新配置

javascript 复制代码
// 为每个入口添加HMR客户端
Object.keys(baseConfig.entry).forEach((v) => {
  if (v !== "vendor") {
    baseConfig.entry[v] = [
      baseConfig.entry[v],
      `webpack-hot-middleware/client?path=http://${HOST}:${PORT}/${HMR_PATH}?timeout=${TIMEOUT}&reload=true`,
    ];
  }
});

plugins: [
  new webpack.HotModuleReplacementPlugin({ multiStep: false })
]

3.2.2 Source Map配置

javascript 复制代码
devtool: "eval-cheap-module-source-map"

选择原因:

  • eval:快速重新构建
  • cheap:只包含行信息,构建更快
  • module:包含loader的source map

3.3 生产环境配置 (webpack.prod.js)

3.3.1 CSS提取和压缩

javascript 复制代码
plugins: [
  new MiniCssExtractPlugin({
    chunkFilename: "css/[name]_[contenthash:8].bundle.css",
  }),
  new CssMinimizerPlugin(),
]

3.3.2 JavaScript压缩优化

javascript 复制代码
optimization: {
  minimize: true,
  minimizer: [
    new TerserPlugin({
      parallel: true,
      cache: true,
      terserOptions: {
        compress: {
          drop_console: true, // 移除console.log
        },
      },
    }),
  ],
}

3.3.3 多线程构建加速

javascript 复制代码
new HappyPack({
  id: "js",
  threadPool: HappyPack.ThreadPool({ size: os.cpus().length }),
  loaders: [
    `babel-loader?${JSON.stringify({
      presets: ["@babel/preset-env"],
      plugins: ["@babel/plugin-transform-runtime"],
    })}`,
  ],
})

4. 开发服务器配置

4.1 Express + Webpack中间件

javascript 复制代码
const devMiddleware = webpackDevMiddleware(compiler, {
  writeToDisk: (files) => files.endsWith(".tpl"),
  publicPath: webpackConfig.output.publicPath,
  headers: {
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
    "Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Authorization",
  },
});

const hotMiddleware = webpackHotMiddleware(compiler, {
  path: `/${HMR_PATH}`,
  log: false,
});

关键特性:

  • 内存编译:文件保存在内存中,提高访问速度
  • 选择性写盘:只有.tpl文件写入磁盘(后端需要)
  • CORS支持:解决跨域问题
  • 热更新通信:实时推送代码变更

结语

学习前端工程化有助于提升开发效率与项目质量,但不应盲目套用现有方案,而应深入理解其本质。我们应掌握其整体思路与工作流程,思考性能优化方向,并能够结合具体业务需求进行工程化配置。

相关推荐
JackieDYH10 分钟前
vue3中reactive和ref如何使用和区别
前端·javascript·vue.js
ZZHow10241 小时前
React前端开发_Day4
前端·笔记·react.js·前端框架·web
前端开发爱好者1 小时前
弃用 html2canvas!快 93 倍的截图神器
前端·javascript·vue.js
ss2731 小时前
手写MyBatis第39弹:深入MyBatis BatchExecutor实现原理与最佳实践
前端·javascript·html
leon_teacher2 小时前
HarmonyOS权限管理应用
android·服务器·前端·javascript·华为·harmonyos
lumi.2 小时前
HarmonyOS image组件深度解析:多场景应用与性能优化指南(2.4详细解析,完整见uniapp官网)
前端·javascript·小程序·uni-app·html·css3
OEC小胖胖2 小时前
动态UI的秘诀:React中的条件渲染
前端·react.js·ui·前端框架·web
dreams_dream3 小时前
django注册app时两种方式比较
前端·python·django
liangshanbo12155 小时前
Speculation Rules API
前端·javascript·html
石国旺5 小时前
前端javascript在线生成excel,word模板-通用场景(免费)
前端·javascript·excel