Webpack 基础配置与懒加载

Webpack 基础配置与懒加载

一、引言

Webpack 是一个强大的模块打包工具,在当前项目中,它负责将各种资源(如 JavaScript、CSS、图片等)打包成浏览器可以理解的形式。合理的 Webpack 配置能够提高项目的构建效率、优化资源加载,而懒加载则是优化项目性能的重要手段之一。本文将详细解释当前工程中的 Webpack 基础配置,并引申出懒加载的相关内容。

二、Webpack 基础配置

2.1 入口与出口配置

d:\workspace\elpis\app\webpack\config\webpack.base.js 文件中,定义了 Webpack 的基础配置。

js 复制代码
webpack.base.js
// 动态构造 pages 入口文件
const pageEntries = {};
// 动态构造 htmlWebpackPluginList 渲染模板
const htmlWebpackPluginList = [];
// 获取 app/pages 下所有的入口文件 (entry.xx.js)
const entryList = path.resolve(process.cwd(), "./app/pages/**/entry.*.js");
glob.sync(entryList).forEach((file) => {
  const entryName = path.basename(file, ".js");
  // 构造 entry
  pageEntries[entryName] = file;
  htmlWebpackPluginList.push(
    // html-webpack-plugin 插件 辅助注入打包后的 boundle 文件到tpl文件中
    new HtmlWebpackPlugin({
      // 产物 最终模板 输出路径
      filename: path.resolve(
        process.cwd(),
        "./app/public/dist/",
        `${entryName}.tpl`
      ),
      // 指定要使用的模板文件
      template: path.resolve(process.cwd(), "./app/views/entry.tpl"),
      // 注入的代码块
      chunks: [entryName],
    })
  );
  // 构造最终渲染的页面文件
});

module.exports = {
  // 入口文件
  entry: pageEntries,
  // 出口文件 产物输出路径,开发和生产环境输出不一致,须在各自环境中配置
  output: {},
  // ...其他配置...
};
  • 入口(entry) :通过 glob 模块动态获取 app/pages 目录下所有以 entry. 开头的 .js 文件作为入口文件,将它们的路径存储在 pageEntries 对象中。这样做的好处是可以方便地管理多个页面的入口,无需手动逐个添加。
  • 出口(output) :在基础配置中,output 部分仅占位,具体的输出路径和文件名在开发和生产环境的配置文件中进行设置。

2.2 模块加载规则

js 复制代码
webpack.base.js
module.exports = {
  // ...其他配置...
  // 模块加载解析器
  module: {
    rules: [
      {
        test: /.vue$/,
        use: "vue-loader",
      },
      {
        test: /.js$/,
        include: [path.resolve(process.cwd(), "./app/pages")], //只针对 业务代码 进行babel转换 加快webpack打包速度
        use: { loader: "babel-loader" },
      },
      {
        test: /.(png|jpe?g|gif)(?.+)?$/,
        use: {
          loader: "url-loader",
          options: {
            limit: 1024, // 1024 以下的图片打包成 base64 格式
            esModule: false,
          },
        },
      },
      {
        test: /.css$/,
        use: ["style-loader", "css-loader"],
      },
      {
        test: /.less$/,
        use: ["style-loader", "css-loader", "less-loader"],
      },
      {
        test: /.(eot|svg|ttf|woff|woff2)(?\S*)?$/,
        use: "file-loader",
      },
    ],
  },
  // ...其他配置...
};
  • Vue 文件处理 :使用 vue-loader 处理 .vue 文件,将 Vue 组件的各个部分(模板、脚本、样式)进行打包。
  • JavaScript 文件处理 :使用 babel-loaderapp/pages 目录下的 .js 文件进行转换,确保代码在不同浏览器中的兼容性。
  • 图片处理 :使用 url-loader 处理图片文件,当图片大小小于 1024 字节时,将其打包成 base64 格式,减少 HTTP 请求。
  • CSS 和 Less 处理 :使用 style-loadercss-loaderless-loader 处理 CSS 和 Less 文件,将样式文件打包到 JavaScript 中。
  • 字体文件处理 :使用 file-loader 处理字体文件,将其复制到输出目录。

2.3 模块解析与别名配置

