文章目录

  • vue-cli cdn 方式引入 Vue 模块
    • 前言
    • 选择 Vue 的 cdn
    • 如何引入 cdn ?
      • 一手插入
      • 一手准备
    • 小结 + 打包测试
    • 快速配置篇
    • FAQ
      • 是否需要删除 import Vue 语句?
      • cdn 哪里找?
      • 兼容性
      • 样式表怎么使用第三方 CDN ?

vue-cli cdn 方式引入 Vue 模块

前言

如果你只是想快速配置 cdn,可以直接看快速配置篇。

Chrome 将于不久后默认开启 限制子资源在私有网络的分发 策略,它会导致非 https 协议无法使用第三方外链,这将导致开发环境无法使用 cdn。这个策略我在测试时对 CSS 样式表无效。
这个安全策略开启后,你可能会在未来遇到这个错误:
我当前是 Chrome 91,可以在 Chrome 浏览器的地址栏中输入 chrome://flags/#block-insecure-private-network-requests 来找到这个策略,在未来的版本它会被默认开启,如果你现在主动启用该策略,那么开发环境使用 cdn 你将遇到一个错误:The request client is not a secure context and the resource is in more-private address space \local`.`
综上,该博客于 2021-07-08 日做了非常大的改动。本来 Vue 也出 3 了,这篇模块也没还没讨论 Vue3 的 cdn 引入方式。

选择 Vue 的 cdn

引入的 vue 文件必须是游览器版本,最少需要 运行时源码,根据你的 Vue 版本不同,选择的文件也不同:

  • Vue2 版本的用户选择: vue.runtime.min.js
  • Vue3 版本的用户选择: vue.runtime.global.prod.js

运行时源码和完整版有什么不同?
运行时源码少了编译器,而完整版有,因为 vue-loader 已经编译了 template,所以不需要再次编译。这意味着运行时源码还要小一点,详见vue2 官方文档 或者 vue3 官方文档。

我使用的是 bootcdn 的运行时压缩模块,体积会更小。切记,使用的 cdn 需要和你的 package.json 中依赖包的版本号相同,以免产生版本 bug。

如何引入 cdn ?

因为开发环境不能安全使用第三方外链,所以第三方 cdn 只能在生产环境中使用。

具体引入方式是在 vue.config.js 中注册 cdn 的模板变量,然后在 public/index.html 中插入。一手准备,一手插入。

一手插入

使用 vue-cli 构建的项目,可以在 项目/public/index.html 的 head 元素中 插入准备好的 cdn 模板。

我的代码如下:

<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>vue-app</title><!-- 这里是插入的 CDN 位置,编写下面这行代码即可。 --><%= htmlWebpackPlugin.options.cdns %>
</head>

这里使用了 html-webpack-plugin 插件的模板参数,你可以通过此插件准备一些参数插入到这个模板中。

可以看到,我们插入了 <%= htmlWebpackPlugin.options.cdns %> 参数,这就是我们需要准备的 cdn 模板。

诸如 <%= %> 这类语法是 EJS 模板语法,想要详细了解可以看看它的 中文文档。

一手准备

来到 项目/vue.config.js 文件,如果没有就创建。

准备分两步:

  • 设置外部依赖:在打包时忽略已经用 cdn 引入的模块。

  • 添加模板参数:准备插入的 cdn 资源元素。

以下代码中,Moment.js 和 Vue3 就是用了 cdn 来引入,并且在打包时忽略这两个模块:

