vite使用CDN引入第三方库
2022年6月20日 • ... • ☕️ 3 min read
vite的打包部分,完全交给了rollup。所以打包这部分的配置,在官方文档介绍的并不多,一行带过,而且是库模式的
当这个库要进行发布构建时,请使用 build.lib 配置项,以确保将那些你不想打包进库的依赖进行外部化处理,例如 vue 或 react
如果是以页面应用模式发布的时候,如何配置才能以第三方库的方式(如CDN)引入呢?
既然全部交给了rollup,那么配置自然是在build -> rollupOptions
里
初步设想是只在打包的时候把需要外部化(external)的第三方库拿出去,在开发模式,依然是用npm安装的模块方式来运行。
// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
return {
build: {
rollupOptions: {
external: ["@antv/g2plot", "@antv/l7plot"],
output: {
globals: {
"@antv/g2plot": "G2Plot",
"@antv/l7plot": "L7Plot",
},
paths: {
"@antv/g2plot":
"https://unpkg.com/@antv/g2plot@latest/dist/g2plot.min.js",
"@antv/l7plot":
"https://unpkg.com/@antv/l7plot@latest/dist/umd/l7plot.min.js",
},
}
}
}
}
};
如果使用的是iife
或者umd
模式的文件,上面的配置就够用了。但是很多库只有cjs(commonjs)
格式的输出,这个时候如果直接配置,就会 报错,例如
The requested module 'https://unpkg.com/@antv/g2plot@2.4.5/dist/g2plot.min.js' does not provide an export named 'Area'
需要的插件:rollup-plugin-external-globals
import externalGlobals from "rollup-plugin-external-globals";
// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
return {
build: {
rollupOptions: {
plugins: [
externalGlobals({
"@antv/g2plot": "G2Plot",
"@antv/l7plot": "L7Plot",
}),
],
}
}
}
};
这个插件会为引入的第三方库创建一个全局变量,并把代码转码:
import jq from "jquery";
console.log(jq(".test"));
// into
console.log($(".test"));
关于iife、amd、cmd、cjs、umd、esm
iife全称Immediately Invoked Function Expression,即立即执行函数,我们在做闭包题目中肯定会遇到的那种函数。
(function(){
// ... stuff
})();
commonjs又叫cjs,是nodejs即服务端广泛使用的模块化机制。简而言之,必须通过module.exports
导出变量或者接口,通过require()
来导入变量或接口。
// rollup生成的AMD格式文件
define(['exports'], function (exports) {
const foo = '123';
function someFunc() {
// ...stuff
}
exports.someFunc = someFunc;
Object.defineProperty(exports, '__esModule', {value: true});
});
AMD全称Asynchronous Module Definition,它诞生于cjs,但是支持异步模块加载。它使用RequireJS等模块,在浏览器端进行模块加载。CMD就不说了,过渡产品,本身特性被RequireJS支持而退出历史舞台。
UMD全程是Universal Module Definition,兼容iife、amd和iife的写法。
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.NAME = factory());
}(this, (function () {
//code
return obj;
})));
ESM最近使用vite
出镜率特别高的词,是ES2015以来的官方标准。我们在TypeScript
常用的import / export
方法,就是这种。
const increase = (val, total) => total + val;
// ... stuff
export { increase };
浏览器端不能执行,但是较新的浏览器(chrome 61+,firefox 60+,safari 11+),如果把script
的type
设置为module
,即可识别 import / export
。