• 在 vue-cli 构建的项目中配置使用资源CDN,加速我们的项目


    vue-cli 构建的项目中配置使用资源CDN,加速我们的项目

    写在前面

    出于对网站性能的要求,有时候我们不希望一些比较大的第三方库直接打包到最后的 bundle 中,而会选择在打包的时候忽略他们,并直接使用 CDN 上面的资源。

    生产环境中将项目依赖的一些第三方包替换成通过 cdn 方式外部加载,而不是打包到 vender,对于提升应用的加载、响应速度很有意义。

    vue-cli3 及以后的项目中,相关配置都需要在 vue.config.js 这个文件中进行,如果你没有这个文件请自己新建一个(与 package.json 同级)。

    实现目标

    以目前常见的前端项目为例,建议把常用的资源进行 cdn 引用及配置;如:vuevuexvue-routeraxioselementUI ...

    目标过程

    一、配置需要拎出来的模块

    这里我们首先配置 configureWebpackexternals 字段,把不需要打包的资源进行相应的配置。如下所示:

    module.exports = {
      ...
      configureWebpack: {
        externals: {
          'vue': 'Vue',
          'element-ui': 'ELEMENT',
          'vue-router': 'VueRouter',
          'vuex': 'Vuex'
        }
      },
      ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这里我们排除了 vueelement-uivue-routervuex

    关于这个配置怎么写的问题:

    以打包时忽略 element-ui 为例,'element-ui' 指的是你 import 语句中 import ElementUI from 'element-ui' 中的 'element-ui''ELEMENT'element-ui 这个库暴露出来的全局对象。这个对象你可以从 cdn 资源的源码中找到或者根据需要引用的文件去 node_modules 文件夹下去寻找。下面我们从 node_modules 文件夹下的源码找一下 element-uivue-routervuex 暴露出的全局对象,以下是各源码的截图:

    以后需要排除其他的三方库或者插件的时候,大家可以自己去找暴露出来的全局对象了。

    二、配置 cdn 链接

    配置完 externals 之后我们还需要利用 htmlWebpackPlugin 的能力让我们在打包的时候可以获取我们需要的 cdn 资源数据。首先我们在 vue.config.js 定义一个存放 cdn 资源连接的对象 cdn,如下所示:

    const cdn = {
      css: ['//unpkg.com/element-ui@2.13.0/lib/theme-chalk/index.css'],
      js: [
        '//unpkg.com/vue@2.6.11/dist/vue.min.js',
        '//unpkg.com/vue-router@2.8.1/dist/vue-router.min.js',
        '//unpkg.com/vuex@3.1.2/dist/vuex.min.js',
        '//unpkg.com/element-ui@2.13.0/lib/index.js'
      ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    其次我们把 cdn 这个对象放入我们配置中的 page 字段里,完整配置如下:

    
    const cdn = {
      css: ['//unpkg.com/element-ui@2.13.0/lib/theme-chalk/index.css'],
      js: [
        '//unpkg.com/vue@2.6.11/dist/vue.min.js',
        '//unpkg.com/vue-router@2.8.1/dist/vue-router.min.js',
        '//unpkg.com/vuex@3.1.2/dist/vuex.min.js',
        '//unpkg.com/element-ui@2.13.0/lib/index.js'
      ]
    }
     
    module.exports = {
      publicPath: '/',
      productionSourceMap: process.env.NODE_ENV !== 'production',
      devServer: {
        port: 8077
      },
      chainWebpack: config => {
        config.resolve.symlinks(true)
      },
      configureWebpack: {
        externals: {
          'vue': 'Vue',
          'element-ui': 'ELEMENT',
          'vue-router': 'VueRouter',
          'vuex': 'Vuex'
        }
      },
      pages: {
        index: {
          entry: 'src/main.ts',
          template: 'public/index.html',
          filename: 'index.html',
          title: 'sass-admin',
          chunks: ['chunk-vendors', 'chunk-common', 'index'],
          cdn: cdn
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    做完这些之后,我们还需要在入口文件的 html 模板处加上生成 cssjs 脚本的代码,比如这里的 html 模板位置就是 'public/index.html'

    这里比较简单就直接放送完整的 html 模板代码了,如下:

    DOCTYPE html>
    <html lang="en">
      <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>
        <% for (let i in htmlWebpackPlugin.options.cdn.css) { %>
          <link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" />
        <% } %>
      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>
        
        <% for (let i in htmlWebpackPlugin.options.cdn.js) { %>
          <script
            type="text/javascript"
            src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"
          >script>
        <% } %>
      body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    其中:

    • <%= VALUE %> 用来做不转义插值
    • <% expression %> 用来描述 JavaScript 流程控制

    这些用到了 lodash template 的语法 ,感兴趣的朋友可以去了解更多内容,这里不做展开。

    做完这一切之后我们用打包分析工具分析一下配置完 CDN 前后 bundle 内容的变化。

    配置 cdn 之前的分析图:

    配置 cdn 之后的分析图:

    通过对比,发现我们的 chunk-vendors 已经少了我们配置在 CDN 中的第三方资源,另一个直观的比较就是打包后 chunk-vendors 的资源大小,这里不再展开。另一个重要的变化就是我们打包之后的 html 上也加上了相应的资源脚本,如图所示:

    把资源放在 CDN 上一方面可以减轻自己服务器的带宽消耗(资源从别的服务器下载,而不是你自己的服务器),另一方面 CDN 上的资源一般是你不会轻易修改的,而且浏览器访问之后还会缓存下来,用户再次访问就无需二次下载资源,网站后续的整体访问速度就更快了,同时 CDN 还可以做加速。

    —————————— 【正文完】——————————

    推荐阅读:灰信网(软件开发博客聚合 - 程序员专属的优秀博客文章阅读平台

    前端学习交流群,想进来面基的,可以加群: 832485817685486827
    前端顶级学习交流群(一) 前端顶级学习交流群(二)

    写在最后: 约定优于配置 —— 软件开发的简约原则

    ——————————【完】——————————

    我的:
    个人网站: https://neveryu.github.io/neveryu/
    Github: https://github.com/Neveryu
    新浪微博: https://weibo.com/Neveryu
    微信: miracle421354532

    更多学习资源请关注我的新浪微博…好吗

  • 相关阅读:
    基于 HBase & Phoenix 构建实时数仓(4)—— Kafka 集群安装部署
    YZ系列工具之YZ13:VBA_过滤数据并行删除
    行业落地呈现新进展 | 2022开放原子全球开源峰会OpenAtom OpenHarmony分论坛圆满召开
    财务指标初步学习笔记
    解决循环依赖import cycle not allowed的多个办法
    Mybatis的多表操作之多对多查询与练习
    scipy.optimize.leastsq()拟合函数
    如何搭建游戏平台?
    vue中用ref实现父子组件、孙组件、兄弟组件、非亲子孙组件互相调用的方法
    Microbiome 跨组学功能网络预测神器
  • 原文地址:https://blog.csdn.net/csdn_yudong/article/details/126781602