@deot/docs-playground 1.1.2 → 1.1.3

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
@@ -53,6 +53,7 @@ const files = ref({
53
53
  | `id` | `string` | `''` | 标题锚点 id;未传时从 `title` 自动生成。仅挂在内联 runtime 标题上,弹窗不重复。 |
54
54
  | `expandable` | `true \| number` | `undefined` | 开启预览高度展开;未传不显示控件;`true` 展开到剩余视口;正数为目标高度(px)。 |
55
55
  | `previewScroller` | `boolean` | `false` | 在 iframe 内用 `@deot/vc` Scroller 替换原生滚动条;开启后会动态探测 `Scroller`,不存在则回退原生滚动。 |
56
+ | `local` | `boolean` | `false` | 在当前文档编译并挂载,不使用 iframe。`vue` 使用宿主同一份实例;其余 import map 仍是 URL,加载后作为模块变量。 |
56
57
  | `options` | `PlaygroundOptions` | `{}` | 传给 Vue REPL store 的实例级选项;`cdnURL` 会同时作用于预览样式和默认 import map。 |
57
58
  | `previewOptions` | `SandboxProps['previewOptions']` | `undefined` | 传给当前 iframe 的 preview 选项。 |
58
59
  | `locale` | `Language` | `en-US` | 界面语言;未传入时使用上层 Locale Provider。 |
@@ -158,6 +159,7 @@ const handleMessage = async () => {
158
159
  - Vue SFC 的 `<style lang="scss">` / `lang="sass"` 以及独立 `.scss` / `.sass` 文件会在浏览器里编译;`_partial.scss` 只作为 `@use` 依赖。
159
160
  - `options.builtinImportMap.imports` 可以覆盖默认模块 URL。Vue 运行时仍从 `play.vuejs.org` 加载。
160
161
  - 每个 Playground 实例都使用自己的 preview 配置和 iframe 消息来源校验。
162
+ - `local` 默认开启:同一份 `files` 在当前文档里编译。内置依赖默认用宿主副本;`modules` 里与默认 CDN 不同的地址会覆盖,包括 `vue` 和 `vue/server-renderer`。直接渲染不撑开预览高度,`expandable` 固定为关闭,`docs:playground.run` 不会申请临时高度;`<DocsLink>` 仍通过 `docs:navigate` 通知。`local: false` 改回 iframe Sandbox。
161
163
 
162
164
  ## 仓库内 examples
163
165
 
@@ -0,0 +1,94 @@
1
+ //#region packages/playground/src/constants.ts
2
+ var DEFAULT_ENTRY = "App.vue";
3
+ /** 预览样式和默认 import map 共用的 npm CDN 前缀。 */
4
+ var DEFAULT_CDN_URL = "https://cdn.jsdelivr.net/npm";
5
+ var NEW_SFC_CODE = `<script setup lang="ts"><\/script>\n\n<template>\n <div>\n <slot />\n <\/div>\n<\/template>\n`;
6
+ //#endregion
7
+ //#region packages/playground/src/cdn.ts
8
+ var PREVIEW_STYLE_ASSETS = [
9
+ "@deot/style/dist/index.normalize-only.css",
10
+ "@deot/vc-components/dist/index.style.css",
11
+ "@deot/style/dist/index.css"
12
+ ];
13
+ var BUILTIN_IMPORT_ASSETS = {
14
+ "@deot/vc": "@deot/vc/dist/index.js",
15
+ "@deot/vc-shared": "@deot/vc-shared/dist/index.js",
16
+ "@deot/vc-hooks": "@deot/vc-hooks/dist/index.js",
17
+ "@deot/vc-locale": "@deot/vc-locale/dist/index.js",
18
+ "@deot/vc-components": "@deot/vc-components/dist/index.js",
19
+ "@deot/helper-resize": "@deot/helper-resize/dist/index.js",
20
+ "@deot/helper-utils": "@deot/helper-utils/dist/index.js",
21
+ "@deot/helper-cache": "@deot/helper-cache/dist/index.js",
22
+ "@deot/helper-fp": "@deot/helper-fp/dist/index.js",
23
+ "@deot/helper-dom": "@deot/helper-dom/dist/index.js",
24
+ "@deot/helper-wheel": "@deot/helper-wheel/dist/index.js",
25
+ "@deot/helper-validator": "@deot/helper-validator/dist/index.js",
26
+ "@deot/helper-load": "@deot/helper-load/dist/index.js",
27
+ "@deot/helper-scheduler": "@deot/helper-scheduler/dist/index.js",
28
+ "@deot/helper-emitter": "@deot/helper-emitter/dist/index.js",
29
+ "@deot/helper-is": "@deot/helper-is/dist/index.js",
30
+ "@deot/helper-device": "@deot/helper-device/dist/index.js",
31
+ "@deot/helper-route": "@deot/helper-route/dist/index.js",
32
+ "@deot/helper-unicode": "@deot/helper-unicode/dist/index.js",
33
+ "@deot/helper": "@deot/helper/dist/index.js",
34
+ "normalize-wheel": "normalize-wheel-es/dist/index.mjs",
35
+ "photoswipe": "photoswipe/dist/photoswipe.esm.js",
36
+ "photoswipe/lightbox": "photoswipe/dist/photoswipe-lightbox.esm.js",
37
+ "vue": "vue/dist/vue.runtime.esm-browser.js",
38
+ "vue/server-renderer": "vue/dist/server-renderer.esm-browser.js"
39
+ };
40
+ var normalizeCdnURL = (cdnURL = DEFAULT_CDN_URL) => {
41
+ return cdnURL.trim().replace(/\/+$/u, "") || "https://cdn.jsdelivr.net/npm";
42
+ };
43
+ var cdnJoin = (origin, asset) => `${origin}/${asset.replace(/^\/+/u, "")}`;
44
+ var jsdelivrEsmURL = (asset) => cdnJoin(DEFAULT_CDN_URL, asset);
45
+ var SASS_CDN_URL = jsdelivrEsmURL("sass/+esm");
46
+ var cdnAsset = (cdnURL, asset) => cdnJoin(normalizeCdnURL(cdnURL), asset);
47
+ var createBuiltinImports = (cdnURL = DEFAULT_CDN_URL) => ({
48
+ ...Object.fromEntries(Object.entries(BUILTIN_IMPORT_ASSETS).map(([specifier, asset]) => [specifier, cdnAsset(cdnURL, asset)])),
49
+ "lodash-es": jsdelivrEsmURL("lodash-es/+esm")
50
+ });
51
+ var createBuiltinStyles = (cdnURL = DEFAULT_CDN_URL) => Object.fromEntries(PREVIEW_STYLE_ASSETS.map((asset) => [asset, cdnAsset(cdnURL, asset)]));
52
+ //#endregion
53
+ Object.defineProperty(exports, "DEFAULT_CDN_URL", {
54
+ enumerable: true,
55
+ get: function() {
56
+ return DEFAULT_CDN_URL;
57
+ }
58
+ });
59
+ Object.defineProperty(exports, "DEFAULT_ENTRY", {
60
+ enumerable: true,
61
+ get: function() {
62
+ return DEFAULT_ENTRY;
63
+ }
64
+ });
65
+ Object.defineProperty(exports, "NEW_SFC_CODE", {
66
+ enumerable: true,
67
+ get: function() {
68
+ return NEW_SFC_CODE;
69
+ }
70
+ });
71
+ Object.defineProperty(exports, "SASS_CDN_URL", {
72
+ enumerable: true,
73
+ get: function() {
74
+ return SASS_CDN_URL;
75
+ }
76
+ });
77
+ Object.defineProperty(exports, "createBuiltinImports", {
78
+ enumerable: true,
79
+ get: function() {
80
+ return createBuiltinImports;
81
+ }
82
+ });
83
+ Object.defineProperty(exports, "createBuiltinStyles", {
84
+ enumerable: true,
85
+ get: function() {
86
+ return createBuiltinStyles;
87
+ }
88
+ });
89
+ Object.defineProperty(exports, "normalizeCdnURL", {
90
+ enumerable: true,
91
+ get: function() {
92
+ return normalizeCdnURL;
93
+ }
94
+ });
@@ -0,0 +1,53 @@
1
+ //#region packages/playground/src/constants.ts
2
+ var DEFAULT_ENTRY = "App.vue";
3
+ /** 预览样式和默认 import map 共用的 npm CDN 前缀。 */
4
+ var DEFAULT_CDN_URL = "https://cdn.jsdelivr.net/npm";
5
+ var NEW_SFC_CODE = `<script setup lang="ts"><\/script>\n\n<template>\n <div>\n <slot />\n <\/div>\n<\/template>\n`;
6
+ //#endregion
7
+ //#region packages/playground/src/cdn.ts
8
+ var PREVIEW_STYLE_ASSETS = [
9
+ "@deot/style/dist/index.normalize-only.css",
10
+ "@deot/vc-components/dist/index.style.css",
11
+ "@deot/style/dist/index.css"
12
+ ];
13
+ var BUILTIN_IMPORT_ASSETS = {
14
+ "@deot/vc": "@deot/vc/dist/index.js",
15
+ "@deot/vc-shared": "@deot/vc-shared/dist/index.js",
16
+ "@deot/vc-hooks": "@deot/vc-hooks/dist/index.js",
17
+ "@deot/vc-locale": "@deot/vc-locale/dist/index.js",
18
+ "@deot/vc-components": "@deot/vc-components/dist/index.js",
19
+ "@deot/helper-resize": "@deot/helper-resize/dist/index.js",
20
+ "@deot/helper-utils": "@deot/helper-utils/dist/index.js",
21
+ "@deot/helper-cache": "@deot/helper-cache/dist/index.js",
22
+ "@deot/helper-fp": "@deot/helper-fp/dist/index.js",
23
+ "@deot/helper-dom": "@deot/helper-dom/dist/index.js",
24
+ "@deot/helper-wheel": "@deot/helper-wheel/dist/index.js",
25
+ "@deot/helper-validator": "@deot/helper-validator/dist/index.js",
26
+ "@deot/helper-load": "@deot/helper-load/dist/index.js",
27
+ "@deot/helper-scheduler": "@deot/helper-scheduler/dist/index.js",
28
+ "@deot/helper-emitter": "@deot/helper-emitter/dist/index.js",
29
+ "@deot/helper-is": "@deot/helper-is/dist/index.js",
30
+ "@deot/helper-device": "@deot/helper-device/dist/index.js",
31
+ "@deot/helper-route": "@deot/helper-route/dist/index.js",
32
+ "@deot/helper-unicode": "@deot/helper-unicode/dist/index.js",
33
+ "@deot/helper": "@deot/helper/dist/index.js",
34
+ "normalize-wheel": "normalize-wheel-es/dist/index.mjs",
35
+ "photoswipe": "photoswipe/dist/photoswipe.esm.js",
36
+ "photoswipe/lightbox": "photoswipe/dist/photoswipe-lightbox.esm.js",
37
+ "vue": "vue/dist/vue.runtime.esm-browser.js",
38
+ "vue/server-renderer": "vue/dist/server-renderer.esm-browser.js"
39
+ };
40
+ var normalizeCdnURL = (cdnURL = DEFAULT_CDN_URL) => {
41
+ return cdnURL.trim().replace(/\/+$/u, "") || "https://cdn.jsdelivr.net/npm";
42
+ };
43
+ var cdnJoin = (origin, asset) => `${origin}/${asset.replace(/^\/+/u, "")}`;
44
+ var jsdelivrEsmURL = (asset) => cdnJoin(DEFAULT_CDN_URL, asset);
45
+ var SASS_CDN_URL = jsdelivrEsmURL("sass/+esm");
46
+ var cdnAsset = (cdnURL, asset) => cdnJoin(normalizeCdnURL(cdnURL), asset);
47
+ var createBuiltinImports = (cdnURL = DEFAULT_CDN_URL) => ({
48
+ ...Object.fromEntries(Object.entries(BUILTIN_IMPORT_ASSETS).map(([specifier, asset]) => [specifier, cdnAsset(cdnURL, asset)])),
49
+ "lodash-es": jsdelivrEsmURL("lodash-es/+esm")
50
+ });
51
+ var createBuiltinStyles = (cdnURL = DEFAULT_CDN_URL) => Object.fromEntries(PREVIEW_STYLE_ASSETS.map((asset) => [asset, cdnAsset(cdnURL, asset)]));
52
+ //#endregion
53
+ export { DEFAULT_CDN_URL as a, normalizeCdnURL as i, createBuiltinImports as n, DEFAULT_ENTRY as o, createBuiltinStyles as r, NEW_SFC_CODE as s, SASS_CDN_URL as t };
@@ -0,0 +1,333 @@
1
+ import { n as compileScssSource } from "./scss-Co2it4vB.js";
2
+ import { collectReachableFilenames, createFileIndex, getExtension, normalizeVirtualPath, resolveEntry } from "./files-C5UMzYxA.js";
3
+ import { n as transformScript } from "./script-xKUjE8pf.js";
4
+ import { n as collectCss } from "./local-sandbox-B8IJ5jWb.js";
5
+ import { compileString } from "sass";
6
+ //#region packages/playground/src/core/runtime/local/compile/scss.ts
7
+ /**
8
+ * 直接渲染使用已安装的 sass,importer 与 iframe 预览共用,不注入额外 BEM。
9
+ */
10
+ var compiler = { compileString(source, options) {
11
+ return { css: compileString(source, options).css };
12
+ } };
13
+ var toScssFiles = (files) => {
14
+ const map = {};
15
+ Object.entries(files || {}).forEach(([filename, code]) => {
16
+ const normalized = filename.replace(/\\/gu, "/");
17
+ map[normalized] = code;
18
+ map[normalized.replace(/^\/+/u, "")] = code;
19
+ });
20
+ return map;
21
+ };
22
+ var compileLocalScss = (source, filename, files, lang) => {
23
+ try {
24
+ return compileScssSource(source, filename.replace(/^\/+/u, ""), compiler, toScssFiles(files), lang);
25
+ } catch (error) {
26
+ /* istanbul ignore next -- Sass 失败时 message 总是字符串 */
27
+ const message = error instanceof Error ? error.message : String(error);
28
+ throw new Error(`[Playground] SCSS 编译失败 ${filename}: ${message}`, { cause: error });
29
+ }
30
+ };
31
+ //#endregion
32
+ //#region packages/playground/src/core/runtime/local/compile/sfc.ts
33
+ var compilerPromise = null;
34
+ /**
35
+ * 只加载浏览器构建,避免 `@vue/compiler-sfc` 的 Node 主入口碰文件系统。
36
+ * @returns 浏览器版 compiler-sfc。
37
+ */
38
+ var loadCompiler = () => {
39
+ compilerPromise ??= import("@vue/compiler-sfc/dist/compiler-sfc.esm-browser.js").then((mod) => {
40
+ return mod.default || mod;
41
+ });
42
+ return compilerPromise;
43
+ };
44
+ var hashId = (filename) => {
45
+ let hash = 0;
46
+ for (let i = 0; i < filename.length; i += 1) {
47
+ hash = (hash << 5) - hash + filename.charCodeAt(i);
48
+ hash |= 0;
49
+ }
50
+ return Math.abs(hash).toString(36).slice(0, 8);
51
+ };
52
+ var messageOf$1 = (error) => error instanceof Error ? error.message : String(error);
53
+ var isScssLang = (lang) => lang === "scss" || lang === "sass";
54
+ var isSupportedStyleLang = (lang) => !lang || lang === "css" || isScssLang(lang);
55
+ var compileSfc = async (code, filename, files = {}) => {
56
+ const compiler = await loadCompiler();
57
+ const errors = [];
58
+ const id = hashId(filename);
59
+ const { descriptor, errors: parseErrors } = compiler.parse(code, {
60
+ filename,
61
+ sourceMap: false
62
+ });
63
+ parseErrors.forEach((error) => {
64
+ errors.push(messageOf$1(error));
65
+ });
66
+ if (errors.length) return {
67
+ js: "export default {}",
68
+ css: "",
69
+ errors
70
+ };
71
+ const srcBlock = [
72
+ descriptor.script,
73
+ descriptor.scriptSetup,
74
+ descriptor.template,
75
+ ...descriptor.styles
76
+ ].find((block) => block?.src);
77
+ if (srcBlock) {
78
+ errors.push(`[Playground] 不支持 <${srcBlock.type} src>,请把源码放进 files。文件: ${filename}`);
79
+ return {
80
+ js: "export default {}",
81
+ css: "",
82
+ errors
83
+ };
84
+ }
85
+ const hasScript = !!(descriptor.script || descriptor.scriptSetup);
86
+ const isTS = !!(descriptor.script?.lang?.startsWith("ts") || descriptor.scriptSetup?.lang?.startsWith("ts"));
87
+ let clientCode;
88
+ let bindings;
89
+ if (hasScript) try {
90
+ const scriptResult = compiler.compileScript(descriptor, {
91
+ id,
92
+ inlineTemplate: true,
93
+ genDefaultAs: "__sfc__",
94
+ templateOptions: {
95
+ filename,
96
+ id,
97
+ scoped: descriptor.styles.some((style) => style.scoped)
98
+ }
99
+ });
100
+ clientCode = scriptResult.content;
101
+ bindings = scriptResult.bindings;
102
+ } catch (error) {
103
+ errors.push(`[Playground] compileScript ${filename}: ${messageOf$1(error)}`);
104
+ return {
105
+ js: "export default {}",
106
+ css: "",
107
+ errors
108
+ };
109
+ }
110
+ else clientCode = "const __sfc__ = {};";
111
+ const templateInlined = !!(descriptor.scriptSetup && hasScript);
112
+ if (descriptor.template && !templateInlined) try {
113
+ const templateResult = compiler.compileTemplate({
114
+ id,
115
+ filename,
116
+ source: descriptor.template.content,
117
+ scoped: descriptor.styles.some((style) => style.scoped),
118
+ compilerOptions: {
119
+ bindingMetadata: bindings,
120
+ isTS
121
+ }
122
+ });
123
+ if (templateResult.errors?.length) templateResult.errors.forEach((error) => {
124
+ errors.push(messageOf$1(error));
125
+ });
126
+ else {
127
+ clientCode += `\n${templateResult.code}`;
128
+ clientCode += "\n__sfc__.render = typeof render === \"function\" ? render : exports.render;";
129
+ }
130
+ } catch (error) {
131
+ errors.push(`[Playground] compileTemplate ${filename}: ${messageOf$1(error)}`);
132
+ }
133
+ if (descriptor.styles.some((style) => style.scoped)) clientCode += `\n__sfc__.__scopeId = ${JSON.stringify(`data-v-${id}`)};`;
134
+ clientCode += `\n__sfc__.__file = ${JSON.stringify(filename)};`;
135
+ clientCode += "\nexport default __sfc__;";
136
+ let css = "";
137
+ for (const style of descriptor.styles) {
138
+ if (!isSupportedStyleLang(style.lang)) {
139
+ errors.push(`[Playground] <style lang="${style.lang}"> 暂不支持(仅 CSS / SCSS / Sass)。文件: ${filename}`);
140
+ continue;
141
+ }
142
+ let source = style.content;
143
+ if (isScssLang(style.lang)) try {
144
+ source = compileLocalScss(source, filename, files, style.lang);
145
+ } catch (error) {
146
+ errors.push(messageOf$1(error));
147
+ continue;
148
+ }
149
+ try {
150
+ const styleResult = await compiler.compileStyleAsync({
151
+ id: style.scoped ? `data-v-${id}` : id,
152
+ filename,
153
+ source,
154
+ scoped: !!style.scoped
155
+ });
156
+ if (styleResult.errors?.length) styleResult.errors.forEach((error) => {
157
+ errors.push(messageOf$1(error));
158
+ });
159
+ else css += `${styleResult.code}\n`;
160
+ } catch (error) {
161
+ /* istanbul ignore next -- 样式编译失败会走 errors 数组,这里只兜底抛错 */
162
+ errors.push(`[Playground] compileStyle ${filename}: ${messageOf$1(error)}`);
163
+ }
164
+ }
165
+ return {
166
+ js: clientCode,
167
+ css,
168
+ errors
169
+ };
170
+ };
171
+ //#endregion
172
+ //#region packages/playground/src/core/runtime/local/compile/index.ts
173
+ var JSON_IDENT = /^[$A-Z_][0-9A-Z_$]*$/iu;
174
+ var messageOf = (error) => error instanceof Error ? error.message : String(error);
175
+ /**
176
+ * Vite 语义:default 是整份对象,合法标识符键再挂成具名导出。
177
+ * @param parsed JSON.parse 的结果。
178
+ * @param filename 当前虚拟文件名,写入 sourceURL。
179
+ * @returns 可执行的 CJS 文本。
180
+ */
181
+ var transformJson = (parsed, filename) => {
182
+ const lines = [`exports.default = ${JSON.stringify(parsed)};`];
183
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) Object.keys(parsed).forEach((key) => {
184
+ if (!JSON_IDENT.test(key) || key === "__esModule" || key === "default") return;
185
+ lines.push(`exports[${JSON.stringify(key)}] = exports.default[${JSON.stringify(key)}];`);
186
+ });
187
+ lines.push(`//# sourceURL=playground://${filename}`);
188
+ return lines.join("\n");
189
+ };
190
+ var compileOne = async (filename, code, files) => {
191
+ const ext = getExtension(filename);
192
+ const errors = [];
193
+ if (ext === ".vue") {
194
+ if (/lang\s*=\s*["']jsx["']/iu.test(code) || /lang\s*=\s*["']tsx["']/iu.test(code)) {
195
+ errors.push(`[Playground] JSX/TSX 暂不支持: ${filename}`);
196
+ return {
197
+ filename,
198
+ js: "exports.default = {}",
199
+ css: "",
200
+ errors
201
+ };
202
+ }
203
+ const result = await compileSfc(code, filename, files);
204
+ errors.push(...result.errors);
205
+ return {
206
+ filename,
207
+ js: transformScript(result.js, filename, { typescript: true }),
208
+ css: result.css,
209
+ errors
210
+ };
211
+ }
212
+ if (ext === ".css") return {
213
+ filename,
214
+ js: `exports.default = {};\n//# sourceURL=playground://${filename}`,
215
+ css: code,
216
+ errors
217
+ };
218
+ if (ext === ".scss" || ext === ".sass") try {
219
+ const css = compileLocalScss(code, filename, files);
220
+ return {
221
+ filename,
222
+ js: `exports.default = {};\n//# sourceURL=playground://${filename}`,
223
+ css,
224
+ errors
225
+ };
226
+ } catch (error) {
227
+ errors.push(messageOf(error));
228
+ return {
229
+ filename,
230
+ js: "exports.default = {};",
231
+ css: "",
232
+ errors
233
+ };
234
+ }
235
+ if (ext === ".json") try {
236
+ return {
237
+ filename,
238
+ js: transformJson(JSON.parse(code), filename),
239
+ css: "",
240
+ errors
241
+ };
242
+ } catch (error) {
243
+ errors.push(`[Playground] JSON 解析失败 ${filename}: ${messageOf(error)}`);
244
+ return {
245
+ filename,
246
+ js: "exports.default = {};",
247
+ css: "",
248
+ errors
249
+ };
250
+ }
251
+ if (ext === ".js" || ext === ".ts" || ext === ".jsx" || ext === ".tsx") {
252
+ if (ext === ".jsx" || ext === ".tsx") {
253
+ errors.push(`[Playground] JSX/TSX 暂不支持: ${filename}`);
254
+ return {
255
+ filename,
256
+ js: "exports.default = {};",
257
+ css: "",
258
+ errors
259
+ };
260
+ }
261
+ try {
262
+ return {
263
+ filename,
264
+ js: transformScript(code, filename, { typescript: ext === ".ts" }),
265
+ css: "",
266
+ errors
267
+ };
268
+ } catch (error) {
269
+ errors.push(messageOf(error));
270
+ return {
271
+ filename,
272
+ js: "exports.default = {};",
273
+ css: "",
274
+ errors
275
+ };
276
+ }
277
+ }
278
+ errors.push(`[Playground] 不支持的文件类型: ${filename}`);
279
+ return {
280
+ filename,
281
+ js: "exports.default = {};",
282
+ css: "",
283
+ errors
284
+ };
285
+ };
286
+ /**
287
+ * 浏览器内编译整份 files。入口和相对路径与 Playground 的 files 键一致。
288
+ * @param files 当前 Playground 文件表。
289
+ * @param entryOrOptions 入口文件名,或带入口的编译选项。
290
+ * @returns 编译出的模块、样式和错误。
291
+ */
292
+ var compilePlayground = async (files, entryOrOptions) => {
293
+ const options = typeof entryOrOptions === "string" ? { entry: entryOrOptions } : entryOrOptions || {};
294
+ const errors = [];
295
+ let entry;
296
+ try {
297
+ entry = resolveEntry(files, options.entry);
298
+ } catch (error) {
299
+ return {
300
+ entry: "",
301
+ modules: {},
302
+ css: [],
303
+ errors: [messageOf(error)]
304
+ };
305
+ }
306
+ const fileIndex = createFileIndex(files);
307
+ const reachable = collectReachableFilenames(files, entry);
308
+ const modules = {};
309
+ const cssChunks = [];
310
+ for (const filename of reachable) {
311
+ const code = fileIndex.get(filename);
312
+ if (typeof code !== "string") continue;
313
+ const compiled = await compileOne(filename, code, files);
314
+ errors.push(...compiled.errors);
315
+ modules[filename] = {
316
+ filename,
317
+ js: compiled.js,
318
+ css: compiled.css
319
+ };
320
+ cssChunks.push(...collectCss([compiled.css]));
321
+ }
322
+ const normalizedEntry = normalizeVirtualPath(entry);
323
+ /* istanbul ignore if -- 可达编译总会留下入口模块 */
324
+ if (!modules[normalizedEntry]) errors.push(`[Playground] 入口编译结果缺失: ${normalizedEntry}`);
325
+ return {
326
+ entry: normalizedEntry,
327
+ modules,
328
+ css: cssChunks,
329
+ errors
330
+ };
331
+ };
332
+ //#endregion
333
+ export { compilePlayground };