Webpack 特性探讨:CDN、分包、Tree Shaking 与热更新

文章目录

前言

Webpack 作为现代前端开发中的核心构建工具,提供了丰富的特性来帮助开发者优化和打包应用。本文将探讨 Webpack 的 CDN 集成、代码分包、Tree Shaking 以及热更新(HMR)等关键特性。
我们将使用前一篇文章中的代码,然后我们引入一些图片、css 等资源文件已经一些常用的第三方库,如lodash

包准备

安装文件处理的 loader 和后续分析的包

js 复制代码
yarn add webpack-bundle-analyzer  terser-webpack-plugin url-loader file-loader -D

在 webpack.config.js 添加 处理文件的 loader , file-loader

js 复制代码
module: {
    rules: [
      //  ... 省略
      {
        test: /\.(jpg|png|jpeg|gif)$/,
        use: ["file-loader"],
      },
    ],
  },

修改 list.vue

js 复制代码
<template>
  <div>
    <img :src="jsJpg" />
    <h3>前端三大框架:</h3>
    <ul>
      <li v-for="item in list" :key="item">{{ item }}</li>
    </ul>
  </div>
</template>

<script>
import jsJpg from '@/static/js.jpg'
export default {
  name:'List',
  data() {
    return {
      list: ["Vue", "React", "Angular"],
      jsJpg
    };
  },
};
</script>

运行结果:

打包结果:

执行 yarn build

CDN 集成

CDN(内容分发网络)的使用可以显著提高资源加载速度,特别是对于静态资源。

我们可以有三种种方式来完成:

  1. output 配置中的 publicPath

这里我们如果没有 cdn,可以通过修改 hosts 文件的方式, 文件路径:C:\Windows\System32\drivers\etc,添加内容127.0.0.1 ziyu.aliyun.com, 最后我们添加启动端口

js 复制代码
const mode =
  process.env.NODE_ENV === "development" ? "development" : "production";
const isDev = process.env.NODE_ENV === "development";


output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
    publicPath: isDev ? "/" : "http://ziyu.aliyun.com:3000/",
  },

添加前运行文件

打包运行后文件效果

  1. 配置externals属性将某些依赖项从打包文件中排除,并通过 CDN 链接直接引入。
js 复制代码
externals: {
   vue: "Vue",
   "vue-router": "VueRouter",
}

在 html 文件中添加

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title><%= htmlWebpackPlugin.options.title %></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router@3.0.0/dist/vue-router.js"></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

添加打包分析器:

js 复制代码
const BundleAnalyzerPlugin  = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

  plugins: [
	//   ...
    new BundleAnalyzerPlugin({
      analyzerMode: 'static',
      reportFilename: 'report.html',
      openAnalyzer: false,
    }),
  ],

执行 yarn build, 查看report.html , 没有 vue和vue-router的代码

  1. 使用html-webpack-plugin插件,在生成的 HTML 文件中动态插入 CDN 资源链接。
js 复制代码
// 1. 配置插件
 new HtmlWebpackPlugin({
      title: "vuew + webpack",
      template: "./src/index.html",
    }),
// 2. 配置html

// 可以随便添加cdn

代码分包

代码分包是 Webpack 优化应用加载性能的重要手段。通过将代码分割成多个包,可以实现按需加载,减少单次加载的数据量。

代码准备:

我们新建一个utils/calc.js文件,然后补充代码:

js 复制代码
export const sum = (a, b) => a + b;

常规使用: hello.vue 中引用

vue 复制代码
<template>
  <button @click="calcRes">计算 : 5 +6 结果</button> {{ res }}
</template>

<script>
import { sum } from "../utils/calc";
export default {
  data() {
    return {
      res: 0,
    };
  },
  methods: {
    calcRes() {
      this.res = sum(5, 6);
    },
  },
};
</script>

打包结果

  1. import() 分包:
vue 复制代码
<template>
  <button @click="calcRes">计算 : 5 +6 结果</button> {{ res }}
