vite-add-cdn-script 0.0.8 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
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 | 重试次数 | number | 3 |
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,23 @@
1
- var D = Object.defineProperty;
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 S = (n, t, e) => (F(n, typeof t != "symbol" ? t + "" : t, e), e);
1
+ var G = Object.defineProperty;
2
+ var B = (r, t, e) => t in r ? G(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
+ var m = (r, t, e) => (B(r, typeof t != "symbol" ? t + "" : t, e), e);
4
4
  import O from "node:path";
5
- import y from "node:fs";
6
- import b from "node:https";
7
- class E {
5
+ import U from "node:fs";
6
+ import V from "node-fetch";
7
+ import J from "semver";
8
+ class z {
8
9
  constructor() {
9
- S(this, "cdnCache", {});
10
- S(this, "cdnCachePath", "");
10
+ m(this, "cdnCache", {});
11
+ m(this, "cdnCachePath", "");
11
12
  this.cdnCachePath = O.resolve(process.cwd(), "./.cdn-cache.json");
12
13
  }
13
14
  // 初始化cdn缓存
14
15
  async init() {
15
16
  try {
16
- const t = await y.readFileSync(this.cdnCachePath, "utf-8");
17
+ const t = await U.readFileSync(this.cdnCachePath, "utf-8");
17
18
  this.cdnCache = JSON.parse(t);
18
19
  } catch {
19
- console.log("cdn缓存文件不存在,创建缓存文件"), this.cdnCache = {}, await y.writeFileSync(this.cdnCachePath, "", "utf-8");
20
+ console.log("cdn缓存文件不存在,创建缓存文件"), this.cdnCache = {}, await U.writeFileSync(this.cdnCachePath, "", "utf-8");
20
21
  }
21
22
  }
22
23
  /**
@@ -25,8 +26,8 @@ class E {
25
26
  * @param version 版本
26
27
  */
27
28
  getCdnCache(t, e) {
28
- var r;
29
- return (r = this.cdnCache[t]) == null ? void 0 : r[e];
29
+ var s;
30
+ return (s = this.cdnCache[t]) == null ? void 0 : s[e];
30
31
  }
31
32
  /**
32
33
  * 设置cdn缓存
@@ -34,144 +35,279 @@ class E {
34
35
  * @param version 版本
35
36
  * @param urls 地址列表
36
37
  */
37
- setCdnCache(t, e, r) {
38
- this.cdnCache[t] ? this.cdnCache[t][e] = r : this.cdnCache[t] = {
39
- [e]: r
38
+ setCdnCache(t, e, s) {
39
+ this.cdnCache[t] ? this.cdnCache[t][e] = s : this.cdnCache[t] = {
40
+ [e]: s
40
41
  };
41
42
  }
42
43
  /**
43
44
  * 更新cdn缓存
44
45
  */
45
46
  async save() {
46
- await y.writeFileSync(this.cdnCachePath, JSON.stringify(this.cdnCache), "utf-8");
47
+ await U.writeFileSync(this.cdnCachePath, JSON.stringify(this.cdnCache), "utf-8");
47
48
  }
48
49
  }
49
- let C;
50
- const L = async () => (C || (C = new E(), await C.init()), C), $ = {
50
+ let b;
51
+ const K = async () => (b || (b = new z(), await b.init()), b);
52
+ class u extends Error {
53
+ constructor(t) {
54
+ super(t), this.name = "NetworkError";
55
+ }
56
+ }
57
+ class C extends u {
58
+ constructor({ packageName: t, version: e, cdn: s }) {
59
+ super(`${s} ${t}@${e} 网络请求失败`), this.name = "PackageNetworkError";
60
+ }
61
+ }
62
+ class $ extends Error {
63
+ constructor({ packageName: t, version: e, cdn: s }) {
64
+ super(`${s}上没有${t}@${e}的版本`), this.name = "NoVersionError";
65
+ }
66
+ }
67
+ class W extends Error {
68
+ constructor({ packageName: t, version: e, cdn: s }) {
69
+ super(`在 ${s} 中找不到 ${t}@${e} 文件,请检查包名或版本号`), this.name = "GetFileListError";
70
+ }
71
+ }
72
+ class X {
73
+ constructor(t) {
74
+ m(this, "_max");
75
+ m(this, "_count");
76
+ m(this, "_taskQueue");
77
+ this._max = t || 5, this._count = 0, this._taskQueue = [];
78
+ }
79
+ /**
80
+ * 请求封装
81
+ * @param caller 请求函数
82
+ * @param args 请求参数
83
+ * @returns {Promise<any>} 返回一个promise
84
+ */
85
+ call(t, ...e) {
86
+ return new Promise((s, n) => {
87
+ const o = this._createTask(t, e, s, n);
88
+ this._count >= this._max ? this._taskQueue.push(o) : o();
89
+ });
90
+ }
91
+ /**
92
+ * 创建一个任务
93
+ * @param caller 实际执行的函数
94
+ * @param args 执行函数的参数
95
+ * @param resolve
96
+ * @param reject
97
+ * @returns {Function} 返回一个任务函数
98
+ * @private
99
+ */
100
+ _createTask(t, e, s, n) {
101
+ return () => {
102
+ t(...e).then(s).catch(n).finally(() => {
103
+ this._count--, this._taskQueue.length && this._taskQueue.shift()();
104
+ }), this._count++;
105
+ };
106
+ }
107
+ }
108
+ const D = new X(5), M = async (r) => {
109
+ try {
110
+ const t = await V(r, { method: "HEAD", redirect: "manual" });
111
+ return t.status >= 300 && t.status < 400 ? await M(t.headers.get("location") || "") : r;
112
+ } catch (t) {
113
+ throw Promise.reject(new u(t.message));
114
+ }
115
+ }, Y = {
51
116
  //get请求封装
52
- get: (n, t, e) => new Promise((r, s) => {
117
+ get: async (r) => {
53
118
  try {
54
- b.get(n, (c) => {
55
- let o = "";
56
- c.on("data", (i) => {
57
- o += i;
58
- }), c.on("end", () => {
59
- t == null || t(o), r(o);
60
- });
119
+ const t = await V(r);
120
+ if (t.ok) {
121
+ const e = t.headers.get("content-type"), s = await t.text();
122
+ return e && e.includes("application/json") ? JSON.parse(s) : s;
123
+ } else
124
+ throw new u(`请求失败,状态码:${t.status}`);
125
+ } catch (t) {
126
+ throw new u(t.message);
127
+ }
128
+ }
129
+ }, y = {
130
+ get: D.call.bind(D, Y.get)
131
+ }, Z = async (r, t) => {
132
+ try {
133
+ const e = await y.get(`https://api.bootcdn.cn/libraries/${r}`);
134
+ if (e.length === 0)
135
+ throw new $({
136
+ packageName: r,
137
+ version: t,
138
+ cdn: "bootcdn"
139
+ });
140
+ const s = e[0], o = s.assets.reverse().find((c) => {
141
+ if (J.satisfies(c.version, t))
142
+ return !0;
143
+ });
144
+ if (!o)
145
+ throw new $({
146
+ packageName: r,
147
+ version: t,
148
+ cdn: "bootcdn"
149
+ });
150
+ return { fileList: o.files.map((c) => ({
151
+ name: "/" + c
152
+ })), recommendFileName: s.filename, version: o.version };
153
+ } catch (e) {
154
+ throw e instanceof u ? new C({
155
+ packageName: r,
156
+ version: t,
157
+ cdn: "unpkg"
158
+ }) : e;
159
+ }
160
+ }, N = (r, t, e) => `https://cdn.bootcdn.net/ajax/libs/${r}/${t}${e}`, tt = {
161
+ getFileList: Z,
162
+ getUrl: N
163
+ };
164
+ async function I(r, t, e = !1) {
165
+ try {
166
+ if (!e && t.match(/^\D/)) {
167
+ const n = await rt(r, t);
168
+ for (let o of n)
169
+ if (J.satisfies(o, t))
170
+ return I(r, o, !0);
171
+ throw new $({
172
+ packageName: r,
173
+ version: t,
174
+ cdn: "cdnjs"
61
175
  });
62
- } catch (c) {
63
- e == null || e(c), s(c);
64
176
  }
65
- })
66
- }, N = async (n) => {
67
- const t = /^(https:\/\/.*\d+\.\d+\.\d+\/).+?\.js$/;
68
- if (t.test(n)) {
69
- const e = n.replace(t, (r, s) => `${s}package.json`);
70
- return JSON.parse(await $.get(e));
71
- } else
72
- throw new Error(`${n} 不是正确的url`);
73
- }, I = (n, t) => {
74
- var e, r;
75
- return ((e = n.dependencies) == null ? void 0 : e[t]) || ((r = n.devDependencies) == null ? void 0 : r[t]);
76
- }, J = (n) => n.reduce((t, e) => (e.type === "file" ? t.push({ name: e.path }) : e.files && t.push(...J(e.files)), t), []), k = {
77
- jsdelivr: {
78
- getFileList: (n, t) => new Promise((e, r) => {
79
- $.get(
80
- `https://data.jsdelivr.com/v1/stats/packages/npm/${n}@${t}/files`,
81
- (s) => {
82
- const c = JSON.parse(s);
83
- if (c.length === 0) {
84
- r(new Error(`${n}@${t} not found`));
85
- return;
86
- }
87
- e({ fileList: c });
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
- $.get(
100
- `https://unpkg.com/${n}@${t}/?meta`,
101
- (s) => {
102
- const c = JSON.parse(s);
103
- e({ fileList: J(c.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
- $.get(
115
- `https://api.bootcdn.cn/libraries/${n}`,
116
- (s) => {
117
- const c = JSON.parse(s);
118
- if (c.length === 0) {
119
- r(new Error(`${n} not found in bootcdn`));
120
- return;
121
- }
122
- const o = c[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
- $.get(
142
- `https://api.cdnjs.com/libraries/${n}/${t}`,
143
- (s) => {
144
- const c = JSON.parse(s);
145
- if (c.error) {
146
- r(new Error(`cdnjs: ${n}@${t} not found`));
147
- return;
148
- }
149
- e({
150
- fileList: c.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}`
177
+ const s = await y.get(`https://api.cdnjs.com/libraries/${r}/${t}`);
178
+ if (s.error)
179
+ throw new $({
180
+ packageName: r,
181
+ version: t,
182
+ cdn: "cdnjs"
183
+ });
184
+ return {
185
+ fileList: s.rawFiles.map((n) => ({
186
+ name: "/" + n
187
+ })),
188
+ version: t
189
+ };
190
+ } catch (s) {
191
+ throw s instanceof u ? new C({
192
+ packageName: r,
193
+ version: t,
194
+ cdn: "unpkg"
195
+ }) : s;
196
+ }
197
+ }
198
+ const et = (r, t, e) => `https://cdnjs.cloudflare.com/ajax/libs/${r}/${t}${e}`, rt = async (r, t) => {
199
+ try {
200
+ return (await y.get(`https://api.cdnjs.com/libraries/${r}?fields=versions`)).versions;
201
+ } catch (e) {
202
+ throw e instanceof u ? new C({
203
+ packageName: r,
204
+ version: t,
205
+ cdn: "unpkg"
206
+ }) : e;
207
+ }
208
+ }, st = {
209
+ getFileList: I,
210
+ getUrl: et
211
+ }, T = (r, t = "") => r.reduce((e, s) => (s.type === "file" ? e.push({ name: `${t}/${s.name}` }) : s.files && e.push(...T(s.files, `${t}/${s.name}`)), e), []);
212
+ async function Q(r, t, e = !1) {
213
+ try {
214
+ if (!e && t.match(/^\D/)) {
215
+ const n = await ot(r, t);
216
+ if (typeof n == "string")
217
+ return Q(r, n, !0);
218
+ throw new $({
219
+ packageName: r,
220
+ version: t,
221
+ cdn: "jsdelivr"
222
+ });
223
+ }
224
+ const s = await y.get(`https://data.jsdelivr.com/v1/packages/npm/${r}@${t}`);
225
+ if (s.status)
226
+ throw new $({
227
+ packageName: r,
228
+ version: t,
229
+ cdn: "jsdelivr"
230
+ });
231
+ return { fileList: T(s.files), version: t };
232
+ } catch (s) {
233
+ throw s instanceof u ? new C({
234
+ packageName: r,
235
+ version: t,
236
+ cdn: "unpkg"
237
+ }) : s;
238
+ }
239
+ }
240
+ const nt = (r, t, e) => `https://cdn.jsdelivr.net/npm/${r}@${t}${e}`, ot = async (r, t) => {
241
+ try {
242
+ return (await y.get(
243
+ `https://data.jsdelivr.com/v1/packages/npm/${r}/resolved?specifier=${t}`
244
+ )).version;
245
+ } catch (e) {
246
+ throw e instanceof u ? new C({
247
+ packageName: r,
248
+ version: t,
249
+ cdn: "unpkg"
250
+ }) : e;
251
+ }
252
+ }, ct = {
253
+ getFileList: Q,
254
+ // 拼接url
255
+ getUrl: nt
256
+ }, H = (r) => r.reduce((t, e) => (e.type === "file" ? t.push({ name: e.path }) : e.files && t.push(...H(e.files)), t), []);
257
+ async function it(r, t) {
258
+ var e;
259
+ try {
260
+ const n = (e = (await M(`https://unpkg.com/${r}@${t}/?meta`)).match(new RegExp("(?<=@)\\d+\\.\\d+\\.\\d+(?=\\/\\?meta)"))) == null ? void 0 : e[0];
261
+ if (n) {
262
+ const o = await y.get(`https://unpkg.com/${r}@${n}/?meta`);
263
+ return { fileList: H(o.files || []), version: n };
264
+ } else
265
+ throw new $({
266
+ packageName: r,
267
+ version: t,
268
+ cdn: "unpkg"
269
+ });
270
+ } catch (s) {
271
+ throw s instanceof u ? new C({
272
+ packageName: r,
273
+ version: t,
274
+ cdn: "unpkg"
275
+ }) : s;
276
+ }
277
+ }
278
+ function at(r, t, e) {
279
+ return `https://unpkg.com/${r}@${t}${e}`;
280
+ }
281
+ const lt = {
282
+ getFileList: it,
283
+ getUrl: at
284
+ }, ut = async (r) => {
285
+ try {
286
+ const t = /^(https?:\/\/.*\d+\.\d+\.\d+\/).+?\.js$/;
287
+ if (t.test(r)) {
288
+ const e = r.replace(t, (s, n) => `${n}package.json`);
289
+ return await y.get(e);
290
+ } else
291
+ throw new Error(`${r} 不是正确的url`);
292
+ } catch (t) {
293
+ throw t;
161
294
  }
162
- }, R = async (n, t, e) => {
163
- var o;
164
- const r = (o = t.match(/\d+(.\d+)?(.\d+)?/)) == null ? void 0 : o[0];
165
- if (!r)
166
- throw new Error(`${n} version ${t} is not valid`);
167
- const s = await k[e].getFileList(n, r).catch((i) => {
168
- throw i;
169
- }), c = A(s, n);
170
- if (!c)
171
- throw new Error(`在 ${e} 中找不到 ${n}@${r} 文件,请检查包名或版本号`);
172
- return k[e].getUrl(n, r, c);
173
- }, A = ({ fileList: n }, t) => {
174
- var c, o;
295
+ }, dt = (r, t) => {
296
+ var e, s;
297
+ return ((e = r.dependencies) == null ? void 0 : e[t]) || ((s = r.devDependencies) == null ? void 0 : s[t]);
298
+ }, ht = async (r, t, e) => {
299
+ if (!t.match(/\d+(.\d+)?(.\d+)?/))
300
+ throw new Error(`${r} version ${t} is not valid`);
301
+ const n = await R[e].getFileList(r, t), o = ft(n, r);
302
+ if (!o)
303
+ throw new W({
304
+ packageName: r,
305
+ version: t,
306
+ cdn: e
307
+ });
308
+ return R[e].getUrl(r, n.version, o);
309
+ }, ft = ({ fileList: r }, t) => {
310
+ var o, a;
175
311
  let e = [
176
312
  `umd/${t}.production.min.js`,
177
313
  /umd\/.+?\.production\.min\.js$/,
@@ -189,137 +325,211 @@ const L = async () => (C || (C = new E(), await C.init()), C), $ = {
189
325
  /\.min\.js$/,
190
326
  /\.js$/
191
327
  ];
192
- const r = ["runtime", "compiler", ".esm", ".cjs", "development"].filter((i) => !t.includes(i));
193
- let s = "";
194
- for (let i of e)
195
- if (i instanceof RegExp ? s = ((c = n.find((a) => i.test(a.name) && !r.some((l) => a.name.includes(l)))) == null ? void 0 : c.name) || "" : s = ((o = n.find((a) => a.name.includes(i) && !r.some((l) => a.name.includes(l)))) == null ? void 0 : o.name) || "", s)
328
+ const s = ["runtime", "compiler", ".esm", ".cjs", "development"].filter((c) => !t.includes(c));
329
+ let n = "";
330
+ for (let c of e)
331
+ if (c instanceof RegExp ? n = ((o = r.find((i) => c.test(i.name) && !s.some((l) => i.name.includes(l)))) == null ? void 0 : o.name) || "" : n = ((a = r.find((i) => i.name.includes(c) && !s.some((l) => i.name.includes(l)))) == null ? void 0 : a.name) || "", n)
196
332
  break;
197
- return s;
333
+ return n;
334
+ }, R = {
335
+ jsdelivr: ct,
336
+ bootcdn: tt,
337
+ cdnjs: st,
338
+ unpkg: lt
198
339
  };
199
- function M(n, t) {
200
- const e = n.replace(/^\D/, "").split("."), r = t.replace(/^\D/, "").split("."), s = Math.max(e.length, r.length);
201
- for (; e.length < s; )
340
+ function pt(r, t) {
341
+ const e = r.replace(/^\D/, "").split("."), s = t.replace(/^\D/, "").split("."), n = Math.max(e.length, s.length);
342
+ for (; e.length < n; )
202
343
  e.push("0");
203
- for (; r.length < s; )
204
- r.push("0");
205
- for (let c = 0; c < s; c++) {
206
- const o = parseInt(e[c], 10), i = parseInt(r[c], 10);
207
- if (o > i)
344
+ for (; s.length < n; )
345
+ s.push("0");
346
+ for (let o = 0; o < n; o++) {
347
+ const a = parseInt(e[o], 10), c = parseInt(s[o], 10);
348
+ if (a > c)
208
349
  return 1;
209
- if (o < i)
350
+ if (a < c)
210
351
  return -1;
211
352
  }
212
353
  return 0;
213
354
  }
214
- function V(n, t) {
355
+ function wt(r, t) {
215
356
  for (let e in t)
216
- Object.prototype.hasOwnProperty.call(t, e) && (n[e] ? M(n[e], t[e]) === -1 && (n[e] = t[e]) : n[e] = t[e]);
217
- return n;
357
+ Object.prototype.hasOwnProperty.call(t, e) && (r[e] ? pt(r[e], t[e]) === -1 && (r[e] = t[e]) : r[e] = t[e]);
358
+ return r;
359
+ }
360
+ class gt {
361
+ constructor() {
362
+ // 打印记录
363
+ m(this, "logList", []);
364
+ }
365
+ // 打印方法
366
+ log(t) {
367
+ this.logList.push({
368
+ type: "log",
369
+ message: t
370
+ });
371
+ }
372
+ warn(t) {
373
+ this.logList.push({
374
+ type: "warn",
375
+ message: t
376
+ });
377
+ }
378
+ error(t) {
379
+ this.logList.push({
380
+ type: "error",
381
+ message: t
382
+ });
383
+ }
384
+ info(t) {
385
+ this.logList.push({
386
+ type: "info",
387
+ message: t
388
+ });
389
+ }
390
+ // 打印全部
391
+ consoleAll() {
392
+ this.logList.forEach((t) => {
393
+ console[t.type](`${q} ${t.message}`);
394
+ });
395
+ }
396
+ // 清除打印记录
397
+ clear() {
398
+ this.logList = [];
399
+ }
218
400
  }
219
- async function v({ external: n, packageData: t, customScript: e, defaultCdns: r }) {
220
- let s = [], c = !1;
221
- const o = await L();
401
+ const q = "vite-add-cdn-script", S = new gt();
402
+ async function A({
403
+ external: r,
404
+ packageData: t,
405
+ customScript: e,
406
+ defaultCdns: s
407
+ }) {
408
+ let n = [], o = !1;
409
+ const a = await K();
222
410
  return await Promise.all(
223
- n.map(async (i) => {
224
- const a = I(t, i);
225
- if (e[i])
411
+ r.map(async (c) => {
412
+ const i = dt(t, c);
413
+ if (e[c])
226
414
  return {
227
415
  urls: [],
228
- key: i
416
+ key: c
229
417
  };
230
- if (!a)
231
- return s.push(i), {
418
+ if (!i)
419
+ return n.push(c), {
232
420
  urls: [],
233
- key: i
421
+ key: c
234
422
  };
235
- const l = o.getCdnCache(i, a);
423
+ const l = a.getCdnCache(c, i);
236
424
  if (l)
237
425
  return {
238
426
  urls: l,
239
- key: i
427
+ key: c
240
428
  };
241
429
  {
242
- c = !0, console.log(`从网络获取${i}${a}的cdn地址`);
430
+ o = !0, console.log(`从网络获取${c}${i}的cdn地址`);
431
+ const L = await Promise.allSettled(
432
+ s.map(async (w) => await ht(c, i, w))
433
+ ).then((w) => w.filter((f) => {
434
+ if (f.status === "fulfilled")
435
+ return f.value, !0;
436
+ S.warn(f.reason.toString());
437
+ }).map((f) => f.value));
438
+ if (L.length === 0)
439
+ throw new Error(`获取${c} ${i}的cdn地址失败`);
243
440
  const d = {
244
- urls: await Promise.all(
245
- r.map(async (h) => await R(i, a, h))
246
- ),
247
- key: i
441
+ urls: L,
442
+ key: c
248
443
  };
249
- return o.setCdnCache(i, a, d.urls), d;
444
+ return a.setCdnCache(c, i, d.urls), d;
250
445
  }
251
446
  })
252
- ).then((i) => (c && o.save(), {
253
- urls: i,
254
- noVersionPackages: s
447
+ ).then((c) => (o && a.save(), {
448
+ urls: c,
449
+ noVersionPackages: n
255
450
  }));
256
451
  }
257
- function q(n) {
258
- const { customScript: t = {}, retryTimes: e = 1, defaultCdns: r = ["jsdelivr", "unpkg"] } = n;
259
- let s;
452
+ function Pt(r) {
453
+ const { customScript: t = {}, retryTimes: e = 1, defaultCdns: s = ["jsdelivr", "unpkg"] } = r;
454
+ let n;
260
455
  return {
261
- name: "vite-add-cdn-script",
456
+ name: q,
262
457
  enforce: "pre",
263
458
  apply: "build",
264
- config(c) {
265
- s = c;
459
+ config(o) {
460
+ n = o;
266
461
  },
267
- async transformIndexHtml(c) {
268
- if (!r || r.length === 0)
462
+ async transformIndexHtml(o) {
463
+ var c, i;
464
+ if (!s || s.length === 0)
269
465
  throw new Error("defaultCdns不能为空");
270
- const o = O.resolve(process.cwd(), "package.json");
466
+ const a = O.resolve(process.cwd(), "package.json");
271
467
  try {
272
- const i = y.readFileSync(o, "utf-8"), a = JSON.parse(i), l = s.build.rollupOptions.external, d = {};
273
- let h = "";
274
- const { urls: P, noVersionPackages: U } = await v({
275
- external: l,
276
- packageData: a,
468
+ const l = U.readFileSync(a, "utf-8"), L = JSON.parse(l), d = (i = (c = n.build) == null ? void 0 : c.rollupOptions) == null ? void 0 : i.external;
469
+ if (!d)
470
+ return o;
471
+ let w = [];
472
+ if (typeof d == "string")
473
+ w = [d];
474
+ else if (Array.isArray(d))
475
+ w = d.filter((g) => typeof g == "string");
476
+ else if (typeof d == "object")
477
+ return o;
478
+ const f = {};
479
+ let k = "";
480
+ const { urls: v, noVersionPackages: _ } = await A({
481
+ external: w,
482
+ packageData: L,
277
483
  customScript: t,
278
- defaultCdns: r
484
+ defaultCdns: s
279
485
  });
280
- if (U.length > 0) {
281
- const f = { dependencies: {} };
282
- await Promise.all(
283
- P.map(async (p) => {
284
- if (!p)
486
+ if (_.length > 0) {
487
+ const g = { dependencies: {} };
488
+ await Promise.allSettled(
489
+ v.map(async (h) => {
490
+ if (!h)
285
491
  return;
286
- const { key: j, urls: x } = p, m = t[j] || x[0];
287
- if (!m)
492
+ const { key: j, urls: F } = h, P = t[j] || F[0];
493
+ if (!P)
288
494
  return;
289
- const g = await N(m);
290
- V(f.dependencies, g.dependencies);
495
+ const x = await ut(P);
496
+ wt(g.dependencies, x.dependencies);
291
497
  })
292
- );
293
- const { urls: w, noVersionPackages: u } = await v({
294
- external: U,
295
- packageData: f,
498
+ ).then((h) => {
499
+ h.forEach((j) => {
500
+ j.status === "rejected" && S.warn(j.reason.toString());
501
+ });
502
+ });
503
+ const { urls: E, noVersionPackages: p } = await A({
504
+ external: _,
505
+ packageData: g,
296
506
  customScript: t,
297
- defaultCdns: r
507
+ defaultCdns: s
298
508
  });
299
- if (w.map((p) => {
300
- var m;
301
- if (!p)
509
+ if (E.map((h) => {
510
+ var P;
511
+ if (!h)
302
512
  return;
303
- const { urls: j, key: x } = p;
304
- (m = P.find((g) => (g == null ? void 0 : g.key) === x)) == null || m.urls.push(...j);
305
- }), u.length > 0)
306
- throw console.error(`找不到${u.join(",")}的版本`), new Error(`找不到${u.join(",")}的版本`);
513
+ const { urls: j, key: F } = h;
514
+ (P = v.find((x) => (x == null ? void 0 : x.key) === F)) == null || P.urls.push(...j);
515
+ }), p.length > 0)
516
+ throw console.error(`找不到${p.join(",")}的版本`), new Error(`找不到${p.join(",")}的版本`);
307
517
  }
308
- return P.forEach((f) => {
309
- if (!f)
518
+ return S.consoleAll(), v.forEach((g) => {
519
+ if (!g)
310
520
  return;
311
- const { urls: w, key: u } = f;
312
- if (t[u])
313
- h += t[u];
521
+ const { urls: E, key: p } = g;
522
+ if (t[p])
523
+ k += t[p];
314
524
  else {
315
- d[u] = w;
316
- const p = w[0];
317
- h += `<script src="${p}" type="text/javascript" crossorigin="anonymous" onerror="errorCDN(this)" data-cur="0" data-key="${u}"><\/script>
525
+ f[p] = E;
526
+ const h = E[0];
527
+ k += `<script src="${h}" type="text/javascript" crossorigin="anonymous" onerror="errorCDN(this)" data-cur="0" data-key="${p}"><\/script>
318
528
  `;
319
529
  }
320
- }), h = `<script>
530
+ }), k = `<script>
321
531
  function errorCDN(e) {
322
- const packNameUrl = JSON.parse('${JSON.stringify(d)}');
532
+ const packNameUrl = JSON.parse('${JSON.stringify(f)}');
323
533
  const nextCur = parseInt(e.getAttribute("data-cur")) + 1;
324
534
  if(nextCur>${e}){return;}
325
535
 
@@ -339,13 +549,14 @@ function q(n) {
339
549
  document.head.appendChild(cdnDOM);
340
550
  e.remove();
341
551
  }
342
- <\/script>` + h, c = c.replace("</head>", `${h}</head>`), c;
343
- } catch (i) {
344
- console.error("获取dependencies出错:", i);
552
+ <\/script>` + k, o = o.replace("</head>", `${k}</head>`), o;
553
+ } catch (l) {
554
+ S.consoleAll(), console.error("vite-add-cdn-script error:", l.message), process.exit(1);
345
555
  }
346
556
  }
347
557
  };
348
558
  }
349
559
  export {
350
- q as default
560
+ Pt as default,
561
+ q as libName
351
562
  };
@@ -1,9 +1,9 @@
1
- (function(u,a){typeof exports=="object"&&typeof module<"u"?module.exports=a(require("node:path"),require("node:fs"),require("node:https")):typeof define=="function"&&define.amd?define(["node:path","node:fs","node:https"],a):(u=typeof globalThis<"u"?globalThis:u||self,u.index=a(u.path,u.fs,u.https))})(this,function(u,a,f){"use strict";var V=Object.defineProperty;var T=(u,a,f)=>a in u?V(u,a,{enumerable:!0,configurable:!0,writable:!0,value:f}):u[a]=f;var k=(u,a,f)=>(T(u,typeof a!="symbol"?a+"":a,f),f);class F{constructor(){k(this,"cdnCache",{});k(this,"cdnCachePath","");this.cdnCachePath=u.resolve(process.cwd(),"./.cdn-cache.json")}async init(){try{const e=await a.readFileSync(this.cdnCachePath,"utf-8");this.cdnCache=JSON.parse(e)}catch{console.log("cdn缓存文件不存在,创建缓存文件"),this.cdnCache={},await a.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 a.writeFileSync(this.cdnCachePath,JSON.stringify(this.cdnCache),"utf-8")}}let j;const E=async()=>(j||(j=new F,await j.init()),j),$={get:(n,e,t)=>new Promise((r,s)=>{try{f.get(n,i=>{let o="";i.on("data",c=>{o+=c}),i.on("end",()=>{e==null||e(o),r(o)})})}catch(i){t==null||t(i),s(i)}})},L=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 $.get(t))}else throw new Error(`${n} 不是正确的url`)},b=(n,e)=>{var t,r;return((t=n.dependencies)==null?void 0:t[e])||((r=n.devDependencies)==null?void 0:r[e])},v=n=>n.reduce((e,t)=>(t.type==="file"?e.push({name:t.path}):t.files&&e.push(...v(t.files)),e),[]),O={jsdelivr:{getFileList:(n,e)=>new Promise((t,r)=>{$.get(`https://data.jsdelivr.com/v1/stats/packages/npm/${n}@${e}/files`,s=>{const i=JSON.parse(s);if(i.length===0){r(new Error(`${n}@${e} not found`));return}t({fileList:i})},s=>{r(s)})}),getUrl:(n,e,t)=>`https://cdn.jsdelivr.net/npm/${n}@${e}${t}`},unpkg:{getFileList:(n,e)=>new Promise((t,r)=>{$.get(`https://unpkg.com/${n}@${e}/?meta`,s=>{const i=JSON.parse(s);t({fileList:v(i.files||[])})},s=>{r(s)})}),getUrl:(n,e,t)=>`https://unpkg.com/${n}@${e}${t}`},bootcdn:{getFileList:(n,e)=>new Promise((t,r)=>{$.get(`https://api.bootcdn.cn/libraries/${n}`,s=>{const i=JSON.parse(s);if(i.length===0){r(new Error(`${n} not found in bootcdn`));return}const o=i[0],d=o.assets.find(h=>h.version===e);if(!d){r(new Error(`${n}@${e} not found in ${o.name}`));return}const l=d.files.map(h=>({name:"/"+h}));t({fileList:l,recommendFileName:o.filename})},s=>{r(s)})}),getUrl:(n,e,t)=>`https://cdn.bootcdn.net/ajax/libs/${n}/${e}${t}`},cdnjs:{getFileList:(n,e)=>new Promise((t,r)=>{$.get(`https://api.cdnjs.com/libraries/${n}/${e}`,s=>{const i=JSON.parse(s);if(i.error){r(new Error(`cdnjs: ${n}@${e} not found`));return}t({fileList:i.rawFiles.map(o=>({name:"/"+o}))})},s=>{r(s)})}),getUrl:(n,e,t)=>`https://cdnjs.cloudflare.com/ajax/libs/${n}/${e}${t}`}},N=async(n,e,t)=>{var o;const r=(o=e.match(/\d+(.\d+)?(.\d+)?/))==null?void 0:o[0];if(!r)throw new Error(`${n} version ${e} is not valid`);const s=await O[t].getFileList(n,r).catch(c=>{throw c}),i=I(s,n);if(!i)throw new Error(`在 ${t} 中找不到 ${n}@${r} 文件,请检查包名或版本号`);return O[t].getUrl(n,r,i)},I=({fileList:n},e)=>{var i,o;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(c=>!e.includes(c));let s="";for(let c of t)if(c instanceof RegExp?s=((i=n.find(d=>c.test(d.name)&&!r.some(l=>d.name.includes(l))))==null?void 0:i.name)||"":s=((o=n.find(d=>d.name.includes(c)&&!r.some(l=>d.name.includes(l))))==null?void 0:o.name)||"",s)break;return s};function R(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 i=0;i<s;i++){const o=parseInt(t[i],10),c=parseInt(r[i],10);if(o>c)return 1;if(o<c)return-1}return 0}function A(n,e){for(let t in e)Object.prototype.hasOwnProperty.call(e,t)&&(n[t]?R(n[t],e[t])===-1&&(n[t]=e[t]):n[t]=e[t]);return n}async function J({external:n,packageData:e,customScript:t,defaultCdns:r}){let s=[],i=!1;const o=await E();return await Promise.all(n.map(async c=>{const d=b(e,c);if(t[c])return{urls:[],key:c};if(!d)return s.push(c),{urls:[],key:c};const l=o.getCdnCache(c,d);if(l)return{urls:l,key:c};{i=!0,console.log(`从网络获取${c}${d}的cdn地址`);const h={urls:await Promise.all(r.map(async m=>await N(c,d,m))),key:c};return o.setCdnCache(c,d,h.urls),h}})).then(c=>(i&&o.save(),{urls:c,noVersionPackages:s}))}function M(n){const{customScript:e={},retryTimes:t=1,defaultCdns:r=["jsdelivr","unpkg"]}=n;let s;return{name:"vite-add-cdn-script",enforce:"pre",apply:"build",config(i){s=i},async transformIndexHtml(i){if(!r||r.length===0)throw new Error("defaultCdns不能为空");const o=u.resolve(process.cwd(),"package.json");try{const c=a.readFileSync(o,"utf-8"),d=JSON.parse(c),l=s.build.rollupOptions.external,h={};let m="";const{urls:x,noVersionPackages:D}=await J({external:l,packageData:d,customScript:e,defaultCdns:r});if(D.length>0){const w={dependencies:{}};await Promise.all(x.map(async g=>{if(!g)return;const{key:S,urls:U}=g,C=e[S]||U[0];if(!C)return;const y=await L(C);A(w.dependencies,y.dependencies)}));const{urls:P,noVersionPackages:p}=await J({external:D,packageData:w,customScript:e,defaultCdns:r});if(P.map(g=>{var C;if(!g)return;const{urls:S,key:U}=g;(C=x.find(y=>(y==null?void 0:y.key)===U))==null||C.urls.push(...S)}),p.length>0)throw console.error(`找不到${p.join(",")}的版本`),new Error(`找不到${p.join(",")}的版本`)}return x.forEach(w=>{if(!w)return;const{urls:P,key:p}=w;if(e[p])m+=e[p];else{h[p]=P;const g=P[0];m+=`<script src="${g}" type="text/javascript" crossorigin="anonymous" onerror="errorCDN(this)" data-cur="0" data-key="${p}"><\/script>
2
- `}}),m=`<script>
1
+ (function(c,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("node:path"),require("node:fs"),require("node-fetch"),require("semver")):typeof define=="function"&&define.amd?define(["exports","node:path","node:fs","node-fetch","semver"],l):(c=typeof globalThis<"u"?globalThis:c||self,l(c.index={},c.path,c.fs,c.fetch,c.semver))})(this,function(c,l,d,R,A){"use strict";var wt=Object.defineProperty;var gt=(c,l,d)=>l in c?wt(c,l,{enumerable:!0,configurable:!0,writable:!0,value:d}):c[l]=d;var k=(c,l,d)=>(gt(c,typeof l!="symbol"?l+"":l,d),d);class B{constructor(){k(this,"cdnCache",{});k(this,"cdnCachePath","");this.cdnCachePath=l.resolve(process.cwd(),"./.cdn-cache.json")}async init(){try{const t=await d.readFileSync(this.cdnCachePath,"utf-8");this.cdnCache=JSON.parse(t)}catch{console.log("cdn缓存文件不存在,创建缓存文件"),this.cdnCache={},await d.writeFileSync(this.cdnCachePath,"","utf-8")}}getCdnCache(t,e){var n;return(n=this.cdnCache[t])==null?void 0:n[e]}setCdnCache(t,e,n){this.cdnCache[t]?this.cdnCache[t][e]=n:this.cdnCache[t]={[e]:n}}async save(){await d.writeFileSync(this.cdnCachePath,JSON.stringify(this.cdnCache),"utf-8")}}let b;const z=async()=>(b||(b=new B,await b.init()),b);class h extends Error{constructor(t){super(t),this.name="NetworkError"}}class P extends h{constructor({packageName:t,version:e,cdn:n}){super(`${n} ${t}@${e} 网络请求失败`),this.name="PackageNetworkError"}}class $ extends Error{constructor({packageName:t,version:e,cdn:n}){super(`${n}上没有${t}@${e}的版本`),this.name="NoVersionError"}}class K extends Error{constructor({packageName:t,version:e,cdn:n}){super(`在 ${n} 中找不到 ${t}@${e} 文件,请检查包名或版本号`),this.name="GetFileListError"}}class W{constructor(t){k(this,"_max");k(this,"_count");k(this,"_taskQueue");this._max=t||5,this._count=0,this._taskQueue=[]}call(t,...e){return new Promise((n,s)=>{const i=this._createTask(t,e,n,s);this._count>=this._max?this._taskQueue.push(i):i()})}_createTask(t,e,n,s){return()=>{t(...e).then(n).catch(s).finally(()=>{this._count--,this._taskQueue.length&&this._taskQueue.shift()()}),this._count++}}}const V=new W(5),J=async r=>{try{const t=await R(r,{method:"HEAD",redirect:"manual"});return t.status>=300&&t.status<400?await J(t.headers.get("location")||""):r}catch(t){throw Promise.reject(new h(t.message))}},X={get:async r=>{try{const t=await R(r);if(t.ok){const e=t.headers.get("content-type"),n=await t.text();return e&&e.includes("application/json")?JSON.parse(n):n}else throw new h(`请求失败,状态码:${t.status}`)}catch(t){throw new h(t.message)}}},y={get:V.call.bind(V,X.get)},Y={getFileList:async(r,t)=>{try{const e=await y.get(`https://api.bootcdn.cn/libraries/${r}`);if(e.length===0)throw new $({packageName:r,version:t,cdn:"bootcdn"});const n=e[0],i=n.assets.reverse().find(o=>{if(A.satisfies(o.version,t))return!0});if(!i)throw new $({packageName:r,version:t,cdn:"bootcdn"});return{fileList:i.files.map(o=>({name:"/"+o})),recommendFileName:n.filename,version:i.version}}catch(e){throw e instanceof h?new P({packageName:r,version:t,cdn:"unpkg"}):e}},getUrl:(r,t,e)=>`https://cdn.bootcdn.net/ajax/libs/${r}/${t}${e}`};async function M(r,t,e=!1){try{if(!e&&t.match(/^\D/)){const s=await N(r,t);for(let i of s)if(A.satisfies(i,t))return M(r,i,!0);throw new $({packageName:r,version:t,cdn:"cdnjs"})}const n=await y.get(`https://api.cdnjs.com/libraries/${r}/${t}`);if(n.error)throw new $({packageName:r,version:t,cdn:"cdnjs"});return{fileList:n.rawFiles.map(s=>({name:"/"+s})),version:t}}catch(n){throw n instanceof h?new P({packageName:r,version:t,cdn:"unpkg"}):n}}const Z=(r,t,e)=>`https://cdnjs.cloudflare.com/ajax/libs/${r}/${t}${e}`,N=async(r,t)=>{try{return(await y.get(`https://api.cdnjs.com/libraries/${r}?fields=versions`)).versions}catch(e){throw e instanceof h?new P({packageName:r,version:t,cdn:"unpkg"}):e}},tt={getFileList:M,getUrl:Z},T=(r,t="")=>r.reduce((e,n)=>(n.type==="file"?e.push({name:`${t}/${n.name}`}):n.files&&e.push(...T(n.files,`${t}/${n.name}`)),e),[]);async function I(r,t,e=!1){try{if(!e&&t.match(/^\D/)){const s=await rt(r,t);if(typeof s=="string")return I(r,s,!0);throw new $({packageName:r,version:t,cdn:"jsdelivr"})}const n=await y.get(`https://data.jsdelivr.com/v1/packages/npm/${r}@${t}`);if(n.status)throw new $({packageName:r,version:t,cdn:"jsdelivr"});return{fileList:T(n.files),version:t}}catch(n){throw n instanceof h?new P({packageName:r,version:t,cdn:"unpkg"}):n}}const et=(r,t,e)=>`https://cdn.jsdelivr.net/npm/${r}@${t}${e}`,rt=async(r,t)=>{try{return(await y.get(`https://data.jsdelivr.com/v1/packages/npm/${r}/resolved?specifier=${t}`)).version}catch(e){throw e instanceof h?new P({packageName:r,version:t,cdn:"unpkg"}):e}},nt={getFileList:I,getUrl:et},q=r=>r.reduce((t,e)=>(e.type==="file"?t.push({name:e.path}):e.files&&t.push(...q(e.files)),t),[]);async function st(r,t){var e;try{const s=(e=(await J(`https://unpkg.com/${r}@${t}/?meta`)).match(new RegExp("(?<=@)\\d+\\.\\d+\\.\\d+(?=\\/\\?meta)")))==null?void 0:e[0];if(s){const i=await y.get(`https://unpkg.com/${r}@${s}/?meta`);return{fileList:q(i.files||[]),version:s}}else throw new $({packageName:r,version:t,cdn:"unpkg"})}catch(n){throw n instanceof h?new P({packageName:r,version:t,cdn:"unpkg"}):n}}function it(r,t,e){return`https://unpkg.com/${r}@${t}${e}`}const ot={getFileList:st,getUrl:it},ct=async r=>{try{const t=/^(https?:\/\/.*\d+\.\d+\.\d+\/).+?\.js$/;if(t.test(r)){const e=r.replace(t,(n,s)=>`${s}package.json`);return await y.get(e)}else throw new Error(`${r} 不是正确的url`)}catch(t){throw t}},at=(r,t)=>{var e,n;return((e=r.dependencies)==null?void 0:e[t])||((n=r.devDependencies)==null?void 0:n[t])},lt=async(r,t,e)=>{if(!t.match(/\d+(.\d+)?(.\d+)?/))throw new Error(`${r} version ${t} is not valid`);const s=await Q[e].getFileList(r,t),i=ut(s,r);if(!i)throw new K({packageName:r,version:t,cdn:e});return Q[e].getUrl(r,s.version,i)},ut=({fileList:r},t)=>{var i,u;let e=[`umd/${t}.production.min.js`,/umd\/.+?\.production\.min\.js$/,/dist\/.+?\.production\.min\.js$/,/dist\/.+?\.umd\.min\.js$/,`dist/${t}.prod.min.js`,/dist\/.+?\.global.prod.min.js/,`dist/${t}.min.js`,/.+?\.global.prod.min.js/,/.+?.global.prod.js/,/lib\/.+?\.min\.js$/,/dist\/.+?\.min\.js$/,/index\.min\.js$/,/index\.js$/,/\.min\.js$/,/\.js$/];const n=["runtime","compiler",".esm",".cjs","development"].filter(o=>!t.includes(o));let s="";for(let o of e)if(o instanceof RegExp?s=((i=r.find(a=>o.test(a.name)&&!n.some(f=>a.name.includes(f))))==null?void 0:i.name)||"":s=((u=r.find(a=>a.name.includes(o)&&!n.some(f=>a.name.includes(f))))==null?void 0:u.name)||"",s)break;return s},Q={jsdelivr:nt,bootcdn:Y,cdnjs:tt,unpkg:ot};function dt(r,t){const e=r.replace(/^\D/,"").split("."),n=t.replace(/^\D/,"").split("."),s=Math.max(e.length,n.length);for(;e.length<s;)e.push("0");for(;n.length<s;)n.push("0");for(let i=0;i<s;i++){const u=parseInt(e[i],10),o=parseInt(n[i],10);if(u>o)return 1;if(u<o)return-1}return 0}function ht(r,t){for(let e in t)Object.prototype.hasOwnProperty.call(t,e)&&(r[e]?dt(r[e],t[e])===-1&&(r[e]=t[e]):r[e]=t[e]);return r}class ft{constructor(){k(this,"logList",[])}log(t){this.logList.push({type:"log",message:t})}warn(t){this.logList.push({type:"warn",message:t})}error(t){this.logList.push({type:"error",message:t})}info(t){this.logList.push({type:"info",message:t})}consoleAll(){this.logList.forEach(t=>{console[t.type](`${F} ${t.message}`)})}clear(){this.logList=[]}}const F="vite-add-cdn-script",v=new ft;async function H({external:r,packageData:t,customScript:e,defaultCdns:n}){let s=[],i=!1;const u=await z();return await Promise.all(r.map(async o=>{const a=at(t,o);if(e[o])return{urls:[],key:o};if(!a)return s.push(o),{urls:[],key:o};const f=u.getCdnCache(o,a);if(f)return{urls:f,key:o};{i=!0,console.log(`从网络获取${o}${a}的cdn地址`);const S=await Promise.allSettled(n.map(async j=>await lt(o,a,j))).then(j=>j.filter(g=>{if(g.status==="fulfilled")return g.value,!0;v.warn(g.reason.toString())}).map(g=>g.value));if(S.length===0)throw new Error(`获取${o} ${a}的cdn地址失败`);const p={urls:S,key:o};return u.setCdnCache(o,a,p.urls),p}})).then(o=>(i&&u.save(),{urls:o,noVersionPackages:s}))}function pt(r){const{customScript:t={},retryTimes:e=1,defaultCdns:n=["jsdelivr","unpkg"]}=r;let s;return{name:F,enforce:"pre",apply:"build",config(i){s=i},async transformIndexHtml(i){var o,a;if(!n||n.length===0)throw new Error("defaultCdns不能为空");const u=l.resolve(process.cwd(),"package.json");try{const f=d.readFileSync(u,"utf-8"),S=JSON.parse(f),p=(a=(o=s.build)==null?void 0:o.rollupOptions)==null?void 0:a.external;if(!p)return i;let j=[];if(typeof p=="string")j=[p];else if(Array.isArray(p))j=p.filter(C=>typeof C=="string");else if(typeof p=="object")return i;const g={};let L="";const{urls:D,noVersionPackages:G}=await H({external:j,packageData:S,customScript:t,defaultCdns:n});if(G.length>0){const C={dependencies:{}};await Promise.allSettled(D.map(async w=>{if(!w)return;const{key:x,urls:O}=w,E=t[x]||O[0];if(!E)return;const U=await ct(E);ht(C.dependencies,U.dependencies)})).then(w=>{w.forEach(x=>{x.status==="rejected"&&v.warn(x.reason.toString())})});const{urls:_,noVersionPackages:m}=await H({external:G,packageData:C,customScript:t,defaultCdns:n});if(_.map(w=>{var E;if(!w)return;const{urls:x,key:O}=w;(E=D.find(U=>(U==null?void 0:U.key)===O))==null||E.urls.push(...x)}),m.length>0)throw console.error(`找不到${m.join(",")}的版本`),new Error(`找不到${m.join(",")}的版本`)}return v.consoleAll(),D.forEach(C=>{if(!C)return;const{urls:_,key:m}=C;if(t[m])L+=t[m];else{g[m]=_;const w=_[0];L+=`<script src="${w}" type="text/javascript" crossorigin="anonymous" onerror="errorCDN(this)" data-cur="0" data-key="${m}"><\/script>
2
+ `}}),L=`<script>
3
3
  function errorCDN(e) {
4
- const packNameUrl = JSON.parse('${JSON.stringify(h)}');
4
+ const packNameUrl = JSON.parse('${JSON.stringify(g)}');
5
5
  const nextCur = parseInt(e.getAttribute("data-cur")) + 1;
6
- if(nextCur>${t}){return;}
6
+ if(nextCur>${e}){return;}
7
7
 
8
8
  const key = e.getAttribute("data-key");
9
9
  if(nextCur>=packNameUrl[key].length){return;}
@@ -21,4 +21,4 @@
21
21
  document.head.appendChild(cdnDOM);
22
22
  e.remove();
23
23
  }
24
- <\/script>`+m,i=i.replace("</head>",`${m}</head>`),i}catch(c){console.error("获取dependencies出错:",c)}}}}return M});
24
+ <\/script>`+L,i=i.replace("</head>",`${L}</head>`),i}catch(f){v.consoleAll(),console.error("vite-add-cdn-script error:",f.message),process.exit(1)}}}}c.default=pt,c.libName=F,Object.defineProperties(c,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-add-cdn-script",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "keywords": [
5
5
  "vite",
6
6
  "cdn",
@@ -37,13 +37,15 @@
37
37
  "devDependencies": {
38
38
  "@jest/globals": "^29.7.0",
39
39
  "@types/node": "^20.12.11",
40
+ "@types/node-fetch": "2",
40
41
  "@types/react": "^18.3.2",
41
42
  "@types/react-dom": "^18.3.0",
43
+ "@types/semver": "^7.5.8",
42
44
  "@vitejs/plugin-react": "^4.2.1",
43
45
  "cross-env": "^7.0.3",
44
46
  "jest": "^29.7.0",
45
- "react": "^18.3.1",
46
- "react-dom": "^18.3.1",
47
+ "react": "^18.2.0",
48
+ "react-dom": "^18.2.0",
47
49
  "react-router-dom": "^6.23.1",
48
50
  "rollup-plugin-external-globals": "^0.10.0",
49
51
  "rollup-plugin-node-externals": "^7.1.2",
@@ -55,5 +57,8 @@
55
57
  "publishConfig": {
56
58
  "registry": "https://registry.npmjs.org/"
57
59
  },
58
- "dependencies": {}
60
+ "dependencies": {
61
+ "node-fetch": "2",
62
+ "semver": "^7.6.2"
63
+ }
59
64
  }