@deot/docs-playground 1.1.3 → 1.1.4
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 +1 -0
- package/dist/{cdn-Czve5_9b.cjs → cdn-BoYKnGD3.cjs} +7 -0
- package/dist/{cdn-DEvdGJu2.js → cdn-DQoETju_.js} +2 -1
- package/dist/{compile-Bw7v7QE-.js → compile-BHD98Ttf.js} +24 -32
- package/dist/{compile-DSMuM8zl.cjs → compile-Da095AyM.cjs} +24 -32
- package/dist/{files-C5UMzYxA.js → files-BqucFldk.js} +33 -4
- package/dist/{files-D5LNOtjp.cjs → files-BsAOZiPN.cjs} +93 -18
- package/dist/index.cjs +35 -30
- package/dist/index.js +35 -30
- package/dist/index.style.css +1 -1
- package/dist/{linker-B--sjERT.cjs → linker-DIpEiean.cjs} +2 -2
- package/dist/{linker-JHdz37DK.js → linker-xqjVl0X0.js} +2 -2
- package/dist/{local-sandbox-DnkKrBhf.cjs → local-sandbox-0ojvBQPO.cjs} +12 -8
- package/dist/{local-sandbox-B8IJ5jWb.js → local-sandbox-DvcgaBOa.js} +14 -21
- package/dist/{modules-DlLJF_vd.js → modules-BGzPcoRR.js} +7 -1
- package/dist/{modules-CInmL-8h.cjs → modules-E6kK6ZJH.cjs} +7 -1
- package/dist/{remote-CKMzn1J3.cjs → remote-BG0E1Ugo.cjs} +67 -21
- package/dist/{remote-DfXAsO9n.js → remote-mq4zvrI1.js} +67 -21
- package/dist/script-BiCcpu3G.cjs +111 -0
- package/dist/script-DjUf9uWK.js +98 -0
- package/dist/{scss-DaIqB_qT.cjs → scss-B8OFbz1k.cjs} +23 -5
- package/dist/{scss-Co2it4vB.js → scss-DIh6971q.js} +18 -6
- package/dist/{store-D8vwi-HV.js → store-BOyC8F2y.js} +149 -6
- package/dist/{store-BF7z-oaO.cjs → store-DKawhFZu.cjs} +151 -6
- package/package.json +8 -7
- package/dist/script-5Xzzx7u5.cjs +0 -57
- package/dist/script-xKUjE8pf.js +0 -46
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const
|
|
1
|
+
const require_cdn = require("./cdn-BoYKnGD3.cjs");
|
|
2
|
+
const require_files = require("./files-BsAOZiPN.cjs");
|
|
3
|
+
const require_script = require("./script-BiCcpu3G.cjs");
|
|
4
|
+
const require_modules = require("./modules-E6kK6ZJH.cjs");
|
|
5
|
+
let es_module_lexer = require("es-module-lexer");
|
|
4
6
|
let sucrase = require("sucrase");
|
|
5
7
|
//#region packages/playground/src/core/runtime/local/remote.ts
|
|
6
8
|
var HOST_VUE = /* @__PURE__ */ new Set(["vue", "vue/server-renderer"]);
|
|
7
9
|
/**
|
|
8
10
|
* 把 CDN 上的 ESM 先拉完整张依赖图,再在当前页面里执行。
|
|
9
|
-
*
|
|
11
|
+
* 裸导入优先走 import map,缺失的 npm 依赖回退到 CDN ESM;import() 按需加载。
|
|
10
12
|
* @param imports 合并后的 import map。
|
|
11
13
|
* @param builtins 宿主 Vue 与 vue-router。
|
|
12
14
|
* @param cdnURL 当前 CDN 根,用来识别默认地址。
|
|
15
|
+
* @param importModule 浏览器原生 ESM 加载器。
|
|
13
16
|
* @returns 按 URL 加载并执行远程模块的加载器。
|
|
14
17
|
*/
|
|
15
|
-
var createRemoteLoader = (imports, builtins, cdnURL) =>
|
|
18
|
+
var createRemoteLoader = (imports, builtins, cdnURL, importModule = (url) => import(
|
|
19
|
+
/* @vite-ignore */
|
|
20
|
+
url
|
|
21
|
+
)) => {
|
|
16
22
|
const hostModules = {
|
|
17
23
|
"vue": builtins.vue,
|
|
18
24
|
"vue-router": builtins.vueRouter
|
|
@@ -21,6 +27,19 @@ var createRemoteLoader = (imports, builtins, cdnURL) => {
|
|
|
21
27
|
const texts = /* @__PURE__ */ new Map();
|
|
22
28
|
const evaluated = /* @__PURE__ */ new Map();
|
|
23
29
|
const crawled = /* @__PURE__ */ new Set();
|
|
30
|
+
const nativeModules = /* @__PURE__ */ new Map();
|
|
31
|
+
const loadNative = (url) => {
|
|
32
|
+
let pending = nativeModules.get(url);
|
|
33
|
+
if (!pending) {
|
|
34
|
+
pending = importModule(url).then((module) => {
|
|
35
|
+
const exports = require_modules.toHostModule(module);
|
|
36
|
+
evaluated.set(url, exports);
|
|
37
|
+
return exports;
|
|
38
|
+
});
|
|
39
|
+
nativeModules.set(url, pending);
|
|
40
|
+
}
|
|
41
|
+
return pending;
|
|
42
|
+
};
|
|
24
43
|
const localBuiltinId = (id) => {
|
|
25
44
|
if (imports[id] && !require_modules.prefersLocalBuiltin(id, imports, cdnURL)) return null;
|
|
26
45
|
if (require_modules.prefersLocalBuiltin(id, imports, cdnURL)) return id;
|
|
@@ -34,7 +53,7 @@ var createRemoteLoader = (imports, builtins, cdnURL) => {
|
|
|
34
53
|
}
|
|
35
54
|
};
|
|
36
55
|
const dependencyUrl = (from, specifier) => {
|
|
37
|
-
if (require_files.isRelativeSpecifier(specifier)) return new URL(specifier, from).href;
|
|
56
|
+
if (require_files.isRelativeSpecifier(specifier) || /^https?:\/\//.test(specifier)) return new URL(specifier, from).href;
|
|
38
57
|
if (imports[specifier] && !require_modules.prefersLocalBuiltin(specifier, imports, cdnURL)) return imports[specifier];
|
|
39
58
|
if (HOST_VUE.has(specifier) && require_modules.prefersLocalBuiltin(specifier, imports, cdnURL)) return null;
|
|
40
59
|
let cursor = specifier;
|
|
@@ -48,19 +67,29 @@ var createRemoteLoader = (imports, builtins, cdnURL) => {
|
|
|
48
67
|
cursor = cursor.slice(0, slash);
|
|
49
68
|
}
|
|
50
69
|
const target = imports[specifier] ? specifier : require_modules.resolveImportTarget(specifier, imports);
|
|
51
|
-
if (!target
|
|
70
|
+
if (!target) {
|
|
71
|
+
imports[specifier] = require_cdn.resolveNpmImport(specifier);
|
|
72
|
+
return imports[specifier];
|
|
73
|
+
}
|
|
52
74
|
return imports[target];
|
|
53
75
|
};
|
|
54
76
|
const crawl = async (url) => {
|
|
77
|
+
if (/\/\+esm(?:[?#]|$)/.test(url)) {
|
|
78
|
+
await loadNative(url);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
55
81
|
if (crawled.has(url)) return;
|
|
56
82
|
crawled.add(url);
|
|
57
83
|
const response = await fetch(url);
|
|
58
84
|
if (!response.ok) throw new Error(`${response.status} ${url}`);
|
|
59
85
|
const text = await response.text();
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
86
|
+
await es_module_lexer.init;
|
|
87
|
+
const [specifiers] = (0, es_module_lexer.parse)(text);
|
|
88
|
+
let source = text;
|
|
89
|
+
for (const item of [...specifiers].reverse()) if (item.d >= 0) source = source.slice(0, item.ss) + "__import" + source.slice(item.ss + 6);
|
|
90
|
+
texts.set(url, source);
|
|
91
|
+
await Promise.all(specifiers.filter((item) => item.d === -1).map(async (item) => {
|
|
92
|
+
const next = dependencyUrl(url, item.n);
|
|
64
93
|
if (next) await crawl(next);
|
|
65
94
|
}));
|
|
66
95
|
};
|
|
@@ -68,7 +97,7 @@ var createRemoteLoader = (imports, builtins, cdnURL) => {
|
|
|
68
97
|
if (HOST_VUE.has(id) && require_modules.prefersLocalBuiltin(id, imports, cdnURL)) return require_modules.toHostModule(builtins.vue);
|
|
69
98
|
const builtinId = localBuiltinId(id);
|
|
70
99
|
if (builtinId) return require_modules.toHostModule(hostModules[builtinId]);
|
|
71
|
-
if (require_files.isRelativeSpecifier(id)) return evaluate(new URL(id, from).href);
|
|
100
|
+
if (require_files.isRelativeSpecifier(id) || /^https?:\/\//.test(id)) return evaluate(new URL(id, from).href);
|
|
72
101
|
const target = imports[id] ? id : require_modules.resolveImportTarget(id, imports);
|
|
73
102
|
if (!target || !imports[target]) throw new Error(`[Playground] 未注册的模块 "${id}"`);
|
|
74
103
|
const loaded = evaluate(imports[target]);
|
|
@@ -84,23 +113,40 @@ var createRemoteLoader = (imports, builtins, cdnURL) => {
|
|
|
84
113
|
if (text == null) throw new Error(`[Playground] 远程模块尚未下载: ${url}`);
|
|
85
114
|
const cjs = (0, sucrase.transform)(require_script.rewriteImportMeta(text, url), {
|
|
86
115
|
transforms: ["imports"],
|
|
116
|
+
disableESTransforms: true,
|
|
87
117
|
production: true,
|
|
88
118
|
filePath: url
|
|
89
119
|
}).code;
|
|
90
120
|
const module = { exports: {} };
|
|
91
121
|
evaluated.set(url, module.exports);
|
|
92
|
-
new Function("require", "module", "exports", cjs)(requireFrom(url), module, module.exports)
|
|
122
|
+
new Function("require", "module", "exports", "__import", cjs)(requireFrom(url), module, module.exports, async (id) => {
|
|
123
|
+
const next = dependencyUrl(url, id);
|
|
124
|
+
if (next) await load(next);
|
|
125
|
+
else {
|
|
126
|
+
const builtinId = localBuiltinId(id);
|
|
127
|
+
if (builtinId && !(builtinId in hostModules)) hostModules[builtinId] = await require_modules.ensureLocalBuiltin(builtinId);
|
|
128
|
+
}
|
|
129
|
+
return requireFrom(url)(id);
|
|
130
|
+
});
|
|
93
131
|
evaluated.set(url, module.exports);
|
|
94
132
|
return module.exports;
|
|
95
133
|
};
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
134
|
+
const loading = /* @__PURE__ */ new Map();
|
|
135
|
+
const load = (url) => {
|
|
136
|
+
const pending = loading.get(url);
|
|
137
|
+
if (pending) return pending;
|
|
138
|
+
const task = (async () => {
|
|
139
|
+
await crawl(url);
|
|
140
|
+
await Promise.all([...pendingBuiltins].map(async (id) => {
|
|
141
|
+
if (id === "vue" || id === "vue-router") return;
|
|
142
|
+
hostModules[id] = await require_modules.ensureLocalBuiltin(id);
|
|
143
|
+
}));
|
|
144
|
+
return evaluate(url);
|
|
145
|
+
})();
|
|
146
|
+
loading.set(url, task);
|
|
147
|
+
return task;
|
|
148
|
+
};
|
|
149
|
+
return { load };
|
|
104
150
|
};
|
|
105
151
|
//#endregion
|
|
106
152
|
exports.createRemoteLoader = createRemoteLoader;
|
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
import { isRelativeSpecifier
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { l as isRelativeSpecifier } from "./files-BqucFldk.js";
|
|
2
|
+
import { a as resolveNpmImport } from "./cdn-DQoETju_.js";
|
|
3
|
+
import { t as rewriteImportMeta } from "./script-DjUf9uWK.js";
|
|
4
|
+
import { n as localBuiltinIds, prefersLocalBuiltin, resolveHostModule, resolveImportTarget, t as ensureLocalBuiltin, toHostModule } from "./modules-BGzPcoRR.js";
|
|
5
|
+
import { init, parse } from "es-module-lexer";
|
|
4
6
|
import { transform } from "sucrase";
|
|
5
7
|
//#region packages/playground/src/core/runtime/local/remote.ts
|
|
6
8
|
var HOST_VUE = /* @__PURE__ */ new Set(["vue", "vue/server-renderer"]);
|
|
7
9
|
/**
|
|
8
10
|
* 把 CDN 上的 ESM 先拉完整张依赖图,再在当前页面里执行。
|
|
9
|
-
*
|
|
11
|
+
* 裸导入优先走 import map,缺失的 npm 依赖回退到 CDN ESM;import() 按需加载。
|
|
10
12
|
* @param imports 合并后的 import map。
|
|
11
13
|
* @param builtins 宿主 Vue 与 vue-router。
|
|
12
14
|
* @param cdnURL 当前 CDN 根,用来识别默认地址。
|
|
15
|
+
* @param importModule 浏览器原生 ESM 加载器。
|
|
13
16
|
* @returns 按 URL 加载并执行远程模块的加载器。
|
|
14
17
|
*/
|
|
15
|
-
var createRemoteLoader = (imports, builtins, cdnURL) =>
|
|
18
|
+
var createRemoteLoader = (imports, builtins, cdnURL, importModule = (url) => import(
|
|
19
|
+
/* @vite-ignore */
|
|
20
|
+
url
|
|
21
|
+
)) => {
|
|
16
22
|
const hostModules = {
|
|
17
23
|
"vue": builtins.vue,
|
|
18
24
|
"vue-router": builtins.vueRouter
|
|
@@ -21,6 +27,19 @@ var createRemoteLoader = (imports, builtins, cdnURL) => {
|
|
|
21
27
|
const texts = /* @__PURE__ */ new Map();
|
|
22
28
|
const evaluated = /* @__PURE__ */ new Map();
|
|
23
29
|
const crawled = /* @__PURE__ */ new Set();
|
|
30
|
+
const nativeModules = /* @__PURE__ */ new Map();
|
|
31
|
+
const loadNative = (url) => {
|
|
32
|
+
let pending = nativeModules.get(url);
|
|
33
|
+
if (!pending) {
|
|
34
|
+
pending = importModule(url).then((module) => {
|
|
35
|
+
const exports = toHostModule(module);
|
|
36
|
+
evaluated.set(url, exports);
|
|
37
|
+
return exports;
|
|
38
|
+
});
|
|
39
|
+
nativeModules.set(url, pending);
|
|
40
|
+
}
|
|
41
|
+
return pending;
|
|
42
|
+
};
|
|
24
43
|
const localBuiltinId = (id) => {
|
|
25
44
|
if (imports[id] && !prefersLocalBuiltin(id, imports, cdnURL)) return null;
|
|
26
45
|
if (prefersLocalBuiltin(id, imports, cdnURL)) return id;
|
|
@@ -34,7 +53,7 @@ var createRemoteLoader = (imports, builtins, cdnURL) => {
|
|
|
34
53
|
}
|
|
35
54
|
};
|
|
36
55
|
const dependencyUrl = (from, specifier) => {
|
|
37
|
-
if (isRelativeSpecifier(specifier)) return new URL(specifier, from).href;
|
|
56
|
+
if (isRelativeSpecifier(specifier) || /^https?:\/\//.test(specifier)) return new URL(specifier, from).href;
|
|
38
57
|
if (imports[specifier] && !prefersLocalBuiltin(specifier, imports, cdnURL)) return imports[specifier];
|
|
39
58
|
if (HOST_VUE.has(specifier) && prefersLocalBuiltin(specifier, imports, cdnURL)) return null;
|
|
40
59
|
let cursor = specifier;
|
|
@@ -48,19 +67,29 @@ var createRemoteLoader = (imports, builtins, cdnURL) => {
|
|
|
48
67
|
cursor = cursor.slice(0, slash);
|
|
49
68
|
}
|
|
50
69
|
const target = imports[specifier] ? specifier : resolveImportTarget(specifier, imports);
|
|
51
|
-
if (!target
|
|
70
|
+
if (!target) {
|
|
71
|
+
imports[specifier] = resolveNpmImport(specifier);
|
|
72
|
+
return imports[specifier];
|
|
73
|
+
}
|
|
52
74
|
return imports[target];
|
|
53
75
|
};
|
|
54
76
|
const crawl = async (url) => {
|
|
77
|
+
if (/\/\+esm(?:[?#]|$)/.test(url)) {
|
|
78
|
+
await loadNative(url);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
55
81
|
if (crawled.has(url)) return;
|
|
56
82
|
crawled.add(url);
|
|
57
83
|
const response = await fetch(url);
|
|
58
84
|
if (!response.ok) throw new Error(`${response.status} ${url}`);
|
|
59
85
|
const text = await response.text();
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
86
|
+
await init;
|
|
87
|
+
const [specifiers] = parse(text);
|
|
88
|
+
let source = text;
|
|
89
|
+
for (const item of [...specifiers].reverse()) if (item.d >= 0) source = source.slice(0, item.ss) + "__import" + source.slice(item.ss + 6);
|
|
90
|
+
texts.set(url, source);
|
|
91
|
+
await Promise.all(specifiers.filter((item) => item.d === -1).map(async (item) => {
|
|
92
|
+
const next = dependencyUrl(url, item.n);
|
|
64
93
|
if (next) await crawl(next);
|
|
65
94
|
}));
|
|
66
95
|
};
|
|
@@ -68,7 +97,7 @@ var createRemoteLoader = (imports, builtins, cdnURL) => {
|
|
|
68
97
|
if (HOST_VUE.has(id) && prefersLocalBuiltin(id, imports, cdnURL)) return toHostModule(builtins.vue);
|
|
69
98
|
const builtinId = localBuiltinId(id);
|
|
70
99
|
if (builtinId) return toHostModule(hostModules[builtinId]);
|
|
71
|
-
if (isRelativeSpecifier(id)) return evaluate(new URL(id, from).href);
|
|
100
|
+
if (isRelativeSpecifier(id) || /^https?:\/\//.test(id)) return evaluate(new URL(id, from).href);
|
|
72
101
|
const target = imports[id] ? id : resolveImportTarget(id, imports);
|
|
73
102
|
if (!target || !imports[target]) throw new Error(`[Playground] 未注册的模块 "${id}"`);
|
|
74
103
|
const loaded = evaluate(imports[target]);
|
|
@@ -84,23 +113,40 @@ var createRemoteLoader = (imports, builtins, cdnURL) => {
|
|
|
84
113
|
if (text == null) throw new Error(`[Playground] 远程模块尚未下载: ${url}`);
|
|
85
114
|
const cjs = transform(rewriteImportMeta(text, url), {
|
|
86
115
|
transforms: ["imports"],
|
|
116
|
+
disableESTransforms: true,
|
|
87
117
|
production: true,
|
|
88
118
|
filePath: url
|
|
89
119
|
}).code;
|
|
90
120
|
const module = { exports: {} };
|
|
91
121
|
evaluated.set(url, module.exports);
|
|
92
|
-
new Function("require", "module", "exports", cjs)(requireFrom(url), module, module.exports)
|
|
122
|
+
new Function("require", "module", "exports", "__import", cjs)(requireFrom(url), module, module.exports, async (id) => {
|
|
123
|
+
const next = dependencyUrl(url, id);
|
|
124
|
+
if (next) await load(next);
|
|
125
|
+
else {
|
|
126
|
+
const builtinId = localBuiltinId(id);
|
|
127
|
+
if (builtinId && !(builtinId in hostModules)) hostModules[builtinId] = await ensureLocalBuiltin(builtinId);
|
|
128
|
+
}
|
|
129
|
+
return requireFrom(url)(id);
|
|
130
|
+
});
|
|
93
131
|
evaluated.set(url, module.exports);
|
|
94
132
|
return module.exports;
|
|
95
133
|
};
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
134
|
+
const loading = /* @__PURE__ */ new Map();
|
|
135
|
+
const load = (url) => {
|
|
136
|
+
const pending = loading.get(url);
|
|
137
|
+
if (pending) return pending;
|
|
138
|
+
const task = (async () => {
|
|
139
|
+
await crawl(url);
|
|
140
|
+
await Promise.all([...pendingBuiltins].map(async (id) => {
|
|
141
|
+
if (id === "vue" || id === "vue-router") return;
|
|
142
|
+
hostModules[id] = await ensureLocalBuiltin(id);
|
|
143
|
+
}));
|
|
144
|
+
return evaluate(url);
|
|
145
|
+
})();
|
|
146
|
+
loading.set(url, task);
|
|
147
|
+
return task;
|
|
148
|
+
};
|
|
149
|
+
return { load };
|
|
104
150
|
};
|
|
105
151
|
//#endregion
|
|
106
152
|
export { createRemoteLoader };
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
2
|
+
let sucrase = require("sucrase");
|
|
3
|
+
let _vue_compiler_sfc_dist_compiler_sfc_esm_browser_js = require("@vue/compiler-sfc/dist/compiler-sfc.esm-browser.js");
|
|
4
|
+
_vue_compiler_sfc_dist_compiler_sfc_esm_browser_js = require_rolldown_runtime.__toESM(_vue_compiler_sfc_dist_compiler_sfc_esm_browser_js);
|
|
5
|
+
//#region packages/playground/src/core/runtime/local/compile/script.ts
|
|
6
|
+
var { babelParse, walkIdentifiers, MagicString } = _vue_compiler_sfc_dist_compiler_sfc_esm_browser_js;
|
|
7
|
+
var rewriteJsxAttributes = (code) => {
|
|
8
|
+
const replacements = [];
|
|
9
|
+
for (const match of code.matchAll(/\b([\w-]+:[\w-]+)\s*=\s*\{/g)) {
|
|
10
|
+
let depth = 1;
|
|
11
|
+
let quote = "";
|
|
12
|
+
const start = match.index + match[0].length;
|
|
13
|
+
let end = start;
|
|
14
|
+
for (; end < code.length; end += 1) {
|
|
15
|
+
const character = code[end];
|
|
16
|
+
if (quote) {
|
|
17
|
+
if (character === "\\") end += 1;
|
|
18
|
+
else if (character === quote) quote = "";
|
|
19
|
+
} else if ("\"'`".includes(character)) quote = character;
|
|
20
|
+
else if (character === "{") depth += 1;
|
|
21
|
+
else if (character === "}" && --depth === 0) break;
|
|
22
|
+
}
|
|
23
|
+
replacements.push({
|
|
24
|
+
start: match.index,
|
|
25
|
+
end: end + 1,
|
|
26
|
+
text: `{...{${JSON.stringify(match[1])}: ${code.slice(start, end)}}}`
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
for (const item of replacements.reverse()) code = code.slice(0, item.start) + item.text + code.slice(item.end);
|
|
30
|
+
return code;
|
|
31
|
+
};
|
|
32
|
+
var removeImportedTypeExports = (code) => {
|
|
33
|
+
const types = /* @__PURE__ */ new Set();
|
|
34
|
+
for (const match of code.matchAll(/\bimport\s+type\s*\{([^}]+)\}\s*from\s*['"][^'"]+['"]/g)) for (const item of match[1].split(",")) types.add(item.trim().split(/\s+as\s+/).pop());
|
|
35
|
+
return code.replace(/\bexport\s*\{([^}]+)\}(?!\s*from)/g, (_statement, names) => `export {${names.split(",").filter((item) => !types.has(item.trim().split(/\s+as\s+/)[0])).join(",")}}`);
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* files 里的 `import.meta.env` 没有 Vite 注入,接到开发态占位对象上。
|
|
39
|
+
* @param code 源码文本。
|
|
40
|
+
* @param filename 当前虚拟文件名。
|
|
41
|
+
* @returns 替换 `import.meta` 之后的源码。
|
|
42
|
+
*/
|
|
43
|
+
var rewriteImportMeta = (code, filename) => {
|
|
44
|
+
if (!code.includes("process") && !code.includes("import.meta")) return code;
|
|
45
|
+
const source = new MagicString(code);
|
|
46
|
+
let hasMeta = false;
|
|
47
|
+
walkIdentifiers(babelParse(code, { sourceType: "module" }), (id, parent, parents) => {
|
|
48
|
+
if (id.name === "import" && parent?.type === "MetaProperty") {
|
|
49
|
+
source.overwrite(parent.start, parent.end, "import_meta");
|
|
50
|
+
hasMeta = true;
|
|
51
|
+
}
|
|
52
|
+
const outer = parents[parents.length - 2];
|
|
53
|
+
if (id.name === "process" && parent?.type === "MemberExpression" && parent.object === id && !parent.computed && parent.property.type === "Identifier" && parent.property.name === "env" && outer?.type === "MemberExpression" && outer.object === parent && !outer.computed && outer.property.type === "Identifier" && outer.property.name === "NODE_ENV") source.overwrite(outer.start, outer.end, JSON.stringify("development"));
|
|
54
|
+
}, true);
|
|
55
|
+
if (!hasMeta) return source.toString();
|
|
56
|
+
const meta = {
|
|
57
|
+
url: `playground://${filename}`,
|
|
58
|
+
env: {
|
|
59
|
+
MODE: "development",
|
|
60
|
+
DEV: true,
|
|
61
|
+
PROD: false,
|
|
62
|
+
SSR: false
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
return `var import_meta = ${JSON.stringify(meta)};\n${source}`;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* 将 TS / ESM 转成可被 `new Function('require','module','exports', code)` 执行的 CJS。
|
|
69
|
+
* @param code 源码文本。
|
|
70
|
+
* @param filename 当前虚拟文件名,用来判断是否按 TypeScript 转换。
|
|
71
|
+
* @param options 转换选项。
|
|
72
|
+
* @param options.typescript 是否启用 TypeScript 转换。
|
|
73
|
+
* @param options.jsx 是否转换 Vue JSX。
|
|
74
|
+
* @param options.esm 是否保留 ESM 导入导出供 iframe 使用。
|
|
75
|
+
* @returns 可执行的 CJS 文本。
|
|
76
|
+
*/
|
|
77
|
+
var transformScript = (code, filename, options = {}) => {
|
|
78
|
+
const transforms = options.esm ? [] : ["imports"];
|
|
79
|
+
const wantTs = options.typescript === true || options.typescript !== false && (filename.endsWith(".ts") || filename.endsWith(".tsx"));
|
|
80
|
+
if (wantTs) transforms.unshift("typescript");
|
|
81
|
+
if (options.jsx) transforms.unshift("jsx");
|
|
82
|
+
try {
|
|
83
|
+
const script = wantTs ? removeImportedTypeExports(code) : code;
|
|
84
|
+
const source = options.jsx ? `import { h as __docs_h, Fragment as __docs_Fragment } from 'vue';\n${rewriteJsxAttributes(script)}` : script;
|
|
85
|
+
return `${rewriteImportMeta((0, sucrase.transform)(source, {
|
|
86
|
+
transforms,
|
|
87
|
+
disableESTransforms: true,
|
|
88
|
+
production: true,
|
|
89
|
+
jsxRuntime: "classic",
|
|
90
|
+
jsxPragma: "__docs_h",
|
|
91
|
+
jsxFragmentPragma: "__docs_Fragment",
|
|
92
|
+
filePath: filename
|
|
93
|
+
}).code, filename)}\n//# sourceURL=playground://${filename}`;
|
|
94
|
+
} catch (error) {
|
|
95
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
96
|
+
throw new Error(`[Playground] 脚本转换失败 ${filename}: ${message}`, { cause: error });
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
//#endregion
|
|
100
|
+
Object.defineProperty(exports, "rewriteImportMeta", {
|
|
101
|
+
enumerable: true,
|
|
102
|
+
get: function() {
|
|
103
|
+
return rewriteImportMeta;
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
Object.defineProperty(exports, "transformScript", {
|
|
107
|
+
enumerable: true,
|
|
108
|
+
get: function() {
|
|
109
|
+
return transformScript;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { transform } from "sucrase";
|
|
2
|
+
import * as VueCompiler from "@vue/compiler-sfc/dist/compiler-sfc.esm-browser.js";
|
|
3
|
+
//#region packages/playground/src/core/runtime/local/compile/script.ts
|
|
4
|
+
var { babelParse, walkIdentifiers, MagicString } = VueCompiler;
|
|
5
|
+
var rewriteJsxAttributes = (code) => {
|
|
6
|
+
const replacements = [];
|
|
7
|
+
for (const match of code.matchAll(/\b([\w-]+:[\w-]+)\s*=\s*\{/g)) {
|
|
8
|
+
let depth = 1;
|
|
9
|
+
let quote = "";
|
|
10
|
+
const start = match.index + match[0].length;
|
|
11
|
+
let end = start;
|
|
12
|
+
for (; end < code.length; end += 1) {
|
|
13
|
+
const character = code[end];
|
|
14
|
+
if (quote) {
|
|
15
|
+
if (character === "\\") end += 1;
|
|
16
|
+
else if (character === quote) quote = "";
|
|
17
|
+
} else if ("\"'`".includes(character)) quote = character;
|
|
18
|
+
else if (character === "{") depth += 1;
|
|
19
|
+
else if (character === "}" && --depth === 0) break;
|
|
20
|
+
}
|
|
21
|
+
replacements.push({
|
|
22
|
+
start: match.index,
|
|
23
|
+
end: end + 1,
|
|
24
|
+
text: `{...{${JSON.stringify(match[1])}: ${code.slice(start, end)}}}`
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
for (const item of replacements.reverse()) code = code.slice(0, item.start) + item.text + code.slice(item.end);
|
|
28
|
+
return code;
|
|
29
|
+
};
|
|
30
|
+
var removeImportedTypeExports = (code) => {
|
|
31
|
+
const types = /* @__PURE__ */ new Set();
|
|
32
|
+
for (const match of code.matchAll(/\bimport\s+type\s*\{([^}]+)\}\s*from\s*['"][^'"]+['"]/g)) for (const item of match[1].split(",")) types.add(item.trim().split(/\s+as\s+/).pop());
|
|
33
|
+
return code.replace(/\bexport\s*\{([^}]+)\}(?!\s*from)/g, (_statement, names) => `export {${names.split(",").filter((item) => !types.has(item.trim().split(/\s+as\s+/)[0])).join(",")}}`);
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* files 里的 `import.meta.env` 没有 Vite 注入,接到开发态占位对象上。
|
|
37
|
+
* @param code 源码文本。
|
|
38
|
+
* @param filename 当前虚拟文件名。
|
|
39
|
+
* @returns 替换 `import.meta` 之后的源码。
|
|
40
|
+
*/
|
|
41
|
+
var rewriteImportMeta = (code, filename) => {
|
|
42
|
+
if (!code.includes("process") && !code.includes("import.meta")) return code;
|
|
43
|
+
const source = new MagicString(code);
|
|
44
|
+
let hasMeta = false;
|
|
45
|
+
walkIdentifiers(babelParse(code, { sourceType: "module" }), (id, parent, parents) => {
|
|
46
|
+
if (id.name === "import" && parent?.type === "MetaProperty") {
|
|
47
|
+
source.overwrite(parent.start, parent.end, "import_meta");
|
|
48
|
+
hasMeta = true;
|
|
49
|
+
}
|
|
50
|
+
const outer = parents[parents.length - 2];
|
|
51
|
+
if (id.name === "process" && parent?.type === "MemberExpression" && parent.object === id && !parent.computed && parent.property.type === "Identifier" && parent.property.name === "env" && outer?.type === "MemberExpression" && outer.object === parent && !outer.computed && outer.property.type === "Identifier" && outer.property.name === "NODE_ENV") source.overwrite(outer.start, outer.end, JSON.stringify("development"));
|
|
52
|
+
}, true);
|
|
53
|
+
if (!hasMeta) return source.toString();
|
|
54
|
+
const meta = {
|
|
55
|
+
url: `playground://${filename}`,
|
|
56
|
+
env: {
|
|
57
|
+
MODE: "development",
|
|
58
|
+
DEV: true,
|
|
59
|
+
PROD: false,
|
|
60
|
+
SSR: false
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
return `var import_meta = ${JSON.stringify(meta)};\n${source}`;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* 将 TS / ESM 转成可被 `new Function('require','module','exports', code)` 执行的 CJS。
|
|
67
|
+
* @param code 源码文本。
|
|
68
|
+
* @param filename 当前虚拟文件名,用来判断是否按 TypeScript 转换。
|
|
69
|
+
* @param options 转换选项。
|
|
70
|
+
* @param options.typescript 是否启用 TypeScript 转换。
|
|
71
|
+
* @param options.jsx 是否转换 Vue JSX。
|
|
72
|
+
* @param options.esm 是否保留 ESM 导入导出供 iframe 使用。
|
|
73
|
+
* @returns 可执行的 CJS 文本。
|
|
74
|
+
*/
|
|
75
|
+
var transformScript = (code, filename, options = {}) => {
|
|
76
|
+
const transforms = options.esm ? [] : ["imports"];
|
|
77
|
+
const wantTs = options.typescript === true || options.typescript !== false && (filename.endsWith(".ts") || filename.endsWith(".tsx"));
|
|
78
|
+
if (wantTs) transforms.unshift("typescript");
|
|
79
|
+
if (options.jsx) transforms.unshift("jsx");
|
|
80
|
+
try {
|
|
81
|
+
const script = wantTs ? removeImportedTypeExports(code) : code;
|
|
82
|
+
const source = options.jsx ? `import { h as __docs_h, Fragment as __docs_Fragment } from 'vue';\n${rewriteJsxAttributes(script)}` : script;
|
|
83
|
+
return `${rewriteImportMeta(transform(source, {
|
|
84
|
+
transforms,
|
|
85
|
+
disableESTransforms: true,
|
|
86
|
+
production: true,
|
|
87
|
+
jsxRuntime: "classic",
|
|
88
|
+
jsxPragma: "__docs_h",
|
|
89
|
+
jsxFragmentPragma: "__docs_Fragment",
|
|
90
|
+
filePath: filename
|
|
91
|
+
}).code, filename)}\n//# sourceURL=playground://${filename}`;
|
|
92
|
+
} catch (error) {
|
|
93
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
94
|
+
throw new Error(`[Playground] 脚本转换失败 ${filename}: ${message}`, { cause: error });
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
//#endregion
|
|
98
|
+
export { transformScript as n, rewriteImportMeta as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_cdn = require("./cdn-
|
|
1
|
+
const require_cdn = require("./cdn-BoYKnGD3.cjs");
|
|
2
2
|
let vue = require("vue");
|
|
3
3
|
//#region packages/playground/src/core/scss.ts
|
|
4
4
|
var SCHEME = "docs-playground";
|
|
@@ -8,7 +8,6 @@ var LANG_ATTR_RE = /\s*lang\s*=\s*(['"]?)s[ac]ss\1/i;
|
|
|
8
8
|
var SCSS_ERROR_MARK = "[playground-sass]";
|
|
9
9
|
var INJECT_START = "/* docs-playground-scss-start */";
|
|
10
10
|
var INJECT_END = "/* docs-playground-scss-end */";
|
|
11
|
-
var EMPTY_JS = "export default {}\n";
|
|
12
11
|
var boundStores = /* @__PURE__ */ new WeakSet();
|
|
13
12
|
var wrappedCompilers = /* @__PURE__ */ new WeakSet();
|
|
14
13
|
var testLoader;
|
|
@@ -164,6 +163,20 @@ var syncScssErrors = (store, scssErrors) => {
|
|
|
164
163
|
if (next.map(String).join("\0") === store.errors.map(String).join("\0")) return;
|
|
165
164
|
store.errors = next;
|
|
166
165
|
};
|
|
166
|
+
var extractScssExports = (css, filename) => {
|
|
167
|
+
const exports = {};
|
|
168
|
+
if (/\.module\.(?:scss|sass)$/.test(filename)) css = css.replace(/:export\s*\{([^}]*)\}/g, (_block, declarations) => {
|
|
169
|
+
for (const declaration of declarations.split(";")) {
|
|
170
|
+
const colon = declaration.indexOf(":");
|
|
171
|
+
if (colon >= 0) exports[declaration.slice(0, colon).trim()] = declaration.slice(colon + 1).trim();
|
|
172
|
+
}
|
|
173
|
+
return "";
|
|
174
|
+
});
|
|
175
|
+
return {
|
|
176
|
+
css,
|
|
177
|
+
exports
|
|
178
|
+
};
|
|
179
|
+
};
|
|
167
180
|
var applyStandaloneScss = (store, sass = loadedSass) => {
|
|
168
181
|
if (!sass) return [];
|
|
169
182
|
const fileMap = toPlaygroundFileMap(store.files);
|
|
@@ -172,10 +185,9 @@ var applyStandaloneScss = (store, sass = loadedSass) => {
|
|
|
172
185
|
for (const [filename, file] of Object.entries(store.files)) {
|
|
173
186
|
if (!isScssFile(filename) || !file.compiled) continue;
|
|
174
187
|
try {
|
|
175
|
-
const css = compileScssSource(file.code, filename, sass, fileMap);
|
|
188
|
+
const { css, exports } = extractScssExports(compileScssSource(file.code, filename, sass, fileMap), filename);
|
|
176
189
|
file.compiled.css = css;
|
|
177
|
-
file.compiled.js =
|
|
178
|
-
file.compiled.ssr = EMPTY_JS;
|
|
190
|
+
file.compiled.js = file.compiled.ssr = `export default ${JSON.stringify(exports)};\n`;
|
|
179
191
|
if (!isScssPartial(filename) && css.trim()) injected.push(css);
|
|
180
192
|
} catch (error) {
|
|
181
193
|
errors.push(scssFail(filename, error));
|
|
@@ -225,6 +237,12 @@ Object.defineProperty(exports, "compileScssSource", {
|
|
|
225
237
|
return compileScssSource;
|
|
226
238
|
}
|
|
227
239
|
});
|
|
240
|
+
Object.defineProperty(exports, "extractScssExports", {
|
|
241
|
+
enumerable: true,
|
|
242
|
+
get: function() {
|
|
243
|
+
return extractScssExports;
|
|
244
|
+
}
|
|
245
|
+
});
|
|
228
246
|
Object.defineProperty(exports, "whenSassReady", {
|
|
229
247
|
enumerable: true,
|
|
230
248
|
get: function() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as SASS_CDN_URL } from "./cdn-
|
|
1
|
+
import { t as SASS_CDN_URL } from "./cdn-DQoETju_.js";
|
|
2
2
|
import { watch } from "vue";
|
|
3
3
|
//#region packages/playground/src/core/scss.ts
|
|
4
4
|
var SCHEME = "docs-playground";
|
|
@@ -8,7 +8,6 @@ var LANG_ATTR_RE = /\s*lang\s*=\s*(['"]?)s[ac]ss\1/i;
|
|
|
8
8
|
var SCSS_ERROR_MARK = "[playground-sass]";
|
|
9
9
|
var INJECT_START = "/* docs-playground-scss-start */";
|
|
10
10
|
var INJECT_END = "/* docs-playground-scss-end */";
|
|
11
|
-
var EMPTY_JS = "export default {}\n";
|
|
12
11
|
var boundStores = /* @__PURE__ */ new WeakSet();
|
|
13
12
|
var wrappedCompilers = /* @__PURE__ */ new WeakSet();
|
|
14
13
|
var loadedSass;
|
|
@@ -163,6 +162,20 @@ var syncScssErrors = (store, scssErrors) => {
|
|
|
163
162
|
if (next.map(String).join("\0") === store.errors.map(String).join("\0")) return;
|
|
164
163
|
store.errors = next;
|
|
165
164
|
};
|
|
165
|
+
var extractScssExports = (css, filename) => {
|
|
166
|
+
const exports = {};
|
|
167
|
+
if (/\.module\.(?:scss|sass)$/.test(filename)) css = css.replace(/:export\s*\{([^}]*)\}/g, (_block, declarations) => {
|
|
168
|
+
for (const declaration of declarations.split(";")) {
|
|
169
|
+
const colon = declaration.indexOf(":");
|
|
170
|
+
if (colon >= 0) exports[declaration.slice(0, colon).trim()] = declaration.slice(colon + 1).trim();
|
|
171
|
+
}
|
|
172
|
+
return "";
|
|
173
|
+
});
|
|
174
|
+
return {
|
|
175
|
+
css,
|
|
176
|
+
exports
|
|
177
|
+
};
|
|
178
|
+
};
|
|
166
179
|
var applyStandaloneScss = (store, sass = loadedSass) => {
|
|
167
180
|
if (!sass) return [];
|
|
168
181
|
const fileMap = toPlaygroundFileMap(store.files);
|
|
@@ -171,10 +184,9 @@ var applyStandaloneScss = (store, sass = loadedSass) => {
|
|
|
171
184
|
for (const [filename, file] of Object.entries(store.files)) {
|
|
172
185
|
if (!isScssFile(filename) || !file.compiled) continue;
|
|
173
186
|
try {
|
|
174
|
-
const css = compileScssSource(file.code, filename, sass, fileMap);
|
|
187
|
+
const { css, exports } = extractScssExports(compileScssSource(file.code, filename, sass, fileMap), filename);
|
|
175
188
|
file.compiled.css = css;
|
|
176
|
-
file.compiled.js =
|
|
177
|
-
file.compiled.ssr = EMPTY_JS;
|
|
189
|
+
file.compiled.js = file.compiled.ssr = `export default ${JSON.stringify(exports)};\n`;
|
|
178
190
|
if (!isScssPartial(filename) && css.trim()) injected.push(css);
|
|
179
191
|
} catch (error) {
|
|
180
192
|
errors.push(scssFail(filename, error));
|
|
@@ -212,4 +224,4 @@ var bindPlaygroundScss = (store) => {
|
|
|
212
224
|
};
|
|
213
225
|
};
|
|
214
226
|
//#endregion
|
|
215
|
-
export { compileScssSource as n,
|
|
227
|
+
export { whenSassReady as i, compileScssSource as n, extractScssExports as r, bindPlaygroundScss as t };
|