evolit 0.2.1 → 0.4.0
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 +108 -0
- package/package.json +8 -2
- package/src/build.js +88 -11
- package/src/client-assets.js +1 -0
- package/src/compiler.js +301 -34
- package/src/deployment-runtime.js +77 -8
- package/src/index.js +3 -0
- package/src/litsx-pipeline.d.ts +137 -0
- package/src/litsx-pipeline.js +705 -0
- package/src/render.js +1 -0
- package/src/server-setup.js +65 -0
- package/src/server.js +41 -1
- package/src/urql-ssr.js +67 -2
package/src/compiler.js
CHANGED
|
@@ -20,6 +20,7 @@ import { ensureDirectory } from "./fs-utils.js";
|
|
|
20
20
|
const MODULE_SPECIFIER_PATTERN =
|
|
21
21
|
/\b(?:import|export)\s+(?:[^"']*?\s+from\s+)?["']([^"']+)["']|\bimport\s*\(\s*["']([^"']+)["']\s*\)/g;
|
|
22
22
|
const CSS_DEPENDENCY_PATTERN = /(?:@import\s+(?:url\(\s*)?["']([^"']+)["']\s*\)?|url\(\s*["']?([^"')]+)["']?\s*\))/g;
|
|
23
|
+
const DYNAMIC_IMPORT_WILDCARD = "\u0000EVOLIT_DYNAMIC_IMPORT_WILDCARD\u0000";
|
|
23
24
|
const RESOLVABLE_IMPORT_EXTENSIONS = [
|
|
24
25
|
...MODULE_EXTENSIONS,
|
|
25
26
|
...STATIC_ASSET_EXTENSIONS,
|
|
@@ -181,14 +182,28 @@ async function transformModuleSource(source, {
|
|
|
181
182
|
sourcePath,
|
|
182
183
|
sourceMaps,
|
|
183
184
|
ssr = false,
|
|
185
|
+
target = ssr ? "server" : "client",
|
|
186
|
+
litsxPipeline = null,
|
|
184
187
|
}) {
|
|
185
188
|
if (isLitsxAuthoredModule(sourcePath, source)) {
|
|
186
|
-
const
|
|
187
|
-
filename: sourcePath,
|
|
188
|
-
sourceMaps,
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
const compilerOptions = litsxPipeline
|
|
190
|
+
? litsxPipeline.getCompilerOptions({ filename: sourcePath, sourceMaps, ssr })
|
|
191
|
+
: { filename: sourcePath, sourceMaps, ssr };
|
|
192
|
+
const transformed = restoreSideEffectImports(
|
|
193
|
+
source,
|
|
194
|
+
sourcePath,
|
|
195
|
+
await transformLitsx(source, compilerOptions),
|
|
196
|
+
compilerOptions.sourceMaps === true,
|
|
197
|
+
);
|
|
198
|
+
return litsxPipeline
|
|
199
|
+
? litsxPipeline.processModule(transformed, {
|
|
200
|
+
source,
|
|
201
|
+
sourcePath,
|
|
202
|
+
sourceMaps: compilerOptions.sourceMaps === true,
|
|
203
|
+
ssr: ssr === true,
|
|
204
|
+
target,
|
|
205
|
+
})
|
|
206
|
+
: transformed;
|
|
192
207
|
}
|
|
193
208
|
|
|
194
209
|
if (sourcePath.endsWith(".ts")) {
|
|
@@ -388,17 +403,30 @@ function getCompiledServerComponentExports(code, sourcePath) {
|
|
|
388
403
|
return exports;
|
|
389
404
|
}
|
|
390
405
|
|
|
391
|
-
function
|
|
392
|
-
const sourceFile = ts.createSourceFile(sourcePath, code, ts.ScriptTarget.Latest, true,
|
|
406
|
+
function analyzeModuleReferences(code, sourcePath, scriptKind = ts.ScriptKind.JS) {
|
|
407
|
+
const sourceFile = ts.createSourceFile(sourcePath, code, ts.ScriptTarget.Latest, true, scriptKind);
|
|
393
408
|
const bySpecifier = new Map();
|
|
409
|
+
const staticReferences = [];
|
|
410
|
+
const dynamicReferences = [];
|
|
394
411
|
const add = (specifier, name) => {
|
|
395
412
|
const names = bySpecifier.get(specifier) ?? new Set();
|
|
396
413
|
names.add(name);
|
|
397
414
|
bySpecifier.set(specifier, names);
|
|
398
415
|
};
|
|
416
|
+
const addStaticReference = (node, importedName = null) => {
|
|
417
|
+
const specifier = node.text;
|
|
418
|
+
staticReferences.push({
|
|
419
|
+
specifier,
|
|
420
|
+
start: node.getStart(sourceFile) + 1,
|
|
421
|
+
end: node.end - 1,
|
|
422
|
+
});
|
|
423
|
+
if (importedName) add(specifier, importedName);
|
|
424
|
+
};
|
|
425
|
+
|
|
399
426
|
for (const statement of sourceFile.statements) {
|
|
400
|
-
if (ts.isImportDeclaration(statement) && ts.
|
|
427
|
+
if (ts.isImportDeclaration(statement) && ts.isStringLiteralLike(statement.moduleSpecifier)) {
|
|
401
428
|
const specifier = statement.moduleSpecifier.text;
|
|
429
|
+
addStaticReference(statement.moduleSpecifier);
|
|
402
430
|
if (statement.importClause?.name) add(specifier, "default");
|
|
403
431
|
if (statement.importClause?.namedBindings && ts.isNamedImports(statement.importClause.namedBindings)) {
|
|
404
432
|
for (const element of statement.importClause.namedBindings.elements) {
|
|
@@ -408,9 +436,10 @@ function collectImportedNamesBySpecifier(code, sourcePath) {
|
|
|
408
436
|
} else if (
|
|
409
437
|
ts.isExportDeclaration(statement)
|
|
410
438
|
&& statement.moduleSpecifier
|
|
411
|
-
&& ts.
|
|
439
|
+
&& ts.isStringLiteralLike(statement.moduleSpecifier)
|
|
412
440
|
) {
|
|
413
441
|
const specifier = statement.moduleSpecifier.text;
|
|
442
|
+
addStaticReference(statement.moduleSpecifier);
|
|
414
443
|
if (!statement.exportClause) add(specifier, "*");
|
|
415
444
|
else if (ts.isNamedExports(statement.exportClause)) {
|
|
416
445
|
for (const element of statement.exportClause.elements) add(specifier, element.propertyName?.text ?? element.name.text);
|
|
@@ -421,13 +450,119 @@ function collectImportedNamesBySpecifier(code, sourcePath) {
|
|
|
421
450
|
if (
|
|
422
451
|
ts.isCallExpression(node)
|
|
423
452
|
&& node.expression.kind === ts.SyntaxKind.ImportKeyword
|
|
424
|
-
&& node.arguments.length
|
|
425
|
-
|
|
426
|
-
|
|
453
|
+
&& node.arguments.length >= 1
|
|
454
|
+
) {
|
|
455
|
+
const argument = node.arguments[0];
|
|
456
|
+
if (ts.isStringLiteralLike(argument)) {
|
|
457
|
+
addStaticReference(argument, "*");
|
|
458
|
+
} else if (ts.isTemplateExpression(argument)) {
|
|
459
|
+
const staticParts = [
|
|
460
|
+
argument.head.text,
|
|
461
|
+
...argument.templateSpans.map((span) => span.literal.text),
|
|
462
|
+
];
|
|
463
|
+
dynamicReferences.push({
|
|
464
|
+
pattern: staticParts.join(DYNAMIC_IMPORT_WILDCARD),
|
|
465
|
+
displayPattern: staticParts.join("*"),
|
|
466
|
+
expressionText: code.slice(argument.getStart(sourceFile), argument.end),
|
|
467
|
+
optionsText: node.arguments.length > 1
|
|
468
|
+
? code.slice(node.arguments[1].getStart(sourceFile), node.arguments.at(-1).end)
|
|
469
|
+
: null,
|
|
470
|
+
start: node.getStart(sourceFile),
|
|
471
|
+
end: node.end,
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
}
|
|
427
475
|
ts.forEachChild(node, visit);
|
|
428
476
|
};
|
|
429
477
|
visit(sourceFile);
|
|
430
|
-
|
|
478
|
+
|
|
479
|
+
return {
|
|
480
|
+
importedNamesBySpecifier: bySpecifier,
|
|
481
|
+
staticReferences,
|
|
482
|
+
dynamicReferences,
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function escapeRegExp(value) {
|
|
487
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
function createDynamicImportSegmentPattern(segment) {
|
|
491
|
+
return new RegExp(
|
|
492
|
+
`^${segment.split(DYNAMIC_IMPORT_WILDCARD).map(escapeRegExp).join("[^/]+")}$`,
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
async function discoverDynamicImportCandidates({
|
|
497
|
+
projectRoot,
|
|
498
|
+
sourcePath,
|
|
499
|
+
pattern,
|
|
500
|
+
displayPattern,
|
|
501
|
+
managedSourceRoots,
|
|
502
|
+
}) {
|
|
503
|
+
const normalizedPattern = pattern.replaceAll("\\", "/");
|
|
504
|
+
if (!isRelativeSpecifier(normalizedPattern)) {
|
|
505
|
+
throw new Error(
|
|
506
|
+
`Dynamic import pattern ${JSON.stringify(displayPattern)} in ${sourcePath} must be relative.`,
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
if (!MODULE_EXTENSIONS.some((extension) => normalizedPattern.endsWith(extension))) {
|
|
510
|
+
throw new Error(
|
|
511
|
+
`Dynamic import pattern ${JSON.stringify(displayPattern)} in ${sourcePath} must end in a supported module extension.`,
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
const segments = normalizedPattern.split("/");
|
|
516
|
+
const firstDynamicSegment = segments.findIndex((segment) => segment.includes(DYNAMIC_IMPORT_WILDCARD));
|
|
517
|
+
if (firstDynamicSegment < 0) return { candidates: [], watchedDirectories: [] };
|
|
518
|
+
|
|
519
|
+
const scanRoot = path.resolve(path.dirname(sourcePath), ...segments.slice(0, firstDynamicSegment));
|
|
520
|
+
if (isPathOutsideManagedRoots(projectRoot, managedSourceRoots, scanRoot)) {
|
|
521
|
+
throw new Error(
|
|
522
|
+
`Dynamic import pattern ${JSON.stringify(displayPattern)} in ${sourcePath} resolves outside the managed source roots.`,
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
const segmentPatterns = segments
|
|
527
|
+
.slice(firstDynamicSegment)
|
|
528
|
+
.map(createDynamicImportSegmentPattern);
|
|
529
|
+
const candidates = [];
|
|
530
|
+
const watchedDirectories = new Set();
|
|
531
|
+
|
|
532
|
+
async function visitDirectory(directory, segmentIndex) {
|
|
533
|
+
watchedDirectories.add(directory);
|
|
534
|
+
let entries;
|
|
535
|
+
try {
|
|
536
|
+
entries = await fs.readdir(directory, { withFileTypes: true });
|
|
537
|
+
} catch (error) {
|
|
538
|
+
if (error?.code === "ENOENT" || error?.code === "ENOTDIR") return;
|
|
539
|
+
throw error;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
const matcher = segmentPatterns[segmentIndex];
|
|
543
|
+
const isFinalSegment = segmentIndex === segmentPatterns.length - 1;
|
|
544
|
+
for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
|
|
545
|
+
if (!matcher.test(entry.name)) continue;
|
|
546
|
+
const candidatePath = path.join(directory, entry.name);
|
|
547
|
+
if (isFinalSegment) {
|
|
548
|
+
if (entry.isFile()) candidates.push(candidatePath);
|
|
549
|
+
} else if (entry.isDirectory()) {
|
|
550
|
+
await visitDirectory(candidatePath, segmentIndex + 1);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
await visitDirectory(scanRoot, 0);
|
|
556
|
+
if (candidates.length === 0) {
|
|
557
|
+
throw new Error(
|
|
558
|
+
`Dynamic import pattern ${JSON.stringify(displayPattern)} in ${sourcePath} did not match any modules.`,
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
return {
|
|
563
|
+
candidates,
|
|
564
|
+
watchedDirectories: [...watchedDirectories],
|
|
565
|
+
};
|
|
431
566
|
}
|
|
432
567
|
|
|
433
568
|
function createClientServerComponentImportError(entryPath, sourcePath, parents) {
|
|
@@ -841,23 +976,32 @@ async function rewriteRelativeSpecifiers({
|
|
|
841
976
|
managedSourceRoots,
|
|
842
977
|
serverExportsByModule,
|
|
843
978
|
packageImports,
|
|
979
|
+
dynamicImportDirectories,
|
|
980
|
+
litsxPipeline,
|
|
844
981
|
}) {
|
|
845
982
|
const magicSource = new MagicString(code);
|
|
846
983
|
let didRewrite = false;
|
|
984
|
+
const moduleReferences = analyzeModuleReferences(code, sourcePath);
|
|
847
985
|
const importedNamesBySpecifier = target === "client"
|
|
848
|
-
?
|
|
986
|
+
? moduleReferences.importedNamesBySpecifier
|
|
849
987
|
: new Map();
|
|
850
988
|
|
|
851
|
-
for (const
|
|
852
|
-
const specifier =
|
|
853
|
-
if (!specifier) {
|
|
854
|
-
continue;
|
|
855
|
-
}
|
|
989
|
+
for (const reference of moduleReferences.staticReferences) {
|
|
990
|
+
const { specifier } = reference;
|
|
856
991
|
|
|
857
|
-
const
|
|
992
|
+
const virtualImportPath = litsxPipeline
|
|
993
|
+
? await litsxPipeline.resolveModule(specifier, {
|
|
994
|
+
importer: sourcePath,
|
|
995
|
+
target,
|
|
996
|
+
ssr: target === "server",
|
|
997
|
+
sourceMaps,
|
|
998
|
+
})
|
|
999
|
+
: null;
|
|
1000
|
+
|
|
1001
|
+
const aliasedImportPath = !virtualImportPath && isBareSpecifier(specifier)
|
|
858
1002
|
? await resolveProjectMappedImport(projectRoot, sourcePath, specifier)
|
|
859
1003
|
: null;
|
|
860
|
-
const packageImportPath = isBareSpecifier(specifier) && !aliasedImportPath
|
|
1004
|
+
const packageImportPath = !virtualImportPath && isBareSpecifier(specifier) && !aliasedImportPath
|
|
861
1005
|
? await resolveProjectPackageImport(projectRoot, sourcePath, specifier)
|
|
862
1006
|
: null;
|
|
863
1007
|
const packageAssetPath = packageImportPath && isStaticAssetPath(packageImportPath)
|
|
@@ -867,6 +1011,7 @@ async function rewriteRelativeSpecifiers({
|
|
|
867
1011
|
if (
|
|
868
1012
|
target === "server"
|
|
869
1013
|
&& isBareSpecifier(specifier)
|
|
1014
|
+
&& !virtualImportPath
|
|
870
1015
|
&& !aliasedImportPath
|
|
871
1016
|
&& !packageAssetPath
|
|
872
1017
|
) {
|
|
@@ -876,6 +1021,7 @@ async function rewriteRelativeSpecifiers({
|
|
|
876
1021
|
if (
|
|
877
1022
|
target === "client"
|
|
878
1023
|
&& isBareSpecifier(specifier)
|
|
1024
|
+
&& !virtualImportPath
|
|
879
1025
|
&& !aliasedImportPath
|
|
880
1026
|
&& !packageAssetPath
|
|
881
1027
|
) {
|
|
@@ -890,11 +1036,12 @@ async function rewriteRelativeSpecifiers({
|
|
|
890
1036
|
continue;
|
|
891
1037
|
}
|
|
892
1038
|
|
|
893
|
-
if (!isRelativeSpecifier(specifier) && !aliasedImportPath && !packageAssetPath) {
|
|
1039
|
+
if (!virtualImportPath && !isRelativeSpecifier(specifier) && !aliasedImportPath && !packageAssetPath) {
|
|
894
1040
|
continue;
|
|
895
1041
|
}
|
|
896
1042
|
|
|
897
|
-
const resolvedImportPath =
|
|
1043
|
+
const resolvedImportPath = virtualImportPath
|
|
1044
|
+
?? packageAssetPath
|
|
898
1045
|
?? aliasedImportPath
|
|
899
1046
|
?? await resolveImportPath(sourcePath, specifier);
|
|
900
1047
|
if (!resolvedImportPath) {
|
|
@@ -913,6 +1060,9 @@ async function rewriteRelativeSpecifiers({
|
|
|
913
1060
|
|
|
914
1061
|
if (shouldCompileModule(resolvedImportPath)) {
|
|
915
1062
|
compiledImportPath = await compileModule(resolvedImportPath);
|
|
1063
|
+
if (virtualImportPath) {
|
|
1064
|
+
litsxPipeline?.registerResolvedModule(specifier, resolvedImportPath, compiledImportPath);
|
|
1065
|
+
}
|
|
916
1066
|
const serverExports = serverExportsByModule?.get(resolvedImportPath) ?? new Set();
|
|
917
1067
|
const importedNames = importedNamesBySpecifier.get(specifier) ?? new Set();
|
|
918
1068
|
if (
|
|
@@ -996,18 +1146,99 @@ async function rewriteRelativeSpecifiers({
|
|
|
996
1146
|
) {
|
|
997
1147
|
normalizedReplacement = `${normalizedReplacement}?${serverImportQuery}`;
|
|
998
1148
|
}
|
|
999
|
-
const quotedSpecifierIndex = match.index + match[0].indexOf(specifier);
|
|
1000
1149
|
const replacementValue = normalizedReplacement.split(path.sep).join("/");
|
|
1001
1150
|
if (replacementValue !== specifier) {
|
|
1002
1151
|
didRewrite = true;
|
|
1003
1152
|
magicSource.update(
|
|
1004
|
-
|
|
1005
|
-
|
|
1153
|
+
reference.start,
|
|
1154
|
+
reference.end,
|
|
1006
1155
|
replacementValue,
|
|
1007
1156
|
);
|
|
1008
1157
|
}
|
|
1009
1158
|
}
|
|
1010
1159
|
|
|
1160
|
+
const dynamicImportHelpers = [];
|
|
1161
|
+
for (const [index, reference] of moduleReferences.dynamicReferences.entries()) {
|
|
1162
|
+
const discovery = await discoverDynamicImportCandidates({
|
|
1163
|
+
projectRoot,
|
|
1164
|
+
sourcePath,
|
|
1165
|
+
pattern: reference.pattern,
|
|
1166
|
+
displayPattern: reference.displayPattern,
|
|
1167
|
+
managedSourceRoots,
|
|
1168
|
+
});
|
|
1169
|
+
discovery.watchedDirectories.forEach((directory) => dynamicImportDirectories.add(directory));
|
|
1170
|
+
|
|
1171
|
+
const cases = [];
|
|
1172
|
+
for (const resolvedImportPath of discovery.candidates) {
|
|
1173
|
+
const compiledImportPath = await compileModule(resolvedImportPath);
|
|
1174
|
+
const serverExports = serverExportsByModule?.get(resolvedImportPath) ?? new Set();
|
|
1175
|
+
if (target === "client" && serverExports.size > 0) {
|
|
1176
|
+
throw new Error(
|
|
1177
|
+
`Client module ${sourcePath} dynamically imports Server Component export(s) from ${resolvedImportPath}: `
|
|
1178
|
+
+ `${[...serverExports].join(", ")}. Split the server exports into a separate module.`,
|
|
1179
|
+
);
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
const importerOutputPath = toOutputPath(projectRoot, outputRoot, sourcePath);
|
|
1183
|
+
let replacementPath = path.relative(path.dirname(importerOutputPath), compiledImportPath);
|
|
1184
|
+
if (!replacementPath.startsWith(".")) replacementPath = `./${replacementPath}`;
|
|
1185
|
+
replacementPath = replacementPath.split(path.sep).join("/");
|
|
1186
|
+
if (
|
|
1187
|
+
target === "server"
|
|
1188
|
+
&& mode === "development"
|
|
1189
|
+
&& typeof serverImportQuery === "string"
|
|
1190
|
+
&& serverImportQuery.length > 0
|
|
1191
|
+
) {
|
|
1192
|
+
replacementPath = `${replacementPath}?${serverImportQuery}`;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
let sourceSpecifier = path.relative(path.dirname(sourcePath), resolvedImportPath)
|
|
1196
|
+
.split(path.sep)
|
|
1197
|
+
.join("/");
|
|
1198
|
+
if (!sourceSpecifier.startsWith(".")) sourceSpecifier = `./${sourceSpecifier}`;
|
|
1199
|
+
cases.push(
|
|
1200
|
+
` case ${JSON.stringify(sourceSpecifier)}: return import(${JSON.stringify(replacementPath)}${reference.optionsText ? ", options" : ""});`,
|
|
1201
|
+
);
|
|
1202
|
+
|
|
1203
|
+
if (target === "client") {
|
|
1204
|
+
const sourceMetadata = moduleMetadata.get(sourcePath) ?? {
|
|
1205
|
+
moduleImports: new Set(),
|
|
1206
|
+
vendorImports: new Set(),
|
|
1207
|
+
styleImports: new Set(),
|
|
1208
|
+
assetImports: new Set(),
|
|
1209
|
+
};
|
|
1210
|
+
sourceMetadata.moduleImports.add(
|
|
1211
|
+
path.relative(outputRoot, compiledImportPath).split(path.sep).join("/"),
|
|
1212
|
+
);
|
|
1213
|
+
moduleMetadata.set(sourcePath, sourceMetadata);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
let helperName = `__evolit_dynamic_import_${index}`;
|
|
1218
|
+
while (code.includes(helperName)) helperName = `_${helperName}`;
|
|
1219
|
+
const sourceModuleId = path.relative(projectRoot, sourcePath).split(path.sep).join("/");
|
|
1220
|
+
const unknownImportPrefix = `Unknown dynamic import in ${sourceModuleId}: `;
|
|
1221
|
+
dynamicImportHelpers.push([
|
|
1222
|
+
`function ${helperName}(specifier${reference.optionsText ? ", options" : ""}) {`,
|
|
1223
|
+
" switch (specifier) {",
|
|
1224
|
+
...cases,
|
|
1225
|
+
" default:",
|
|
1226
|
+
` return Promise.reject(new Error(${JSON.stringify(unknownImportPrefix)} + specifier));`,
|
|
1227
|
+
" }",
|
|
1228
|
+
"}",
|
|
1229
|
+
].join("\n"));
|
|
1230
|
+
magicSource.update(
|
|
1231
|
+
reference.start,
|
|
1232
|
+
reference.end,
|
|
1233
|
+
`${helperName}(${reference.expressionText}${reference.optionsText ? `, ${reference.optionsText}` : ""})`,
|
|
1234
|
+
);
|
|
1235
|
+
didRewrite = true;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
if (dynamicImportHelpers.length > 0) {
|
|
1239
|
+
magicSource.append(`\n\n${dynamicImportHelpers.join("\n\n")}\n`);
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1011
1242
|
const rewrittenCode = magicSource.toString();
|
|
1012
1243
|
if (!sourceMaps || !didRewrite) {
|
|
1013
1244
|
return {
|
|
@@ -1044,6 +1275,7 @@ function getDevelopmentGraphCacheKey(entryPath, options) {
|
|
|
1044
1275
|
options.target ?? "server",
|
|
1045
1276
|
options.ssr === true ? "ssr" : "client",
|
|
1046
1277
|
options.sourceMaps === false ? "without-maps" : "with-maps",
|
|
1278
|
+
options.litsxPipeline?.identity?.id ?? "default-litsx",
|
|
1047
1279
|
].join("::");
|
|
1048
1280
|
}
|
|
1049
1281
|
|
|
@@ -1131,7 +1363,10 @@ export function invalidateDevelopmentCompilationCache(projectRoot, changedPaths
|
|
|
1131
1363
|
const shouldInvalidate =
|
|
1132
1364
|
normalizedChangedPaths == null ||
|
|
1133
1365
|
!dependencies ||
|
|
1134
|
-
[...dependencies].some((dependency) => normalizedChangedPaths.has(dependency))
|
|
1366
|
+
[...dependencies.files].some((dependency) => normalizedChangedPaths.has(dependency)) ||
|
|
1367
|
+
[...dependencies.directories].some((directory) =>
|
|
1368
|
+
[...normalizedChangedPaths].some((changedPath) => !isPathOutsideProject(directory, changedPath))
|
|
1369
|
+
);
|
|
1135
1370
|
if (shouldInvalidate) {
|
|
1136
1371
|
developmentGraphCache.delete(key);
|
|
1137
1372
|
developmentGraphDependencies.delete(key);
|
|
@@ -1154,6 +1389,7 @@ async function compileModuleGraphUncached(entryPath, options = {}) {
|
|
|
1154
1389
|
staticAssetPublicUrls = null,
|
|
1155
1390
|
onDevelopmentEvent,
|
|
1156
1391
|
managedSourceRoots,
|
|
1392
|
+
litsxPipeline,
|
|
1157
1393
|
} = options;
|
|
1158
1394
|
|
|
1159
1395
|
const outputRoot = getTypedOutputRoot(projectRoot, mode, target);
|
|
@@ -1163,6 +1399,7 @@ async function compileModuleGraphUncached(entryPath, options = {}) {
|
|
|
1163
1399
|
const moduleMetadata = new Map();
|
|
1164
1400
|
const serverExportsByModule = new Map();
|
|
1165
1401
|
const packageImports = new Set();
|
|
1402
|
+
const dynamicImportDirectories = new Set();
|
|
1166
1403
|
const serverImportQuery = target === "server" && mode === "development"
|
|
1167
1404
|
? `t=${Date.now()}`
|
|
1168
1405
|
: null;
|
|
@@ -1189,6 +1426,8 @@ async function compileModuleGraphUncached(entryPath, options = {}) {
|
|
|
1189
1426
|
sourcePath,
|
|
1190
1427
|
sourceMaps,
|
|
1191
1428
|
ssr,
|
|
1429
|
+
target,
|
|
1430
|
+
litsxPipeline,
|
|
1192
1431
|
});
|
|
1193
1432
|
const isServerComponentModule = isCompiledServerComponentModule(transformed.code);
|
|
1194
1433
|
const isMixedComponentModule = isServerComponentModule
|
|
@@ -1233,6 +1472,8 @@ async function compileModuleGraphUncached(entryPath, options = {}) {
|
|
|
1233
1472
|
managedSourceRoots,
|
|
1234
1473
|
serverExportsByModule,
|
|
1235
1474
|
packageImports,
|
|
1475
|
+
dynamicImportDirectories,
|
|
1476
|
+
litsxPipeline,
|
|
1236
1477
|
});
|
|
1237
1478
|
|
|
1238
1479
|
await fs.writeFile(outputPath, rewritten.code, "utf8");
|
|
@@ -1261,7 +1502,13 @@ async function compileModuleGraphUncached(entryPath, options = {}) {
|
|
|
1261
1502
|
return {
|
|
1262
1503
|
entrypoint: await compileModule(entryPath),
|
|
1263
1504
|
outputRoot,
|
|
1264
|
-
sourceFiles: [...new Set([
|
|
1505
|
+
sourceFiles: [...new Set([
|
|
1506
|
+
...visited.keys(),
|
|
1507
|
+
...staticAssetFiles,
|
|
1508
|
+
...(litsxPipeline?.dependencies ?? []),
|
|
1509
|
+
])],
|
|
1510
|
+
integrationDependencies: litsxPipeline?.dependencies ?? [],
|
|
1511
|
+
watchedDirectories: [...dynamicImportDirectories],
|
|
1265
1512
|
packageImports: [...packageImports].sort(),
|
|
1266
1513
|
};
|
|
1267
1514
|
}
|
|
@@ -1286,7 +1533,10 @@ export async function compileModuleGraph(entryPath, options = {}) {
|
|
|
1286
1533
|
developmentGraphCache.set(cacheKey, pendingCompile);
|
|
1287
1534
|
pendingCompile.then((result) => {
|
|
1288
1535
|
if (developmentGraphCache.get(cacheKey) === pendingCompile) {
|
|
1289
|
-
developmentGraphDependencies.set(cacheKey,
|
|
1536
|
+
developmentGraphDependencies.set(cacheKey, {
|
|
1537
|
+
files: new Set(result.sourceFiles),
|
|
1538
|
+
directories: new Set(result.watchedDirectories ?? []),
|
|
1539
|
+
});
|
|
1290
1540
|
}
|
|
1291
1541
|
}, () => {});
|
|
1292
1542
|
}
|
|
@@ -1415,6 +1665,8 @@ export async function collectClientGraphInventory(entryPaths, options = {}) {
|
|
|
1415
1665
|
projectRoot,
|
|
1416
1666
|
sourcePath,
|
|
1417
1667
|
sourceMaps: false,
|
|
1668
|
+
target: "client",
|
|
1669
|
+
litsxPipeline: options.litsxPipeline,
|
|
1418
1670
|
});
|
|
1419
1671
|
const isServer = isCompiledServerComponentModule(transformed.code);
|
|
1420
1672
|
const isComponent = isCompiledClientBoundaryModule(transformed.code);
|
|
@@ -1425,15 +1677,15 @@ export async function collectClientGraphInventory(entryPaths, options = {}) {
|
|
|
1425
1677
|
if (isComponent && isServer) boundaries.add(sourcePath);
|
|
1426
1678
|
if (!traverseNonBoundary) return;
|
|
1427
1679
|
const componentImportSpecifiers = collectComponentImportSpecifiers(source, sourcePath);
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1680
|
+
const moduleReferences = analyzeModuleReferences(source, sourcePath, ts.ScriptKind.TSX);
|
|
1681
|
+
|
|
1682
|
+
async function visitResolvedSpecifier(specifier) {
|
|
1431
1683
|
const aliasResolved = isBareSpecifier(specifier)
|
|
1432
1684
|
? await resolveProjectMappedImport(projectRoot, sourcePath, specifier)
|
|
1433
1685
|
: null;
|
|
1434
1686
|
const resolved = aliasResolved
|
|
1435
1687
|
?? await resolveProjectModuleSpecifier(projectRoot, sourcePath, specifier);
|
|
1436
|
-
if (!resolved)
|
|
1688
|
+
if (!resolved) return;
|
|
1437
1689
|
if (shouldCompileModule(resolved)) {
|
|
1438
1690
|
if (isBareSpecifier(specifier) && aliasResolved == null) {
|
|
1439
1691
|
if (componentImportSpecifiers.has(specifier)) {
|
|
@@ -1450,6 +1702,21 @@ export async function collectClientGraphInventory(entryPaths, options = {}) {
|
|
|
1450
1702
|
assets.add(resolved);
|
|
1451
1703
|
}
|
|
1452
1704
|
}
|
|
1705
|
+
|
|
1706
|
+
for (const reference of moduleReferences.staticReferences) {
|
|
1707
|
+
await visitResolvedSpecifier(reference.specifier);
|
|
1708
|
+
}
|
|
1709
|
+
for (const reference of moduleReferences.dynamicReferences) {
|
|
1710
|
+
const discovery = await discoverDynamicImportCandidates({
|
|
1711
|
+
projectRoot,
|
|
1712
|
+
sourcePath,
|
|
1713
|
+
pattern: reference.pattern,
|
|
1714
|
+
displayPattern: reference.displayPattern,
|
|
1715
|
+
});
|
|
1716
|
+
for (const candidate of discovery.candidates) {
|
|
1717
|
+
await visit(candidate, true);
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1453
1720
|
}
|
|
1454
1721
|
|
|
1455
1722
|
for (const entryPath of entryPaths) await visit(entryPath);
|