vite-add-cdn-script 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/index.js +240 -188
- package/dist/index.umd.cjs +4 -4
- package/package.json +3 -3
package/README.md
CHANGED
@@ -77,13 +77,13 @@ export default defineConfig({
|
|
77
77
|
|
78
78
|
options
|
79
79
|
|
80
|
-
| 参数 | 解析 | 类型 | 默认值
|
81
|
-
| ------------ | ------------------- | --------------------------- |
|
82
|
-
| customScript | 自定义 cdn 脚本 | { [*key*: string]: string } | 无
|
83
|
-
| retryTimes |
|
80
|
+
| 参数 | 解析 | 类型 | 默认值 |
|
81
|
+
| ------------ | ------------------- | --------------------------- | --------------------------------------- |
|
82
|
+
| customScript | 自定义 cdn 脚本 | { [*key*: string]: string } | 无 |
|
83
|
+
| retryTimes | 换源重试次数 | number | defaultCdns.length - 1 |
|
84
84
|
| defaultCdns | 默认使用 cdn 的顺序 | string[] | ["jsdelivr", "unpkg"] |
|
85
85
|
|
86
86
|
## 注意事项
|
87
87
|
|
88
88
|
- 接入了各大 cdn 的 api 接口进行请求,默认会保存一份 cdn 的缓存在你的根目录中`.cdn-cache.json`。如果发现缓存的资源有问题可以删除该文件,然后重新执行打包流程。
|
89
|
-
- 按顺序添加cdn,如react-router-dom需要依赖react、@remix-run/router、react-router,因此需要放在最后。
|
89
|
+
- 按顺序添加 cdn,如 react-router-dom 需要依赖 react、@remix-run/router、react-router,因此需要放在最后。
|
package/dist/index.js
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
var D = Object.defineProperty;
|
2
2
|
var F = (n, t, e) => t in n ? D(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
|
3
|
-
var
|
4
|
-
import
|
5
|
-
import
|
6
|
-
import
|
7
|
-
class
|
3
|
+
var f = (n, t, e) => (F(n, typeof t != "symbol" ? t + "" : t, e), e);
|
4
|
+
import J from "node:path";
|
5
|
+
import j from "node:fs";
|
6
|
+
import E from "node:https";
|
7
|
+
class L {
|
8
8
|
constructor() {
|
9
|
-
|
10
|
-
|
11
|
-
this.cdnCachePath =
|
9
|
+
f(this, "cdnCache", {});
|
10
|
+
f(this, "cdnCachePath", "");
|
11
|
+
this.cdnCachePath = J.resolve(process.cwd(), "./.cdn-cache.json");
|
12
12
|
}
|
13
13
|
// 初始化cdn缓存
|
14
14
|
async init() {
|
15
15
|
try {
|
16
|
-
const t = await
|
16
|
+
const t = await j.readFileSync(this.cdnCachePath, "utf-8");
|
17
17
|
this.cdnCache = JSON.parse(t);
|
18
18
|
} catch {
|
19
|
-
console.log("cdn缓存文件不存在,创建缓存文件"), this.cdnCache = {}, await
|
19
|
+
console.log("cdn缓存文件不存在,创建缓存文件"), this.cdnCache = {}, await j.writeFileSync(this.cdnCachePath, "", "utf-8");
|
20
20
|
}
|
21
21
|
}
|
22
22
|
/**
|
@@ -43,135 +43,171 @@ class E {
|
|
43
43
|
* 更新cdn缓存
|
44
44
|
*/
|
45
45
|
async save() {
|
46
|
-
await
|
46
|
+
await j.writeFileSync(this.cdnCachePath, JSON.stringify(this.cdnCache), "utf-8");
|
47
47
|
}
|
48
48
|
}
|
49
|
-
let
|
50
|
-
const
|
49
|
+
let y;
|
50
|
+
const I = async () => (y || (y = new L(), await y.init()), y);
|
51
|
+
class N {
|
52
|
+
constructor(t) {
|
53
|
+
f(this, "_max");
|
54
|
+
f(this, "_count");
|
55
|
+
f(this, "_taskQueue");
|
56
|
+
this._max = t || 5, this._count = 0, this._taskQueue = [];
|
57
|
+
}
|
58
|
+
/**
|
59
|
+
* 请求封装
|
60
|
+
* @param caller 请求函数
|
61
|
+
* @param args 请求参数
|
62
|
+
* @returns {Promise<any>} 返回一个promise
|
63
|
+
*/
|
64
|
+
call(t, ...e) {
|
65
|
+
return new Promise((r, s) => {
|
66
|
+
const c = this._createTask(t, e, r, s);
|
67
|
+
this._count >= this._max ? this._taskQueue.push(c) : c();
|
68
|
+
});
|
69
|
+
}
|
70
|
+
/**
|
71
|
+
* 创建一个任务
|
72
|
+
* @param caller 实际执行的函数
|
73
|
+
* @param args 执行函数的参数
|
74
|
+
* @param resolve
|
75
|
+
* @param reject
|
76
|
+
* @returns {Function} 返回一个任务函数
|
77
|
+
* @private
|
78
|
+
*/
|
79
|
+
_createTask(t, e, r, s) {
|
80
|
+
return () => {
|
81
|
+
t(...e).then(r).catch(s).finally(() => {
|
82
|
+
this._count--, this._taskQueue.length && this._taskQueue.shift()();
|
83
|
+
}), this._count++;
|
84
|
+
};
|
85
|
+
}
|
86
|
+
}
|
87
|
+
const U = new N(5), R = {
|
51
88
|
//get请求封装
|
52
89
|
get: (n, t, e) => new Promise((r, s) => {
|
53
90
|
try {
|
54
|
-
|
55
|
-
let
|
56
|
-
|
57
|
-
|
58
|
-
}),
|
59
|
-
t == null || t(
|
91
|
+
E.get(n, (c) => {
|
92
|
+
let i = "";
|
93
|
+
c.on("data", (o) => {
|
94
|
+
i += o;
|
95
|
+
}), c.on("end", () => {
|
96
|
+
t == null || t(i), r(i);
|
60
97
|
});
|
98
|
+
}).on("error", function(c) {
|
99
|
+
e == null || e(c), s(c);
|
61
100
|
});
|
62
|
-
} catch (
|
63
|
-
e == null || e(
|
101
|
+
} catch (c) {
|
102
|
+
e == null || e(c), s(c);
|
64
103
|
}
|
65
104
|
})
|
66
|
-
},
|
67
|
-
|
105
|
+
}, w = {
|
106
|
+
get: U.call.bind(U, R.get)
|
107
|
+
}, A = {
|
108
|
+
getFileList: (n, t) => new Promise((e, r) => {
|
109
|
+
w.get(
|
110
|
+
`https://api.bootcdn.cn/libraries/${n}`,
|
111
|
+
(s) => {
|
112
|
+
const c = JSON.parse(s);
|
113
|
+
if (c.length === 0) {
|
114
|
+
r(new Error(`${n} not found in bootcdn`));
|
115
|
+
return;
|
116
|
+
}
|
117
|
+
const i = c[0], a = i.assets.find((d) => d.version === t);
|
118
|
+
if (!a) {
|
119
|
+
r(new Error(`${n}@${t} not found in ${i.name}`));
|
120
|
+
return;
|
121
|
+
}
|
122
|
+
const l = a.files.map((d) => ({
|
123
|
+
name: "/" + d
|
124
|
+
}));
|
125
|
+
e({ fileList: l, recommendFileName: i.filename });
|
126
|
+
},
|
127
|
+
(s) => {
|
128
|
+
r(s);
|
129
|
+
}
|
130
|
+
);
|
131
|
+
}),
|
132
|
+
getUrl: (n, t, e) => `https://cdn.bootcdn.net/ajax/libs/${n}/${t}${e}`
|
133
|
+
}, M = {
|
134
|
+
getFileList: (n, t) => new Promise((e, r) => {
|
135
|
+
w.get(
|
136
|
+
`https://api.cdnjs.com/libraries/${n}/${t}`,
|
137
|
+
(s) => {
|
138
|
+
const c = JSON.parse(s);
|
139
|
+
if (c.error) {
|
140
|
+
r(new Error(`cdnjs: ${n}@${t} not found`));
|
141
|
+
return;
|
142
|
+
}
|
143
|
+
e({
|
144
|
+
fileList: c.rawFiles.map((i) => ({
|
145
|
+
name: "/" + i
|
146
|
+
}))
|
147
|
+
});
|
148
|
+
},
|
149
|
+
(s) => {
|
150
|
+
r(s);
|
151
|
+
}
|
152
|
+
);
|
153
|
+
}),
|
154
|
+
getUrl: (n, t, e) => `https://cdnjs.cloudflare.com/ajax/libs/${n}/${t}${e}`
|
155
|
+
}, V = {
|
156
|
+
getFileList: (n, t) => new Promise((e, r) => {
|
157
|
+
w.get(
|
158
|
+
`https://data.jsdelivr.com/v1/stats/packages/npm/${n}@${t}/files`,
|
159
|
+
(s) => {
|
160
|
+
const c = JSON.parse(s);
|
161
|
+
if (c.length === 0) {
|
162
|
+
r(new Error(`${n}@${t} not found`));
|
163
|
+
return;
|
164
|
+
}
|
165
|
+
e({ fileList: c });
|
166
|
+
},
|
167
|
+
(s) => {
|
168
|
+
r(s);
|
169
|
+
}
|
170
|
+
);
|
171
|
+
}),
|
172
|
+
// 拼接url
|
173
|
+
getUrl: (n, t, e) => `https://cdn.jsdelivr.net/npm/${n}@${t}${e}`
|
174
|
+
}, b = (n) => n.reduce((t, e) => (e.type === "file" ? t.push({ name: e.path }) : e.files && t.push(...b(e.files)), t), []), T = {
|
175
|
+
getFileList: (n, t) => new Promise((e, r) => {
|
176
|
+
w.get(
|
177
|
+
`https://unpkg.com/${n}@${t}/?meta`,
|
178
|
+
(s) => {
|
179
|
+
const c = JSON.parse(s);
|
180
|
+
e({ fileList: b(c.files || []) });
|
181
|
+
},
|
182
|
+
(s) => {
|
183
|
+
r(s);
|
184
|
+
}
|
185
|
+
);
|
186
|
+
}),
|
187
|
+
getUrl: (n, t, e) => `https://unpkg.com/${n}@${t}${e}`
|
188
|
+
}, Q = async (n) => {
|
189
|
+
const t = /^(https?:\/\/.*\d+\.\d+\.\d+\/).+?\.js$/;
|
68
190
|
if (t.test(n)) {
|
69
191
|
const e = n.replace(t, (r, s) => `${s}package.json`);
|
70
|
-
return JSON.parse(await
|
192
|
+
return JSON.parse(await w.get(e));
|
71
193
|
} else
|
72
194
|
throw new Error(`${n} 不是正确的url`);
|
73
|
-
},
|
195
|
+
}, q = (n, t) => {
|
74
196
|
var e, r;
|
75
197
|
return ((e = n.dependencies) == null ? void 0 : e[t]) || ((r = n.devDependencies) == null ? void 0 : r[t]);
|
76
|
-
},
|
77
|
-
|
78
|
-
|
79
|
-
f.get(
|
80
|
-
`https://data.jsdelivr.com/v1/stats/packages/npm/${n}@${t}/files`,
|
81
|
-
(s) => {
|
82
|
-
const i = JSON.parse(s);
|
83
|
-
if (i.length === 0) {
|
84
|
-
r(new Error(`${n}@${t} not found`));
|
85
|
-
return;
|
86
|
-
}
|
87
|
-
e({ fileList: i });
|
88
|
-
},
|
89
|
-
(s) => {
|
90
|
-
r(s);
|
91
|
-
}
|
92
|
-
);
|
93
|
-
}),
|
94
|
-
// 拼接url
|
95
|
-
getUrl: (n, t, e) => `https://cdn.jsdelivr.net/npm/${n}@${t}${e}`
|
96
|
-
},
|
97
|
-
unpkg: {
|
98
|
-
getFileList: (n, t) => new Promise((e, r) => {
|
99
|
-
f.get(
|
100
|
-
`https://unpkg.com/${n}@${t}/?meta`,
|
101
|
-
(s) => {
|
102
|
-
const i = JSON.parse(s);
|
103
|
-
e({ fileList: k(i.files || []) });
|
104
|
-
},
|
105
|
-
(s) => {
|
106
|
-
r(s);
|
107
|
-
}
|
108
|
-
);
|
109
|
-
}),
|
110
|
-
getUrl: (n, t, e) => `https://unpkg.com/${n}@${t}${e}`
|
111
|
-
},
|
112
|
-
bootcdn: {
|
113
|
-
getFileList: (n, t) => new Promise((e, r) => {
|
114
|
-
f.get(
|
115
|
-
`https://api.bootcdn.cn/libraries/${n}`,
|
116
|
-
(s) => {
|
117
|
-
const i = JSON.parse(s);
|
118
|
-
if (i.length === 0) {
|
119
|
-
r(new Error(`${n} not found in bootcdn`));
|
120
|
-
return;
|
121
|
-
}
|
122
|
-
const o = i[0], a = o.assets.find((d) => d.version === t);
|
123
|
-
if (!a) {
|
124
|
-
r(new Error(`${n}@${t} not found in ${o.name}`));
|
125
|
-
return;
|
126
|
-
}
|
127
|
-
const l = a.files.map((d) => ({
|
128
|
-
name: "/" + d
|
129
|
-
}));
|
130
|
-
e({ fileList: l, recommendFileName: o.filename });
|
131
|
-
},
|
132
|
-
(s) => {
|
133
|
-
r(s);
|
134
|
-
}
|
135
|
-
);
|
136
|
-
}),
|
137
|
-
getUrl: (n, t, e) => `https://cdn.bootcdn.net/ajax/libs/${n}/${t}${e}`
|
138
|
-
},
|
139
|
-
cdnjs: {
|
140
|
-
getFileList: (n, t) => new Promise((e, r) => {
|
141
|
-
f.get(
|
142
|
-
`https://api.cdnjs.com/libraries/${n}/${t}`,
|
143
|
-
(s) => {
|
144
|
-
const i = JSON.parse(s);
|
145
|
-
if (i.error) {
|
146
|
-
r(new Error(`cdnjs: ${n}@${t} not found`));
|
147
|
-
return;
|
148
|
-
}
|
149
|
-
e({
|
150
|
-
fileList: i.rawFiles.map((o) => ({
|
151
|
-
name: "/" + o
|
152
|
-
}))
|
153
|
-
});
|
154
|
-
},
|
155
|
-
(s) => {
|
156
|
-
r(s);
|
157
|
-
}
|
158
|
-
);
|
159
|
-
}),
|
160
|
-
getUrl: (n, t, e) => `https://cdnjs.cloudflare.com/ajax/libs/${n}/${t}${e}`
|
161
|
-
}
|
162
|
-
}, R = async (n, t, e) => {
|
163
|
-
var o;
|
164
|
-
const r = (o = t.match(/\d+(.\d+)?(.\d+)?/)) == null ? void 0 : o[0];
|
198
|
+
}, H = async (n, t, e) => {
|
199
|
+
var i;
|
200
|
+
const r = (i = t.match(/\d+(.\d+)?(.\d+)?/)) == null ? void 0 : i[0];
|
165
201
|
if (!r)
|
166
202
|
throw new Error(`${n} version ${t} is not valid`);
|
167
|
-
const s = await
|
168
|
-
throw
|
169
|
-
}),
|
170
|
-
if (!
|
203
|
+
const s = await v[e].getFileList(n, r).catch((o) => {
|
204
|
+
throw console.log(o), new Error(`${n} ${t} ${e} API 请求失败`);
|
205
|
+
}), c = B(s, n);
|
206
|
+
if (!c)
|
171
207
|
throw new Error(`在 ${e} 中找不到 ${n}@${r} 文件,请检查包名或版本号`);
|
172
|
-
return
|
173
|
-
},
|
174
|
-
var
|
208
|
+
return v[e].getUrl(n, r, c);
|
209
|
+
}, B = ({ fileList: n }, t) => {
|
210
|
+
var c, i;
|
175
211
|
let e = [
|
176
212
|
`umd/${t}.production.min.js`,
|
177
213
|
/umd\/.+?\.production\.min\.js$/,
|
@@ -189,130 +225,146 @@ const L = async () => ($ || ($ = new E(), await $.init()), $), f = {
|
|
189
225
|
/\.min\.js$/,
|
190
226
|
/\.js$/
|
191
227
|
];
|
192
|
-
const r = ["runtime", "compiler", ".esm", ".cjs", "development"].filter((
|
228
|
+
const r = ["runtime", "compiler", ".esm", ".cjs", "development"].filter((o) => !t.includes(o));
|
193
229
|
let s = "";
|
194
|
-
for (let
|
195
|
-
if (
|
230
|
+
for (let o of e)
|
231
|
+
if (o instanceof RegExp ? s = ((c = n.find((a) => o.test(a.name) && !r.some((l) => a.name.includes(l)))) == null ? void 0 : c.name) || "" : s = ((i = n.find((a) => a.name.includes(o) && !r.some((l) => a.name.includes(l)))) == null ? void 0 : i.name) || "", s)
|
196
232
|
break;
|
197
233
|
return s;
|
234
|
+
}, v = {
|
235
|
+
jsdelivr: V,
|
236
|
+
bootcdn: A,
|
237
|
+
cdnjs: M,
|
238
|
+
unpkg: T
|
198
239
|
};
|
199
|
-
function
|
240
|
+
function G(n, t) {
|
200
241
|
const e = n.replace(/^\D/, "").split("."), r = t.replace(/^\D/, "").split("."), s = Math.max(e.length, r.length);
|
201
242
|
for (; e.length < s; )
|
202
243
|
e.push("0");
|
203
244
|
for (; r.length < s; )
|
204
245
|
r.push("0");
|
205
|
-
for (let
|
206
|
-
const
|
207
|
-
if (
|
246
|
+
for (let c = 0; c < s; c++) {
|
247
|
+
const i = parseInt(e[c], 10), o = parseInt(r[c], 10);
|
248
|
+
if (i > o)
|
208
249
|
return 1;
|
209
|
-
if (
|
250
|
+
if (i < o)
|
210
251
|
return -1;
|
211
252
|
}
|
212
253
|
return 0;
|
213
254
|
}
|
214
|
-
function
|
255
|
+
function z(n, t) {
|
215
256
|
for (let e in t)
|
216
|
-
Object.prototype.hasOwnProperty.call(t, e) && (n[e] ?
|
257
|
+
Object.prototype.hasOwnProperty.call(t, e) && (n[e] ? G(n[e], t[e]) === -1 && (n[e] = t[e]) : n[e] = t[e]);
|
217
258
|
return n;
|
218
259
|
}
|
219
|
-
async function
|
220
|
-
let s = [],
|
221
|
-
const
|
260
|
+
async function O({ external: n, packageData: t, customScript: e, defaultCdns: r }) {
|
261
|
+
let s = [], c = !1;
|
262
|
+
const i = await I();
|
222
263
|
return await Promise.all(
|
223
|
-
n.map(async (
|
224
|
-
const a =
|
225
|
-
if (e[
|
264
|
+
n.map(async (o) => {
|
265
|
+
const a = q(t, o);
|
266
|
+
if (e[o])
|
226
267
|
return {
|
227
268
|
urls: [],
|
228
|
-
key:
|
269
|
+
key: o
|
270
|
+
};
|
271
|
+
const l = i.getCdnCache(o, a);
|
272
|
+
if (!a && !l)
|
273
|
+
return s.push(o), {
|
274
|
+
urls: [],
|
275
|
+
key: o
|
229
276
|
};
|
230
|
-
if (!a) {
|
231
|
-
s.push(c);
|
232
|
-
return;
|
233
|
-
}
|
234
|
-
const l = o.getCdnCache(c, a);
|
235
277
|
if (l)
|
236
278
|
return {
|
237
279
|
urls: l,
|
238
|
-
key:
|
280
|
+
key: o
|
239
281
|
};
|
240
282
|
{
|
241
|
-
|
283
|
+
c = !0, console.log(`从网络获取${o}${a}的cdn地址`);
|
242
284
|
const d = {
|
243
285
|
urls: await Promise.all(
|
244
|
-
r.map(async (
|
286
|
+
r.map(async (C) => await H(o, a, C))
|
245
287
|
),
|
246
|
-
key:
|
288
|
+
key: o
|
247
289
|
};
|
248
|
-
return
|
290
|
+
return i.setCdnCache(o, a, d.urls), d;
|
249
291
|
}
|
250
292
|
})
|
251
|
-
).then((
|
252
|
-
urls:
|
293
|
+
).then((o) => (c && i.save(), {
|
294
|
+
urls: o,
|
253
295
|
noVersionPackages: s
|
254
296
|
}));
|
255
297
|
}
|
256
|
-
function
|
257
|
-
const { customScript: t = {}, retryTimes: e
|
258
|
-
let s;
|
298
|
+
function tt(n) {
|
299
|
+
const { customScript: t = {}, retryTimes: e, defaultCdns: r = ["jsdelivr", "unpkg", "cdnjs"] } = n;
|
300
|
+
let s = e;
|
301
|
+
s || (s = r.length - 1);
|
302
|
+
let c;
|
259
303
|
return {
|
260
304
|
name: "vite-add-cdn-script",
|
261
305
|
enforce: "pre",
|
262
306
|
apply: "build",
|
263
307
|
config(i) {
|
264
|
-
|
308
|
+
c = i;
|
265
309
|
},
|
266
310
|
async transformIndexHtml(i) {
|
267
311
|
if (!r || r.length === 0)
|
268
312
|
throw new Error("defaultCdns不能为空");
|
269
|
-
const o =
|
313
|
+
const o = J.resolve(process.cwd(), "package.json");
|
270
314
|
try {
|
271
|
-
const
|
272
|
-
let
|
273
|
-
const { urls:
|
274
|
-
external:
|
275
|
-
packageData:
|
315
|
+
const a = j.readFileSync(o, "utf-8"), l = JSON.parse(a), d = c.build.rollupOptions.external, C = {};
|
316
|
+
let p = "";
|
317
|
+
const { urls: k, noVersionPackages: S } = await O({
|
318
|
+
external: d,
|
319
|
+
packageData: l,
|
276
320
|
customScript: t,
|
277
321
|
defaultCdns: r
|
278
322
|
});
|
279
|
-
if (
|
280
|
-
const
|
323
|
+
if (S.length > 0) {
|
324
|
+
const m = { dependencies: {} };
|
281
325
|
await Promise.all(
|
282
|
-
|
283
|
-
if (!
|
326
|
+
k.map(async (u) => {
|
327
|
+
if (!u)
|
284
328
|
return;
|
285
|
-
const { key:
|
286
|
-
if (!
|
329
|
+
const { key: x, urls: _ } = u, g = t[x] || _[0];
|
330
|
+
if (!g)
|
287
331
|
return;
|
288
|
-
const
|
289
|
-
|
332
|
+
const $ = await Q(g);
|
333
|
+
z(m.dependencies, $.dependencies);
|
290
334
|
})
|
291
|
-
)
|
292
|
-
|
293
|
-
|
294
|
-
|
335
|
+
).catch((u) => {
|
336
|
+
console.log("err", u);
|
337
|
+
});
|
338
|
+
const { urls: P, noVersionPackages: h } = await O({
|
339
|
+
external: S,
|
340
|
+
packageData: m,
|
295
341
|
customScript: t,
|
296
342
|
defaultCdns: r
|
297
343
|
});
|
298
|
-
if (
|
299
|
-
|
344
|
+
if (P.map((u) => {
|
345
|
+
var g;
|
346
|
+
if (!u)
|
347
|
+
return;
|
348
|
+
const { urls: x, key: _ } = u;
|
349
|
+
(g = k.find(($) => ($ == null ? void 0 : $.key) === _)) == null || g.urls.push(...x);
|
350
|
+
}), h.length > 0)
|
351
|
+
throw console.error(`找不到${h.join(",")}的版本`), new Error(`找不到${h.join(",")}的版本`);
|
300
352
|
}
|
301
|
-
return
|
302
|
-
if (!
|
353
|
+
return k.forEach((m) => {
|
354
|
+
if (!m)
|
303
355
|
return;
|
304
|
-
const { urls:
|
305
|
-
if (t[
|
306
|
-
|
356
|
+
const { urls: P, key: h } = m;
|
357
|
+
if (t[h])
|
358
|
+
p += t[h];
|
307
359
|
else {
|
308
|
-
|
309
|
-
const
|
310
|
-
|
360
|
+
C[h] = P;
|
361
|
+
const u = P[0];
|
362
|
+
p += `<script src="${u}" type="text/javascript" crossorigin="anonymous" onerror="errorCDN(this)" data-cur="0" data-key="${h}"><\/script>
|
311
363
|
`;
|
312
364
|
}
|
313
|
-
}),
|
365
|
+
}), p = `<script>
|
314
366
|
function errorCDN(e) {
|
315
|
-
const packNameUrl = JSON.parse('${JSON.stringify(
|
367
|
+
const packNameUrl = JSON.parse('${JSON.stringify(C)}');
|
316
368
|
const nextCur = parseInt(e.getAttribute("data-cur")) + 1;
|
317
369
|
if(nextCur>${e}){return;}
|
318
370
|
|
@@ -332,13 +384,13 @@ function q(n) {
|
|
332
384
|
document.head.appendChild(cdnDOM);
|
333
385
|
e.remove();
|
334
386
|
}
|
335
|
-
<\/script>` +
|
336
|
-
} catch (
|
337
|
-
console.error("获取dependencies出错:",
|
387
|
+
<\/script>` + p, i = i.replace("</head>", `${p}</head>`), i;
|
388
|
+
} catch (a) {
|
389
|
+
console.error("获取dependencies出错:", a);
|
338
390
|
}
|
339
391
|
}
|
340
392
|
};
|
341
393
|
}
|
342
394
|
export {
|
343
|
-
|
395
|
+
tt as default
|
344
396
|
};
|
package/dist/index.umd.cjs
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
(function(d,
|
2
|
-
`}}),
|
1
|
+
(function(d,u){typeof exports=="object"&&typeof module<"u"?module.exports=u(require("node:path"),require("node:fs"),require("node:https")):typeof define=="function"&&define.amd?define(["node:path","node:fs","node:https"],u):(d=typeof globalThis<"u"?globalThis:d||self,d.index=u(d.path,d.fs,d.https))})(this,function(d,u,m){"use strict";var z=Object.defineProperty;var K=(d,u,m)=>u in d?z(d,u,{enumerable:!0,configurable:!0,writable:!0,value:m}):d[u]=m;var $=(d,u,m)=>(K(d,typeof u!="symbol"?u+"":u,m),m);class E{constructor(){$(this,"cdnCache",{});$(this,"cdnCachePath","");this.cdnCachePath=d.resolve(process.cwd(),"./.cdn-cache.json")}async init(){try{const e=await u.readFileSync(this.cdnCachePath,"utf-8");this.cdnCache=JSON.parse(e)}catch{console.log("cdn缓存文件不存在,创建缓存文件"),this.cdnCache={},await u.writeFileSync(this.cdnCachePath,"","utf-8")}}getCdnCache(e,t){var r;return(r=this.cdnCache[e])==null?void 0:r[t]}setCdnCache(e,t,r){this.cdnCache[e]?this.cdnCache[e][t]=r:this.cdnCache[e]={[t]:r}}async save(){await u.writeFileSync(this.cdnCachePath,JSON.stringify(this.cdnCache),"utf-8")}}let j;const L=async()=>(j||(j=new E,await j.init()),j);class b{constructor(e){$(this,"_max");$(this,"_count");$(this,"_taskQueue");this._max=e||5,this._count=0,this._taskQueue=[]}call(e,...t){return new Promise((r,s)=>{const c=this._createTask(e,t,r,s);this._count>=this._max?this._taskQueue.push(c):c()})}_createTask(e,t,r,s){return()=>{e(...t).then(r).catch(s).finally(()=>{this._count--,this._taskQueue.length&&this._taskQueue.shift()()}),this._count++}}}const v=new b(5),I={get:(n,e,t)=>new Promise((r,s)=>{try{m.get(n,c=>{let i="";c.on("data",o=>{i+=o}),c.on("end",()=>{e==null||e(i),r(i)})}).on("error",function(c){t==null||t(c),s(c)})}catch(c){t==null||t(c),s(c)}})},w={get:v.call.bind(v,I.get)},N={getFileList:(n,e)=>new Promise((t,r)=>{w.get(`https://api.bootcdn.cn/libraries/${n}`,s=>{const c=JSON.parse(s);if(c.length===0){r(new Error(`${n} not found in bootcdn`));return}const i=c[0],a=i.assets.find(p=>p.version===e);if(!a){r(new Error(`${n}@${e} not found in ${i.name}`));return}const l=a.files.map(p=>({name:"/"+p}));t({fileList:l,recommendFileName:i.filename})},s=>{r(s)})}),getUrl:(n,e,t)=>`https://cdn.bootcdn.net/ajax/libs/${n}/${e}${t}`},R={getFileList:(n,e)=>new Promise((t,r)=>{w.get(`https://api.cdnjs.com/libraries/${n}/${e}`,s=>{const c=JSON.parse(s);if(c.error){r(new Error(`cdnjs: ${n}@${e} not found`));return}t({fileList:c.rawFiles.map(i=>({name:"/"+i}))})},s=>{r(s)})}),getUrl:(n,e,t)=>`https://cdnjs.cloudflare.com/ajax/libs/${n}/${e}${t}`},A={getFileList:(n,e)=>new Promise((t,r)=>{w.get(`https://data.jsdelivr.com/v1/stats/packages/npm/${n}@${e}/files`,s=>{const c=JSON.parse(s);if(c.length===0){r(new Error(`${n}@${e} not found`));return}t({fileList:c})},s=>{r(s)})}),getUrl:(n,e,t)=>`https://cdn.jsdelivr.net/npm/${n}@${e}${t}`},O=n=>n.reduce((e,t)=>(t.type==="file"?e.push({name:t.path}):t.files&&e.push(...O(t.files)),e),[]),T={getFileList:(n,e)=>new Promise((t,r)=>{w.get(`https://unpkg.com/${n}@${e}/?meta`,s=>{const c=JSON.parse(s);t({fileList:O(c.files||[])})},s=>{r(s)})}),getUrl:(n,e,t)=>`https://unpkg.com/${n}@${e}${t}`},M=async n=>{const e=/^(https?:\/\/.*\d+\.\d+\.\d+\/).+?\.js$/;if(e.test(n)){const t=n.replace(e,(r,s)=>`${s}package.json`);return JSON.parse(await w.get(t))}else throw new Error(`${n} 不是正确的url`)},V=(n,e)=>{var t,r;return((t=n.dependencies)==null?void 0:t[e])||((r=n.devDependencies)==null?void 0:r[e])},q=async(n,e,t)=>{var i;const r=(i=e.match(/\d+(.\d+)?(.\d+)?/))==null?void 0:i[0];if(!r)throw new Error(`${n} version ${e} is not valid`);const s=await J[t].getFileList(n,r).catch(o=>{throw console.log(o),new Error(`${n} ${e} ${t} API 请求失败`)}),c=Q(s,n);if(!c)throw new Error(`在 ${t} 中找不到 ${n}@${r} 文件,请检查包名或版本号`);return J[t].getUrl(n,r,c)},Q=({fileList:n},e)=>{var c,i;let t=[`umd/${e}.production.min.js`,/umd\/.+?\.production\.min\.js$/,/dist\/.+?\.production\.min\.js$/,/dist\/.+?\.umd\.min\.js$/,`dist/${e}.prod.min.js`,/dist\/.+?\.global.prod.min.js/,`dist/${e}.min.js`,/.+?\.global.prod.min.js/,/.+?.global.prod.js/,/lib\/.+?\.min\.js$/,/dist\/.+?\.min\.js$/,/index\.min\.js$/,/index\.js$/,/\.min\.js$/,/\.js$/];const r=["runtime","compiler",".esm",".cjs","development"].filter(o=>!e.includes(o));let s="";for(let o of t)if(o instanceof RegExp?s=((c=n.find(a=>o.test(a.name)&&!r.some(l=>a.name.includes(l))))==null?void 0:c.name)||"":s=((i=n.find(a=>a.name.includes(o)&&!r.some(l=>a.name.includes(l))))==null?void 0:i.name)||"",s)break;return s},J={jsdelivr:A,bootcdn:N,cdnjs:R,unpkg:T};function H(n,e){const t=n.replace(/^\D/,"").split("."),r=e.replace(/^\D/,"").split("."),s=Math.max(t.length,r.length);for(;t.length<s;)t.push("0");for(;r.length<s;)r.push("0");for(let c=0;c<s;c++){const i=parseInt(t[c],10),o=parseInt(r[c],10);if(i>o)return 1;if(i<o)return-1}return 0}function B(n,e){for(let t in e)Object.prototype.hasOwnProperty.call(e,t)&&(n[t]?H(n[t],e[t])===-1&&(n[t]=e[t]):n[t]=e[t]);return n}async function D({external:n,packageData:e,customScript:t,defaultCdns:r}){let s=[],c=!1;const i=await L();return await Promise.all(n.map(async o=>{const a=V(e,o);if(t[o])return{urls:[],key:o};const l=i.getCdnCache(o,a);if(!a&&!l)return s.push(o),{urls:[],key:o};if(l)return{urls:l,key:o};{c=!0,console.log(`从网络获取${o}${a}的cdn地址`);const p={urls:await Promise.all(r.map(async k=>await q(o,a,k))),key:o};return i.setCdnCache(o,a,p.urls),p}})).then(o=>(c&&i.save(),{urls:o,noVersionPackages:s}))}function G(n){const{customScript:e={},retryTimes:t,defaultCdns:r=["jsdelivr","unpkg","cdnjs"]}=n;let s=t;s||(s=r.length-1);let c;return{name:"vite-add-cdn-script",enforce:"pre",apply:"build",config(i){c=i},async transformIndexHtml(i){if(!r||r.length===0)throw new Error("defaultCdns不能为空");const o=d.resolve(process.cwd(),"package.json");try{const a=u.readFileSync(o,"utf-8"),l=JSON.parse(a),p=c.build.rollupOptions.external,k={};let g="";const{urls:_,noVersionPackages:F}=await D({external:p,packageData:l,customScript:e,defaultCdns:r});if(F.length>0){const C={dependencies:{}};await Promise.all(_.map(async h=>{if(!h)return;const{key:S,urls:U}=h,P=e[S]||U[0];if(!P)return;const y=await M(P);B(C.dependencies,y.dependencies)})).catch(h=>{console.log("err",h)});const{urls:x,noVersionPackages:f}=await D({external:F,packageData:C,customScript:e,defaultCdns:r});if(x.map(h=>{var P;if(!h)return;const{urls:S,key:U}=h;(P=_.find(y=>(y==null?void 0:y.key)===U))==null||P.urls.push(...S)}),f.length>0)throw console.error(`找不到${f.join(",")}的版本`),new Error(`找不到${f.join(",")}的版本`)}return _.forEach(C=>{if(!C)return;const{urls:x,key:f}=C;if(e[f])g+=e[f];else{k[f]=x;const h=x[0];g+=`<script src="${h}" type="text/javascript" crossorigin="anonymous" onerror="errorCDN(this)" data-cur="0" data-key="${f}"><\/script>
|
2
|
+
`}}),g=`<script>
|
3
3
|
function errorCDN(e) {
|
4
|
-
const packNameUrl = JSON.parse('${JSON.stringify(
|
4
|
+
const packNameUrl = JSON.parse('${JSON.stringify(k)}');
|
5
5
|
const nextCur = parseInt(e.getAttribute("data-cur")) + 1;
|
6
6
|
if(nextCur>${t}){return;}
|
7
7
|
|
@@ -21,4 +21,4 @@
|
|
21
21
|
document.head.appendChild(cdnDOM);
|
22
22
|
e.remove();
|
23
23
|
}
|
24
|
-
<\/script>`+
|
24
|
+
<\/script>`+g,i=i.replace("</head>",`${g}</head>`),i}catch(a){console.error("获取dependencies出错:",a)}}}}return G});
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "vite-add-cdn-script",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.9",
|
4
4
|
"keywords": [
|
5
5
|
"vite",
|
6
6
|
"cdn",
|
@@ -42,8 +42,8 @@
|
|
42
42
|
"@vitejs/plugin-react": "^4.2.1",
|
43
43
|
"cross-env": "^7.0.3",
|
44
44
|
"jest": "^29.7.0",
|
45
|
-
"react": "^18.
|
46
|
-
"react-dom": "^18.
|
45
|
+
"react": "^18.2.0",
|
46
|
+
"react-dom": "^18.2.0",
|
47
47
|
"react-router-dom": "^6.23.1",
|
48
48
|
"rollup-plugin-external-globals": "^0.10.0",
|
49
49
|
"rollup-plugin-node-externals": "^7.1.2",
|