@kurot/cli 1.0.2
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/CHANGELOG.md +128 -0
- package/README.md +296 -0
- package/dist/commands/build.d.ts +3 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +59 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/clean.d.ts +3 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +15 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/create.d.ts +3 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +24 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/dev.d.ts +3 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +25 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/core/config.d.ts +94 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +70 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/dev-server.d.ts +21 -0
- package/dist/core/dev-server.d.ts.map +1 -0
- package/dist/core/dev-server.js +113 -0
- package/dist/core/dev-server.js.map +1 -0
- package/dist/core/errors.d.ts +16 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +23 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/exml/ast.d.ts +243 -0
- package/dist/core/exml/ast.d.ts.map +1 -0
- package/dist/core/exml/ast.js +8 -0
- package/dist/core/exml/ast.js.map +1 -0
- package/dist/core/exml/codegen.d.ts +23 -0
- package/dist/core/exml/codegen.d.ts.map +1 -0
- package/dist/core/exml/codegen.js +422 -0
- package/dist/core/exml/codegen.js.map +1 -0
- package/dist/core/exml/exml-parser.d.ts +27 -0
- package/dist/core/exml/exml-parser.d.ts.map +1 -0
- package/dist/core/exml/exml-parser.js +466 -0
- package/dist/core/exml/exml-parser.js.map +1 -0
- package/dist/core/exml/index.d.ts +52 -0
- package/dist/core/exml/index.d.ts.map +1 -0
- package/dist/core/exml/index.js +51 -0
- package/dist/core/exml/index.js.map +1 -0
- package/dist/core/exml/registry.d.ts +92 -0
- package/dist/core/exml/registry.d.ts.map +1 -0
- package/dist/core/exml/registry.js +177 -0
- package/dist/core/exml/registry.js.map +1 -0
- package/dist/core/exml/xml-parser.d.ts +61 -0
- package/dist/core/exml/xml-parser.d.ts.map +1 -0
- package/dist/core/exml/xml-parser.js +201 -0
- package/dist/core/exml/xml-parser.js.map +1 -0
- package/dist/core/namespace-external-plugin.d.ts +45 -0
- package/dist/core/namespace-external-plugin.d.ts.map +1 -0
- package/dist/core/namespace-external-plugin.js +66 -0
- package/dist/core/namespace-external-plugin.js.map +1 -0
- package/dist/core/pipeline.d.ts +75 -0
- package/dist/core/pipeline.d.ts.map +1 -0
- package/dist/core/pipeline.js +30 -0
- package/dist/core/pipeline.js.map +1 -0
- package/dist/core/plugins/clean-output.d.ts +3 -0
- package/dist/core/plugins/clean-output.d.ts.map +1 -0
- package/dist/core/plugins/clean-output.js +11 -0
- package/dist/core/plugins/clean-output.js.map +1 -0
- package/dist/core/plugins/compile-custom-namespaces.d.ts +19 -0
- package/dist/core/plugins/compile-custom-namespaces.d.ts.map +1 -0
- package/dist/core/plugins/compile-custom-namespaces.js +104 -0
- package/dist/core/plugins/compile-custom-namespaces.js.map +1 -0
- package/dist/core/plugins/compile-engine.d.ts +19 -0
- package/dist/core/plugins/compile-engine.d.ts.map +1 -0
- package/dist/core/plugins/compile-engine.js +75 -0
- package/dist/core/plugins/compile-engine.js.map +1 -0
- package/dist/core/plugins/compile-exml.d.ts +14 -0
- package/dist/core/plugins/compile-exml.d.ts.map +1 -0
- package/dist/core/plugins/compile-exml.js +223 -0
- package/dist/core/plugins/compile-exml.js.map +1 -0
- package/dist/core/plugins/compile-source.d.ts +14 -0
- package/dist/core/plugins/compile-source.d.ts.map +1 -0
- package/dist/core/plugins/compile-source.js +132 -0
- package/dist/core/plugins/compile-source.js.map +1 -0
- package/dist/core/plugins/copy-assets.d.ts +12 -0
- package/dist/core/plugins/copy-assets.d.ts.map +1 -0
- package/dist/core/plugins/copy-assets.js +33 -0
- package/dist/core/plugins/copy-assets.js.map +1 -0
- package/dist/core/plugins/generate-html.d.ts +16 -0
- package/dist/core/plugins/generate-html.d.ts.map +1 -0
- package/dist/core/plugins/generate-html.js +137 -0
- package/dist/core/plugins/generate-html.js.map +1 -0
- package/dist/core/plugins/index.d.ts +21 -0
- package/dist/core/plugins/index.d.ts.map +1 -0
- package/dist/core/plugins/index.js +39 -0
- package/dist/core/plugins/index.js.map +1 -0
- package/dist/core/plugins/manifest.d.ts +14 -0
- package/dist/core/plugins/manifest.d.ts.map +1 -0
- package/dist/core/plugins/manifest.js +28 -0
- package/dist/core/plugins/manifest.js.map +1 -0
- package/dist/core/project.d.ts +95 -0
- package/dist/core/project.d.ts.map +1 -0
- package/dist/core/project.js +79 -0
- package/dist/core/project.js.map +1 -0
- package/dist/core/template.d.ts +13 -0
- package/dist/core/template.d.ts.map +1 -0
- package/dist/core/template.js +79 -0
- package/dist/core/template.js.map +1 -0
- package/dist/define.d.ts +2 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +2 -0
- package/dist/define.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/fs.d.ts +5 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +30 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +18 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +45 -0
- package/templates/empty/kurot.config.ts +13 -0
- package/templates/empty/package.json +17 -0
- package/templates/empty/pnpm-workspace.yaml +3 -0
- package/templates/empty/src/Main.ts +32 -0
- package/templates/empty/template/web/index.html +38 -0
- package/templates/empty/tsconfig.json +10 -0
- package/templates/game/kurot.config.ts +16 -0
- package/templates/game/package.json +19 -0
- package/templates/game/pnpm-workspace.yaml +3 -0
- package/templates/game/resource/assets/eui.json +24 -0
- package/templates/game/resource/assets/eui.png +0 -0
- package/templates/game/resource/default.res.json +15 -0
- package/templates/game/resource/default.thm.json +19 -0
- package/templates/game/resource/skins/ButtonSkin.exml +16 -0
- package/templates/game/resource/skins/CheckBoxSkin.exml +18 -0
- package/templates/game/resource/skins/ComboBoxSkin.exml +31 -0
- package/templates/game/resource/skins/GroupSkin.exml +4 -0
- package/templates/game/resource/skins/HScrollBarSkin.exml +6 -0
- package/templates/game/resource/skins/HSliderSkin.exml +7 -0
- package/templates/game/resource/skins/ImageSkin.exml +4 -0
- package/templates/game/resource/skins/ItemRendererSkin.exml +15 -0
- package/templates/game/resource/skins/LabelSkin.exml +7 -0
- package/templates/game/resource/skins/ListSkin.exml +11 -0
- package/templates/game/resource/skins/PanelSkin.exml +15 -0
- package/templates/game/resource/skins/ProgressBarSkin.exml +11 -0
- package/templates/game/resource/skins/RadioButtonSkin.exml +18 -0
- package/templates/game/resource/skins/ScrollerSkin.exml +8 -0
- package/templates/game/resource/skins/TabBarSkin.exml +6 -0
- package/templates/game/resource/skins/TextInputSkin.exml +22 -0
- package/templates/game/resource/skins/ToggleButtonSkin.exml +21 -0
- package/templates/game/resource/skins/ToggleSwitchSkin.exml +15 -0
- package/templates/game/resource/skins/VScrollBarSkin.exml +6 -0
- package/templates/game/resource/skins/VSliderSkin.exml +7 -0
- package/templates/game/resource/skins/ViewStackSkin.exml +4 -0
- package/templates/game/src/LoadingUI.ts +27 -0
- package/templates/game/src/Main.ts +165 -0
- package/templates/game/template/web/index.html +109 -0
- package/templates/game/template/web/logo.png +0 -0
- package/templates/game/tsconfig.json +10 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import * as esbuild from 'esbuild';
|
|
2
|
+
import * as os from 'node:os';
|
|
3
|
+
import * as fs from 'node:fs/promises';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import { ensureDir, writeFile } from '../../utils/fs.js';
|
|
6
|
+
import { logger } from '../../utils/logger.js';
|
|
7
|
+
import { parseToIR, generateCode } from '../exml/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Compiles `.exml` skin files into a single ESM module and rewrites the theme.
|
|
10
|
+
*
|
|
11
|
+
* Each skin becomes a real JS factory (`import { Skin, ... } from '@kurot/ui'`)
|
|
12
|
+
* bundled into `js/default.thm.js` (dev) or `js/default.thm.min_<hash>.js`
|
|
13
|
+
* (release). The module registers each factory on `globalThis` under its class
|
|
14
|
+
* name. The output `default.thm.json` keeps only the `skins` mapping plus a
|
|
15
|
+
* `skinsJs` pointer to that module, which the runtime `Theme` imports.
|
|
16
|
+
*
|
|
17
|
+
* The input theme follows Egret conventions; no `.exml` is shipped.
|
|
18
|
+
*/
|
|
19
|
+
export function compileExml() {
|
|
20
|
+
return {
|
|
21
|
+
name: 'compile EXML',
|
|
22
|
+
async apply(ctx) {
|
|
23
|
+
const { project } = ctx;
|
|
24
|
+
if (!project.config.exml || !project.themeFile)
|
|
25
|
+
return;
|
|
26
|
+
const theme = await loadTheme(project);
|
|
27
|
+
const files = await resolveExmlFiles(project, theme);
|
|
28
|
+
if (files.length === 0) {
|
|
29
|
+
logger.step('no .exml files found, skipping');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const skins = files.map(file => ({ file, className: extractClassName(file) }));
|
|
33
|
+
const skinsFile = await buildSkinsModule(ctx, skins);
|
|
34
|
+
ctx.outputs.skinsScript = `js/${skinsFile}`;
|
|
35
|
+
const relThemePath = project.config.exml.themeFile;
|
|
36
|
+
const outTheme = { ...theme };
|
|
37
|
+
delete outTheme.exmls;
|
|
38
|
+
delete outTheme.autoGenerateExmlsList;
|
|
39
|
+
outTheme.skins = remapSkins(project, theme.skins ?? {}, skins);
|
|
40
|
+
outTheme.skinsJs = toPosix(path.relative(path.dirname(relThemePath), `js/${skinsFile}`));
|
|
41
|
+
await writeFile(path.join(project.outputDir, relThemePath), JSON.stringify(outTheme, null, '\t'));
|
|
42
|
+
logger.step(`compiled ${skins.length} skin(s) → ${ctx.outputs.skinsScript}`);
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Generates one ESM module per skin in a temp dir, plus an index that imports
|
|
48
|
+
* and registers them, then bundles to `js/default.thm[.min_<hash>].js`.
|
|
49
|
+
*
|
|
50
|
+
* Engine packages and custom namespaces stay external (resolved by the page
|
|
51
|
+
* import map — see `compile-engine.ts` and `compile-custom-namespaces.ts`).
|
|
52
|
+
*/
|
|
53
|
+
async function buildSkinsModule(ctx, skins) {
|
|
54
|
+
const { project } = ctx;
|
|
55
|
+
const jsDir = path.join(project.outputDir, 'js');
|
|
56
|
+
await ensureDir(jsDir);
|
|
57
|
+
const customNamespaces = project.customNamespaces.map(ns => ({ prefix: ns.prefix, specifier: ns.specifier }));
|
|
58
|
+
const isRelease = project.mode === 'release';
|
|
59
|
+
const stubDir = await fs.mkdtemp(path.join(os.tmpdir(), 'kurot-skins-'));
|
|
60
|
+
try {
|
|
61
|
+
const indexLines = [];
|
|
62
|
+
await Promise.all(skins.map(async (skin, i) => {
|
|
63
|
+
const code = generateSkinModule(skin, customNamespaces, isRelease);
|
|
64
|
+
await fs.writeFile(path.join(stubDir, `skin${i}.ts`), code);
|
|
65
|
+
const funcName = factoryName(skin.className);
|
|
66
|
+
indexLines.push(`import { ${funcName} as s${i} } from './skin${i}.js';\n` +
|
|
67
|
+
`globalThis[${JSON.stringify(skin.className)}] = s${i};`);
|
|
68
|
+
}));
|
|
69
|
+
await fs.writeFile(path.join(stubDir, 'index.ts'), indexLines.join('\n\n') + '\n');
|
|
70
|
+
const engineExternal = project.enginePackages.length > 0 ? project.enginePackages : ['@kurot/ui', '@kurot/core'];
|
|
71
|
+
const result = await esbuild.build({
|
|
72
|
+
entryPoints: [path.join(stubDir, 'index.ts')],
|
|
73
|
+
outdir: jsDir,
|
|
74
|
+
entryNames: isRelease ? 'default.thm.min_[hash]' : 'default.thm',
|
|
75
|
+
bundle: true,
|
|
76
|
+
format: 'esm',
|
|
77
|
+
platform: 'browser',
|
|
78
|
+
target: 'es2022',
|
|
79
|
+
minify: isRelease,
|
|
80
|
+
metafile: true,
|
|
81
|
+
logLevel: 'warning',
|
|
82
|
+
external: [...engineExternal, ...project.customNamespaces.map(ns => ns.specifier)],
|
|
83
|
+
});
|
|
84
|
+
const output = Object.keys(result.metafile.outputs).find(f => f.endsWith('.js'));
|
|
85
|
+
return path.basename(output ?? 'default.thm.js');
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
await fs.rm(stubDir, { recursive: true, force: true });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Generates an ESM skin factory, returning a stub on parse failure.
|
|
93
|
+
*/
|
|
94
|
+
function generateSkinModule(skin, customNamespaces, strict) {
|
|
95
|
+
try {
|
|
96
|
+
const ir = parseToIR(skin.file.contents, skin.className, customNamespaces);
|
|
97
|
+
if (ir.unresolvedTags.length > 0) {
|
|
98
|
+
const tags = [...new Set(ir.unresolvedTags)].join(', ');
|
|
99
|
+
logger.warn(`${skin.file.relPath}: unresolved tag(s) dropped from skin: ${tags}`);
|
|
100
|
+
}
|
|
101
|
+
return generateCode(ir, { format: 'esm' });
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
105
|
+
if (strict) {
|
|
106
|
+
throw new Error(`EXML compile failed for ${skin.file.relPath}: ${message}`, { cause: err });
|
|
107
|
+
}
|
|
108
|
+
logger.warn(`EXML compile failed for ${skin.file.relPath}: ${message}`);
|
|
109
|
+
return `// Failed to compile ${skin.file.relPath}: ${message}\nexport function ${factoryName(skin.className)}() { return {}; }\n`;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Determines which `.exml` files to compile (honours `autoGenerateExmlsList`).
|
|
114
|
+
*/
|
|
115
|
+
async function resolveExmlFiles(project, theme) {
|
|
116
|
+
const declared = (theme.exmls ?? []).map(e => (typeof e === 'string' ? e : e?.path)).filter(Boolean);
|
|
117
|
+
if (theme.autoGenerateExmlsList === false && declared.length > 0) {
|
|
118
|
+
const files = [];
|
|
119
|
+
for (const rel of declared) {
|
|
120
|
+
try {
|
|
121
|
+
files.push(await readExmlAt(project.resourceDir, resolveExmlPath(project, rel)));
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
logger.warn(`declared EXML not found, skipping: ${rel}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return files;
|
|
128
|
+
}
|
|
129
|
+
return collectExmlFiles(project.resourceDir);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Recursively collects every `.exml` file under `resource/`, sorted by path.
|
|
133
|
+
*/
|
|
134
|
+
async function collectExmlFiles(resourceDir) {
|
|
135
|
+
const results = [];
|
|
136
|
+
async function walk(dir) {
|
|
137
|
+
let entries;
|
|
138
|
+
try {
|
|
139
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
for (const entry of entries) {
|
|
145
|
+
const full = path.join(dir, entry.name);
|
|
146
|
+
if (entry.isDirectory())
|
|
147
|
+
await walk(full);
|
|
148
|
+
else if (entry.name.endsWith('.exml'))
|
|
149
|
+
results.push(await readExmlAt(resourceDir, full));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
await walk(resourceDir);
|
|
153
|
+
return results.sort((a, b) => a.relPath.localeCompare(b.relPath));
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Resolves a theme-declared EXML path (project-root- or resource-relative).
|
|
157
|
+
*/
|
|
158
|
+
function resolveExmlPath(project, declared) {
|
|
159
|
+
const normalized = declared.replace(/^\.\//, '');
|
|
160
|
+
return normalized.startsWith('resource/')
|
|
161
|
+
? path.resolve(project.root, normalized)
|
|
162
|
+
: path.resolve(project.resourceDir, normalized);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Reads a `.exml` file at an absolute path, computing its `resource/`-relative path.
|
|
166
|
+
*/
|
|
167
|
+
async function readExmlAt(resourceDir, absolute) {
|
|
168
|
+
return {
|
|
169
|
+
path: absolute,
|
|
170
|
+
relPath: toPosix(path.relative(resourceDir, absolute)),
|
|
171
|
+
contents: await fs.readFile(absolute, 'utf-8'),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Reads the existing theme file, or returns an empty theme on miss.
|
|
176
|
+
*/
|
|
177
|
+
async function loadTheme(project) {
|
|
178
|
+
try {
|
|
179
|
+
return JSON.parse(await fs.readFile(project.themeFile, 'utf-8'));
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return { skins: {} };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Rewrites the `skins` map to class names: Egret path values
|
|
187
|
+
* (`resource/skins/X.exml`) are matched to their compiled skin; values that are
|
|
188
|
+
* already class names pass through.
|
|
189
|
+
*/
|
|
190
|
+
function remapSkins(project, skins, compiled) {
|
|
191
|
+
const byRelPath = new Map(compiled.map(s => [s.file.relPath, s.className]));
|
|
192
|
+
const result = {};
|
|
193
|
+
for (const [host, value] of Object.entries(skins)) {
|
|
194
|
+
if (/\.exml$/i.test(value) || value.includes('/')) {
|
|
195
|
+
const relPath = toPosix(path.relative(project.resourceDir, resolveExmlPath(project, value)));
|
|
196
|
+
result[host] = byRelPath.get(relPath) ?? value;
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
result[host] = value;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Reads the `class="..."` attribute, falling back to the file name.
|
|
206
|
+
*/
|
|
207
|
+
function extractClassName(file) {
|
|
208
|
+
const match = file.contents.match(/class="([^"]+)"/);
|
|
209
|
+
return match ? match[1] : path.basename(file.path, '.exml');
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* `skins.ButtonSkin` → `createButtonSkin` (matches the EXML codegen).
|
|
213
|
+
*/
|
|
214
|
+
function factoryName(className) {
|
|
215
|
+
return `create${className.split('.').pop()}`;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Converts a file system path to forward-slash form (a no-op on POSIX).
|
|
219
|
+
*/
|
|
220
|
+
function toPosix(p) {
|
|
221
|
+
return p.split(path.sep).join('/');
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=compile-exml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile-exml.js","sourceRoot":"","sources":["../../../src/core/plugins/compile-exml.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BuildPlugin } from '../pipeline.js';
|
|
2
|
+
/**
|
|
3
|
+
* Compiles the project source with esbuild, matching Egret's output shape:
|
|
4
|
+
*
|
|
5
|
+
* - **development**: each `src/**\/*.ts` is emitted to a mirrored `.js` path
|
|
6
|
+
* (`Main.js`, `com/akakata/LoadingUI.js`), preserving directory structure.
|
|
7
|
+
* - **release**: all source is bundled and minified into `js/main.min_<hash>.js`.
|
|
8
|
+
*
|
|
9
|
+
* Engine packages stay external in both modes (resolved by the HTML import map),
|
|
10
|
+
* so engine code is never duplicated into the app output. The entry script path
|
|
11
|
+
* is reported via `ctx.outputs.entryScript`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function compileSource(): BuildPlugin;
|
|
14
|
+
//# sourceMappingURL=compile-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile-source.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/compile-source.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGhE;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,IAAI,WAAW,CAU3C"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as esbuild from 'esbuild';
|
|
2
|
+
import * as fs from 'node:fs/promises';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { ensureDir } from '../../utils/fs.js';
|
|
5
|
+
import { logger } from '../../utils/logger.js';
|
|
6
|
+
import { namespaceModuleExternalPlugin, normalizeModuleKey } from '../namespace-external-plugin.js';
|
|
7
|
+
/**
|
|
8
|
+
* Compiles the project source with esbuild, matching Egret's output shape:
|
|
9
|
+
*
|
|
10
|
+
* - **development**: each `src/**\/*.ts` is emitted to a mirrored `.js` path
|
|
11
|
+
* (`Main.js`, `com/akakata/LoadingUI.js`), preserving directory structure.
|
|
12
|
+
* - **release**: all source is bundled and minified into `js/main.min_<hash>.js`.
|
|
13
|
+
*
|
|
14
|
+
* Engine packages stay external in both modes (resolved by the HTML import map),
|
|
15
|
+
* so engine code is never duplicated into the app output. The entry script path
|
|
16
|
+
* is reported via `ctx.outputs.entryScript`.
|
|
17
|
+
*/
|
|
18
|
+
export function compileSource() {
|
|
19
|
+
return {
|
|
20
|
+
name: 'compile source',
|
|
21
|
+
async apply(ctx) {
|
|
22
|
+
const { project } = ctx;
|
|
23
|
+
await ensureDir(project.outputDir);
|
|
24
|
+
return project.mode === 'release' ? buildRelease(ctx) : buildDevelopment(ctx);
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const COMMON = {
|
|
29
|
+
bundle: true,
|
|
30
|
+
format: 'esm',
|
|
31
|
+
platform: 'browser',
|
|
32
|
+
target: 'es2022',
|
|
33
|
+
logLevel: 'warning',
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Per-file output preserving the source tree (development).
|
|
37
|
+
*/
|
|
38
|
+
async function buildDevelopment(ctx) {
|
|
39
|
+
const { project } = ctx;
|
|
40
|
+
const allSources = await collectSources(project.srcDir);
|
|
41
|
+
// Files already bundled into a custom-namespace chunk (compile-custom-namespaces.ts)
|
|
42
|
+
// must not also become their own dev entry point — that would emit a second,
|
|
43
|
+
// distinct copy of the same classes instead of resolving to the shared chunk.
|
|
44
|
+
const sources = allSources.filter(file => !ctx.outputs.namespaceModules.has(normalizeModuleKey(file)));
|
|
45
|
+
const entryPoints = sources.length > 0 ? sources : [project.entry];
|
|
46
|
+
const options = {
|
|
47
|
+
...COMMON,
|
|
48
|
+
entryPoints,
|
|
49
|
+
outdir: project.outputDir,
|
|
50
|
+
outbase: project.srcDir,
|
|
51
|
+
entryNames: '[dir]/[name]',
|
|
52
|
+
chunkNames: 'js/chunks/[name]-[hash]',
|
|
53
|
+
splitting: true,
|
|
54
|
+
sourcemap: ctx.sourcemap,
|
|
55
|
+
external: [...project.enginePackages, ...project.customNamespaces.map(ns => ns.specifier)],
|
|
56
|
+
plugins: [namespaceModuleExternalPlugin(ctx.outputs.namespaceModules)],
|
|
57
|
+
define: defines(false),
|
|
58
|
+
};
|
|
59
|
+
ctx.outputs.entryScript = toOutputPath(project, project.entry);
|
|
60
|
+
if (ctx.watch) {
|
|
61
|
+
const context = await esbuild.context(options);
|
|
62
|
+
await context.watch();
|
|
63
|
+
ctx.disposers.push(() => context.dispose());
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
await esbuild.build(options);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Single minified, content-hashed bundle under `js/` (release).
|
|
70
|
+
*/
|
|
71
|
+
async function buildRelease(ctx) {
|
|
72
|
+
const { project } = ctx;
|
|
73
|
+
const result = await esbuild.build({
|
|
74
|
+
...COMMON,
|
|
75
|
+
entryPoints: [project.entry],
|
|
76
|
+
outdir: path.join(project.outputDir, 'js'),
|
|
77
|
+
entryNames: 'main.min_[hash]',
|
|
78
|
+
minify: true,
|
|
79
|
+
sourcemap: ctx.sourcemap,
|
|
80
|
+
metafile: true,
|
|
81
|
+
external: [...project.enginePackages, ...project.customNamespaces.map(ns => ns.specifier)],
|
|
82
|
+
plugins: [namespaceModuleExternalPlugin(ctx.outputs.namespaceModules)],
|
|
83
|
+
define: defines(true),
|
|
84
|
+
});
|
|
85
|
+
const output = Object.keys(result.metafile.outputs).find(f => f.endsWith('.js'));
|
|
86
|
+
ctx.outputs.entryScript = output ? `js/${path.basename(output)}` : 'js/main.min.js';
|
|
87
|
+
if (ctx.analyze) {
|
|
88
|
+
logger.info('Bundle analysis:\n' + (await esbuild.analyzeMetafile(result.metafile)));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Build-time `define` replacements for `process.env.DEBUG`/`process.env.RELEASE`.
|
|
93
|
+
*/
|
|
94
|
+
function defines(isRelease) {
|
|
95
|
+
return {
|
|
96
|
+
'process.env.DEBUG': JSON.stringify(!isRelease),
|
|
97
|
+
'process.env.RELEASE': JSON.stringify(isRelease),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Maps an absolute source path to its output path, relative to the output dir.
|
|
102
|
+
*/
|
|
103
|
+
function toOutputPath(project, sourceFile) {
|
|
104
|
+
return path.relative(project.srcDir, sourceFile).replace(/\.ts$/, '.js').split(path.sep).join('/');
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Collects every `.ts` source (excluding `.d.ts`) under the source directory.
|
|
108
|
+
*/
|
|
109
|
+
async function collectSources(srcDir) {
|
|
110
|
+
const results = [];
|
|
111
|
+
async function walk(dir) {
|
|
112
|
+
let entries;
|
|
113
|
+
try {
|
|
114
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
for (const entry of entries) {
|
|
120
|
+
const full = path.join(dir, entry.name);
|
|
121
|
+
if (entry.isDirectory()) {
|
|
122
|
+
await walk(full);
|
|
123
|
+
}
|
|
124
|
+
else if (entry.name.endsWith('.ts') && !entry.name.endsWith('.d.ts')) {
|
|
125
|
+
results.push(full);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
await walk(srcDir);
|
|
130
|
+
return results.sort();
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=compile-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile-source.js","sourceRoot":"","sources":["../../../src/core/plugins/compile-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BuildPlugin } from '../pipeline.js';
|
|
2
|
+
/**
|
|
3
|
+
* Copies the project's `resource/` directory into the output.
|
|
4
|
+
*
|
|
5
|
+
* - The theme file is skipped — `compile EXML` emits it with the resolved skin
|
|
6
|
+
* payload, so copying the source version would overwrite it.
|
|
7
|
+
* - `.exml` source files are skipped when EXML is enabled, since skins are
|
|
8
|
+
* compiled to a JS module and the runtime never reads raw `.exml` — this
|
|
9
|
+
* keeps the output clean, matching Egret's release.
|
|
10
|
+
*/
|
|
11
|
+
export declare function copyAssets(): BuildPlugin;
|
|
12
|
+
//# sourceMappingURL=copy-assets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copy-assets.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/copy-assets.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEhE;;;;;;;;GAQG;AACH,wBAAgB,UAAU,IAAI,WAAW,CAmBxC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import { copyDir, exists } from '../../utils/fs.js';
|
|
3
|
+
/**
|
|
4
|
+
* Copies the project's `resource/` directory into the output.
|
|
5
|
+
*
|
|
6
|
+
* - The theme file is skipped — `compile EXML` emits it with the resolved skin
|
|
7
|
+
* payload, so copying the source version would overwrite it.
|
|
8
|
+
* - `.exml` source files are skipped when EXML is enabled, since skins are
|
|
9
|
+
* compiled to a JS module and the runtime never reads raw `.exml` — this
|
|
10
|
+
* keeps the output clean, matching Egret's release.
|
|
11
|
+
*/
|
|
12
|
+
export function copyAssets() {
|
|
13
|
+
return {
|
|
14
|
+
name: 'copy assets',
|
|
15
|
+
async apply(ctx) {
|
|
16
|
+
const { project } = ctx;
|
|
17
|
+
if (!(await exists(project.resourceDir)))
|
|
18
|
+
return;
|
|
19
|
+
const exml = project.config.exml;
|
|
20
|
+
const themeName = exml ? path.basename(exml.themeFile) : undefined;
|
|
21
|
+
const dest = path.join(project.outputDir, 'resource');
|
|
22
|
+
await copyDir(project.resourceDir, dest, name => {
|
|
23
|
+
if (name === themeName)
|
|
24
|
+
return false;
|
|
25
|
+
// Skins are compiled to a JS module — never ship raw .exml sources.
|
|
26
|
+
if (exml && name.endsWith('.exml'))
|
|
27
|
+
return false;
|
|
28
|
+
return true;
|
|
29
|
+
});
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=copy-assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copy-assets.js","sourceRoot":"","sources":["../../../src/core/plugins/copy-assets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGpD;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU;IACzB,OAAO;QACN,IAAI,EAAE,aAAa;QACnB,KAAK,CAAC,KAAK,CAAC,GAAiB;YAC5B,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC;YACxB,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;gBAAE,OAAO;YAEjD,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;YACjC,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAEnE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YACtD,MAAM,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;gBAC/C,IAAI,IAAI,KAAK,SAAS;oBAAE,OAAO,KAAK,CAAC;gBACrC,oEAAoE;gBACpE,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;oBAAE,OAAO,KAAK,CAAC;gBACjD,OAAO,IAAI,CAAC;YACb,CAAC,CAAC,CAAC;QACJ,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BuildPlugin } from '../pipeline.js';
|
|
2
|
+
import type { Project } from '../project.js';
|
|
3
|
+
/**
|
|
4
|
+
* Writes `index.html`.
|
|
5
|
+
*
|
|
6
|
+
* Engine packages are wired up through an ES module import map
|
|
7
|
+
* (`@kurot/core` → `./js/kurot.core.js`), so the bundled app and engine
|
|
8
|
+
* chunks resolve bare specifiers in the browser. The entry script bootstraps
|
|
9
|
+
* the engine via the user's own `createPlayer()` call.
|
|
10
|
+
*/
|
|
11
|
+
export declare function generateHtml(): BuildPlugin;
|
|
12
|
+
/**
|
|
13
|
+
* Replaces every required Kurot placeholder in the page template.
|
|
14
|
+
*/
|
|
15
|
+
export declare function renderHtml(template: string, project: Project, entryScript: string, engine: Record<string, string>): string;
|
|
16
|
+
//# sourceMappingURL=generate-html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-html.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/generate-html.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAqD7C;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,WAAW,CAW1C;AAiCD;;GAEG;AACH,wBAAgB,UAAU,CACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,MAAM,CAuBR"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import * as fs from 'node:fs/promises';
|
|
3
|
+
import { writeFile } from '../../utils/fs.js';
|
|
4
|
+
import { BuildError } from '../errors.js';
|
|
5
|
+
const PLACEHOLDERS = {
|
|
6
|
+
importMap: '{{KUROT_IMPORT_MAP}}',
|
|
7
|
+
stageWidth: '{{KUROT_STAGE_WIDTH}}',
|
|
8
|
+
stageHeight: '{{KUROT_STAGE_HEIGHT}}',
|
|
9
|
+
scaleMode: '{{KUROT_SCALE_MODE}}',
|
|
10
|
+
orientation: '{{KUROT_ORIENTATION}}',
|
|
11
|
+
frameRate: '{{KUROT_FRAME_RATE}}',
|
|
12
|
+
entryScript: '{{KUROT_ENTRY_SCRIPT}}',
|
|
13
|
+
};
|
|
14
|
+
const DEFAULT_TEMPLATE = `<!DOCTYPE html>
|
|
15
|
+
<html>
|
|
16
|
+
<head>
|
|
17
|
+
<meta charset="utf-8">
|
|
18
|
+
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
|
|
19
|
+
<title>Kurot Game</title>
|
|
20
|
+
<style>
|
|
21
|
+
html, body {
|
|
22
|
+
margin: 0;
|
|
23
|
+
padding: 0;
|
|
24
|
+
width: 100%;
|
|
25
|
+
height: 100%;
|
|
26
|
+
background: #000000;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
body {
|
|
31
|
+
display: flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
justify-content: center;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
canvas {
|
|
37
|
+
display: block;
|
|
38
|
+
}
|
|
39
|
+
</style>
|
|
40
|
+
{{KUROT_IMPORT_MAP}}
|
|
41
|
+
</head>
|
|
42
|
+
<body>
|
|
43
|
+
<canvas id="gameCanvas"
|
|
44
|
+
data-content-width="{{KUROT_STAGE_WIDTH}}"
|
|
45
|
+
data-content-height="{{KUROT_STAGE_HEIGHT}}"
|
|
46
|
+
data-scale-mode="{{KUROT_SCALE_MODE}}"
|
|
47
|
+
data-orientation="{{KUROT_ORIENTATION}}"
|
|
48
|
+
data-frame-rate="{{KUROT_FRAME_RATE}}"></canvas>
|
|
49
|
+
<script type="module" src="{{KUROT_ENTRY_SCRIPT}}"></script>
|
|
50
|
+
</body>
|
|
51
|
+
</html>
|
|
52
|
+
`;
|
|
53
|
+
/**
|
|
54
|
+
* Writes `index.html`.
|
|
55
|
+
*
|
|
56
|
+
* Engine packages are wired up through an ES module import map
|
|
57
|
+
* (`@kurot/core` → `./js/kurot.core.js`), so the bundled app and engine
|
|
58
|
+
* chunks resolve bare specifiers in the browser. The entry script bootstraps
|
|
59
|
+
* the engine via the user's own `createPlayer()` call.
|
|
60
|
+
*/
|
|
61
|
+
export function generateHtml() {
|
|
62
|
+
return {
|
|
63
|
+
name: 'generate index.html',
|
|
64
|
+
async apply(ctx) {
|
|
65
|
+
const entryScript = ctx.outputs.entryScript ?? 'main.js';
|
|
66
|
+
const template = await loadTemplate(ctx.project);
|
|
67
|
+
const html = renderHtml(template, ctx.project, entryScript, ctx.outputs.engine);
|
|
68
|
+
await writeFile(path.join(ctx.project.outputDir, 'index.html'), html);
|
|
69
|
+
await copyTemplateAssets(ctx.project);
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Copies files placed beside the project HTML template into the web output.
|
|
75
|
+
*
|
|
76
|
+
* This keeps page-shell assets such as a startup logo separate from game
|
|
77
|
+
* resources. The template itself is skipped because the rendered HTML has
|
|
78
|
+
* already been written to the output directory.
|
|
79
|
+
*/
|
|
80
|
+
async function copyTemplateAssets(project) {
|
|
81
|
+
if (!project.htmlTemplate)
|
|
82
|
+
return;
|
|
83
|
+
const templateDirectory = path.dirname(project.htmlTemplate);
|
|
84
|
+
const templateFileName = path.basename(project.htmlTemplate);
|
|
85
|
+
const entries = await fs.readdir(templateDirectory, { withFileTypes: true });
|
|
86
|
+
for (const entry of entries) {
|
|
87
|
+
if (entry.name === templateFileName)
|
|
88
|
+
continue;
|
|
89
|
+
const source = path.join(templateDirectory, entry.name);
|
|
90
|
+
const destination = path.join(project.outputDir, entry.name);
|
|
91
|
+
await fs.cp(source, destination, { recursive: true });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Loads the project-owned template or falls back to the built-in page.
|
|
96
|
+
*/
|
|
97
|
+
async function loadTemplate(project) {
|
|
98
|
+
if (!project.htmlTemplate)
|
|
99
|
+
return DEFAULT_TEMPLATE;
|
|
100
|
+
return fs.readFile(project.htmlTemplate, 'utf-8');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Replaces every required Kurot placeholder in the page template.
|
|
104
|
+
*/
|
|
105
|
+
export function renderHtml(template, project, entryScript, engine) {
|
|
106
|
+
const missing = Object.values(PLACEHOLDERS).filter(placeholder => !template.includes(placeholder));
|
|
107
|
+
if (missing.length > 0) {
|
|
108
|
+
const source = project.htmlTemplate ?? 'the built-in HTML template';
|
|
109
|
+
throw new BuildError(`HTML template '${source}' is missing required placeholders: ${missing.join(', ')}`);
|
|
110
|
+
}
|
|
111
|
+
const { stage } = project.config;
|
|
112
|
+
const replacements = new Map([
|
|
113
|
+
[PLACEHOLDERS.importMap, Object.keys(engine).length > 0 ? renderImportMap(engine) : ''],
|
|
114
|
+
[PLACEHOLDERS.stageWidth, String(stage.width)],
|
|
115
|
+
[PLACEHOLDERS.stageHeight, String(stage.height)],
|
|
116
|
+
[PLACEHOLDERS.scaleMode, stage.scaleMode],
|
|
117
|
+
[PLACEHOLDERS.orientation, stage.orientation],
|
|
118
|
+
[PLACEHOLDERS.frameRate, String(stage.frameRate)],
|
|
119
|
+
[PLACEHOLDERS.entryScript, entryScript],
|
|
120
|
+
]);
|
|
121
|
+
let html = template;
|
|
122
|
+
for (const [placeholder, value] of replacements) {
|
|
123
|
+
html = html.replaceAll(placeholder, value);
|
|
124
|
+
}
|
|
125
|
+
return html;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Renders the `<script type="importmap">` tag mapping engine package
|
|
129
|
+
* specifiers to their bundled chunk paths.
|
|
130
|
+
*/
|
|
131
|
+
function renderImportMap(engine) {
|
|
132
|
+
const imports = Object.entries(engine)
|
|
133
|
+
.map(([pkg, file]) => `\t\t\t"${pkg}": "./${file}"`)
|
|
134
|
+
.join(',\n');
|
|
135
|
+
return `<script type="importmap">\n\t{\n\t\t"imports": {\n${imports}\n\t\t}\n\t}\n\t</script>\n`;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=generate-html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-html.js","sourceRoot":"","sources":["../../../src/core/plugins/generate-html.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BuildPlugin } from '../pipeline.js';
|
|
2
|
+
export { cleanOutput } from './clean-output.js';
|
|
3
|
+
export { compileExml } from './compile-exml.js';
|
|
4
|
+
export { compileEngine } from './compile-engine.js';
|
|
5
|
+
export { compileCustomNamespaces } from './compile-custom-namespaces.js';
|
|
6
|
+
export { compileSource } from './compile-source.js';
|
|
7
|
+
export { generateHtml } from './generate-html.js';
|
|
8
|
+
export { writeManifest } from './manifest.js';
|
|
9
|
+
export { copyAssets } from './copy-assets.js';
|
|
10
|
+
/**
|
|
11
|
+
* The standard build sequence.
|
|
12
|
+
*
|
|
13
|
+
* Order matters: `compileCustomNamespaces` must run before `compileSource`,
|
|
14
|
+
* since the latter reads `ctx.outputs.namespaceModules` to mark namespace
|
|
15
|
+
* files external and exclude them from per-file dev output (see
|
|
16
|
+
* `compile-source.ts`). Engine and source compilation report their output
|
|
17
|
+
* paths, then the HTML and manifest referencing them are written, and
|
|
18
|
+
* finally static assets are copied.
|
|
19
|
+
*/
|
|
20
|
+
export declare function defaultPlugins(): BuildPlugin[];
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAUlD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAgB,cAAc,IAAI,WAAW,EAAE,CAW9C"}
|