前言
如果你只是想快速配置 cdn,可以直接看快速配置篇。
选择 Vue 的 cdn
引入的 vue 文件必须是游览器版本,最少需要 ==运行时源码==,根据你的 Vue 版本不同,选择的文件也不同:
- Vue2 版本的用户选择: vue.runtime.min.js;
- Vue3 版本的用户选择: vue.runtime.global.prod.js。
我使用的是 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 模板。
一手准备
来到 项目/vue.config.js
文件,如果没有就创建。
准备分两步:
-
设置外部依赖:在打包时忽略已经用 cdn 引入的模块。
-
添加模板参数:准备插入的 cdn 资源元素。
以下代码中,Moment.js 和 Vue3 就是用了 cdn 来引入,并且在打包时忽略这两个模块:
/** @file vue.config.js */
module.exports = {
chainWebpack: (config) => {
// 只在生产环境使用 cdn
if (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"
这句话,模块"Vue"
是不变的,这个就是键名。 -
值:值就是使用 cdn 后,这个模块在全局上的引用。 比如 Vue 使用 cdn 引入后,全局上使用
Vue
变量来访问,那么外部扩展的值就是 Vue。
-
-
config.plugin("html").tap
用于修改 HtmlWebpackPlugin 这个插件的参数,这里插入一个cdns
参数,所以在public/index.html
中可以使用<%= htmlWebpackPlugin.options.cdns %>
来访问这个参数。
小结 + 打包测试
注意:源代码只是改了 “项目/public/index.html” 文件和配置了 vue.config.js,没有修改其他代码。此方法并不会在开发环境中使用 cdn,具体原因参考第一节前言。
测试代码的 package.json
依赖为:
{
"dependencies": {
"core-js": "^3.6.5",
"moment": "^2.29.1",
"vue": "^3.0.0"
}
}
其中 moment
和 vue
使用了 cdn 引入。
不使用 cdn 的打包情况(注释掉 vue.config.js 添加的代码就可测试):
warning
webpack 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 Gzipped
dist\js\chunk-vendors.50f67bb1.js 379.14 KiB 110.63 KiB
dist\js\app.d4b48aed.js 6.54 KiB 2.45 KiB
Images 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.html
Done in 5.03s.
上来直接报一个包太大警告,这项目还什么都没写,就是在 App.vue
里面引入了 Moment.js。
其中 chunk-vendors
为 379.14 KB,包含了 core-js
、moment
和 vue
三个模块。
使用 cdn 的打包情况:
DONE Compiled successfully in 720ms 下午2:52:47
File Size Gzipped
dist\js\chunk-vendors.20dbb2c7.js 24.82 KiB 9.06 KiB
dist\js\app.08fbc8da.js 2.02 KiB 0.99 KiB
Images 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.html
Done in 3.49s.
此时 chunk-venders 降到 24KB,只剩一些关于 core-js
的依赖了。
小结:
这种打包方式只是阐述基本实现方式,如果你觉得比较麻烦,可以看最后一节快速配置篇。
如果想继续优化打包,建议了解异步路由,异步加载等,谨慎使用 require.context
。
快速配置篇
我自己也没那么多时间每次去查怎么配置,所以直接封装了一个函数。
- 首先,在
public/index.html
的head
元素里面添加下面这行代码用来插入 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>`,
},
]);
},
};
其中,mod
和 refer
对应了外部扩展的模块名和引用名,el
为 cdn 元素。
关于 useCDNs
详细使用参考原文件,注释已经写满了。
FAQ
是否需要删除 import Vue 语句?
==不用删除,也不能删除。==
因为本文方法只是配置了生成环境使用 cdn,开发环境使用的还是 node_moduels
中的本地包,删了开发环境就 GG。
cdn 哪里找?
以前我使用的是 bootcdn,但这家前年过年前后崩过一次,后来没怎么使用。
你可以使用 UNPKG,这个是和 npm 库直接关联的。
或者 JSDELIVR,老牌 cdn 有保障,还支持 SRI。
兼容性
vue-cli3 和 vue-cli4 都兼容这种配置方式。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!