@caryhu/codemine-forge 0.0.1-alpha.1 → 0.0.1-alpha.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/dist/build-pipeline/browser-bundle.d.ts +2 -1
- package/dist/build-pipeline/browser-bundle.js +204 -24
- package/dist/build-pipeline/diagnostics.js +1 -1
- package/dist/build-pipeline/index.d.ts +1 -1
- package/dist/build-pipeline/pipeline.js +28 -30
- package/dist/build-pipeline/types.d.ts +18 -0
- package/dist/build-pipeline/vite-config.d.ts +8 -0
- package/dist/build-pipeline/vite-config.js +215 -0
- package/dist/dev-server-preview/index.d.ts +2 -2
- package/dist/dev-server-preview/index.js +2 -1
- package/dist/dev-server-preview/preview-document.d.ts +2 -1
- package/dist/dev-server-preview/preview-document.js +203 -1
- package/dist/dev-server-preview/server.d.ts +8 -1
- package/dist/dev-server-preview/server.js +246 -32
- package/dist/dev-server-preview/types.d.ts +38 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -2
- package/package.json +3 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ForgePackageResolutionResult } from "../package-resolution";
|
|
2
2
|
import { type ForgeVirtualFileSystem } from "../virtual-file-system";
|
|
3
|
-
import type { ForgeBrowserBundle, ForgeBuildOutputFile, ForgeBuildPipelineDiagnostic } from "./types";
|
|
3
|
+
import type { ForgeBrowserBundle, ForgeBuildOutputFile, ForgeBuildPipelineDiagnostic, ForgeViteConfigMetadata } from "./types";
|
|
4
4
|
export interface ForgeBrowserBundleResult {
|
|
5
5
|
readonly browserBundle?: ForgeBrowserBundle;
|
|
6
6
|
readonly diagnostics: readonly ForgeBuildPipelineDiagnostic[];
|
|
@@ -11,6 +11,7 @@ interface CreateBrowserBundleOptions {
|
|
|
11
11
|
readonly fileSystem: ForgeVirtualFileSystem;
|
|
12
12
|
readonly packageResolution: ForgePackageResolutionResult;
|
|
13
13
|
readonly scriptTransformer?: ForgeBrowserBundleScriptTransformer;
|
|
14
|
+
readonly viteConfig?: ForgeViteConfigMetadata;
|
|
14
15
|
}
|
|
15
16
|
export type ForgeBrowserBundleScriptLoader = "ts" | "tsx";
|
|
16
17
|
export interface ForgeBrowserBundleScriptTransformRequest {
|
|
@@ -24,6 +24,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.createBrowserBundle = void 0;
|
|
27
|
+
const compiler_sfc_1 = require("@vue/compiler-sfc");
|
|
27
28
|
const ts = __importStar(require("typescript"));
|
|
28
29
|
const virtual_file_system_1 = require("../virtual-file-system");
|
|
29
30
|
const diagnostics_1 = require("./diagnostics");
|
|
@@ -36,6 +37,7 @@ const DEFAULT_RESOLVE_EXTENSIONS = [
|
|
|
36
37
|
".js",
|
|
37
38
|
".json",
|
|
38
39
|
".css",
|
|
40
|
+
".vue",
|
|
39
41
|
];
|
|
40
42
|
const INDEX_RESOLVE_EXTENSIONS = [
|
|
41
43
|
"/index.tsx",
|
|
@@ -44,6 +46,7 @@ const INDEX_RESOLVE_EXTENSIONS = [
|
|
|
44
46
|
"/index.js",
|
|
45
47
|
"/index.json",
|
|
46
48
|
"/index.css",
|
|
49
|
+
"/index.vue",
|
|
47
50
|
];
|
|
48
51
|
const SCRIPT_EXTENSIONS = new Set([".js", ".jsx", ".ts", ".tsx"]);
|
|
49
52
|
async function createBrowserBundle(options) {
|
|
@@ -64,7 +67,8 @@ async function createBrowserBundle(options) {
|
|
|
64
67
|
const extension = getExtension(sourcePath);
|
|
65
68
|
if (!SCRIPT_EXTENSIONS.has(extension) &&
|
|
66
69
|
extension !== ".css" &&
|
|
67
|
-
extension !== ".json"
|
|
70
|
+
extension !== ".json" &&
|
|
71
|
+
extension !== ".vue") {
|
|
68
72
|
modules.set(sourcePath, {
|
|
69
73
|
outputPath: createModuleOutputPath(sourcePath),
|
|
70
74
|
sourcePath,
|
|
@@ -74,12 +78,24 @@ async function createBrowserBundle(options) {
|
|
|
74
78
|
return;
|
|
75
79
|
}
|
|
76
80
|
const source = await options.fileSystem.readText(sourcePath);
|
|
77
|
-
const
|
|
81
|
+
const importSource = extension === ".vue" ? createVueSfcModule(sourcePath, source) : source;
|
|
82
|
+
const imports = extractImportReferences(importSource).map((reference) => reference.specifier);
|
|
78
83
|
const rewrites = new Map();
|
|
79
84
|
for (const specifier of imports) {
|
|
80
85
|
if (isExternalUrl(specifier)) {
|
|
81
86
|
continue;
|
|
82
87
|
}
|
|
88
|
+
const aliasSpecifier = resolveAliasSpecifier(specifier, options.viteConfig?.aliases ?? {});
|
|
89
|
+
if (aliasSpecifier !== undefined) {
|
|
90
|
+
const resolvedPath = await resolveLocalImport(options.fileSystem, sourcePath, aliasSpecifier);
|
|
91
|
+
if (resolvedPath === undefined) {
|
|
92
|
+
diagnostics.push((0, diagnostics_1.createUnresolvedImportDiagnostic)(specifier, sourcePath));
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
rewrites.set(specifier, createModuleOutputPath(resolvedPath));
|
|
96
|
+
await visitWorkspaceModule(resolvedPath);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
83
99
|
if (isLocalSpecifier(specifier)) {
|
|
84
100
|
const resolvedPath = await resolveLocalImport(options.fileSystem, sourcePath, specifier);
|
|
85
101
|
if (resolvedPath === undefined) {
|
|
@@ -102,7 +118,7 @@ async function createBrowserBundle(options) {
|
|
|
102
118
|
await visitPackageModule(packageImport.packageRecord, packageImport.filePath);
|
|
103
119
|
}
|
|
104
120
|
}
|
|
105
|
-
const transformResult = await transformWorkspaceModule(sourcePath, source, options.scriptTransformer);
|
|
121
|
+
const transformResult = await transformWorkspaceModule(sourcePath, source, options.scriptTransformer, options.viteConfig?.define ?? {});
|
|
106
122
|
if (!transformResult.success) {
|
|
107
123
|
diagnostics.push(...transformResult.diagnostics);
|
|
108
124
|
visiting.delete(sourcePath);
|
|
@@ -196,6 +212,7 @@ async function createBrowserBundle(options) {
|
|
|
196
212
|
const localImports = Object.fromEntries(moduleOutputFiles.map((file) => [file.path, file.path]));
|
|
197
213
|
const packageImportEntries = Object.fromEntries(Array.from(packageImports.entries()).sort(([left], [right]) => left.localeCompare(right)));
|
|
198
214
|
const packageEntryImports = createPackageEntryImports(options.packageResolution.packages);
|
|
215
|
+
const bundleModules = createBrowserBundleModules(Array.from(modules.values()), Array.from(packageModules.values()));
|
|
199
216
|
const importMap = {
|
|
200
217
|
imports: sortRecord({
|
|
201
218
|
...packageEntryImports,
|
|
@@ -213,34 +230,60 @@ async function createBrowserBundle(options) {
|
|
|
213
230
|
format: "esm",
|
|
214
231
|
importMap,
|
|
215
232
|
importMapPath: BROWSER_IMPORT_MAP_PATH,
|
|
216
|
-
moduleCount:
|
|
233
|
+
moduleCount: bundleModules.length,
|
|
234
|
+
modules: bundleModules,
|
|
217
235
|
outputPaths: allOutputFiles.map((file) => file.path),
|
|
236
|
+
viteConfig: options.viteConfig,
|
|
218
237
|
},
|
|
219
238
|
diagnostics: [],
|
|
220
239
|
outputFiles: allOutputFiles,
|
|
221
240
|
};
|
|
222
241
|
}
|
|
223
242
|
exports.createBrowserBundle = createBrowserBundle;
|
|
224
|
-
|
|
243
|
+
function createBrowserBundleModules(workspaceModules, packageModules) {
|
|
244
|
+
return [
|
|
245
|
+
...workspaceModules.map((moduleRecord) => ({
|
|
246
|
+
origin: "workspace",
|
|
247
|
+
outputPath: moduleRecord.outputPath,
|
|
248
|
+
sourcePath: moduleRecord.sourcePath,
|
|
249
|
+
})),
|
|
250
|
+
...packageModules.map((moduleRecord) => ({
|
|
251
|
+
origin: "package",
|
|
252
|
+
outputPath: moduleRecord.outputPath,
|
|
253
|
+
sourcePath: createPackageImporterPath(moduleRecord.packageRecord, moduleRecord.filePath),
|
|
254
|
+
})),
|
|
255
|
+
].sort((left, right) => left.outputPath.localeCompare(right.outputPath));
|
|
256
|
+
}
|
|
257
|
+
async function transformWorkspaceModule(sourcePath, source, scriptTransformer, defineReplacements) {
|
|
225
258
|
const extension = getExtension(sourcePath);
|
|
226
259
|
if (extension === ".css") {
|
|
227
|
-
return transformSuccess(
|
|
260
|
+
return transformSuccess(createWorkspaceCssModule(sourcePath, source));
|
|
228
261
|
}
|
|
229
262
|
if (extension === ".json") {
|
|
230
263
|
return transformSuccess(createJsonModule(source));
|
|
231
264
|
}
|
|
265
|
+
const applyDefines = (outputText) => applyDefineReplacements(outputText, defineReplacements);
|
|
266
|
+
if (extension === ".vue") {
|
|
267
|
+
return transformSuccess(applyDefines(transpileScript(sourcePath, createVueSfcModule(sourcePath, source))));
|
|
268
|
+
}
|
|
232
269
|
if (!SCRIPT_EXTENSIONS.has(extension)) {
|
|
233
270
|
return transformSuccess(source);
|
|
234
271
|
}
|
|
235
272
|
const loader = scriptLoaderForExtension(extension);
|
|
236
273
|
if (loader !== undefined && scriptTransformer !== undefined) {
|
|
237
|
-
|
|
274
|
+
const transformResult = await scriptTransformer({
|
|
238
275
|
loader,
|
|
239
276
|
sourcePath,
|
|
240
277
|
sourceText: source,
|
|
241
278
|
});
|
|
279
|
+
return transformResult.success
|
|
280
|
+
? transformSuccess(applyDefines(transformResult.outputText))
|
|
281
|
+
: transformResult;
|
|
242
282
|
}
|
|
243
|
-
return transformSuccess(
|
|
283
|
+
return transformSuccess(applyDefines(transpileScript(sourcePath, source)));
|
|
284
|
+
}
|
|
285
|
+
function transpileScript(sourcePath, source) {
|
|
286
|
+
return ts.transpileModule(source, {
|
|
244
287
|
compilerOptions: {
|
|
245
288
|
esModuleInterop: true,
|
|
246
289
|
importsNotUsedAsValues: ts.ImportsNotUsedAsValues.Remove,
|
|
@@ -252,7 +295,7 @@ async function transformWorkspaceModule(sourcePath, source, scriptTransformer) {
|
|
|
252
295
|
},
|
|
253
296
|
fileName: sourcePath,
|
|
254
297
|
reportDiagnostics: false,
|
|
255
|
-
}).outputText
|
|
298
|
+
}).outputText;
|
|
256
299
|
}
|
|
257
300
|
function transformSuccess(outputText) {
|
|
258
301
|
return {
|
|
@@ -271,7 +314,7 @@ function transformPackageModule(importer, filePath, content) {
|
|
|
271
314
|
}
|
|
272
315
|
const source = typeof content === "string" ? content : new TextDecoder().decode(content);
|
|
273
316
|
if (extension === ".css") {
|
|
274
|
-
return transformSuccess(
|
|
317
|
+
return transformSuccess(createPlainCssModule(importer, source));
|
|
275
318
|
}
|
|
276
319
|
if (extension === ".json") {
|
|
277
320
|
return transformSuccess(createJsonModule(source));
|
|
@@ -279,21 +322,63 @@ function transformPackageModule(importer, filePath, content) {
|
|
|
279
322
|
if (!SCRIPT_EXTENSIONS.has(extension)) {
|
|
280
323
|
return transformSuccess(source);
|
|
281
324
|
}
|
|
282
|
-
return transformSuccess(
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
325
|
+
return transformSuccess(transpileScript(importer, source));
|
|
326
|
+
}
|
|
327
|
+
function createVueSfcModule(sourcePath, source) {
|
|
328
|
+
const filename = sourcePath;
|
|
329
|
+
const id = `forge-vue-${hashText(sourcePath)}`;
|
|
330
|
+
const parseResult = (0, compiler_sfc_1.parse)(source, { filename });
|
|
331
|
+
if (parseResult.errors.length > 0) {
|
|
332
|
+
throw new Error(formatVueCompilerErrors(parseResult.errors));
|
|
333
|
+
}
|
|
334
|
+
const { descriptor } = parseResult;
|
|
335
|
+
const script = descriptor.script === null && descriptor.scriptSetup === null
|
|
336
|
+
? undefined
|
|
337
|
+
: (0, compiler_sfc_1.compileScript)(descriptor, {
|
|
338
|
+
genDefaultAs: "__forgeVueDefault",
|
|
339
|
+
id,
|
|
340
|
+
});
|
|
341
|
+
const scriptContent = script?.content ?? "const __forgeVueDefault = {};";
|
|
342
|
+
const template = descriptor.template === null
|
|
343
|
+
? undefined
|
|
344
|
+
: (0, compiler_sfc_1.compileTemplate)({
|
|
345
|
+
compilerOptions: {
|
|
346
|
+
bindingMetadata: script?.bindings ?? {},
|
|
347
|
+
},
|
|
348
|
+
filename,
|
|
349
|
+
id,
|
|
350
|
+
scoped: descriptor.styles.some((style) => style.scoped),
|
|
351
|
+
source: descriptor.template.content,
|
|
352
|
+
});
|
|
353
|
+
if (template?.errors !== undefined && template.errors.length > 0) {
|
|
354
|
+
throw new Error(formatVueCompilerErrors(template.errors));
|
|
355
|
+
}
|
|
356
|
+
const templateContent = template?.code ?? "function render() { return null; }";
|
|
357
|
+
return [
|
|
358
|
+
scriptContent,
|
|
359
|
+
"",
|
|
360
|
+
templateContent,
|
|
361
|
+
"",
|
|
362
|
+
"const __forgeVueComponent = Object.assign(__forgeVueDefault, {",
|
|
363
|
+
` __file: ${JSON.stringify(sourcePath)},`,
|
|
364
|
+
" render,",
|
|
365
|
+
"});",
|
|
366
|
+
"",
|
|
367
|
+
"export default __forgeVueComponent;",
|
|
368
|
+
"",
|
|
369
|
+
].join("\n");
|
|
295
370
|
}
|
|
296
|
-
function
|
|
371
|
+
function formatVueCompilerErrors(errors) {
|
|
372
|
+
return errors
|
|
373
|
+
.map((error) => (error instanceof Error ? error.message : String(error)))
|
|
374
|
+
.join("\n");
|
|
375
|
+
}
|
|
376
|
+
function createWorkspaceCssModule(sourcePath, css) {
|
|
377
|
+
return isCssModulePath(sourcePath)
|
|
378
|
+
? createCssModule(sourcePath, css)
|
|
379
|
+
: createPlainCssModule(sourcePath, css);
|
|
380
|
+
}
|
|
381
|
+
function createPlainCssModule(sourcePath, css) {
|
|
297
382
|
return [
|
|
298
383
|
`const css = ${JSON.stringify(css)};`,
|
|
299
384
|
`const id = ${JSON.stringify(`forge-css:${sourcePath}`)};`,
|
|
@@ -306,6 +391,70 @@ function createCssModule(sourcePath, css) {
|
|
|
306
391
|
"",
|
|
307
392
|
].join("\n");
|
|
308
393
|
}
|
|
394
|
+
function createCssModule(sourcePath, css) {
|
|
395
|
+
const protectedCss = protectCssModuleGlobalSelectors(css);
|
|
396
|
+
const classMap = createCssModuleClassMap(sourcePath, protectedCss.css);
|
|
397
|
+
const rewrittenCss = restoreCssModuleGlobalSelectors(rewriteCssModuleClassSelectors(protectedCss.css, classMap), protectedCss.globalSelectors);
|
|
398
|
+
return [
|
|
399
|
+
`const css = ${JSON.stringify(rewrittenCss)};`,
|
|
400
|
+
`const id = ${JSON.stringify(`forge-css:${sourcePath}`)};`,
|
|
401
|
+
"const previous = document.querySelector(`style[data-forge-css=\"${id}\"]`);",
|
|
402
|
+
"const style = previous ?? document.createElement('style');",
|
|
403
|
+
"style.setAttribute('data-forge-css', id);",
|
|
404
|
+
"style.textContent = css;",
|
|
405
|
+
"if (previous === null) document.head.append(style);",
|
|
406
|
+
`const classes = ${JSON.stringify(classMap, null, 2)};`,
|
|
407
|
+
"export default classes;",
|
|
408
|
+
"",
|
|
409
|
+
].join("\n");
|
|
410
|
+
}
|
|
411
|
+
function protectCssModuleGlobalSelectors(css) {
|
|
412
|
+
const globalSelectors = [];
|
|
413
|
+
const protectedCss = css.replace(/:global\(([^()]*)\)/g, (_match, selector) => {
|
|
414
|
+
const placeholder = `/*__forge_css_module_global_${globalSelectors.length}__*/`;
|
|
415
|
+
globalSelectors.push({ placeholder, selector });
|
|
416
|
+
return placeholder;
|
|
417
|
+
});
|
|
418
|
+
return { css: protectedCss, globalSelectors };
|
|
419
|
+
}
|
|
420
|
+
function restoreCssModuleGlobalSelectors(css, globalSelectors) {
|
|
421
|
+
return globalSelectors.reduce((currentCss, globalSelector) => currentCss
|
|
422
|
+
.split(globalSelector.placeholder)
|
|
423
|
+
.join(globalSelector.selector), css);
|
|
424
|
+
}
|
|
425
|
+
function createCssModuleClassMap(sourcePath, css) {
|
|
426
|
+
const classNames = new Set();
|
|
427
|
+
for (const match of css.matchAll(/\.([A-Za-z_][\w-]*)/g)) {
|
|
428
|
+
classNames.add(match[1]);
|
|
429
|
+
}
|
|
430
|
+
return Object.fromEntries(Array.from(classNames)
|
|
431
|
+
.sort((left, right) => left.localeCompare(right))
|
|
432
|
+
.map((className) => [
|
|
433
|
+
className,
|
|
434
|
+
createCssModuleScopedClassName(sourcePath, className),
|
|
435
|
+
]));
|
|
436
|
+
}
|
|
437
|
+
function rewriteCssModuleClassSelectors(css, classMap) {
|
|
438
|
+
return css.replace(/(^|[\s,{>+~])\.([A-Za-z_][\w-]*)/g, (match, prefix, className) => {
|
|
439
|
+
const scopedClassName = classMap[className];
|
|
440
|
+
return scopedClassName === undefined
|
|
441
|
+
? match
|
|
442
|
+
: `${prefix}.${scopedClassName}`;
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
function createCssModuleScopedClassName(sourcePath, className) {
|
|
446
|
+
const pathParts = sourcePath.split("/");
|
|
447
|
+
const fileName = pathParts[pathParts.length - 1] ?? "style.module.css";
|
|
448
|
+
const baseName = fileName
|
|
449
|
+
.replace(/\.module\.css$/i, "")
|
|
450
|
+
.replace(/[^a-z0-9_-]+/gi, "_");
|
|
451
|
+
const safeClassName = className.replace(/[^a-z0-9_-]+/gi, "_");
|
|
452
|
+
const hash = hashText(`${sourcePath}:${className}`).slice(0, 8);
|
|
453
|
+
return `_${baseName}_${safeClassName}_${hash}`;
|
|
454
|
+
}
|
|
455
|
+
function isCssModulePath(path) {
|
|
456
|
+
return /\.module\.css$/i.test(path);
|
|
457
|
+
}
|
|
309
458
|
function createJsonModule(json) {
|
|
310
459
|
return `export default ${json.trim()};\n`;
|
|
311
460
|
}
|
|
@@ -346,6 +495,31 @@ function extractImportReferences(source) {
|
|
|
346
495
|
}
|
|
347
496
|
return references;
|
|
348
497
|
}
|
|
498
|
+
function resolveAliasSpecifier(specifier, aliases) {
|
|
499
|
+
for (const [find, replacement] of Object.entries(aliases).sort(([left], [right]) => right.length - left.length || left.localeCompare(right))) {
|
|
500
|
+
if (specifier === find) {
|
|
501
|
+
return replacement;
|
|
502
|
+
}
|
|
503
|
+
if (specifier.startsWith(`${find}/`)) {
|
|
504
|
+
const normalizedReplacement = replacement.endsWith("/")
|
|
505
|
+
? replacement.slice(0, -1)
|
|
506
|
+
: replacement;
|
|
507
|
+
return `${normalizedReplacement}${specifier.slice(find.length)}`;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
return undefined;
|
|
511
|
+
}
|
|
512
|
+
function applyDefineReplacements(source, defineReplacements) {
|
|
513
|
+
let output = source;
|
|
514
|
+
for (const [key, value] of Object.entries(defineReplacements).sort(([left], [right]) => right.length - left.length || left.localeCompare(right))) {
|
|
515
|
+
if (!isSupportedDefineKey(key)) {
|
|
516
|
+
continue;
|
|
517
|
+
}
|
|
518
|
+
const pattern = new RegExp(`(^|[^A-Za-z0-9_$.])${escapeRegExp(key)}(?![A-Za-z0-9_$])`, "g");
|
|
519
|
+
output = output.replace(pattern, (_match, prefix) => `${prefix}${value}`);
|
|
520
|
+
}
|
|
521
|
+
return output;
|
|
522
|
+
}
|
|
349
523
|
async function resolveLocalImport(fileSystem, importer, specifier) {
|
|
350
524
|
const basePath = specifier.startsWith("/")
|
|
351
525
|
? specifier
|
|
@@ -517,6 +691,12 @@ function isLocalSpecifier(specifier) {
|
|
|
517
691
|
function isExternalUrl(specifier) {
|
|
518
692
|
return /^https?:\/\//i.test(specifier) || specifier.startsWith("data:");
|
|
519
693
|
}
|
|
694
|
+
function isSupportedDefineKey(key) {
|
|
695
|
+
return /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(key);
|
|
696
|
+
}
|
|
697
|
+
function escapeRegExp(value) {
|
|
698
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
699
|
+
}
|
|
520
700
|
function dirname(path) {
|
|
521
701
|
const index = path.lastIndexOf("/");
|
|
522
702
|
return index <= 0 ? "/" : path.slice(0, index);
|
|
@@ -64,7 +64,7 @@ function createViteConfigNotExecutedDiagnostic(path) {
|
|
|
64
64
|
code: "vite_config_not_executed",
|
|
65
65
|
severity: "warning",
|
|
66
66
|
message: `Forge detected ${path} but did not execute it. ` +
|
|
67
|
-
"
|
|
67
|
+
"Only static aliases, defines, and base are parsed; plugins and dynamic config are ignored.",
|
|
68
68
|
path,
|
|
69
69
|
};
|
|
70
70
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { createBuildCancelledDiagnostic, createEsbuildWorkerTransformDiagnostic, createMissingBuildScriptDiagnostic, createMissingEntryDiagnostic, createUnresolvedImportDiagnostic, createUnsupportedBuildScriptDiagnostic, createViteConfigNotExecutedDiagnostic, } from "./diagnostics";
|
|
2
2
|
export { createBuildPipeline, DefaultBuildPipeline, isSupportedViteBuildScript, } from "./pipeline";
|
|
3
|
-
export { BUILD_PIPELINE_CAPABILITY, type ForgeBrowserBundle, type ForgeBrowserBundleManifest, type ForgeBuildDiagnostic, type ForgeBuildManifest, type ForgeBuildMode, type ForgeBuildOutputFile, type ForgeBuildPipeline, type ForgeBuildPipelineDiagnostic, type ForgeBuildPipelineDiagnosticCode, type ForgeBuildPipelineOptions, type ForgeBuildRequest, type ForgeBuildResult, type ForgeBuildTiming, } from "./types";
|
|
3
|
+
export { BUILD_PIPELINE_CAPABILITY, type ForgeBrowserBundle, type ForgeBrowserBundleManifest, type ForgeBrowserBundleModule, type ForgeBrowserBundleModuleOrigin, type ForgeBuildDiagnostic, type ForgeBuildManifest, type ForgeBuildMode, type ForgeBuildOutputFile, type ForgeBuildPipeline, type ForgeBuildPipelineDiagnostic, type ForgeBuildPipelineDiagnosticCode, type ForgeBuildPipelineOptions, type ForgeBuildRequest, type ForgeBuildResult, type ForgeBuildTiming, type ForgeViteConfigMetadata, } from "./types";
|
|
@@ -7,12 +7,8 @@ const virtual_file_system_1 = require("../virtual-file-system");
|
|
|
7
7
|
const diagnostics_1 = require("./diagnostics");
|
|
8
8
|
const browser_bundle_1 = require("./browser-bundle");
|
|
9
9
|
const types_1 = require("./types");
|
|
10
|
+
const vite_config_1 = require("./vite-config");
|
|
10
11
|
const BUILD_MANIFEST_PATH = "/.forge/build/build-manifest.json";
|
|
11
|
-
const VITE_CONFIG_PATHS = [
|
|
12
|
-
"/vite.config.js",
|
|
13
|
-
"/vite.config.mjs",
|
|
14
|
-
"/vite.config.ts",
|
|
15
|
-
];
|
|
16
12
|
const DEFAULT_ENTRY_CANDIDATES = [
|
|
17
13
|
"/src/main.tsx",
|
|
18
14
|
"/src/main.jsx",
|
|
@@ -32,10 +28,12 @@ class DefaultBuildPipeline {
|
|
|
32
28
|
if (initialCancellation !== undefined) {
|
|
33
29
|
return this.failure(mode, [initialCancellation], timingStart);
|
|
34
30
|
}
|
|
35
|
-
const
|
|
31
|
+
const viteConfigRead = await (0, vite_config_1.readViteConfigMetadata)(this.options.fileSystem);
|
|
32
|
+
const warningDiagnostics = createViteConfigDiagnostics(viteConfigRead.detectedPaths);
|
|
33
|
+
const viteConfig = viteConfigRead.metadata;
|
|
36
34
|
const configCancellation = getCancellationDiagnostic(request.signal);
|
|
37
35
|
if (configCancellation !== undefined) {
|
|
38
|
-
return this.failure(mode, [configCancellation, ...warningDiagnostics], timingStart);
|
|
36
|
+
return this.failure(mode, [configCancellation, ...warningDiagnostics], timingStart, viteConfig);
|
|
39
37
|
}
|
|
40
38
|
let manifest;
|
|
41
39
|
try {
|
|
@@ -43,34 +41,34 @@ class DefaultBuildPipeline {
|
|
|
43
41
|
}
|
|
44
42
|
catch (error) {
|
|
45
43
|
if (error instanceof package_resolution_1.ForgePackageResolutionError) {
|
|
46
|
-
return this.failure(mode, [error.diagnostic, ...error.warnings, ...warningDiagnostics], timingStart);
|
|
44
|
+
return this.failure(mode, [error.diagnostic, ...error.warnings, ...warningDiagnostics], timingStart, viteConfig);
|
|
47
45
|
}
|
|
48
46
|
throw error;
|
|
49
47
|
}
|
|
50
48
|
const buildScript = manifest.scripts.build;
|
|
51
49
|
if (buildScript === undefined) {
|
|
52
|
-
return this.failure(mode, [(0, diagnostics_1.createMissingBuildScriptDiagnostic)(), ...warningDiagnostics], timingStart);
|
|
50
|
+
return this.failure(mode, [(0, diagnostics_1.createMissingBuildScriptDiagnostic)(), ...warningDiagnostics], timingStart, viteConfig);
|
|
53
51
|
}
|
|
54
52
|
if (!isSupportedViteBuildScript(buildScript)) {
|
|
55
53
|
return this.failure(mode, [
|
|
56
54
|
(0, diagnostics_1.createUnsupportedBuildScriptDiagnostic)(buildScript),
|
|
57
55
|
...warningDiagnostics,
|
|
58
|
-
], timingStart);
|
|
56
|
+
], timingStart, viteConfig);
|
|
59
57
|
}
|
|
60
58
|
const manifestCancellation = getCancellationDiagnostic(request.signal);
|
|
61
59
|
if (manifestCancellation !== undefined) {
|
|
62
|
-
return this.failure(mode, [manifestCancellation, ...warningDiagnostics], timingStart);
|
|
60
|
+
return this.failure(mode, [manifestCancellation, ...warningDiagnostics], timingStart, viteConfig);
|
|
63
61
|
}
|
|
64
62
|
const entry = await this.resolveEntry(request.entry);
|
|
65
63
|
if (entry === undefined) {
|
|
66
|
-
return this.failure(mode, [(0, diagnostics_1.createMissingEntryDiagnostic)(), ...warningDiagnostics], timingStart);
|
|
64
|
+
return this.failure(mode, [(0, diagnostics_1.createMissingEntryDiagnostic)(), ...warningDiagnostics], timingStart, viteConfig);
|
|
67
65
|
}
|
|
68
66
|
try {
|
|
69
67
|
const packageResolution = await this.options.packageResolver.resolve();
|
|
70
68
|
const packageWarnings = packageResolution.warnings;
|
|
71
69
|
const packageCancellation = getCancellationDiagnostic(request.signal);
|
|
72
70
|
if (packageCancellation !== undefined) {
|
|
73
|
-
return this.failure(mode, [packageCancellation, ...packageWarnings, ...warningDiagnostics], timingStart);
|
|
71
|
+
return this.failure(mode, [packageCancellation, ...packageWarnings, ...warningDiagnostics], timingStart, viteConfig);
|
|
74
72
|
}
|
|
75
73
|
const sourceFiles = await collectSourceFiles(this.options.fileSystem);
|
|
76
74
|
const browserBundleResult = await (0, browser_bundle_1.createBrowserBundle)({
|
|
@@ -78,38 +76,39 @@ class DefaultBuildPipeline {
|
|
|
78
76
|
fileSystem: this.options.fileSystem,
|
|
79
77
|
packageResolution,
|
|
80
78
|
scriptTransformer: createEsbuildWorkerScriptTransformer(this.options.esbuildWorker),
|
|
79
|
+
viteConfig,
|
|
81
80
|
});
|
|
82
81
|
if (browserBundleResult.diagnostics.length > 0) {
|
|
83
82
|
return this.failure(mode, [
|
|
84
83
|
...browserBundleResult.diagnostics,
|
|
85
84
|
...packageWarnings,
|
|
86
85
|
...warningDiagnostics,
|
|
87
|
-
], timingStart);
|
|
86
|
+
], timingStart, viteConfig);
|
|
88
87
|
}
|
|
89
88
|
if (browserBundleResult.browserBundle === undefined) {
|
|
90
89
|
throw new Error("Browser bundle output was missing after a successful build.");
|
|
91
90
|
}
|
|
92
91
|
const bundleCancellation = getCancellationDiagnostic(request.signal);
|
|
93
92
|
if (bundleCancellation !== undefined) {
|
|
94
|
-
return this.failure(mode, [bundleCancellation, ...packageWarnings, ...warningDiagnostics], timingStart);
|
|
93
|
+
return this.failure(mode, [bundleCancellation, ...packageWarnings, ...warningDiagnostics], timingStart, viteConfig);
|
|
95
94
|
}
|
|
96
|
-
const buildManifest = createBuildManifest(entry, mode, sourceFiles, packageResolution, browserBundleResult.browserBundle);
|
|
95
|
+
const buildManifest = createBuildManifest(entry, mode, sourceFiles, packageResolution, browserBundleResult.browserBundle, viteConfig);
|
|
97
96
|
const outputFiles = [
|
|
98
97
|
createBuildManifestOutput(buildManifest),
|
|
99
98
|
...browserBundleResult.outputFiles,
|
|
100
99
|
];
|
|
101
100
|
const outputCancellation = getCancellationDiagnostic(request.signal);
|
|
102
101
|
if (outputCancellation !== undefined) {
|
|
103
|
-
return this.failure(mode, [outputCancellation, ...packageWarnings, ...warningDiagnostics], timingStart);
|
|
102
|
+
return this.failure(mode, [outputCancellation, ...packageWarnings, ...warningDiagnostics], timingStart, viteConfig);
|
|
104
103
|
}
|
|
105
104
|
const outputWriteDiagnostic = await writeBuildOutputFilesAtomically(this.options.fileSystem, outputFiles);
|
|
106
105
|
if (outputWriteDiagnostic !== undefined) {
|
|
107
|
-
return this.failure(mode, [outputWriteDiagnostic, ...packageWarnings, ...warningDiagnostics], timingStart);
|
|
106
|
+
return this.failure(mode, [outputWriteDiagnostic, ...packageWarnings, ...warningDiagnostics], timingStart, viteConfig);
|
|
108
107
|
}
|
|
109
108
|
const buildCacheWarnings = await this.writeBuildCacheRecord(entry, mode, buildManifest, browserBundleResult.browserBundle, outputFiles);
|
|
110
109
|
const cacheCancellation = getCancellationDiagnostic(request.signal);
|
|
111
110
|
if (cacheCancellation !== undefined) {
|
|
112
|
-
return this.failure(mode, [cacheCancellation, ...packageWarnings, ...buildCacheWarnings, ...warningDiagnostics], timingStart);
|
|
111
|
+
return this.failure(mode, [cacheCancellation, ...packageWarnings, ...buildCacheWarnings, ...warningDiagnostics], timingStart, viteConfig);
|
|
113
112
|
}
|
|
114
113
|
return this.complete({
|
|
115
114
|
success: true,
|
|
@@ -124,12 +123,13 @@ class DefaultBuildPipeline {
|
|
|
124
123
|
...warningDiagnostics,
|
|
125
124
|
],
|
|
126
125
|
packageResolution,
|
|
126
|
+
viteConfig,
|
|
127
127
|
timing: completeTiming(timingStart, this.now()),
|
|
128
128
|
});
|
|
129
129
|
}
|
|
130
130
|
catch (error) {
|
|
131
131
|
if (error instanceof package_resolution_1.ForgePackageResolutionError) {
|
|
132
|
-
return this.failure(mode, [error.diagnostic, ...error.warnings, ...warningDiagnostics], timingStart);
|
|
132
|
+
return this.failure(mode, [error.diagnostic, ...error.warnings, ...warningDiagnostics], timingStart, viteConfig);
|
|
133
133
|
}
|
|
134
134
|
throw error;
|
|
135
135
|
}
|
|
@@ -153,12 +153,13 @@ class DefaultBuildPipeline {
|
|
|
153
153
|
}
|
|
154
154
|
return undefined;
|
|
155
155
|
}
|
|
156
|
-
failure(mode, diagnostics, timingStart) {
|
|
156
|
+
failure(mode, diagnostics, timingStart, viteConfig) {
|
|
157
157
|
return this.complete({
|
|
158
158
|
success: false,
|
|
159
159
|
mode,
|
|
160
160
|
outputFiles: [],
|
|
161
161
|
diagnostics,
|
|
162
|
+
viteConfig,
|
|
162
163
|
timing: completeTiming(timingStart, this.now()),
|
|
163
164
|
});
|
|
164
165
|
}
|
|
@@ -255,14 +256,8 @@ function createEsbuildWorkerScriptTransformer(esbuildWorker) {
|
|
|
255
256
|
};
|
|
256
257
|
};
|
|
257
258
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
for (const path of VITE_CONFIG_PATHS) {
|
|
261
|
-
if (await fileSystem.exists(path)) {
|
|
262
|
-
diagnostics.push((0, diagnostics_1.createViteConfigNotExecutedDiagnostic)(path));
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
return diagnostics;
|
|
259
|
+
function createViteConfigDiagnostics(paths) {
|
|
260
|
+
return paths.map((path) => (0, diagnostics_1.createViteConfigNotExecutedDiagnostic)(path));
|
|
266
261
|
}
|
|
267
262
|
function createBuildPipeline(options) {
|
|
268
263
|
return new DefaultBuildPipeline(options);
|
|
@@ -309,13 +304,14 @@ async function collectSourceFiles(fileSystem, path = "/") {
|
|
|
309
304
|
}
|
|
310
305
|
return files.sort((left, right) => left.localeCompare(right));
|
|
311
306
|
}
|
|
312
|
-
function createBuildManifest(entry, mode, sourceFiles, packageResolution, browserBundle) {
|
|
307
|
+
function createBuildManifest(entry, mode, sourceFiles, packageResolution, browserBundle, viteConfig) {
|
|
313
308
|
return {
|
|
314
309
|
entry,
|
|
315
310
|
mode,
|
|
316
311
|
sourceFiles,
|
|
317
312
|
packageNames: packageResolution.packages.map((record) => record.name),
|
|
318
313
|
packageResolutionMode: packageResolution.lock.resolutionMode,
|
|
314
|
+
viteConfig,
|
|
319
315
|
browserBundle: browserBundle === undefined
|
|
320
316
|
? undefined
|
|
321
317
|
: {
|
|
@@ -323,7 +319,9 @@ function createBuildManifest(entry, mode, sourceFiles, packageResolution, browse
|
|
|
323
319
|
format: browserBundle.format,
|
|
324
320
|
importMapPath: browserBundle.importMapPath,
|
|
325
321
|
moduleCount: browserBundle.moduleCount,
|
|
322
|
+
modules: browserBundle.modules,
|
|
326
323
|
outputPaths: browserBundle.outputPaths,
|
|
324
|
+
viteConfig: browserBundle.viteConfig,
|
|
327
325
|
},
|
|
328
326
|
};
|
|
329
327
|
}
|
|
@@ -23,6 +23,12 @@ export interface ForgeBuildOutputFile {
|
|
|
23
23
|
readonly contentType: string;
|
|
24
24
|
readonly size: number;
|
|
25
25
|
}
|
|
26
|
+
export interface ForgeViteConfigMetadata {
|
|
27
|
+
readonly path: string;
|
|
28
|
+
readonly aliases: Readonly<Record<string, string>>;
|
|
29
|
+
readonly define: Readonly<Record<string, string>>;
|
|
30
|
+
readonly base?: string;
|
|
31
|
+
}
|
|
26
32
|
export interface ForgeBuildManifest {
|
|
27
33
|
readonly entry: string;
|
|
28
34
|
readonly mode: ForgeBuildMode;
|
|
@@ -30,13 +36,22 @@ export interface ForgeBuildManifest {
|
|
|
30
36
|
readonly packageNames: readonly string[];
|
|
31
37
|
readonly packageResolutionMode: string;
|
|
32
38
|
readonly browserBundle?: ForgeBrowserBundleManifest;
|
|
39
|
+
readonly viteConfig?: ForgeViteConfigMetadata;
|
|
40
|
+
}
|
|
41
|
+
export type ForgeBrowserBundleModuleOrigin = "package" | "workspace";
|
|
42
|
+
export interface ForgeBrowserBundleModule {
|
|
43
|
+
readonly origin: ForgeBrowserBundleModuleOrigin;
|
|
44
|
+
readonly outputPath: string;
|
|
45
|
+
readonly sourcePath: string;
|
|
33
46
|
}
|
|
34
47
|
export interface ForgeBrowserBundleManifest {
|
|
35
48
|
readonly entryOutputPath: string;
|
|
36
49
|
readonly format: "esm";
|
|
37
50
|
readonly importMapPath: string;
|
|
38
51
|
readonly moduleCount: number;
|
|
52
|
+
readonly modules: readonly ForgeBrowserBundleModule[];
|
|
39
53
|
readonly outputPaths: readonly string[];
|
|
54
|
+
readonly viteConfig?: ForgeViteConfigMetadata;
|
|
40
55
|
}
|
|
41
56
|
export interface ForgeBrowserBundle {
|
|
42
57
|
readonly entry: string;
|
|
@@ -45,7 +60,9 @@ export interface ForgeBrowserBundle {
|
|
|
45
60
|
readonly importMap: ForgeImportMap;
|
|
46
61
|
readonly importMapPath: string;
|
|
47
62
|
readonly moduleCount: number;
|
|
63
|
+
readonly modules: readonly ForgeBrowserBundleModule[];
|
|
48
64
|
readonly outputPaths: readonly string[];
|
|
65
|
+
readonly viteConfig?: ForgeViteConfigMetadata;
|
|
49
66
|
}
|
|
50
67
|
export interface ForgeBuildTiming {
|
|
51
68
|
readonly startedAt: string;
|
|
@@ -61,6 +78,7 @@ export interface ForgeBuildResult {
|
|
|
61
78
|
readonly outputFiles: readonly ForgeBuildOutputFile[];
|
|
62
79
|
readonly diagnostics: readonly ForgeBuildDiagnostic[];
|
|
63
80
|
readonly packageResolution?: ForgePackageResolutionResult;
|
|
81
|
+
readonly viteConfig?: ForgeViteConfigMetadata;
|
|
64
82
|
readonly timing: ForgeBuildTiming;
|
|
65
83
|
}
|
|
66
84
|
export interface ForgeBuildPipelineOptions {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ForgeVirtualFileSystem } from "../virtual-file-system";
|
|
2
|
+
import type { ForgeViteConfigMetadata } from "./types";
|
|
3
|
+
export declare const VITE_CONFIG_PATHS: readonly ["/vite.config.js", "/vite.config.mjs", "/vite.config.ts"];
|
|
4
|
+
export interface ForgeViteConfigReadResult {
|
|
5
|
+
readonly detectedPaths: readonly string[];
|
|
6
|
+
readonly metadata?: ForgeViteConfigMetadata;
|
|
7
|
+
}
|
|
8
|
+
export declare function readViteConfigMetadata(fileSystem: ForgeVirtualFileSystem): Promise<ForgeViteConfigReadResult>;
|