</template>

<script>
import { sum } from "../utils/calc";
export default {
  data() {
    return {
      res: 0,
    };
  },
  methods: {
    calcRes() {
      this.res = import(/* webpackChunkName: "calc" */ "../utils/calc").then(
        ({ sum }) => {
          this.res = sum(5, 6);
        }
      );
    },
  },
};
</script>
  1. 自动分包 :Webpack 的SplitChunksPlugin插件可以自动分析模块依赖关系,将共享模块提取到单独的包中 , 供我们自定义更加细粒度的分包策略
js 复制代码
  optimization: {
    splitChunks: {
      chunks: 'all', // all, async, and initial
      minChunks :10,
      // 当包大于1000byte,就拆分
      maxSize: 1000,
      // 拆分的每个包不能小于500byte
      minSize: 500,
      cacheGroups:{
          utils: {
            test: /utils/,
            filename: '[id]_utils.js'
        }
      }
    },
  },
  1. 多入口分包 :通过entry属性手动定义多个入口点,Webpack 会为每个入口点生成一个独立的包。

Tree Shaking

Tree Shaking 是移除代码中未引用部分的过程,它利用了 ES2015 模块的静态结构特性。

原理

  1. 一是先「标记」出模块导出值中哪些没有被用过
  2. 二是使用 Terser 删掉这些没被用到的导出代码

实现条件:

  1. 使用 ES2015 模块 :确保项目使用importexport语法。
  2. 配置sideEffects :在package.json中添加 "sideEffects": false字段,告诉 Webpack 哪些文件是纯模块,可以安全地进行 Tree Shaking。
  3. 在配置中开始标记optimization.usedExports = true, 将构建设置成生产模式 mode ='production'

解决 treeShaking 无效方案:

  1. @babel/preset-envbabel-preset-env 不要将 target 设置为 node
  2. 第三方包中的 "sideEffects": false

示例代码:

我们安装 loadsh-es包来测试,它比 lodash 包更好的 tree-shaking

yarn add lodash-es
yarn add terser-webpack-plugin -D
js 复制代码
  
<button @click="log">防抖函数</button>

<script>

  import { debounce } from 'lodash-es';
  export default {
    methods: {
      log: debounce(()=>console.log("log...."), 500),
    }
  }
</script>

更新配置文件:

js 复制代码
 optimization: {
    minimize: true,
    minimizer: [new TerserPlugin()],
    usedExports: true,
  },

打包结果:可以看到结果中只有loadsh-es包的 debunce函数

热更新(HMR)

热更新允许在开发过程中实时更新应用,而无需刷新页面。

  1. 配置webpack-dev-server :通过webpack-dev-server提供热更新服务。
  2. 使用HotModuleReplacementPlugin:在 Webpack 配置中添加此插件,实现模块的热替换。
js 复制代码
devServer:{
  hot:true
}

plugins: [
  new webpack.HotModuleReplacementPlugin()
]

  mounted() {
    if (module.hot) {
      module.hot.accept('./Hello.vue', () => {
        
      });
    }
  },
相关推荐
秦jh_1 小时前
【Linux】多线程(概念,控制)
linux·运维·前端
蜗牛快跑2131 小时前
面向对象编程 vs 函数式编程
前端·函数式编程·面向对象编程
Dread_lxy1 小时前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
涔溪2 小时前
Ecmascript(ES)标准
前端·elasticsearch·ecmascript
榴莲千丞2 小时前
第8章利用CSS制作导航菜单
前端·css
奔跑草-2 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
羡与2 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts
guokanglun2 小时前
CSS样式实现3D效果
前端·css·3d
咔咔库奇2 小时前
ES6进阶知识一
前端·ecmascript·es6
渗透测试老鸟-九青3 小时前
通过投毒Bingbot索引挖掘必应中的存储型XSS
服务器·前端·javascript·安全·web安全·缓存·xss