优化原因

在没有使用cdn加速之前打包后数据如下,可以看出element-ui、vue、vuex、vue-router这些依赖都打进chunk-vendors.js中导致体积很大,假设再来很多依赖项是不是更大,同时也会影响单页面应用首屏加载速度,所以这里采用一种打包优化手段之一来分离依赖项。

Vue打包优化篇-CDN加速

查看依赖版本

首先项目中需要使用依赖项,我这里项目中打算将element-ui、vue、vuex、vue-router这些依赖项进行分离,记录依赖版本方便后面使用。

依赖名称 依赖版本
vue 2.6.11
vue-router 3.2.0
vuex 3.4.0
element-ui 2.15.9

Vue打包优化篇-CDN加速

查看依赖引用

在main.js中可以看到这些依赖被引用。
在项目中开发环境和生成环境一些配置是不同的,所以这里截图方便后面理解。

Vue打包优化篇-CDN加速

配置开发环境和生产环境

在上面我们已经看到main.js中如何引用依赖,现在我们需要做一些改动在main.js改为main-dev.js作为我们的开发环境,然后在同级目录下创建一个新的文件叫main-prod.js作为我们的生产环境,实际开发中开发环境(main-dev.js)和生产环境(main-prod.js)配置存在不同。

开发环境入口 - main-dev.js

Vue打包优化篇-CDN加速

// 这是给ElementUI组件库组件设置默认参数
Vue.use(ElementUI, { size: 'small', zIndex: 3000 });

生产环境入口 - main-prod.js

Vue打包优化篇-CDN加速

// 这是给ElementUI组件库组件设置默认参数(cdn加速和生产环境配置有区别)
Vue.prototype.$ELEMENT = {
  size: 'small',
  zIndex: 3000
};

配置开发环境入口和生产环境入口

这里需要注意一下的是配置入口,因为默认入口文件只有一个main.js但是你给改成了main-dev.js而且还新增了一个main-prod.js,然后你运行项目或打包项目肯定报错,因为它去找main.js找不到啊,所以这里需要通过vue.config.js文件来指定生产环境和开发环境入口。

vue.config.js

// 判断是否是生产环境
const isProduction = process.env.NODE_ENV !== 'development';
module.exports = {
    publicPath: './', // 不加这个可能会导致静态资源找不到的情况。
    chainWebpack: config => {
        config.when(isProduction, config => {
        	// 如果是生产环境,那么将main-prod.js作为入口文件(我这里是ts和js一样)。
            config.entry('app').clear().add('./src/main-prod.ts');
        });
        config.when(!isProduction, config => {
        	// 如果是不是生产环境,那么将main-dev.js作为入口文件(我这里是ts和js一样).
            config.entry('app').clear().add('./src/main-dev.ts');
        });
    }
};

Vue打包优化篇-CDN加速

配置CDN加速

完成上面环境配置已经成功一半啦,接下来就需要配置cdn加速相关的啦。

vue.config.js

这里需要说明一下,看下面的cdn加速链接中依赖的版本和上面查看依赖版本表格展示是不是一样的?肯定要一样啊不然出现依赖版本冲突问题怎么办。
关于externals属性告诉webpack需要排除的依赖名称和挂载在window上的对象属性名称,这里简单列出常用的表,如需要其它的可以插件依赖导出到window的对象名称,也可以面向百度查找对应的对象属性名称。

依赖名称 挂载在window上的对象属性名称
vue Vue
vue-router VueRouter
vuex Vuex
lodash _
element-ui ELEMENT

const isProduction = process.env.NODE_ENV !== 'development';
const cdn = {
    externals: {
        vue: 'Vue',
        'vue-router': 'VueRouter',
        vuex: 'Vuex',
        "element-ui": "ELEMENT"
    },
    css: [
        'https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.9/theme-chalk/index.min.css',
    ],
    js: [
        'https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js',
        'https://cdn.jsdelivr.net/npm/vue-router@3.2.0/dist/vue-router.min.js',
        'https://cdn.jsdelivr.net/npm/vuex@3.4.0/dist/vuex.min.js',
        'https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.9/index.min.js'
    ]
};
module.exports = {
    publicPath: './',
    chainWebpack: config => {
        config.when(isProduction, config => {
            config.entry('app').clear().add('./src/main-prod.ts');
            // 我们希望的是在生产环境下才进行cdn优化!!!这点理解很重要。
            // 告诉webpack需要排除的依赖名称和挂载在window上的对象属性名称。
            config.set('externals', cdn.externals);
            // 这里的作用是在后面index.html页面中通过link,script标签加载这些cdn链接。
            config.plugin('html').tap(args => {
                args[0].cdn = cdn;
                return args;
            });
        });
        config.when(!isProduction, config => {
            config.entry('app').clear().add('./src/main-dev.ts');
        });
    }
};

Vue打包优化篇-CDN加速

index.html

这里也需要说明一下,这个index.html页面的位置一般在public目录下。
下面的htmlWebpackPlugin.options.cdn对象是不是很眼熟,不就是我们通过vue.config.js中生产环境配置config.plugin(‘html’)加入的属性?真是一环扣一环呐。

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
  <title>
    <%= htmlWebpackPlugin.options.title %>
  </title>
  <!-- 这里从cdn配置里面加载css文件 -->
  <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
    <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style" />
    <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet" />
  <% } %>
  <!-- 这里从cdn配置里面加载js文件 -->
  <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
    <link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="preload" as="script" />
  <% } %>
</head>
<body>
  <noscript>
    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
        Please enable it to continue.</strong>
  </noscript>
  <div id="app"></div>
  <!-- built files will be auto injected -->
  <!-- 这里从cdn配置里面加载js文件 -->
  <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
    <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
  <% } %>
</body>
</html>

打包测试

完成以上步骤后,cdn打包优化就完成啦,现在运行打包测试一下。
下面打包数据和没有cdn优化的打包数据对比一下,是不是依赖项排除了?打包时间也变快了。
面试的时候是不是又多了一些底气了?

Vue打包优化篇-CDN加速