create-dalila 1.2.15 → 1.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +1 -1
- package/template/build.mjs +1174 -22
- package/template/package.json +1 -1
- package/template/src/app/page.ts +1 -1
- package/template/src/main.ts +1 -1
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ my-app/
|
|
|
49
49
|
- `npm run dev` - Start dev server and route watcher
|
|
50
50
|
- `npm run routes` - Generate route files once
|
|
51
51
|
- `npm run routes:watch` - Watch route files and regenerate outputs
|
|
52
|
-
- `npm run build` - Generate routes, compile TypeScript, and package
|
|
52
|
+
- `npm run build` - Generate routes, compile TypeScript, and package an optimized standalone `dist/`
|
|
53
53
|
- `npm run preview` - Serve the built `dist/` output locally
|
|
54
54
|
|
|
55
55
|
## Learn More
|
package/package.json
CHANGED
package/template/build.mjs
CHANGED
|
@@ -8,6 +8,8 @@ const require = createRequire(import.meta.url);
|
|
|
8
8
|
const FOUC_PREVENTION_STYLE = ` <style>[d-loading]{visibility:hidden}</style>`;
|
|
9
9
|
const SCRIPT_SOURCE_EXTENSIONS = new Set(['.ts', '.mts', '.cts']);
|
|
10
10
|
const SCRIPT_REQUEST_SOURCE_EXTENSIONS = new Set(['.js', '.mjs', '.cjs']);
|
|
11
|
+
const JAVASCRIPT_EXTENSIONS = new Set(['.js', '.mjs', '.cjs']);
|
|
12
|
+
const TYPE_ARTIFACT_EXTENSIONS = ['.d.ts', '.d.ts.map', '.js.map', '.mjs.map', '.cjs.map'];
|
|
11
13
|
const STATIC_DIR_EXCLUDES = new Set([
|
|
12
14
|
'src',
|
|
13
15
|
'public',
|
|
@@ -233,6 +235,7 @@ function loadTypeScriptBuildConfig(projectDir) {
|
|
|
233
235
|
: projectDir;
|
|
234
236
|
|
|
235
237
|
if (!configPath) {
|
|
238
|
+
const ts = require(resolvePackageModule('typescript', projectDir));
|
|
236
239
|
return {
|
|
237
240
|
projectDir,
|
|
238
241
|
configPath: null,
|
|
@@ -241,6 +244,7 @@ function loadTypeScriptBuildConfig(projectDir) {
|
|
|
241
244
|
packageOutDirAbs,
|
|
242
245
|
rootDirAbs: projectDir,
|
|
243
246
|
sourceDirAbs: defaultSourceDirAbs,
|
|
247
|
+
ts,
|
|
244
248
|
};
|
|
245
249
|
}
|
|
246
250
|
|
|
@@ -263,6 +267,7 @@ function loadTypeScriptBuildConfig(projectDir) {
|
|
|
263
267
|
packageOutDirAbs,
|
|
264
268
|
rootDirAbs: explicitRootDirAbs ?? inferredRootDirAbs,
|
|
265
269
|
sourceDirAbs,
|
|
270
|
+
ts,
|
|
266
271
|
};
|
|
267
272
|
}
|
|
268
273
|
|
|
@@ -659,8 +664,1024 @@ function renderImportMapScript(importMap) {
|
|
|
659
664
|
return ` <script type="importmap">\n${payload}\n </script>`;
|
|
660
665
|
}
|
|
661
666
|
|
|
667
|
+
function renderModulePreloadLinks(moduleUrls) {
|
|
668
|
+
return [...new Set(moduleUrls)]
|
|
669
|
+
.sort()
|
|
670
|
+
.map((moduleUrl) => ` <link rel="modulepreload" href="${moduleUrl}">`)
|
|
671
|
+
.join('\n');
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
function collectModuleSpecifierKinds(source, ts) {
|
|
675
|
+
const staticSpecifiers = new Set();
|
|
676
|
+
const dynamicSpecifiers = new Set();
|
|
677
|
+
const runtimeUrlSpecifiers = new Set();
|
|
678
|
+
const bindingExpressions = new Map();
|
|
679
|
+
const resolvedBindings = new Map();
|
|
680
|
+
const serviceWorkerAliases = new Set();
|
|
681
|
+
const navigatorAliases = new Set();
|
|
682
|
+
const serviceWorkerRegisterAliases = new Set();
|
|
683
|
+
const workerConstructorAliases = new Set();
|
|
684
|
+
let hasUnresolvedDalilaDynamicImport = false;
|
|
685
|
+
let hasUnresolvedDynamicImport = false;
|
|
686
|
+
let hasUnresolvedRuntimeUrl = false;
|
|
687
|
+
const sourceFile = ts.createSourceFile(
|
|
688
|
+
'module.js',
|
|
689
|
+
source,
|
|
690
|
+
ts.ScriptTarget.Latest,
|
|
691
|
+
true,
|
|
692
|
+
ts.ScriptKind.JS
|
|
693
|
+
);
|
|
694
|
+
|
|
695
|
+
const isImportMetaUrl = (node) =>
|
|
696
|
+
ts.isPropertyAccessExpression(node)
|
|
697
|
+
&& ts.isMetaProperty(node.expression)
|
|
698
|
+
&& node.expression.keywordToken === ts.SyntaxKind.ImportKeyword
|
|
699
|
+
&& node.expression.name.text === 'meta'
|
|
700
|
+
&& node.name.text === 'url';
|
|
701
|
+
|
|
702
|
+
const isImportMetaUrlAlias = (node) =>
|
|
703
|
+
ts.isIdentifier(node)
|
|
704
|
+
&& bindingExpressions.get(node.text)?.length === 1
|
|
705
|
+
&& isImportMetaUrl(bindingExpressions.get(node.text)[0]);
|
|
706
|
+
|
|
707
|
+
const isNavigatorReference = (node) =>
|
|
708
|
+
ts.isIdentifier(node)
|
|
709
|
+
&& (node.text === 'navigator' || navigatorAliases.has(node.text));
|
|
710
|
+
|
|
711
|
+
const isServiceWorkerReference = (node) =>
|
|
712
|
+
(
|
|
713
|
+
ts.isPropertyAccessExpression(node)
|
|
714
|
+
&& ts.isIdentifier(node.name)
|
|
715
|
+
&& node.name.text === 'serviceWorker'
|
|
716
|
+
&& isNavigatorReference(node.expression)
|
|
717
|
+
)
|
|
718
|
+
|| (ts.isIdentifier(node) && serviceWorkerAliases.has(node.text));
|
|
719
|
+
|
|
720
|
+
const isScopeBoundaryNode = (node) =>
|
|
721
|
+
node !== sourceFile
|
|
722
|
+
&& (
|
|
723
|
+
ts.isBlock(node)
|
|
724
|
+
|| ts.isFunctionLike(node)
|
|
725
|
+
|| ts.isClassLike(node)
|
|
726
|
+
|| ts.isModuleBlock(node)
|
|
727
|
+
);
|
|
728
|
+
|
|
729
|
+
const collectScopeDeclaredNames = (scopeNode) => {
|
|
730
|
+
const names = new Set();
|
|
731
|
+
|
|
732
|
+
const visitScopeNode = (node) => {
|
|
733
|
+
if (node !== scopeNode && isScopeBoundaryNode(node)) {
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)) {
|
|
738
|
+
names.add(node.name.text);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
if ((ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node)) && node.name && ts.isIdentifier(node.name)) {
|
|
742
|
+
names.add(node.name.text);
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
if (ts.isParameter(node) && ts.isIdentifier(node.name)) {
|
|
746
|
+
names.add(node.name.text);
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
ts.forEachChild(node, visitScopeNode);
|
|
750
|
+
};
|
|
751
|
+
|
|
752
|
+
visitScopeNode(scopeNode);
|
|
753
|
+
return names;
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
const resolveStringExpression = (node, options = {}) => {
|
|
757
|
+
const allowBindings = options.allowBindings !== false;
|
|
758
|
+
if (!node) {
|
|
759
|
+
return { value: null, referencesDalila: false };
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
if (ts.isStringLiteralLike(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
|
|
763
|
+
return {
|
|
764
|
+
value: node.text,
|
|
765
|
+
referencesDalila: node.text.includes('dalila'),
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
if (ts.isIdentifier(node)) {
|
|
770
|
+
const resolvedLiteral = allowBindings
|
|
771
|
+
? (resolvedBindings.get(node.text) ?? resolveBinding(node.text))
|
|
772
|
+
: null;
|
|
773
|
+
if (typeof resolvedLiteral === 'string') {
|
|
774
|
+
return {
|
|
775
|
+
value: resolvedLiteral,
|
|
776
|
+
referencesDalila: resolvedLiteral.includes('dalila'),
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
return {
|
|
781
|
+
value: null,
|
|
782
|
+
referencesDalila: node.text.toLowerCase().includes('dalila'),
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
787
|
+
return allowBindings
|
|
788
|
+
? resolveObjectProperty(node.expression, node.name.text, options)
|
|
789
|
+
: { value: null, referencesDalila: false };
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.PlusToken) {
|
|
793
|
+
const left = resolveStringExpression(node.left, options);
|
|
794
|
+
const right = resolveStringExpression(node.right, options);
|
|
795
|
+
return {
|
|
796
|
+
value: typeof left.value === 'string' && typeof right.value === 'string'
|
|
797
|
+
? `${left.value}${right.value}`
|
|
798
|
+
: null,
|
|
799
|
+
referencesDalila: left.referencesDalila || right.referencesDalila,
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
if (ts.isTemplateExpression(node)) {
|
|
804
|
+
let value = node.head.text;
|
|
805
|
+
let isFullyResolved = true;
|
|
806
|
+
let referencesDalila = node.head.text.includes('dalila');
|
|
807
|
+
|
|
808
|
+
for (const span of node.templateSpans) {
|
|
809
|
+
const expressionResult = resolveStringExpression(span.expression, options);
|
|
810
|
+
if (typeof expressionResult.value !== 'string') {
|
|
811
|
+
isFullyResolved = false;
|
|
812
|
+
} else {
|
|
813
|
+
value += expressionResult.value;
|
|
814
|
+
}
|
|
815
|
+
referencesDalila = referencesDalila || expressionResult.referencesDalila;
|
|
816
|
+
value += span.literal.text;
|
|
817
|
+
referencesDalila = referencesDalila || span.literal.text.includes('dalila');
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
return {
|
|
821
|
+
value: isFullyResolved ? value : null,
|
|
822
|
+
referencesDalila,
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
return {
|
|
827
|
+
value: null,
|
|
828
|
+
referencesDalila: node.getText(sourceFile).includes('dalila'),
|
|
829
|
+
};
|
|
830
|
+
};
|
|
831
|
+
|
|
832
|
+
const resolveObjectProperty = (node, propertyName, options = {}) => {
|
|
833
|
+
if (!node) {
|
|
834
|
+
return { value: null, referencesDalila: false };
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
if (ts.isParenthesizedExpression(node)) {
|
|
838
|
+
return resolveObjectProperty(node.expression, propertyName, options);
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
if (ts.isIdentifier(node)) {
|
|
842
|
+
const bindingCandidates = options.allowBindings === false ? null : bindingExpressions.get(node.text);
|
|
843
|
+
if (bindingCandidates?.length === 1) {
|
|
844
|
+
return resolveObjectProperty(bindingCandidates[0], propertyName, options);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
return { value: null, referencesDalila: false };
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
if (!ts.isObjectLiteralExpression(node)) {
|
|
851
|
+
return { value: null, referencesDalila: false };
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
for (const property of node.properties) {
|
|
855
|
+
if (!ts.isPropertyAssignment(property) || property.name == null) {
|
|
856
|
+
continue;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
let candidateName = null;
|
|
860
|
+
if (ts.isIdentifier(property.name) || ts.isStringLiteralLike(property.name) || ts.isNumericLiteral(property.name)) {
|
|
861
|
+
candidateName = property.name.text;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
if (candidateName !== propertyName) {
|
|
865
|
+
continue;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
return resolveStringExpression(property.initializer, options);
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
return { value: null, referencesDalila: false };
|
|
872
|
+
};
|
|
873
|
+
|
|
874
|
+
const resolveRuntimeUrlExpression = (node, options = {}) => {
|
|
875
|
+
if (!node) {
|
|
876
|
+
return { value: null, isRemote: false };
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
if (ts.isIdentifier(node)) {
|
|
880
|
+
const bindingCandidates = options.allowBindings === false ? null : bindingExpressions.get(node.text);
|
|
881
|
+
if (bindingCandidates?.length === 1) {
|
|
882
|
+
return resolveRuntimeUrlExpression(bindingCandidates[0], options);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
887
|
+
const propertyValue = resolveObjectProperty(node.expression, node.name.text, options);
|
|
888
|
+
if (typeof propertyValue.value === 'string') {
|
|
889
|
+
return { value: propertyValue.value, isRemote: false };
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
const direct = resolveStringExpression(node, options);
|
|
894
|
+
if (typeof direct.value === 'string') {
|
|
895
|
+
return { value: direct.value, isRemote: false };
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
if (ts.isNewExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === 'URL') {
|
|
899
|
+
const [firstArgument, secondArgument] = node.arguments ?? [];
|
|
900
|
+
const importMetaUrlAlias = ts.isIdentifier(secondArgument)
|
|
901
|
+
? isImportMetaUrlAlias(secondArgument)
|
|
902
|
+
: false;
|
|
903
|
+
if (!secondArgument || isImportMetaUrl(secondArgument) || importMetaUrlAlias) {
|
|
904
|
+
const resolvedArgument = resolveStringExpression(firstArgument, options);
|
|
905
|
+
if (typeof resolvedArgument.value === 'string') {
|
|
906
|
+
return { value: resolvedArgument.value, isRemote: false };
|
|
907
|
+
}
|
|
908
|
+
} else {
|
|
909
|
+
return { value: null, isRemote: true };
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
return { value: null, isRemote: false };
|
|
914
|
+
};
|
|
915
|
+
|
|
916
|
+
const collectBindings = (node, scopeDepth = 0) => {
|
|
917
|
+
const isScopeBoundary = node !== sourceFile && (
|
|
918
|
+
ts.isBlock(node)
|
|
919
|
+
|| ts.isFunctionLike(node)
|
|
920
|
+
|| ts.isClassLike(node)
|
|
921
|
+
|| ts.isModuleBlock(node)
|
|
922
|
+
|| ts.isSourceFile(node)
|
|
923
|
+
);
|
|
924
|
+
const nextScopeDepth = isScopeBoundary ? scopeDepth + 1 : scopeDepth;
|
|
925
|
+
|
|
926
|
+
if (scopeDepth === 0) {
|
|
927
|
+
if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer) {
|
|
928
|
+
const expressions = bindingExpressions.get(node.name.text) ?? [];
|
|
929
|
+
expressions.push(node.initializer);
|
|
930
|
+
bindingExpressions.set(node.name.text, expressions);
|
|
931
|
+
|
|
932
|
+
if (ts.isIdentifier(node.initializer) && node.initializer.text === 'navigator') {
|
|
933
|
+
navigatorAliases.add(node.name.text);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
if (isServiceWorkerReference(node.initializer)) {
|
|
937
|
+
serviceWorkerAliases.add(node.name.text);
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
if (
|
|
941
|
+
ts.isPropertyAccessExpression(node.initializer)
|
|
942
|
+
&& ts.isIdentifier(node.initializer.name)
|
|
943
|
+
&& node.initializer.name.text === 'register'
|
|
944
|
+
&& isServiceWorkerReference(node.initializer.expression)
|
|
945
|
+
) {
|
|
946
|
+
serviceWorkerRegisterAliases.add(node.name.text);
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
if (
|
|
950
|
+
ts.isPropertyAccessExpression(node.initializer)
|
|
951
|
+
&& ts.isIdentifier(node.initializer.expression)
|
|
952
|
+
&& ['window', 'globalThis', 'self'].includes(node.initializer.expression.text)
|
|
953
|
+
&& ['Worker', 'SharedWorker'].includes(node.initializer.name.text)
|
|
954
|
+
) {
|
|
955
|
+
workerConstructorAliases.add(node.name.text);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
if (ts.isVariableDeclaration(node) && ts.isObjectBindingPattern(node.name) && node.initializer && ts.isIdentifier(node.initializer) && node.initializer.text === 'navigator') {
|
|
960
|
+
for (const element of node.name.elements) {
|
|
961
|
+
if (!ts.isBindingElement(element)) continue;
|
|
962
|
+
const propertyName = element.propertyName && ts.isIdentifier(element.propertyName)
|
|
963
|
+
? element.propertyName.text
|
|
964
|
+
: ts.isIdentifier(element.name)
|
|
965
|
+
? element.name.text
|
|
966
|
+
: null;
|
|
967
|
+
const aliasName = ts.isIdentifier(element.name) ? element.name.text : null;
|
|
968
|
+
if (propertyName === 'serviceWorker' && aliasName) {
|
|
969
|
+
serviceWorkerAliases.add(aliasName);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
if (ts.isVariableDeclaration(node) && ts.isObjectBindingPattern(node.name) && node.initializer && isServiceWorkerReference(node.initializer)) {
|
|
975
|
+
for (const element of node.name.elements) {
|
|
976
|
+
if (!ts.isBindingElement(element)) continue;
|
|
977
|
+
const propertyName = element.propertyName && ts.isIdentifier(element.propertyName)
|
|
978
|
+
? element.propertyName.text
|
|
979
|
+
: ts.isIdentifier(element.name)
|
|
980
|
+
? element.name.text
|
|
981
|
+
: null;
|
|
982
|
+
const aliasName = ts.isIdentifier(element.name) ? element.name.text : null;
|
|
983
|
+
if (propertyName === 'register' && aliasName) {
|
|
984
|
+
serviceWorkerRegisterAliases.add(aliasName);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
if (
|
|
990
|
+
ts.isVariableDeclaration(node)
|
|
991
|
+
&& ts.isObjectBindingPattern(node.name)
|
|
992
|
+
&& node.initializer
|
|
993
|
+
&& ts.isIdentifier(node.initializer)
|
|
994
|
+
&& navigatorAliases.has(node.initializer.text)
|
|
995
|
+
) {
|
|
996
|
+
for (const element of node.name.elements) {
|
|
997
|
+
if (!ts.isBindingElement(element)) continue;
|
|
998
|
+
const propertyName = element.propertyName && ts.isIdentifier(element.propertyName)
|
|
999
|
+
? element.propertyName.text
|
|
1000
|
+
: ts.isIdentifier(element.name)
|
|
1001
|
+
? element.name.text
|
|
1002
|
+
: null;
|
|
1003
|
+
const aliasName = ts.isIdentifier(element.name) ? element.name.text : null;
|
|
1004
|
+
if (propertyName === 'serviceWorker' && aliasName) {
|
|
1005
|
+
serviceWorkerAliases.add(aliasName);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
if (
|
|
1011
|
+
ts.isVariableDeclaration(node)
|
|
1012
|
+
&& ts.isObjectBindingPattern(node.name)
|
|
1013
|
+
&& node.initializer
|
|
1014
|
+
&& ts.isIdentifier(node.initializer)
|
|
1015
|
+
&& ['window', 'globalThis', 'self'].includes(node.initializer.text)
|
|
1016
|
+
) {
|
|
1017
|
+
for (const element of node.name.elements) {
|
|
1018
|
+
if (!ts.isBindingElement(element)) continue;
|
|
1019
|
+
const propertyName = element.propertyName && ts.isIdentifier(element.propertyName)
|
|
1020
|
+
? element.propertyName.text
|
|
1021
|
+
: ts.isIdentifier(element.name)
|
|
1022
|
+
? element.name.text
|
|
1023
|
+
: null;
|
|
1024
|
+
const aliasName = ts.isIdentifier(element.name) ? element.name.text : null;
|
|
1025
|
+
if (aliasName && ['Worker', 'SharedWorker'].includes(propertyName)) {
|
|
1026
|
+
workerConstructorAliases.add(aliasName);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && ts.isIdentifier(node.left)) {
|
|
1032
|
+
const expressions = bindingExpressions.get(node.left.text) ?? [];
|
|
1033
|
+
expressions.push(node.right);
|
|
1034
|
+
bindingExpressions.set(node.left.text, expressions);
|
|
1035
|
+
|
|
1036
|
+
if (ts.isIdentifier(node.right) && node.right.text === 'navigator') {
|
|
1037
|
+
navigatorAliases.add(node.left.text);
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
ts.forEachChild(node, (child) => collectBindings(child, nextScopeDepth));
|
|
1043
|
+
};
|
|
1044
|
+
|
|
1045
|
+
const resolutionStack = new Set();
|
|
1046
|
+
const bindingReferencesDalila = (name) => {
|
|
1047
|
+
const bindingCandidates = bindingExpressions.get(name);
|
|
1048
|
+
if (!bindingCandidates || bindingCandidates.length === 0) {
|
|
1049
|
+
return false;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
return bindingCandidates.some((bindingExpression) => resolveStringExpression(bindingExpression).referencesDalila);
|
|
1053
|
+
};
|
|
1054
|
+
|
|
1055
|
+
const resolveBinding = (name) => {
|
|
1056
|
+
if (resolvedBindings.has(name)) {
|
|
1057
|
+
return resolvedBindings.get(name) ?? null;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
if (resolutionStack.has(name)) {
|
|
1061
|
+
return null;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
const bindingCandidates = bindingExpressions.get(name);
|
|
1065
|
+
if (!bindingCandidates || bindingCandidates.length === 0) {
|
|
1066
|
+
return null;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
resolutionStack.add(name);
|
|
1070
|
+
const resolvedValues = new Set();
|
|
1071
|
+
let hasAmbiguity = false;
|
|
1072
|
+
|
|
1073
|
+
for (const bindingExpression of bindingCandidates) {
|
|
1074
|
+
const resolved = resolveStringExpression(bindingExpression);
|
|
1075
|
+
if (typeof resolved.value === 'string') {
|
|
1076
|
+
resolvedValues.add(resolved.value);
|
|
1077
|
+
} else {
|
|
1078
|
+
hasAmbiguity = true;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
resolutionStack.delete(name);
|
|
1082
|
+
|
|
1083
|
+
if (!hasAmbiguity && resolvedValues.size === 1) {
|
|
1084
|
+
const [resolvedValue] = resolvedValues;
|
|
1085
|
+
resolvedBindings.set(name, resolvedValue);
|
|
1086
|
+
return resolvedValue;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
return null;
|
|
1090
|
+
};
|
|
1091
|
+
|
|
1092
|
+
const visit = (node, scopeDepth = 0, scopeDeclarations = []) => {
|
|
1093
|
+
const nestedScope = isScopeBoundaryNode(node);
|
|
1094
|
+
const nextScopeDepth = nestedScope ? scopeDepth + 1 : scopeDepth;
|
|
1095
|
+
const nextScopeDeclarations = nestedScope
|
|
1096
|
+
? [...scopeDeclarations, collectScopeDeclaredNames(node)]
|
|
1097
|
+
: scopeDeclarations;
|
|
1098
|
+
|
|
1099
|
+
if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer) {
|
|
1100
|
+
const resolvedLiteral = resolveBinding(node.name.text);
|
|
1101
|
+
if (typeof resolvedLiteral === 'string') {
|
|
1102
|
+
resolvedBindings.set(node.name.text, resolvedLiteral);
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) && node.moduleSpecifier && ts.isStringLiteralLike(node.moduleSpecifier)) {
|
|
1107
|
+
staticSpecifiers.add(node.moduleSpecifier.text);
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
|
1111
|
+
const [firstArgument] = node.arguments;
|
|
1112
|
+
if (firstArgument) {
|
|
1113
|
+
const localShadowed = ts.isIdentifier(firstArgument)
|
|
1114
|
+
&& nextScopeDeclarations.some((declaredNames) => declaredNames.has(firstArgument.text));
|
|
1115
|
+
const importArg = resolveStringExpression(firstArgument, {
|
|
1116
|
+
allowBindings: scopeDepth === 0 && !localShadowed,
|
|
1117
|
+
});
|
|
1118
|
+
if (typeof importArg.value === 'string') {
|
|
1119
|
+
dynamicSpecifiers.add(importArg.value);
|
|
1120
|
+
} else if (importArg.referencesDalila) {
|
|
1121
|
+
hasUnresolvedDalilaDynamicImport = true;
|
|
1122
|
+
hasUnresolvedDynamicImport = true;
|
|
1123
|
+
} else {
|
|
1124
|
+
if (!localShadowed && ts.isIdentifier(firstArgument)) {
|
|
1125
|
+
const resolvedTopLevel = resolveBinding(firstArgument.text);
|
|
1126
|
+
if (typeof resolvedTopLevel === 'string' && resolvedTopLevel.startsWith('dalila')) {
|
|
1127
|
+
hasUnresolvedDalilaDynamicImport = true;
|
|
1128
|
+
} else if (bindingReferencesDalila(firstArgument.text)) {
|
|
1129
|
+
hasUnresolvedDalilaDynamicImport = true;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
hasUnresolvedDynamicImport = true;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
if (
|
|
1138
|
+
ts.isCallExpression(node)
|
|
1139
|
+
&& ts.isPropertyAccessExpression(node.expression)
|
|
1140
|
+
&& node.expression.name.text === 'register'
|
|
1141
|
+
&& (
|
|
1142
|
+
(
|
|
1143
|
+
ts.isPropertyAccessExpression(node.expression.expression)
|
|
1144
|
+
&& ts.isIdentifier(node.expression.expression.name)
|
|
1145
|
+
&& node.expression.expression.name.text === 'serviceWorker'
|
|
1146
|
+
&& ts.isIdentifier(node.expression.expression.expression)
|
|
1147
|
+
&& (
|
|
1148
|
+
node.expression.expression.expression.text === 'navigator'
|
|
1149
|
+
|| navigatorAliases.has(node.expression.expression.expression.text)
|
|
1150
|
+
)
|
|
1151
|
+
)
|
|
1152
|
+
|| (ts.isIdentifier(node.expression.expression) && serviceWorkerAliases.has(node.expression.expression.text))
|
|
1153
|
+
)
|
|
1154
|
+
) {
|
|
1155
|
+
const localShadowed = ts.isIdentifier(node.arguments[0])
|
|
1156
|
+
&& nextScopeDeclarations.some((declaredNames) => declaredNames.has(node.arguments[0].text));
|
|
1157
|
+
const runtimeUrl = resolveRuntimeUrlExpression(node.arguments[0], {
|
|
1158
|
+
allowBindings: scopeDepth === 0 && !localShadowed,
|
|
1159
|
+
});
|
|
1160
|
+
if (runtimeUrl.value) {
|
|
1161
|
+
runtimeUrlSpecifiers.add(runtimeUrl.value);
|
|
1162
|
+
} else if (node.arguments[0] && !runtimeUrl.isRemote) {
|
|
1163
|
+
hasUnresolvedRuntimeUrl = true;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
if (
|
|
1168
|
+
ts.isCallExpression(node)
|
|
1169
|
+
&& ts.isIdentifier(node.expression)
|
|
1170
|
+
&& serviceWorkerRegisterAliases.has(node.expression.text)
|
|
1171
|
+
) {
|
|
1172
|
+
const localShadowed = ts.isIdentifier(node.arguments[0])
|
|
1173
|
+
&& nextScopeDeclarations.some((declaredNames) => declaredNames.has(node.arguments[0].text));
|
|
1174
|
+
const runtimeUrl = resolveRuntimeUrlExpression(node.arguments[0], {
|
|
1175
|
+
allowBindings: scopeDepth === 0 && !localShadowed,
|
|
1176
|
+
});
|
|
1177
|
+
if (runtimeUrl.value) {
|
|
1178
|
+
runtimeUrlSpecifiers.add(runtimeUrl.value);
|
|
1179
|
+
} else if (node.arguments[0] && !runtimeUrl.isRemote) {
|
|
1180
|
+
hasUnresolvedRuntimeUrl = true;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
if (
|
|
1185
|
+
ts.isCallExpression(node)
|
|
1186
|
+
&& (
|
|
1187
|
+
(ts.isIdentifier(node.expression) && node.expression.text === 'importScripts')
|
|
1188
|
+
|| (
|
|
1189
|
+
ts.isPropertyAccessExpression(node.expression)
|
|
1190
|
+
&& ts.isIdentifier(node.expression.expression)
|
|
1191
|
+
&& node.expression.expression.text === 'self'
|
|
1192
|
+
&& node.expression.name.text === 'importScripts'
|
|
1193
|
+
)
|
|
1194
|
+
)
|
|
1195
|
+
) {
|
|
1196
|
+
for (const argument of node.arguments) {
|
|
1197
|
+
const localShadowed = ts.isIdentifier(argument)
|
|
1198
|
+
&& nextScopeDeclarations.some((declaredNames) => declaredNames.has(argument.text));
|
|
1199
|
+
const runtimeUrl = resolveRuntimeUrlExpression(argument, {
|
|
1200
|
+
allowBindings: scopeDepth === 0 && !localShadowed,
|
|
1201
|
+
});
|
|
1202
|
+
if (runtimeUrl.value) {
|
|
1203
|
+
runtimeUrlSpecifiers.add(runtimeUrl.value);
|
|
1204
|
+
} else if (!runtimeUrl.isRemote) {
|
|
1205
|
+
hasUnresolvedRuntimeUrl = true;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
const isWorkerConstructor = ts.isNewExpression(node) && (
|
|
1211
|
+
(ts.isIdentifier(node.expression) && ['Worker', 'SharedWorker'].includes(node.expression.text))
|
|
1212
|
+
|| (ts.isIdentifier(node.expression) && workerConstructorAliases.has(node.expression.text))
|
|
1213
|
+
|| (
|
|
1214
|
+
ts.isPropertyAccessExpression(node.expression)
|
|
1215
|
+
&& ts.isIdentifier(node.expression.expression)
|
|
1216
|
+
&& ['window', 'globalThis', 'self'].includes(node.expression.expression.text)
|
|
1217
|
+
&& ['Worker', 'SharedWorker'].includes(node.expression.name.text)
|
|
1218
|
+
)
|
|
1219
|
+
);
|
|
1220
|
+
|
|
1221
|
+
if (isWorkerConstructor) {
|
|
1222
|
+
const localShadowed = ts.isIdentifier(node.arguments?.[0])
|
|
1223
|
+
&& nextScopeDeclarations.some((declaredNames) => declaredNames.has(node.arguments[0].text));
|
|
1224
|
+
const runtimeUrl = resolveRuntimeUrlExpression(node.arguments?.[0], {
|
|
1225
|
+
allowBindings: scopeDepth === 0 && !localShadowed,
|
|
1226
|
+
});
|
|
1227
|
+
if (runtimeUrl.value) {
|
|
1228
|
+
runtimeUrlSpecifiers.add(runtimeUrl.value);
|
|
1229
|
+
} else if (node.arguments?.[0] && !runtimeUrl.isRemote) {
|
|
1230
|
+
hasUnresolvedRuntimeUrl = true;
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
ts.forEachChild(node, (child) => visit(child, nextScopeDepth, nextScopeDeclarations));
|
|
1235
|
+
};
|
|
1236
|
+
|
|
1237
|
+
ts.forEachChild(sourceFile, (child) => collectBindings(child, 0));
|
|
1238
|
+
ts.forEachChild(sourceFile, (child) => visit(child, 0, []));
|
|
1239
|
+
return {
|
|
1240
|
+
staticSpecifiers: [...staticSpecifiers],
|
|
1241
|
+
dynamicSpecifiers: [...dynamicSpecifiers],
|
|
1242
|
+
runtimeUrlSpecifiers: [...runtimeUrlSpecifiers],
|
|
1243
|
+
allSpecifiers: [...new Set([...staticSpecifiers, ...dynamicSpecifiers])],
|
|
1244
|
+
hasUnresolvedDalilaDynamicImport,
|
|
1245
|
+
hasUnresolvedDynamicImport,
|
|
1246
|
+
hasUnresolvedRuntimeUrl,
|
|
1247
|
+
};
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
function resolveRelativeUrl(specifier, referrerUrl) {
|
|
1251
|
+
const resolvedUrl = new URL(specifier, new URL(referrerUrl, 'https://dalila.local'));
|
|
1252
|
+
return `${resolvedUrl.pathname}${resolvedUrl.search}${resolvedUrl.hash}`;
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
function resolveImportMapMatch(specifier, imports = {}) {
|
|
1256
|
+
if (typeof imports[specifier] === 'string') {
|
|
1257
|
+
return imports[specifier];
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
let bestPrefix = null;
|
|
1261
|
+
for (const [prefix, target] of Object.entries(imports)) {
|
|
1262
|
+
if (typeof target !== 'string' || !prefix.endsWith('/')) {
|
|
1263
|
+
continue;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
if (!specifier.startsWith(prefix)) {
|
|
1267
|
+
continue;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
if (!bestPrefix || prefix.length > bestPrefix.length) {
|
|
1271
|
+
bestPrefix = prefix;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
if (!bestPrefix) {
|
|
1276
|
+
return null;
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
const target = imports[bestPrefix];
|
|
1280
|
+
if (typeof target !== 'string') {
|
|
1281
|
+
return null;
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
return `${target}${specifier.slice(bestPrefix.length)}`;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
function resolveImportMapSpecifier(specifier, importMap, referrerUrl) {
|
|
1288
|
+
const scopes = importMap?.scopes ?? {};
|
|
1289
|
+
let bestScope = null;
|
|
1290
|
+
|
|
1291
|
+
for (const scopeName of Object.keys(scopes)) {
|
|
1292
|
+
if (!referrerUrl.startsWith(scopeName)) {
|
|
1293
|
+
continue;
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
if (!bestScope || scopeName.length > bestScope.length) {
|
|
1297
|
+
bestScope = scopeName;
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
if (bestScope) {
|
|
1302
|
+
const scopedMatch = resolveImportMapMatch(specifier, scopes[bestScope]);
|
|
1303
|
+
if (scopedMatch) {
|
|
1304
|
+
return scopedMatch;
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
return resolveImportMapMatch(specifier, importMap?.imports ?? {});
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
function resolveSpecifierToPackagedUrl(specifier, referrerUrl, importMap, importMapBaseUrl = referrerUrl) {
|
|
1312
|
+
if (isUrlWithScheme(specifier) || specifier.startsWith('//')) {
|
|
1313
|
+
return null;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
if (specifier.startsWith('/') || specifier.startsWith('./') || specifier.startsWith('../')) {
|
|
1317
|
+
return resolveRelativeUrl(specifier, referrerUrl);
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
const mappedTarget = resolveImportMapSpecifier(specifier, importMap, referrerUrl);
|
|
1321
|
+
if (!mappedTarget) {
|
|
1322
|
+
return null;
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
if (isUrlWithScheme(mappedTarget) || mappedTarget.startsWith('//')) {
|
|
1326
|
+
return null;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
if (mappedTarget.startsWith('/') || mappedTarget.startsWith('./') || mappedTarget.startsWith('../')) {
|
|
1330
|
+
return resolveRelativeUrl(mappedTarget, importMapBaseUrl);
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
return mappedTarget;
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
function isJavaScriptModuleUrl(moduleUrl) {
|
|
1337
|
+
return JAVASCRIPT_EXTENSIONS.has(path.extname(splitUrlTarget(moduleUrl).pathname));
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
function collectHtmlModuleEntries(html, htmlUrl, ts) {
|
|
1341
|
+
const entryModuleUrls = new Set();
|
|
1342
|
+
const classicScriptUrls = new Set();
|
|
1343
|
+
const inlineModuleSpecifiers = new Set();
|
|
1344
|
+
const inlineStaticModuleSpecifiers = new Set();
|
|
1345
|
+
const inlineRuntimeUrlSpecifiers = new Set();
|
|
1346
|
+
let requiresFullDalilaImportMap = false;
|
|
1347
|
+
let hasUnresolvedDynamicImport = false;
|
|
1348
|
+
let hasUnresolvedRuntimeUrl = false;
|
|
1349
|
+
|
|
1350
|
+
html.replace(/<script\b([^>]*)>([\s\S]*?)<\/script>/gi, (fullMatch, attrs, content) => {
|
|
1351
|
+
const typeMatch = attrs.match(/\btype=["']([^"']+)["']/i);
|
|
1352
|
+
const srcMatch = attrs.match(/\bsrc=["']([^"']+)["']/i);
|
|
1353
|
+
if (!typeMatch || typeMatch[1] !== 'module') {
|
|
1354
|
+
if (srcMatch) {
|
|
1355
|
+
const classicScriptUrl = resolveSpecifierToPackagedUrl(srcMatch[1], htmlUrl, { imports: {}, scopes: {} });
|
|
1356
|
+
if (classicScriptUrl && isJavaScriptModuleUrl(classicScriptUrl)) {
|
|
1357
|
+
classicScriptUrls.add(classicScriptUrl);
|
|
1358
|
+
}
|
|
1359
|
+
} else if (content.trim()) {
|
|
1360
|
+
const collectedClassicSpecifiers = collectModuleSpecifierKinds(content, ts);
|
|
1361
|
+
for (const specifier of collectedClassicSpecifiers.allSpecifiers) {
|
|
1362
|
+
inlineModuleSpecifiers.add(specifier);
|
|
1363
|
+
}
|
|
1364
|
+
for (const runtimeUrlSpecifier of collectedClassicSpecifiers.runtimeUrlSpecifiers ?? []) {
|
|
1365
|
+
inlineRuntimeUrlSpecifiers.add(runtimeUrlSpecifier);
|
|
1366
|
+
}
|
|
1367
|
+
if (collectedClassicSpecifiers.hasUnresolvedDalilaDynamicImport) {
|
|
1368
|
+
requiresFullDalilaImportMap = true;
|
|
1369
|
+
}
|
|
1370
|
+
if (collectedClassicSpecifiers.hasUnresolvedDynamicImport) {
|
|
1371
|
+
hasUnresolvedDynamicImport = true;
|
|
1372
|
+
}
|
|
1373
|
+
if (collectedClassicSpecifiers.hasUnresolvedRuntimeUrl) {
|
|
1374
|
+
hasUnresolvedRuntimeUrl = true;
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
return fullMatch;
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
if (srcMatch) {
|
|
1381
|
+
const entryModuleUrl = resolveSpecifierToPackagedUrl(srcMatch[1], htmlUrl, { imports: {}, scopes: {} });
|
|
1382
|
+
if (entryModuleUrl) {
|
|
1383
|
+
entryModuleUrls.add(entryModuleUrl);
|
|
1384
|
+
}
|
|
1385
|
+
return fullMatch;
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
const collectedSpecifiers = collectModuleSpecifierKinds(content, ts);
|
|
1389
|
+
for (const specifier of collectedSpecifiers.allSpecifiers) {
|
|
1390
|
+
inlineModuleSpecifiers.add(specifier);
|
|
1391
|
+
}
|
|
1392
|
+
for (const specifier of collectedSpecifiers.staticSpecifiers) {
|
|
1393
|
+
inlineStaticModuleSpecifiers.add(specifier);
|
|
1394
|
+
}
|
|
1395
|
+
for (const runtimeUrlSpecifier of collectedSpecifiers.runtimeUrlSpecifiers ?? []) {
|
|
1396
|
+
inlineRuntimeUrlSpecifiers.add(runtimeUrlSpecifier);
|
|
1397
|
+
}
|
|
1398
|
+
if (collectedSpecifiers.hasUnresolvedDalilaDynamicImport) {
|
|
1399
|
+
requiresFullDalilaImportMap = true;
|
|
1400
|
+
}
|
|
1401
|
+
if (collectedSpecifiers.hasUnresolvedDynamicImport) {
|
|
1402
|
+
hasUnresolvedDynamicImport = true;
|
|
1403
|
+
}
|
|
1404
|
+
if (collectedSpecifiers.hasUnresolvedRuntimeUrl) {
|
|
1405
|
+
hasUnresolvedRuntimeUrl = true;
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
return fullMatch;
|
|
1409
|
+
});
|
|
1410
|
+
|
|
1411
|
+
return {
|
|
1412
|
+
classicScriptUrls: [...classicScriptUrls],
|
|
1413
|
+
entryModuleUrls: [...entryModuleUrls],
|
|
1414
|
+
inlineModuleSpecifiers: [...inlineModuleSpecifiers],
|
|
1415
|
+
inlineStaticModuleSpecifiers: [...inlineStaticModuleSpecifiers],
|
|
1416
|
+
inlineRuntimeUrlSpecifiers: [...inlineRuntimeUrlSpecifiers],
|
|
1417
|
+
requiresFullDalilaImportMap,
|
|
1418
|
+
hasUnresolvedDynamicImport,
|
|
1419
|
+
hasUnresolvedRuntimeUrl,
|
|
1420
|
+
};
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
function collectImportMapModuleUrls(importMap, htmlUrl) {
|
|
1424
|
+
const moduleUrls = new Set();
|
|
1425
|
+
|
|
1426
|
+
const addTarget = (target) => {
|
|
1427
|
+
if (typeof target !== 'string') {
|
|
1428
|
+
return;
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
const moduleUrl = resolveSpecifierToPackagedUrl(target, htmlUrl, { imports: {}, scopes: {} });
|
|
1432
|
+
if (moduleUrl && isJavaScriptModuleUrl(moduleUrl)) {
|
|
1433
|
+
moduleUrls.add(moduleUrl);
|
|
1434
|
+
}
|
|
1435
|
+
};
|
|
1436
|
+
|
|
1437
|
+
for (const target of Object.values(importMap?.imports ?? {})) {
|
|
1438
|
+
addTarget(target);
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
for (const scopeImports of Object.values(importMap?.scopes ?? {})) {
|
|
1442
|
+
if (!scopeImports || typeof scopeImports !== 'object' || Array.isArray(scopeImports)) {
|
|
1443
|
+
continue;
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
for (const target of Object.values(scopeImports)) {
|
|
1447
|
+
addTarget(target);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
return [...moduleUrls];
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
function resolvePackagedModuleSourcePath(moduleUrl, buildConfig, dalilaRoot) {
|
|
1455
|
+
const { pathname } = splitUrlTarget(moduleUrl);
|
|
1456
|
+
|
|
1457
|
+
if (pathname.startsWith('/vendor/dalila/')) {
|
|
1458
|
+
return path.join(dalilaRoot, 'dist', pathname.slice('/vendor/dalila/'.length));
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
if (pathname.startsWith('/vendor/node_modules/')) {
|
|
1462
|
+
return path.join(buildConfig.projectDir, 'node_modules', pathname.slice('/vendor/node_modules/'.length));
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
const packagedPath = path.join(buildConfig.packageOutDirAbs, pathname.slice(1));
|
|
1466
|
+
if (fs.existsSync(packagedPath)) {
|
|
1467
|
+
return packagedPath;
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
return path.join(buildConfig.projectDir, pathname.slice(1));
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
function traceReachableModules(page, importMap, buildConfig, dalilaRoot) {
|
|
1474
|
+
const reachableModuleUrls = new Set();
|
|
1475
|
+
const staticReachableModuleUrls = new Set();
|
|
1476
|
+
const usedDalilaSpecifiers = new Set();
|
|
1477
|
+
const classicScriptUrlSet = new Set(page.classicScriptUrls ?? []);
|
|
1478
|
+
const pendingUrls = [];
|
|
1479
|
+
const pendingKeys = new Set();
|
|
1480
|
+
const processedKeys = new Set();
|
|
1481
|
+
let requiresFullDalilaImportMap = page.requiresFullDalilaImportMap === true;
|
|
1482
|
+
let hasUnresolvedDynamicImport = page.hasUnresolvedDynamicImport === true;
|
|
1483
|
+
let hasUnresolvedRuntimeUrl = page.hasUnresolvedRuntimeUrl === true;
|
|
1484
|
+
|
|
1485
|
+
const enqueueResolvedUrl = (moduleUrl, isStatic = false) => {
|
|
1486
|
+
if (!moduleUrl || !isJavaScriptModuleUrl(moduleUrl)) {
|
|
1487
|
+
return;
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
const queueKey = `${moduleUrl}::${isStatic ? 'static' : 'dynamic'}`;
|
|
1491
|
+
if (processedKeys.has(queueKey) || pendingKeys.has(queueKey)) {
|
|
1492
|
+
return;
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
if (reachableModuleUrls.has(moduleUrl) && isStatic) {
|
|
1496
|
+
staticReachableModuleUrls.add(moduleUrl);
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
pendingUrls.push({ moduleUrl, isStatic });
|
|
1500
|
+
pendingKeys.add(queueKey);
|
|
1501
|
+
};
|
|
1502
|
+
|
|
1503
|
+
for (const entryModuleUrl of page.entryModuleUrls) {
|
|
1504
|
+
enqueueResolvedUrl(entryModuleUrl, true);
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
for (const classicScriptUrl of page.classicScriptUrls ?? []) {
|
|
1508
|
+
enqueueResolvedUrl(classicScriptUrl, false);
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
for (const specifier of page.inlineModuleSpecifiers) {
|
|
1512
|
+
if (specifier === 'dalila' || specifier.startsWith('dalila/')) {
|
|
1513
|
+
usedDalilaSpecifiers.add(specifier);
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
const isStatic = page.inlineStaticModuleSpecifiers?.includes(specifier) ?? false;
|
|
1517
|
+
enqueueResolvedUrl(resolveSpecifierToPackagedUrl(specifier, page.htmlUrl, importMap, page.htmlUrl), isStatic);
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
for (const runtimeUrlSpecifier of page.inlineRuntimeUrlSpecifiers ?? []) {
|
|
1521
|
+
enqueueResolvedUrl(resolveSpecifierToPackagedUrl(runtimeUrlSpecifier, page.htmlUrl, importMap, page.htmlUrl), false);
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
while (pendingUrls.length > 0) {
|
|
1525
|
+
const pending = pendingUrls.pop();
|
|
1526
|
+
const moduleUrl = pending?.moduleUrl;
|
|
1527
|
+
const isStaticRoot = pending?.isStatic === true;
|
|
1528
|
+
const queueKey = moduleUrl ? `${moduleUrl}::${isStaticRoot ? 'static' : 'dynamic'}` : null;
|
|
1529
|
+
if (queueKey) {
|
|
1530
|
+
pendingKeys.delete(queueKey);
|
|
1531
|
+
}
|
|
1532
|
+
if (!moduleUrl) {
|
|
1533
|
+
continue;
|
|
1534
|
+
}
|
|
1535
|
+
if (queueKey && processedKeys.has(queueKey)) {
|
|
1536
|
+
continue;
|
|
1537
|
+
}
|
|
1538
|
+
if (queueKey) {
|
|
1539
|
+
processedKeys.add(queueKey);
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
const sourcePath = resolvePackagedModuleSourcePath(moduleUrl, buildConfig, dalilaRoot);
|
|
1543
|
+
ensureFileExists(sourcePath, `module dependency "${moduleUrl}"`);
|
|
1544
|
+
reachableModuleUrls.add(moduleUrl);
|
|
1545
|
+
if (isStaticRoot) {
|
|
1546
|
+
staticReachableModuleUrls.add(moduleUrl);
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
const source = fs.readFileSync(sourcePath, 'utf8');
|
|
1550
|
+
const collectedSpecifiers = collectModuleSpecifierKinds(source, buildConfig.ts);
|
|
1551
|
+
if (collectedSpecifiers.hasUnresolvedDalilaDynamicImport) {
|
|
1552
|
+
requiresFullDalilaImportMap = true;
|
|
1553
|
+
}
|
|
1554
|
+
if (collectedSpecifiers.hasUnresolvedDynamicImport) {
|
|
1555
|
+
hasUnresolvedDynamicImport = true;
|
|
1556
|
+
}
|
|
1557
|
+
if (collectedSpecifiers.hasUnresolvedRuntimeUrl) {
|
|
1558
|
+
hasUnresolvedRuntimeUrl = true;
|
|
1559
|
+
}
|
|
1560
|
+
for (const specifier of collectedSpecifiers.allSpecifiers) {
|
|
1561
|
+
if (specifier === 'dalila' || specifier.startsWith('dalila/')) {
|
|
1562
|
+
usedDalilaSpecifiers.add(specifier);
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
const isStaticDependency = isStaticRoot && collectedSpecifiers.staticSpecifiers.includes(specifier);
|
|
1566
|
+
enqueueResolvedUrl(resolveSpecifierToPackagedUrl(specifier, moduleUrl, importMap, page.htmlUrl), isStaticDependency);
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
const runtimeSpecifierBaseUrl = classicScriptUrlSet.has(moduleUrl) ? page.htmlUrl : moduleUrl;
|
|
1570
|
+
for (const runtimeUrlSpecifier of collectedSpecifiers.runtimeUrlSpecifiers ?? []) {
|
|
1571
|
+
enqueueResolvedUrl(resolveSpecifierToPackagedUrl(runtimeUrlSpecifier, runtimeSpecifierBaseUrl, importMap, page.htmlUrl), false);
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
return {
|
|
1576
|
+
reachableModuleUrls,
|
|
1577
|
+
staticReachableModuleUrls,
|
|
1578
|
+
usedDalilaSpecifiers,
|
|
1579
|
+
requiresFullDalilaImportMap,
|
|
1580
|
+
hasUnresolvedDynamicImport,
|
|
1581
|
+
hasUnresolvedRuntimeUrl,
|
|
1582
|
+
};
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
function copyReachableDalilaModules(reachableModuleUrls, packageOutDirAbs, dalilaRoot) {
|
|
1586
|
+
for (const moduleUrl of reachableModuleUrls) {
|
|
1587
|
+
const { pathname } = splitUrlTarget(moduleUrl);
|
|
1588
|
+
if (!pathname.startsWith('/vendor/dalila/')) {
|
|
1589
|
+
continue;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
const sourcePath = path.join(dalilaRoot, 'dist', pathname.slice('/vendor/dalila/'.length));
|
|
1593
|
+
const destinationPath = path.join(packageOutDirAbs, pathname.slice(1));
|
|
1594
|
+
fs.mkdirSync(path.dirname(destinationPath), { recursive: true });
|
|
1595
|
+
fs.copyFileSync(sourcePath, destinationPath);
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
function copyDalilaModuleClosure(moduleUrls, packageOutDirAbs, dalilaRoot, ts) {
|
|
1600
|
+
const pendingUrls = [...moduleUrls];
|
|
1601
|
+
const copiedUrls = new Set();
|
|
1602
|
+
|
|
1603
|
+
while (pendingUrls.length > 0) {
|
|
1604
|
+
const moduleUrl = pendingUrls.pop();
|
|
1605
|
+
const { pathname } = splitUrlTarget(moduleUrl);
|
|
1606
|
+
if (!pathname.startsWith('/vendor/dalila/') || copiedUrls.has(moduleUrl)) {
|
|
1607
|
+
continue;
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
copiedUrls.add(moduleUrl);
|
|
1611
|
+
const sourcePath = path.join(dalilaRoot, 'dist', pathname.slice('/vendor/dalila/'.length));
|
|
1612
|
+
ensureFileExists(sourcePath, `dalila module "${moduleUrl}"`);
|
|
1613
|
+
const destinationPath = path.join(packageOutDirAbs, pathname.slice(1));
|
|
1614
|
+
fs.mkdirSync(path.dirname(destinationPath), { recursive: true });
|
|
1615
|
+
fs.copyFileSync(sourcePath, destinationPath);
|
|
1616
|
+
|
|
1617
|
+
const source = fs.readFileSync(sourcePath, 'utf8');
|
|
1618
|
+
const collectedSpecifiers = collectModuleSpecifierKinds(source, ts);
|
|
1619
|
+
for (const specifier of collectedSpecifiers.allSpecifiers) {
|
|
1620
|
+
const resolvedUrl = resolveSpecifierToPackagedUrl(specifier, moduleUrl, { imports: {}, scopes: {} });
|
|
1621
|
+
if (resolvedUrl?.startsWith('/vendor/dalila/')) {
|
|
1622
|
+
pendingUrls.push(resolvedUrl);
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
function prunePackagedCompiledArtifacts(
|
|
1629
|
+
buildConfig,
|
|
1630
|
+
_reachableModuleUrls,
|
|
1631
|
+
copiedSourceAssetPaths = new Set(),
|
|
1632
|
+
_preserveCompiledJavaScript = false
|
|
1633
|
+
) {
|
|
1634
|
+
for (const filePath of walkFiles(buildConfig.packageOutDirAbs)) {
|
|
1635
|
+
const relativePath = path.relative(buildConfig.packageOutDirAbs, filePath);
|
|
1636
|
+
if (!isRelativePathInsideBase(relativePath)) {
|
|
1637
|
+
continue;
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
if (relativePath.startsWith(`vendor${path.sep}`) || relativePath === 'vendor') {
|
|
1641
|
+
continue;
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
if (copiedSourceAssetPaths.has(filePath)) {
|
|
1645
|
+
continue;
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
if (TYPE_ARTIFACT_EXTENSIONS.some((extension) => filePath.endsWith(extension))) {
|
|
1649
|
+
fs.rmSync(filePath, { force: true });
|
|
1650
|
+
continue;
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
function pickDalilaImportEntries(dalilaImportEntries, usedDalilaSpecifiers, requiresFullDalilaImportMap = false) {
|
|
1656
|
+
if (requiresFullDalilaImportMap) {
|
|
1657
|
+
return { ...dalilaImportEntries };
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
if (usedDalilaSpecifiers.size === 0) {
|
|
1661
|
+
return {};
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
const selectedEntries = {};
|
|
1665
|
+
for (const specifier of usedDalilaSpecifiers) {
|
|
1666
|
+
if (dalilaImportEntries[specifier]) {
|
|
1667
|
+
selectedEntries[specifier] = dalilaImportEntries[specifier];
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
return selectedEntries;
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
function copyDalilaImportEntryTargets(importEntries, packageOutDirAbs, dalilaRoot, ts) {
|
|
1675
|
+
const dalilaModuleUrls = Object.values(importEntries)
|
|
1676
|
+
.filter((target) => typeof target === 'string' && target.startsWith('/vendor/dalila/'));
|
|
1677
|
+
copyDalilaModuleClosure(dalilaModuleUrls, packageOutDirAbs, dalilaRoot, ts);
|
|
1678
|
+
}
|
|
1679
|
+
|
|
662
1680
|
function shouldPackageHtmlEntry(source) {
|
|
663
1681
|
return /<script[^>]*type=["']module["'][^>]*>/i.test(source)
|
|
1682
|
+
|| /<script[^>]*\bsrc=["'][^"']+\.(?:js|mjs|cjs)(?:[?#][^"']*)?["'][^>]*>/i.test(source)
|
|
1683
|
+
|| /<script\b(?![^>]*type=["'](?:module|importmap)["'])[^>]*>[\s\S]*?\bimport\s*\(/i.test(source)
|
|
1684
|
+
|| /<script\b(?![^>]*type=["']importmap["'])[^>]*>[\s\S]*?(?:\bimportScripts\s*\(|\bnew\s+(?:SharedWorker|Worker)\s*\(|\.serviceWorker\s*\.\s*register\s*\()/i.test(source)
|
|
664
1685
|
|| /<script[^>]*type=["']importmap["'][^>]*>/i.test(source);
|
|
665
1686
|
}
|
|
666
1687
|
|
|
@@ -677,9 +1698,11 @@ function injectHeadContent(html, fragments) {
|
|
|
677
1698
|
const headStart = headOpenMatch.index + headOpenMatch[0].length;
|
|
678
1699
|
const headEnd = headCloseMatch.index;
|
|
679
1700
|
const headContent = html.slice(headStart, headEnd);
|
|
1701
|
+
const anyScriptMatch = headContent.match(/<script\b[^>]*>/i);
|
|
680
1702
|
const moduleScriptMatch = headContent.match(/<script\b[^>]*\btype=["']module["'][^>]*>/i);
|
|
681
1703
|
const stylesheetMatch = headContent.match(/<link\b[^>]*\brel=["']stylesheet["'][^>]*>/i);
|
|
682
|
-
const insertionOffset =
|
|
1704
|
+
const insertionOffset = anyScriptMatch?.index
|
|
1705
|
+
?? moduleScriptMatch?.index
|
|
683
1706
|
?? stylesheetMatch?.index
|
|
684
1707
|
?? headContent.length;
|
|
685
1708
|
const insertionIndex = headStart + insertionOffset;
|
|
@@ -764,14 +1787,11 @@ function rewriteHtmlModuleScripts(html, buildConfig, baseDirAbs = buildConfig.pr
|
|
|
764
1787
|
});
|
|
765
1788
|
}
|
|
766
1789
|
|
|
767
|
-
function buildHtmlDocument(
|
|
768
|
-
const source = fs.readFileSync(sourceHtmlPath, 'utf8');
|
|
769
|
-
const { html: htmlWithoutImportMap } = extractImportMap(source);
|
|
770
|
-
const html = rewriteHtmlModuleScripts(htmlWithoutImportMap, buildConfig, path.dirname(sourceHtmlPath));
|
|
771
|
-
|
|
1790
|
+
function buildHtmlDocument(html, importEntries, buildConfig, modulePreloadUrls = []) {
|
|
772
1791
|
return injectHeadContent(html, [
|
|
773
1792
|
FOUC_PREVENTION_STYLE,
|
|
774
1793
|
renderPreloadScriptTags(buildConfig.sourceDirAbs),
|
|
1794
|
+
renderModulePreloadLinks(modulePreloadUrls),
|
|
775
1795
|
renderImportMapScript(importEntries),
|
|
776
1796
|
]);
|
|
777
1797
|
}
|
|
@@ -859,13 +1879,18 @@ function collectTopLevelStaticDirs(projectDir, buildConfig) {
|
|
|
859
1879
|
.map((entry) => entry.name);
|
|
860
1880
|
}
|
|
861
1881
|
|
|
862
|
-
function copyTopLevelStaticDirs(projectDir, packageOutDirAbs, buildConfig) {
|
|
1882
|
+
function copyTopLevelStaticDirs(projectDir, packageOutDirAbs, buildConfig, copiedAssetPaths = new Set()) {
|
|
863
1883
|
for (const dirName of collectTopLevelStaticDirs(projectDir, buildConfig)) {
|
|
864
|
-
|
|
1884
|
+
const sourceDir = path.join(projectDir, dirName);
|
|
1885
|
+
const destinationDir = path.join(packageOutDirAbs, dirName);
|
|
1886
|
+
copyDirectoryContents(sourceDir, destinationDir);
|
|
1887
|
+
for (const copiedPath of walkFiles(destinationDir)) {
|
|
1888
|
+
copiedAssetPaths.add(copiedPath);
|
|
1889
|
+
}
|
|
865
1890
|
}
|
|
866
1891
|
}
|
|
867
1892
|
|
|
868
|
-
function copyTopLevelStaticFiles(projectDir, packageOutDirAbs) {
|
|
1893
|
+
function copyTopLevelStaticFiles(projectDir, packageOutDirAbs, copiedAssetPaths = new Set()) {
|
|
869
1894
|
for (const entry of fs.readdirSync(projectDir, { withFileTypes: true })) {
|
|
870
1895
|
if (!entry.isFile() || entry.name.startsWith('.') || STATIC_FILE_EXCLUDES.has(entry.name)) {
|
|
871
1896
|
continue;
|
|
@@ -875,6 +1900,7 @@ function copyTopLevelStaticFiles(projectDir, packageOutDirAbs) {
|
|
|
875
1900
|
const destinationPath = path.join(packageOutDirAbs, entry.name);
|
|
876
1901
|
fs.mkdirSync(path.dirname(destinationPath), { recursive: true });
|
|
877
1902
|
fs.copyFileSync(sourcePath, destinationPath);
|
|
1903
|
+
copiedAssetPaths.add(destinationPath);
|
|
878
1904
|
}
|
|
879
1905
|
}
|
|
880
1906
|
|
|
@@ -894,6 +1920,7 @@ function resolveSourceAssetRoots(projectDir, buildConfig) {
|
|
|
894
1920
|
}
|
|
895
1921
|
|
|
896
1922
|
function copyPackagedSourceAssets(projectDir, buildConfig) {
|
|
1923
|
+
const copiedAssetPaths = new Set();
|
|
897
1924
|
for (const sourceDir of resolveSourceAssetRoots(projectDir, buildConfig)) {
|
|
898
1925
|
for (const filePath of walkFiles(sourceDir)) {
|
|
899
1926
|
if (isScriptSourceFile(filePath) || filePath.endsWith('.d.ts')) {
|
|
@@ -914,9 +1941,28 @@ function copyPackagedSourceAssets(projectDir, buildConfig) {
|
|
|
914
1941
|
for (const destinationPath of destinationPaths) {
|
|
915
1942
|
fs.mkdirSync(path.dirname(destinationPath), { recursive: true });
|
|
916
1943
|
fs.copyFileSync(filePath, destinationPath);
|
|
1944
|
+
copiedAssetPaths.add(destinationPath);
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
const publicDir = path.join(projectDir, 'public');
|
|
1950
|
+
if (fs.existsSync(publicDir)) {
|
|
1951
|
+
const publicOutDir = path.join(buildConfig.packageOutDirAbs, 'public');
|
|
1952
|
+
copyDirectoryContents(publicDir, publicOutDir);
|
|
1953
|
+
for (const copiedPath of walkFiles(publicOutDir)) {
|
|
1954
|
+
const relativePath = path.relative(publicOutDir, copiedPath);
|
|
1955
|
+
const sourcePath = path.join(publicDir, relativePath);
|
|
1956
|
+
if (fs.existsSync(sourcePath) && fs.statSync(sourcePath).isFile()) {
|
|
1957
|
+
copiedAssetPaths.add(copiedPath);
|
|
917
1958
|
}
|
|
918
1959
|
}
|
|
919
1960
|
}
|
|
1961
|
+
|
|
1962
|
+
copyTopLevelStaticDirs(projectDir, buildConfig.packageOutDirAbs, buildConfig, copiedAssetPaths);
|
|
1963
|
+
copyTopLevelStaticFiles(projectDir, buildConfig.packageOutDirAbs, copiedAssetPaths);
|
|
1964
|
+
|
|
1965
|
+
return copiedAssetPaths;
|
|
920
1966
|
}
|
|
921
1967
|
|
|
922
1968
|
function walkProjectHtmlFiles(dir, files = []) {
|
|
@@ -945,7 +1991,9 @@ function walkProjectHtmlFiles(dir, files = []) {
|
|
|
945
1991
|
return files;
|
|
946
1992
|
}
|
|
947
1993
|
|
|
948
|
-
function
|
|
1994
|
+
function collectHtmlEntryPoints(projectDir, vendorDir, buildConfig, copiedPackages, dalilaImportEntries, dalilaRoot) {
|
|
1995
|
+
const pages = [];
|
|
1996
|
+
|
|
949
1997
|
for (const sourceHtmlPath of walkProjectHtmlFiles(projectDir)) {
|
|
950
1998
|
const source = fs.readFileSync(sourceHtmlPath, 'utf8');
|
|
951
1999
|
if (!shouldPackageHtmlEntry(source)) {
|
|
@@ -976,19 +2024,95 @@ function packageHtmlEntryPoints(projectDir, vendorDir, buildConfig, copiedPackag
|
|
|
976
2024
|
copiedPackages,
|
|
977
2025
|
baseDirAbs
|
|
978
2026
|
);
|
|
979
|
-
|
|
2027
|
+
|
|
2028
|
+
const { html: htmlWithoutImportMap } = extractImportMap(source);
|
|
2029
|
+
const rewrittenHtml = rewriteHtmlModuleScripts(htmlWithoutImportMap, buildConfig, baseDirAbs);
|
|
2030
|
+
const packagedHtmlPath = path.join(buildConfig.packageOutDirAbs, path.relative(projectDir, sourceHtmlPath));
|
|
2031
|
+
const htmlUrl = `/${toPosixPath(path.relative(projectDir, sourceHtmlPath))}`;
|
|
2032
|
+
const htmlModuleEntries = collectHtmlModuleEntries(rewrittenHtml, htmlUrl, buildConfig.ts);
|
|
2033
|
+
const publicImportMapModuleUrls = collectImportMapModuleUrls(
|
|
2034
|
+
{
|
|
2035
|
+
imports: rewrittenImports,
|
|
2036
|
+
scopes: rewrittenScopes,
|
|
2037
|
+
},
|
|
2038
|
+
htmlUrl
|
|
2039
|
+
);
|
|
2040
|
+
const traceImportMap = {
|
|
980
2041
|
...existingImportMap,
|
|
981
2042
|
imports: {
|
|
982
2043
|
...rewrittenImports,
|
|
983
2044
|
...buildUserProjectImportEntries(buildConfig),
|
|
984
|
-
...
|
|
2045
|
+
...dalilaImportEntries,
|
|
985
2046
|
},
|
|
986
2047
|
scopes: rewrittenScopes,
|
|
987
2048
|
};
|
|
988
|
-
const
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
2049
|
+
const {
|
|
2050
|
+
reachableModuleUrls,
|
|
2051
|
+
staticReachableModuleUrls,
|
|
2052
|
+
usedDalilaSpecifiers,
|
|
2053
|
+
requiresFullDalilaImportMap,
|
|
2054
|
+
hasUnresolvedDynamicImport,
|
|
2055
|
+
hasUnresolvedRuntimeUrl,
|
|
2056
|
+
} = traceReachableModules(
|
|
2057
|
+
{
|
|
2058
|
+
htmlUrl,
|
|
2059
|
+
...htmlModuleEntries,
|
|
2060
|
+
},
|
|
2061
|
+
traceImportMap,
|
|
2062
|
+
buildConfig,
|
|
2063
|
+
dalilaRoot
|
|
2064
|
+
);
|
|
2065
|
+
const publicImportMapTrace = traceReachableModules(
|
|
2066
|
+
{
|
|
2067
|
+
htmlUrl,
|
|
2068
|
+
entryModuleUrls: publicImportMapModuleUrls,
|
|
2069
|
+
inlineModuleSpecifiers: [],
|
|
2070
|
+
},
|
|
2071
|
+
traceImportMap,
|
|
2072
|
+
buildConfig,
|
|
2073
|
+
dalilaRoot
|
|
2074
|
+
);
|
|
2075
|
+
|
|
2076
|
+
pages.push({
|
|
2077
|
+
htmlUrl,
|
|
2078
|
+
packagedHtmlPath,
|
|
2079
|
+
rewrittenHtml,
|
|
2080
|
+
rewrittenImports,
|
|
2081
|
+
rewrittenScopes,
|
|
2082
|
+
existingImportMap,
|
|
2083
|
+
entryModuleUrls: htmlModuleEntries.entryModuleUrls,
|
|
2084
|
+
reachableModuleUrls,
|
|
2085
|
+
staticReachableModuleUrls,
|
|
2086
|
+
preservedModuleUrls: publicImportMapTrace.reachableModuleUrls,
|
|
2087
|
+
usedDalilaSpecifiers: new Set([
|
|
2088
|
+
...usedDalilaSpecifiers,
|
|
2089
|
+
...publicImportMapTrace.usedDalilaSpecifiers,
|
|
2090
|
+
]),
|
|
2091
|
+
requiresFullDalilaImportMap: requiresFullDalilaImportMap || publicImportMapTrace.requiresFullDalilaImportMap,
|
|
2092
|
+
hasUnresolvedDynamicImport: hasUnresolvedDynamicImport || publicImportMapTrace.hasUnresolvedDynamicImport,
|
|
2093
|
+
hasUnresolvedRuntimeUrl: hasUnresolvedRuntimeUrl || publicImportMapTrace.hasUnresolvedRuntimeUrl,
|
|
2094
|
+
});
|
|
2095
|
+
}
|
|
2096
|
+
|
|
2097
|
+
return pages;
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
function writePackagedHtmlEntryPoints(pages, buildConfig, dalilaImportEntries) {
|
|
2101
|
+
for (const page of pages) {
|
|
2102
|
+
const importMap = {
|
|
2103
|
+
...page.existingImportMap,
|
|
2104
|
+
imports: {
|
|
2105
|
+
...page.rewrittenImports,
|
|
2106
|
+
...buildUserProjectImportEntries(buildConfig),
|
|
2107
|
+
...pickDalilaImportEntries(dalilaImportEntries, page.usedDalilaSpecifiers, page.requiresFullDalilaImportMap),
|
|
2108
|
+
},
|
|
2109
|
+
scopes: page.rewrittenScopes,
|
|
2110
|
+
};
|
|
2111
|
+
const modulePreloadUrls = [...page.staticReachableModuleUrls]
|
|
2112
|
+
.filter((moduleUrl) => !page.entryModuleUrls.includes(moduleUrl));
|
|
2113
|
+
const packagedHtml = buildHtmlDocument(page.rewrittenHtml, importMap, buildConfig, modulePreloadUrls);
|
|
2114
|
+
fs.mkdirSync(path.dirname(page.packagedHtmlPath), { recursive: true });
|
|
2115
|
+
fs.writeFileSync(page.packagedHtmlPath, packagedHtml);
|
|
992
2116
|
}
|
|
993
2117
|
}
|
|
994
2118
|
|
|
@@ -1007,21 +2131,49 @@ export async function buildProject(projectDir = process.cwd()) {
|
|
|
1007
2131
|
try {
|
|
1008
2132
|
fs.rmSync(vendorDir, { recursive: true, force: true });
|
|
1009
2133
|
rewritePackagedModuleSpecifiers(buildConfig);
|
|
1010
|
-
|
|
1011
|
-
|
|
2134
|
+
const copiedSourceAssetPaths = copyPackagedSourceAssets(rootDir, buildConfig);
|
|
2135
|
+
const dalilaImportEntries = buildDalilaImportEntries(rootDir);
|
|
2136
|
+
const copiedPackages = new Set();
|
|
2137
|
+
const pages = collectHtmlEntryPoints(
|
|
2138
|
+
rootDir,
|
|
2139
|
+
vendorDir,
|
|
2140
|
+
buildConfig,
|
|
2141
|
+
copiedPackages,
|
|
2142
|
+
dalilaImportEntries,
|
|
2143
|
+
dalilaRoot
|
|
2144
|
+
);
|
|
2145
|
+
const reachableModuleUrls = new Set(
|
|
2146
|
+
pages.flatMap((page) => [...page.reachableModuleUrls, ...page.preservedModuleUrls])
|
|
2147
|
+
);
|
|
2148
|
+
const preserveCompiledJavaScript = pages.some(
|
|
2149
|
+
(page) => page.hasUnresolvedDynamicImport === true || page.hasUnresolvedRuntimeUrl === true
|
|
2150
|
+
);
|
|
2151
|
+
prunePackagedCompiledArtifacts(
|
|
2152
|
+
buildConfig,
|
|
2153
|
+
reachableModuleUrls,
|
|
2154
|
+
copiedSourceAssetPaths,
|
|
2155
|
+
preserveCompiledJavaScript
|
|
2156
|
+
);
|
|
2157
|
+
copyReachableDalilaModules(reachableModuleUrls, distDir, dalilaRoot);
|
|
2158
|
+
for (const page of pages) {
|
|
2159
|
+
const selectedDalilaEntries = pickDalilaImportEntries(
|
|
2160
|
+
dalilaImportEntries,
|
|
2161
|
+
page.usedDalilaSpecifiers,
|
|
2162
|
+
page.requiresFullDalilaImportMap
|
|
2163
|
+
);
|
|
2164
|
+
copyDalilaImportEntryTargets(selectedDalilaEntries, distDir, dalilaRoot, buildConfig.ts);
|
|
2165
|
+
}
|
|
1012
2166
|
copyDirectoryContents(path.join(rootDir, 'public'), path.join(distDir, 'public'));
|
|
1013
2167
|
copyTopLevelStaticDirs(rootDir, distDir, buildConfig);
|
|
1014
2168
|
copyTopLevelStaticFiles(rootDir, distDir);
|
|
1015
|
-
|
|
1016
|
-
const copiedPackages = new Set();
|
|
1017
|
-
packageHtmlEntryPoints(rootDir, vendorDir, buildConfig, copiedPackages);
|
|
2169
|
+
writePackagedHtmlEntryPoints(pages, buildConfig, dalilaImportEntries);
|
|
1018
2170
|
|
|
1019
2171
|
return {
|
|
1020
2172
|
distDir,
|
|
1021
2173
|
importEntries: {
|
|
1022
2174
|
imports: {
|
|
1023
2175
|
...buildUserProjectImportEntries(buildConfig),
|
|
1024
|
-
...
|
|
2176
|
+
...dalilaImportEntries,
|
|
1025
2177
|
},
|
|
1026
2178
|
},
|
|
1027
2179
|
};
|
package/template/package.json
CHANGED
package/template/src/app/page.ts
CHANGED
package/template/src/main.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import DOMPurify from 'dompurify';
|
|
2
|
-
import { configure } from 'dalila/runtime';
|
|
2
|
+
import { configure } from 'dalila/runtime/bind';
|
|
3
3
|
import { createRouter } from 'dalila/router';
|
|
4
4
|
import { routes } from '../routes.generated.js';
|
|
5
5
|
import { routeManifest } from '../routes.generated.manifest.js';
|