vite-add-cdn-script 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +109 -0
- package/dist/index.js +88 -0
- package/dist/index.umd.cjs +26 -0
- package/index.d.ts +7 -0
- package/package.json +49 -0
package/README.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
# vite-add-cdn-script
|
2
|
+
|
3
|
+
这是一个在vite.js中使用公共cdn的库,包括了"bootcdn", "bytedance", "unpkg", "cdnjs", "jsdelivr", "staticfile"等多个cdn资源,如加载失败会自动切换下一个cdn进行加载。
|
4
|
+
|
5
|
+
## 开始
|
6
|
+
|
7
|
+
### 安装
|
8
|
+
|
9
|
+
```
|
10
|
+
pnpm install vite-add-cdn-script rollup-plugin-external-globals -D
|
11
|
+
```
|
12
|
+
|
13
|
+
### 使用
|
14
|
+
|
15
|
+
vite.config.ts
|
16
|
+
|
17
|
+
```typescript
|
18
|
+
import { defineConfig } from "vite";
|
19
|
+
import react from "@vitejs/plugin-react";
|
20
|
+
import viteAddCdnScript from "../vite-add-cdn-script/lib/main";
|
21
|
+
import externalGlobals from "rollup-plugin-external-globals";
|
22
|
+
|
23
|
+
// 需要使用cdn库
|
24
|
+
const externals = {
|
25
|
+
react: "React",
|
26
|
+
"react-dom": "ReactDOM",
|
27
|
+
};
|
28
|
+
|
29
|
+
export default defineConfig({
|
30
|
+
plugins: [
|
31
|
+
react(),
|
32
|
+
viteAddCdnScript({}),
|
33
|
+
],
|
34
|
+
build: {
|
35
|
+
rollupOptions: {
|
36
|
+
external: [...Object.keys(externals)],
|
37
|
+
plugins: [externalGlobals(externals)],
|
38
|
+
},
|
39
|
+
},
|
40
|
+
});
|
41
|
+
```
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
使用自定义的cdn
|
46
|
+
|
47
|
+
```typescript
|
48
|
+
import { defineConfig } from "vite";
|
49
|
+
import react from "@vitejs/plugin-react";
|
50
|
+
import viteAddCdnScript from "../vite-add-cdn-script/lib/main";
|
51
|
+
import externalGlobals from "rollup-plugin-external-globals";
|
52
|
+
|
53
|
+
const externals = {
|
54
|
+
react: "React",
|
55
|
+
"react-dom": "ReactDOM",
|
56
|
+
};
|
57
|
+
|
58
|
+
export default defineConfig({
|
59
|
+
plugins: [
|
60
|
+
react(),
|
61
|
+
viteAddCdnScript({
|
62
|
+
customScript: {
|
63
|
+
react: "<script src='https://cdn.jsdelivr.net/npm/react@17.0.2/umd/react.production.min.js'></script>",
|
64
|
+
"react-dom": "<script src='https://cdn.jsdelivr.net/npm/react-dom@17.0.2/umd/react-dom.production.min.js'></script>",
|
65
|
+
},
|
66
|
+
}),
|
67
|
+
],
|
68
|
+
base: "./",
|
69
|
+
build: {
|
70
|
+
rollupOptions: {
|
71
|
+
external: [...Object.keys(externals)],
|
72
|
+
plugins: [externalGlobals(externals)],
|
73
|
+
},
|
74
|
+
},
|
75
|
+
});
|
76
|
+
|
77
|
+
```
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
options
|
82
|
+
|
83
|
+
| 参数 | 解析 | 类型 | 默认值 |
|
84
|
+
| ------------ | ----------------- | --------------------------- | ------------------------------------------------------------ |
|
85
|
+
| protocol | 协议 | “http”\|“https” | https |
|
86
|
+
| customScript | 自定义cdn脚本 | { [*key*: string]: string } | 无 |
|
87
|
+
| retryTimes | 重试次数 | number | 3 |
|
88
|
+
| defaultCdns | 默认使用cdn的顺序 | string[] | ["bootcdn", "bytedance", "unpkg", "cdnjs", "jsdelivr", "staticfile"] |
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
## 注意事项
|
93
|
+
|
94
|
+
因为cdn对包管理的命名有很大的不同,默认是使用了xxx.min.js的文件,如果您使用的库的cdn文件不是这个的话,则需要配置为自定义的cdn。
|
95
|
+
|
96
|
+
目前做了适配的非xxx.min.js适配的库如下,如果你有合适的cdn源或者,需要适配的库,欢迎提交issue或者pr!!!
|
97
|
+
|
98
|
+
```
|
99
|
+
{
|
100
|
+
react: "umd/react.production.min.js",
|
101
|
+
"react-dom": "umd/react-dom.production.min.js",
|
102
|
+
"react-router-dom": "react-router-dom.production.min.js",
|
103
|
+
mobx: "mobx.umd.production.min.js",
|
104
|
+
"mobx-react": "mobxreact.umd.production.min.js",
|
105
|
+
vue: "vue.global.min.js",
|
106
|
+
"vue-router": "vue-router.global.prod.min.js",
|
107
|
+
}
|
108
|
+
```
|
109
|
+
|
package/dist/index.js
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
import N from "node:path";
|
2
|
+
import v from "node:fs";
|
3
|
+
const d = {
|
4
|
+
unpkg: "unpkg.com",
|
5
|
+
bytedance: "lf26-cdn-tos.bytecdntp.com/cdn",
|
6
|
+
staticfile: "cdn.staticfile.net",
|
7
|
+
cdnjs: "cdnjs.cloudflare.com/ajax/libs",
|
8
|
+
jsdelivr: "cdn.jsdelivr.net/npm",
|
9
|
+
bootcdn: "cdn.bootcdn.net/ajax/libs"
|
10
|
+
}, i = {
|
11
|
+
unpkg: "@",
|
12
|
+
bytedance: "/",
|
13
|
+
staticfile: "/",
|
14
|
+
cdnjs: "/",
|
15
|
+
jsdelivr: "@",
|
16
|
+
bootcdn: "/"
|
17
|
+
}, u = {
|
18
|
+
react: "umd/react.production.min.js",
|
19
|
+
"react-dom": "umd/react-dom.production.min.js",
|
20
|
+
"react-router-dom": "react-router-dom.production.min.js",
|
21
|
+
mobx: "mobx.umd.production.min.js",
|
22
|
+
"mobx-react": "mobxreact.umd.production.min.js",
|
23
|
+
vue: "vue.global.min.js",
|
24
|
+
"vue-router": "vue-router.global.prod.min.js"
|
25
|
+
};
|
26
|
+
function C(p) {
|
27
|
+
const {
|
28
|
+
protocol: l = "https",
|
29
|
+
customScript: c = {},
|
30
|
+
retryTimes: m = 3,
|
31
|
+
defaultCdns: f = ["bootcdn", "bytedance", "unpkg", "cdnjs", "jsdelivr", "staticfile"]
|
32
|
+
} = p;
|
33
|
+
let o;
|
34
|
+
return {
|
35
|
+
name: "vite-add-cdn-script",
|
36
|
+
enforce: "pre",
|
37
|
+
apply: "build",
|
38
|
+
config(e) {
|
39
|
+
o = e;
|
40
|
+
},
|
41
|
+
transformIndexHtml(e) {
|
42
|
+
const b = N.resolve(process.cwd(), "package.json");
|
43
|
+
try {
|
44
|
+
const r = "bootcdn", j = v.readFileSync(b, "utf-8"), a = JSON.parse(j), g = o.build.rollupOptions.external;
|
45
|
+
let n = "" + `<script>
|
46
|
+
const separators = JSON.parse('${JSON.stringify(i)}');
|
47
|
+
const cdnUrlObj = JSON.parse('${JSON.stringify(d)}');
|
48
|
+
const defaultCdns = JSON.parse('${JSON.stringify(f)}');
|
49
|
+
function errorCDN(e) {
|
50
|
+
const nextCur = parseInt(e.getAttribute("data-cur")) + 1;
|
51
|
+
if(nextCur>=${m}){return;}
|
52
|
+
const filename = e.getAttribute("data-filename");
|
53
|
+
const key = e.getAttribute("data-key");
|
54
|
+
const urlName = defaultCdns[nextCur]
|
55
|
+
// 组装新的cdn链接
|
56
|
+
const url = location.protocol + "//" + cdnUrlObj[urlName] + "/" + key + separators[urlName] + filename;
|
57
|
+
// 克隆原标签
|
58
|
+
const tagName = e.tagName
|
59
|
+
const cdnDOM = document.createElement(tagName);
|
60
|
+
cdnDOM.setAttribute(tagName === 'SCRIPT' ?'src' : 'href', url);
|
61
|
+
Object.keys(e.dataset).forEach(_key => {
|
62
|
+
cdnDOM.setAttribute('data-'+_key, e.dataset[_key]);
|
63
|
+
})
|
64
|
+
cdnDOM.setAttribute("data-cur", nextCur.toString());
|
65
|
+
cdnDOM.setAttribute("onerror", "errorCDN(this)");
|
66
|
+
document.head.appendChild(cdnDOM);
|
67
|
+
e.remove();
|
68
|
+
}
|
69
|
+
<\/script>`;
|
70
|
+
return Object.keys(a.dependencies).forEach((t) => {
|
71
|
+
if (g.includes(t))
|
72
|
+
if (c[t])
|
73
|
+
n += c[t];
|
74
|
+
else {
|
75
|
+
const s = a.dependencies[t].replace("^", "") + "/" + (u[t] ? u[t] : `${t}.min.js`), O = `${l}://${d[r]}/${t}${i[r]}${s}`;
|
76
|
+
n += `<script src="${O}" type="text/javascript" onerror="errorCDN(this)" data-cur="0" data-key="${t}" data-filename="${s}"><\/script>
|
77
|
+
`;
|
78
|
+
}
|
79
|
+
}), e = e.replace("</head>", `${n}</head>`), e;
|
80
|
+
} catch (r) {
|
81
|
+
console.error("获取dependencies出错:", r);
|
82
|
+
}
|
83
|
+
}
|
84
|
+
};
|
85
|
+
}
|
86
|
+
export {
|
87
|
+
C as default
|
88
|
+
};
|
@@ -0,0 +1,26 @@
|
|
1
|
+
(function(t,n){typeof exports=="object"&&typeof module<"u"?module.exports=n(require("node:path"),require("node:fs")):typeof define=="function"&&define.amd?define(["node:path","node:fs"],n):(t=typeof globalThis<"u"?globalThis:t||self,t.index=n(t.path,t.fs))})(this,function(t,n){"use strict";const s={unpkg:"unpkg.com",bytedance:"lf26-cdn-tos.bytecdntp.com/cdn",staticfile:"cdn.staticfile.net",cdnjs:"cdnjs.cloudflare.com/ajax/libs",jsdelivr:"cdn.jsdelivr.net/npm",bootcdn:"cdn.bootcdn.net/ajax/libs"},a={unpkg:"@",bytedance:"/",staticfile:"/",cdnjs:"/",jsdelivr:"@",bootcdn:"/"},d={react:"umd/react.production.min.js","react-dom":"umd/react-dom.production.min.js","react-router-dom":"react-router-dom.production.min.js",mobx:"mobx.umd.production.min.js","mobx-react":"mobxreact.umd.production.min.js",vue:"vue.global.min.js","vue-router":"vue-router.global.prod.min.js"};function m(f){const{protocol:b="https",customScript:i={},retryTimes:j=3,defaultCdns:g=["bootcdn","bytedance","unpkg","cdnjs","jsdelivr","staticfile"]}=f;let u;return{name:"vite-add-cdn-script",enforce:"pre",apply:"build",config(r){u=r},transformIndexHtml(r){const O=t.resolve(process.cwd(),"package.json");try{const c="bootcdn",N=n.readFileSync(O,"utf-8"),p=JSON.parse(N),x=u.build.rollupOptions.external;let o=""+`<script>
|
2
|
+
const separators = JSON.parse('${JSON.stringify(a)}');
|
3
|
+
const cdnUrlObj = JSON.parse('${JSON.stringify(s)}');
|
4
|
+
const defaultCdns = JSON.parse('${JSON.stringify(g)}');
|
5
|
+
function errorCDN(e) {
|
6
|
+
const nextCur = parseInt(e.getAttribute("data-cur")) + 1;
|
7
|
+
if(nextCur>=${j}){return;}
|
8
|
+
const filename = e.getAttribute("data-filename");
|
9
|
+
const key = e.getAttribute("data-key");
|
10
|
+
const urlName = defaultCdns[nextCur]
|
11
|
+
// 组装新的cdn链接
|
12
|
+
const url = location.protocol + "//" + cdnUrlObj[urlName] + "/" + key + separators[urlName] + filename;
|
13
|
+
// 克隆原标签
|
14
|
+
const tagName = e.tagName
|
15
|
+
const cdnDOM = document.createElement(tagName);
|
16
|
+
cdnDOM.setAttribute(tagName === 'SCRIPT' ?'src' : 'href', url);
|
17
|
+
Object.keys(e.dataset).forEach(_key => {
|
18
|
+
cdnDOM.setAttribute('data-'+_key, e.dataset[_key]);
|
19
|
+
})
|
20
|
+
cdnDOM.setAttribute("data-cur", nextCur.toString());
|
21
|
+
cdnDOM.setAttribute("onerror", "errorCDN(this)");
|
22
|
+
document.head.appendChild(cdnDOM);
|
23
|
+
e.remove();
|
24
|
+
}
|
25
|
+
<\/script>`;return Object.keys(p.dependencies).forEach(e=>{if(x.includes(e))if(i[e])o+=i[e];else{const l=p.dependencies[e].replace("^","")+"/"+(d[e]?d[e]:`${e}.min.js`),h=`${b}://${s[c]}/${e}${a[c]}${l}`;o+=`<script src="${h}" type="text/javascript" onerror="errorCDN(this)" data-cur="0" data-key="${e}" data-filename="${l}"><\/script>
|
26
|
+
`}}),r=r.replace("</head>",`${o}</head>`),r}catch(c){console.error("获取dependencies出错:",c)}}}}return m});
|
package/index.d.ts
ADDED
package/package.json
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
{
|
2
|
+
"name": "vite-add-cdn-script",
|
3
|
+
"version": "0.0.1",
|
4
|
+
"keywords": [
|
5
|
+
"vite",
|
6
|
+
"cdn",
|
7
|
+
"cdn-script",
|
8
|
+
"auto-add-cdn",
|
9
|
+
"vite-add-cdn-script"
|
10
|
+
],
|
11
|
+
"description": "A plugin for vite to add cdn script to index.html",
|
12
|
+
"repository": {
|
13
|
+
"type": "git",
|
14
|
+
"url": "git+https://github.com/baizeteam/baize-vite-plugin.git"
|
15
|
+
},
|
16
|
+
"homepage": "https://github.com/baizeteam/baize-vite-plugin/tree/master/package/vite-add-cdn-script#readme",
|
17
|
+
"author": "baizeteam",
|
18
|
+
"type": "module",
|
19
|
+
"files": [
|
20
|
+
"dist",
|
21
|
+
"index.d.ts"
|
22
|
+
],
|
23
|
+
"main": "./dist/index.umd.cjs",
|
24
|
+
"module": "./dist/index.js",
|
25
|
+
"types": "./index.d.ts",
|
26
|
+
"exports": {
|
27
|
+
"types": "./index.d.ts",
|
28
|
+
"import": "./dist/index.js",
|
29
|
+
"require": "./dist/index.js"
|
30
|
+
},
|
31
|
+
"scripts": {
|
32
|
+
"dev": "vite",
|
33
|
+
"build": "tsc && vite build"
|
34
|
+
},
|
35
|
+
"devDependencies": {
|
36
|
+
"@types/node": "^20.12.11",
|
37
|
+
"@types/react": "^18.3.2",
|
38
|
+
"@types/react-dom": "^18.3.0",
|
39
|
+
"@vitejs/plugin-react": "^4.2.1",
|
40
|
+
"react": "^18.3.1",
|
41
|
+
"react-dom": "^18.3.1",
|
42
|
+
"rollup-plugin-node-externals": "^7.1.2",
|
43
|
+
"typescript": "^5.4.5",
|
44
|
+
"vite": "^5.2.11"
|
45
|
+
},
|
46
|
+
"publishConfig": {
|
47
|
+
"registry": "https://registry.npmjs.org/"
|
48
|
+
}
|
49
|
+
}
|