js 复制代码
webpack.base.js
module.exports = {
  // ...其他配置...
  // 模块解析具体行为
  resolve: {
    extensions: [".js", ".vue", ".less", ".css"],
    alias: {
      $pages: path.resolve(process.cwd(), "./app/pages"),
      $common: path.resolve(process.cwd(), "./app/pages/common"),
      $widgets: path.resolve(process.cwd(), "./app/pages/widgets"),
      $store: path.resolve(process.cwd(), "./app/pages/store"),
    },
  },
  // ...其他配置...
};
  • 扩展名解析resolve.extensions 配置允许在导入模块时省略指定的扩展名,提高开发效率。
  • 别名配置 :通过 resolve.alias 配置别名,方便在代码中引用特定目录下的模块,减少路径的书写。

2.4 插件配置

js 复制代码
webpack.base.js
module.exports = {
  // ...其他配置...
  // 配置 webpack 插件
  plugins: [
    // 配置 vue-loader 插件 处理.vue文件必须配置
    // 将定义过的其他规则复制并应用到.vue文件里  /.js$/ 他会将该规则定义到.vue中的<script>模块内
    new VueLoaderPlugin(),
    // 配置 ProvidePlugin 插件 将第三方库暴露到window全局 contenxt下
    // 这样就可以在业务代码中直接使用 window.Vue 来使用Vue
    new webpack.ProvidePlugin({ Vue: "vue", axios: "axios", _: "lodash" }),
    // 配置 DefinePlugin 插件 定义全局变量
    new webpack.DefinePlugin({
      __VUE_OPTIONS_API__: "true", // 支持vue解析optionsApi
      __VUE_PROD_DEVTOOLS__: "false", // 禁用Vue调试工具
      __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: "false", // 禁用Vue生产环境下显示 水合 信息
    }),
    ...htmlWebpackPluginList,
  ],
  // ...其他配置...
};
  • VueLoaderPlugin :处理 .vue 文件的必要插件,确保 Vue 组件的各个部分能够正确打包。
  • ProvidePlugin :将第三方库(如 Vueaxioslodash)暴露到全局作用域,方便在业务代码中直接使用。
  • DefinePlugin :定义全局变量,用于配置 Vue 的一些特性,如是否支持 options API、是否启用调试工具等。
  • HtmlWebpackPlugin:用于生成 HTML 文件,并将打包后的 JavaScript 和 CSS 文件注入到 HTML 中。

2.5 代码分割配置

js 复制代码
webpack.base.js
module.exports = {
  // ...其他配置...
  // 配置 打包输出优化 (代码分割|模块合并|缓存|TreeShaking|压缩等优化策略)
  optimization: {
    /**
     * 代码分割 配置
     * 把 js 文件打包成3中类型
     * 1. vendor: 第三方lib库,基本不会改动,除非依赖版本升级
     * 2. common: 业务组件代码公共部分抽离,改动较少
     * 3. entry.{page}: 不同页面 entry 里面业务组件代码差异部分,会经常改动
     * 目的:把改动和引用频率不一样的 js 区分出来,以达到更好利用浏览器缓存效果
     */
    splitChunks: {
      chunks: "all", //对同步和异步模块都进行分割
      maxAsyncRequests: 10, // 按需加载时最大并行请求数
      maxInitialRequests: 10, // 一个入口最大并行请求数
      cacheGroups: {
        vendor: {
          // 打包第三方依赖库
          name: "vendor", // 模块名称
          test: /[\/]node_modules[\/]/, //打包 node_modules下的模块
          priority: 20, // 优先级,值越大优先级越高
          enforce: true, // 强制打包
          reuseExistingChunk: true, // 复用已存在的模块
        },
        common: {
          // 公共模块
          test: /[\\/](common|widgets)[\\/]/,
          name: "common", // 模块名称
          minChunks: 2, // 被引用次数大于等于2次的模块
          minSize: 1, // 最小分割文件大小(1 byte)
          priority: 10, // 优先级,值越大优先级越高
          reuseExistingChunk: true, // 复用已存在的模块
        },
      },
    },
    // 将 webpack 运行时生产的代码打包到 runtime.js 中,减少 main.js 的体积
    runtimeChunk: true,
  },
};
  • 代码分割 :通过 splitChunks 配置将 JavaScript 文件分割成不同的类型,包括第三方库(vendor)、公共模块(common)和页面特定的代码(entry.{page}),提高浏览器缓存的利用率。
  • 运行时代码分割runtimeChunk 配置将 Webpack 运行时代码打包到单独的文件中,减少主文件的体积。

