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 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
@@ -0,0 +1,7 @@
1
+ interface IOptions {
2
+ protocol?: string;
3
+ customScript?: { [key: string]: string };
4
+ retryTimes?: number;
5
+ defaultCdns?: string[];
6
+ }
7
+ export default function viteAddCdnScript(options: IOptions);
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
+ }