乐趣区

前端卡顿的优化思路和方案02实现webpack的chunk文件的命名

webpack + es2015 的 import() 语法进行 code splitting 时,需要指定 chunk name,便于查看 chunk 具体是什么文件分离出的。


参考 vue-router 官方文档的 路由懒加载 部分

vue-router 路由懒加载

  • 如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
  • 结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。

一,import() 路由懒加载

  • 首先,可以将异步组件定义为返回一个 Promise 的工厂函数 (该函数返回的 Promise 应该 resolve 组件本身):
const Login = () => Promise.resolve({ /* 组件定义对象 */})
  • 第二,在 Webpack 2 中,我们可以使用动态 import 语法来定义代码分块点 (split point):
import('./Login.vue') // 返回 Promise
  • 结合这两者,这就是如何定义一个能够被 Webpack 自动代码分割的异步组件。
const Login = () => import('./login.vue')

二,webpackChunkName 注释

  • 有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。
const Login = () => import(/* webpackChunkName: "Login" */ './login.vue')
  • 然后就可以在 vue-router 中引用该组件
const routers = new Router({
    routes: [
        {
            path: '/login',
            name: 'login',
            component: Login
        },
        ...

三,在 webpack.base.conf.js 和 webpack.prod.conf.js 的 output 导出文件处修改设置

  • 具体的修改位置是 filename 和 chunkFilename。如果没有之前的 webpackChunkName 的注释的设置,[name] 就会使用数字,如 1,2,3 等来命名,数字应该是打包顺序,待定。有了注释的话,如 / webpackChunkName: “Login” /,[name] 就按照 Login 来命名。
  • chunkFilename : 非入口 (non-entry) chunk 文件的名称

【注意】webpack.base.conf.js 文件中的 output 修改,影响的是本地开发环境运行的 chunk 文件的名称,

【注意】webpack.prod.conf.js 中的修改,影响 通过 npm run build 打包后的 chunk 文件的名称。

  • 初始的配置为
module.exports = {
  entry: {app: './src/main.js'},
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js', // 打包后的文件名 1.js,...
  • 修改后的配置为
module.exports = {
  entry: {app: './src/main.js'},
  output: {
    path: config.build.assetsRoot,
    filename: '[name].[hash].js',
    chunkFilename: '[name].chunk.[hash].js', // 打包后的文件名 Login.chunk.2f8e6a3b7cd6aaa0d7ba.js
    ...

四,.babelrc 文件 中的 commits 不要设置成 false

  • 该问题是一个隐藏的坑,webpack 相关 issue 具体地址,仔细爬楼,后面有相关回应。以后如果用 TypeScript 写代码,里面也有相关的处理方案,此处不再赘述。
  • 如下是一个总结
To sum up, make sure you set:

comments: true in .babalrc (this is the default)
chunkFilename: '[name].....' in your webpack config

If you are using typescript, also make sure:

removeComments: false under compilerOptions in tsconfig.json
module: esnext in tsconfig.json
  • 具体代码位置,删除该行,webpack 默认 comments 为 true
{
  "comments": false,
  ...

五,syntax-dynamic-import 插件处理 import()

如果您使用的是 Babel,你将需要添加 syntax-dynamic-import 插件,才能使 Babel 可以正确地解析语法。插件地址

  • 首先安装插件
npm install --save-dev @babel/plugin-syntax-dynamic-import
  • 然后在.babelrc 文件中写如下配置
{"plugins": ["@babel/plugin-syntax-dynamic-import"]
}
  • 此外,该插件的实现还需要其他的一些 babel 插件才能使用,有关内容在 babel7 的升级文档中描述
退出移动版