三、懒加载

3.1 懒加载的概念

懒加载(Lazy Loading)是一种优化技术,它允许在需要时才加载模块,而不是在应用启动时一次性加载所有模块。这样可以减少初始加载时间,提高应用的响应速度。

3.2 项目中的懒加载实现

在当前项目中,路由组件的懒加载通过动态导入(Dynamic Import)实现。例如,在 d:\workspace\elpis\app\pages\dashboard\entry.dashboard.js 文件中:

js 复制代码
entry.dashboard.js
// 头部菜单路由
routes.push({
  path: "/iframe",
  component: () => import("./complex-view/iframe-view/iframe-view.vue"),
});
routes.push({
  path: "/schema",
  component: () => import("./complex-view/schema-view/schema-view.vue"),
});
// custom 自定义路由
routes.push({
  path: "/todo",
  component: () => import("./todo/todo-view.vue"),
});

// 侧边栏菜单路由
routes.push({
  path: "/sider",
  component: () => import("./complex-view/sider-view/sider-view.vue"),
  children: [
    {
      path: "/iframe",
      component: () => import("./complex-view/iframe-view/iframe-view.vue"),
    },
    {
      path: "/schema",
      component: () => import("./complex-view/schema-view/schema-view.vue"),
    },
    {
      // custom 自定义路由
      path: "/todo",
      component: () => import("./todo/todo-view.vue"),
    },
  ],
});

通过 () => import('...') 的语法,Webpack 会将这些组件打包成单独的文件,并在需要时动态加载。例如,当用户访问 /iframe 路由时,才会加载 iframe-view.vue 组件。

3.3 懒加载的优势

  • 减少初始加载时间:只加载当前页面所需的模块,避免一次性加载所有模块,从而减少初始加载时间。
  • 提高应用性能:减少了首屏加载的资源量,提高了应用的响应速度,提升用户体验。
  • 节省带宽:用户只下载他们实际需要的代码,节省了带宽资源。

3.4 懒加载的注意事项

  • 错误处理 :在使用懒加载时,需要处理加载失败的情况,例如网络问题导致模块加载失败。可以通过 .catch() 方法捕获错误并进行相应的处理。
  • 预加载:对于一些可能会被频繁访问的模块,可以考虑使用预加载(Preloading)技术,在浏览器空闲时提前加载这些模块,以进一步提高性能。

四、总结

Webpack 的基础配置为项目的构建和打包提供了强大的支持,通过合理配置入口、出口、模块加载规则、插件和代码分割等,可以提高项目的构建效率和性能。懒加载作为一种重要的优化技术,能够进一步提升应用的响应速度和用户体验。在实际项目中,应根据项目的需求和特点,合理运用 Webpack 配置和懒加载技术。

相关推荐
狂炫一碗大米饭43 分钟前
🧠前端面试高频考题---promise,从五个方面搞定它🛠️
前端·javascript·面试
拉不动的猪1 小时前
前端如何判断登录设备是移动端还是pc端
前端·javascript·css
小圆脸儿1 小时前
通用组件库设计方案ui-components
前端·前端框架
拉不动的猪1 小时前
刷刷题38(长连接 +切片上传)
前端·javascript·面试
哀木1 小时前
随笔之 react 接入 @xterm 的踩坑记录
前端
Ares-Wang1 小时前
微服务》》Kubernetes (K8S)安装
微服务·架构·kubernetes
StarRocks_labs2 小时前
StarRocks + Paimon 在阿里集团 Lakehouse 的探索与实践
大数据·starrocks·阿里云·架构·湖仓一体
野生的程序媛2 小时前
重生之我在学Vue--第13天 Vue 3 单元测试实战指南
前端·javascript·vue.js·单元测试
Aphasia3112 小时前
简单介绍清除浮动解决高度塌陷的四种方法✍🏻
前端·css
开发者工具分享2 小时前
微服务架构中10个常用的设计模式
微服务·设计模式·架构