vite-add-cdn-script 0.0.8 → 0.0.10

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 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
  }