/** @file vue.config.js */module.exports = {chainWebpack: (config) => {// 只在生产环境使用 cdnif (process.env.NODE_ENV === "production") {// 忽略 vue 和 moment 这两个模块config.externals({vue: "Vue",moment: "moment",});// 修改 HtmlWebpackPlugin 插件参数,植入 cdns 这个模板参数,值为 Vue3 和 Moment.js 的 cdn 链接config.plugin("html").tap((args) => {args[0].cdns = `<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.1.2/vue.runtime.global.prod.min.js" crossorigin="anonymous"></script><script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.1/moment.min.js" crossorigin="anonymous"></script>`;return args;});}},
};

其中:

  • config.externals 用于配置 外部扩展,其作用是不打包使用外部引入的扩展,也就是 build 的时候不打包这些模块。它的键名和值是有意义的:

    • 键名:键名为使用外部扩展的模块。 比如 import VueLib123 from "vue" 这句话,模块 from "vue" 是不变的,模块名就是这个就是键名。

    • 值:值就是使用 cdn 后,这个模块在全局上的引用。 比如 Vue 使用 cdn 引入后,全局上使用 Vue 变量来访问,那么外部扩展的值就是 Vue。

  • config.plugin("html").tap 用于修改 HtmlWebpackPlugin 这个插件的参数,这里插入一个 cdns 参数,所以在 public/index.html 中可以使用 <%= htmlWebpackPlugin.options.cdns %> 来访问这个参数。

  • 上述代码使用的 Webpack 配置方式是 链式调用,因为涉及修改插件参数,无法使用 简单配置。
  • 我在 script 元素中设置了 crossorigin 属性,取消了用户凭证传递,详见 CORS settings attributes 。
  • 如果你想更安全的使用第三方 cdn ,那么推荐你使用 SRI。

小结 + 打包测试

注意:源代码只是改了 “项目/public/index.html” 文件和配置了 vue.config.js,没有修改其他代码。此方法并不会在开发环境中使用 cdn,具体原因参考第一节前言。

测试代码的 package.json 依赖为:

{"dependencies": {"core-js": "^3.6.5","moment": "^2.29.1","vue": "^3.0.0"}
}

其中 momentvue 使用了 cdn 引入。

不使用 cdn 的打包情况(注释掉 vue.config.js 添加的代码就可测试):

warningwebpack performance recommendations:
You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
For more info visit https://webpack.js.org/guides/code-splitting/File                                 Size                                            Gzippeddist\js\chunk-vendors.50f67bb1.js    379.14 KiB                                      110.63 KiBdist\js\app.d4b48aed.js              6.54 KiB                                        2.45 KiBImages and other types of assets omitted.DONE  Build complete. The dist directory is ready to be deployed.INFO  Check out deployment instructions at https://cli.vuejs.org/guide/deployment.htmlDone in 5.03s.

上来直接报一个包太大警告,这项目还什么都没写,就是在 App.vue 里面引入了 Moment.js。

其中 chunk-vendors 为 379.14 KB,包含了 core-jsmomentvue 三个模块。

使用 cdn 的打包情况:

 DONE  Compiled successfully in 720ms                                                                                         下午2:52:47File                                 Size                                            Gzippeddist\js\chunk-vendors.20dbb2c7.js    24.82 KiB                                       9.06 KiBdist\js\app.08fbc8da.js              2.02 KiB                                        0.99 KiBImages and other types of assets omitted.DONE  Build complete. The dist directory is ready to be deployed.INFO  Check out deployment instructions at https://cli.vuejs.org/guide/deployment.htmlDone in 3.49s.

此时 chunk-venders 降到 24KB,只剩一些关于 core-js 的依赖了。

小结:

这种打包方式只是阐述基本实现方式,如果你觉得比较麻烦,可以看最后一节快速配置篇。

如果想继续优化打包,建议了解异步路由,异步加载等,谨慎使用 require.context

快速配置篇

我自己也没那么多时间每次去查怎么配置,所以直接封装了一个函数。

  • 首先,在 public/index.htmlhead 元素里面添加下面这行代码用来插入 cdn。
<%= htmlWebpackPlugin.options.cdns %>
  • 接着新建一个文件 useCDNs.js 在任意位置,我放到了 根路径/webpack/useCDNs.js 中。新建后复制以下代码粘贴进去即可,注释不想要可以删掉。
/** @file useCDNs.js *//** @typedef {string} ModuleName 模块名   */
/** @typedef {string} ModuleRefer 模块在全局的引用   */
/** @typedef {string} ElementTem 元素模板   */
/** @typedef {{mod:ModuleName;refer:ModuleRefer;el:ElementTem}} CDNItem  cdn 项目 *//*** cdn 使用函数。** 此函数可以在指定开发环境中,指定某些模块作为外部依赖出现,并把准备好的第三方 cdn 模板以 `cdns` 参数通过 HtmlWebpackPlugin 插件插入到 `public/index.html` 文件中。* 你可以在 `public/index.html` 中使用 ejs 语法 <%= htmlWebpackPlugin.options.cdns %> 来插入准备好的 cdn。** @param {import('webpack-chain')} config webpack-chain 实例* @param {CDNItem[]} cdns 传入需要使用的 cdn 数组* @param {string} env 什么环境下使用 cdn ,默认生产环境*/
module.exports = function useCDNs(config, cdns = [], env = "production") {if (process.env.NODE_ENV !== env) return;config.externals(cdns.reduce((prev, v) => {prev[v.mod] = v.refer;return prev;}, {}));config.plugin("html").tap((args) => {args[0].cdns = cdns.map((v) => v.el).join("");return args;});
};
  • 最后在 vue.config.js 中使用如下方式调用:
/** @file vue.config.js */const useCDNs = require("./webpack/useCDNs");module.exports = {chainWebpack: (config) => {useCDNs(config, [{mod: "vue",refer: "Vue",el: `<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.1.2/vue.runtime.global.prod.min.js"></script>`,},{mod: "moment",refer: "moment",el: `<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.1/moment.min.js" crossorigin="anonymous"></script>`,},]);},
};

其中,modrefer 对应了外部扩展的模块名和引用名,el 为 cdn 元素。

关于 useCDNs 详细使用参考原文件,注释已经写满了。

FAQ

是否需要删除 import Vue 语句?

不用删除,也不能删除。

因为本文方法只是配置了生成环境使用 cdn,开发环境使用的还是 node_moduels 中的本地包,删了开发环境就 GG。

cdn 哪里找?

以前我使用的是 bootcdn,但这家前年过年前后崩过一次,后来没怎么使用。

你可以使用 UNPKG,这个是和 npm 库直接关联的。

或者 JSDELIVR,老牌 cdn 有保障,还支持 SRI。

兼容性

vue-cli3 和 vue-cli4 都兼容这种配置方式。

样式表怎么使用第三方 CDN ?

首先,样式表是没有外部扩展的;其次,文章前言中提到的限制子资源策略对 CSS 并无作用。

如果你想让 CSS 使用 CDN,可以直接在 public/index.html 文件的 head 元素中直接引入即可,开发环境和生产环境都有效。

需要说的是,因为样式表没有外部扩展。如果全搬上文中引入 JS 的方式,就需要删除项目中的 CSS 引入,不然在生产环境中就会存在两份样式表。

比如你用了 ElementUI,在项目中你引入了 import "element-ui/lib/theme-chalk/index.css",如果在 public/index.html 中再引入一次,或者在 vue.config.js 中再添加一次,都会造成二次引入。虽然多次引入对渲染结果无影响,但这样做会让浏览器产生额外的样式计算,损耗性能。

vue-cli cdn方式引入Vue模块相关推荐

  1. Vue以CDN方式调用Swiper轮播异常

    Vue以CDN方式调用Swiper轮播异常 参考文章: (1)Vue以CDN方式调用Swiper轮播异常 (2)https://www.cnblogs.com/Tylerrrkd/p/9165886. ...

  2. cdn方式引入外部的js库

    cdn方式引入外部的js库 1.引入jQuery <!-- 引入jQuery使用cdn的方式引入jQuery --> <script src="http://lib.sin ...

  3. vue cli 3 升级到 vue cli 4 方法步骤及升级点总结

    vue cli 3 升级到 vue cli 4 方法步骤及升级点总结 官方升级英文文档,中文文档相对滞后. 简介:vue cli 4 官方已经更新有一段时间了,现在是4.0.5 版本,看了官方文档大概 ...

  4. 使用Yarn全局安装@vue/cli,无法执行vue命令的解决方案

    使用Yarn全局安装@vue/cli,无法执行vue命令的解决方案 使用Yarn全局安装@vue/cli,无法执行vue命令的解决方案 使用Yarn全局安装@vue/cli,无法执行vue命令的解决方 ...

  5. 前端 cdn 方式使用 Vue + element-ui

    一.引入资源 <script src="https://unpkg.com/vue@2.7.10/dist/vue.min.js"></script> &l ...

  6. 原声html中怎么加载vue文件,HTML文件引入Vue开发

    HTML文件引入Vue开发 页面标题 {{text}} {{item.text}} 点击事件 @click {{text}} 添加文本使用两个大括号{{文本}} img标签中src前面得加冒号 new ...

  7. vue引入cdn Vue 优化Vue引入 cdn vue cdn Vue优化引入CDN vue 项目 CDN优化

    vue引入cdn Vue 优化Vue引入 cdn vue cdn Vue优化引入CDN vue 项目 CDN优化 未引入 CDN前 main.js 更改CDN方式引入 在 vue.config 中引入 ...

  8. vue main.js中引入js_手把手教你深入Vue3.0(Vue-cli4)项目打包性能优化实践

    记录了自己的博客在禁用缓存的情况下,从八九秒加载时间到最终985ms的优化实践,开启缓存的情况下能达到138ms的访问速度 本人的个人博客采用的是Vue-cli4.1.2 + typescript构建 ...

  9. vue cli 4 多环境_Vue 笔记整理19

    19.1 vue-cli起步 19.1.1 什么是vue-cli Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供: - 通过 @vue/cli 搭建交互式的项目脚手架. - 通 ...

最新文章

  1. vivado的综合与实现策略怎样设置
  2. android listview分页显示,Android应用中使用ListView来分页显示刷新的内容
  3. CnPack 使用的组件命名约定
  4. linux mysql 知乎_在 Linux 上安装 MariaDB 或 MySQL | Linux 中国
  5. HDU 1573: X问题
  6. GMGridView cell button
  7. 类路径是什么意思_多播是什么意思 多播介绍【详解】
  8. java文件出现字符串_找出三个文本文件中都出现的字符串,并输出到一个文本文件(菜鸟求救)...
  9. 导致溢出_1篇文章搞清楚8种JVM内存溢出(OOM)的原因和解决方法
  10. Linux的Nginx三:类型|特点
  11. 全志A33-gpio驱动程序
  12. Java学习----方法的重载
  13. DHCP服务器如何检测穿过中继代理的IP地址冲突(gratuitous ARP肯定是不行的)
  14. 线程池是如何重复利用空闲线程的?
  15. Linux下mongodb用户管理和设置远程登陆
  16. 广西建工OA系统office插件显示问题解决方案
  17. 2023王道数据结构P40题二.1,关于是否会断链的问题
  18. ubuntu18下载utuntu18镜像
  19. 《读万卷书行万里路》国画大家罗建泉写生艺术
  20. 上位机与下位机交互--让socket不死

热门文章

  1. 矽杰微 X8M2101 单片机
  2. 第3章 软件测试方法--基于直觉和经验的方法
  3. 实例简述Spring AOP之对AspectJ语法的支持
  4. 报错Unknown custom element: <组件名> - did you register the component correctly?的原因及解决办法
  5. 关于中断的分类和优先级(优先级由高到低排序)
  6. Daily record-August
  7. Python内置函数os模块shutil模块
  8. orb-slam2 从单目开始的简单学习(7):Optimizer
  9. Jackson 数据类型转换(使用JavaType)
  10. php 获取必应图片信息,PHP自动获取必应今日美图