@jsenv/plugin-transpilation 1.1.0 → 1.2.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/package.json +4 -4
- package/src/as_js_module/jsenv_plugin_as_js_module.js +14 -31
- package/src/babel/babel_plugin_structure.js +1 -1
- package/src/babel/jsenv_plugin_babel.js +7 -7
- package/src/css/jsenv_plugin_css_transpilation.js +2 -2
- package/src/import_assertions/jsenv_plugin_import_assertions.js +39 -78
- package/src/import_meta_resolve/jsenv_plugin_import_meta_resolve.js +17 -13
- package/src/js_module_fallback/jsenv_plugin_js_module_conversion.js +46 -46
- package/src/js_module_fallback/jsenv_plugin_js_module_fallback.js +1 -27
- package/src/js_module_fallback/jsenv_plugin_js_module_fallback_inside_html.js +43 -25
- package/src/js_module_fallback/jsenv_plugin_js_module_fallback_on_workers.js +15 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/plugin-transpilation",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "TODO",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@babel/plugin-transform-arrow-functions": "7.22.5",
|
|
33
33
|
"@babel/plugin-transform-block-scoped-functions": "7.22.5",
|
|
34
34
|
"@babel/plugin-transform-block-scoping": "7.22.5",
|
|
35
|
-
"@babel/plugin-transform-classes": "7.22.
|
|
35
|
+
"@babel/plugin-transform-classes": "7.22.6",
|
|
36
36
|
"@babel/plugin-transform-computed-properties": "7.22.5",
|
|
37
37
|
"@babel/plugin-transform-destructuring": "7.22.5",
|
|
38
38
|
"@babel/plugin-transform-dotall-regex": "7.22.5",
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
"@babel/plugin-transform-unicode-regex": "7.22.5",
|
|
54
54
|
"babel-plugin-transform-async-to-promises": "0.8.18",
|
|
55
55
|
"construct-style-sheets-polyfill": "3.1.0",
|
|
56
|
-
"@jsenv/ast": "
|
|
56
|
+
"@jsenv/ast": "5.0.0",
|
|
57
57
|
"@jsenv/runtime-compat": "1.0.0",
|
|
58
|
-
"lightningcss": "1.21.
|
|
58
|
+
"lightningcss": "1.21.5"
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -20,41 +20,24 @@ export const jsenvPluginAsJsModule = () => {
|
|
|
20
20
|
redirectReference: (reference) => {
|
|
21
21
|
if (reference.searchParams.has("as_js_module")) {
|
|
22
22
|
reference.expectedType = "js_module";
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
if (!reference.filename) {
|
|
24
|
+
const filename = urlToFilename(reference.url);
|
|
25
|
+
const [basename] = splitFileExtension(filename);
|
|
26
|
+
reference.filename = `${basename}.mjs`;
|
|
27
|
+
}
|
|
26
28
|
}
|
|
27
29
|
},
|
|
28
|
-
fetchUrlContent: async (urlInfo
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// override the expectedType to "js_classic"
|
|
35
|
-
// because when there is ?as_js_module it means the underlying resource
|
|
36
|
-
// is js_classic
|
|
37
|
-
expectedType: "js_classic",
|
|
38
|
-
});
|
|
39
|
-
if (!jsClassicReference) {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
await context.fetchUrlContent(jsClassicUrlInfo, {
|
|
43
|
-
reference: jsClassicReference,
|
|
30
|
+
fetchUrlContent: async (urlInfo) => {
|
|
31
|
+
const jsClassicUrlInfo = urlInfo.getWithoutSearchParam("as_js_module", {
|
|
32
|
+
// override the expectedType to "js_classic"
|
|
33
|
+
// because when there is ?as_js_module it means the underlying resource
|
|
34
|
+
// is js_classic
|
|
35
|
+
expectedType: "js_classic",
|
|
44
36
|
});
|
|
45
|
-
if (
|
|
46
|
-
|
|
47
|
-
type: "js_import",
|
|
48
|
-
subtype: jsClassicReference.subtype,
|
|
49
|
-
specifier: jsClassicReference.url,
|
|
50
|
-
expectedType: "js_classic",
|
|
51
|
-
});
|
|
52
|
-
} else if (
|
|
53
|
-
context.build &&
|
|
54
|
-
!context.urlGraph.hasDependent(jsClassicUrlInfo)
|
|
55
|
-
) {
|
|
56
|
-
context.urlGraph.deleteUrlInfo(jsClassicUrlInfo.url);
|
|
37
|
+
if (!jsClassicUrlInfo) {
|
|
38
|
+
return null;
|
|
57
39
|
}
|
|
40
|
+
await jsClassicUrlInfo.fetchContent();
|
|
58
41
|
const { content, sourcemap } = await convertJsClassicToJsModule({
|
|
59
42
|
input: jsClassicUrlInfo.content,
|
|
60
43
|
inputSourcemap: jsClassicUrlInfo.sourcemap,
|
|
@@ -12,7 +12,7 @@ export const getBaseBabelPluginStructure = ({
|
|
|
12
12
|
// getImportSpecifier,
|
|
13
13
|
}) => {
|
|
14
14
|
const isBabelPluginNeeded = (babelPluginName) => {
|
|
15
|
-
return !isSupported(babelPluginCompatMap[babelPluginName]);
|
|
15
|
+
return !isSupported(babelPluginName, babelPluginCompatMap[babelPluginName]);
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
const babelPluginStructure = {};
|
|
@@ -9,17 +9,17 @@ import { analyzeConstructableStyleSheetUsage } from "./new_stylesheet/constructa
|
|
|
9
9
|
import { babelPluginNewStylesheetInjector } from "./new_stylesheet/babel_plugin_new_stylesheet_injector.js";
|
|
10
10
|
|
|
11
11
|
export const jsenvPluginBabel = ({ babelHelpersAsImport = true } = {}) => {
|
|
12
|
-
const transformWithBabel = async (urlInfo
|
|
12
|
+
const transformWithBabel = async (urlInfo) => {
|
|
13
13
|
const isJsModule = urlInfo.type === "js_module";
|
|
14
14
|
const getImportSpecifier = (clientFileUrl) => {
|
|
15
|
-
const
|
|
15
|
+
const jsImportReference = urlInfo.dependencies.inject({
|
|
16
16
|
type: "js_import",
|
|
17
17
|
expectedType: "js_module",
|
|
18
18
|
specifier: clientFileUrl,
|
|
19
19
|
});
|
|
20
|
-
return JSON.parse(
|
|
20
|
+
return JSON.parse(jsImportReference.generatedSpecifier);
|
|
21
21
|
};
|
|
22
|
-
const isSupported = context.isSupportedOnCurrentClients;
|
|
22
|
+
const isSupported = urlInfo.context.isSupportedOnCurrentClients;
|
|
23
23
|
const babelPluginStructure = getBaseBabelPluginStructure({
|
|
24
24
|
url: urlInfo.originalUrl,
|
|
25
25
|
isSupported,
|
|
@@ -36,7 +36,7 @@ export const jsenvPluginBabel = ({ babelHelpersAsImport = true } = {}) => {
|
|
|
36
36
|
{ babelHelpersAsImport, getImportSpecifier },
|
|
37
37
|
];
|
|
38
38
|
} else {
|
|
39
|
-
|
|
39
|
+
urlInfo.dependencies.foundSideEffectFile({
|
|
40
40
|
sideEffectFileUrl: regeneratorRuntimeClientFileUrl,
|
|
41
41
|
expectedType: "js_classic",
|
|
42
42
|
specifierLine: regeneratorRuntimeUsage.line,
|
|
@@ -55,7 +55,7 @@ export const jsenvPluginBabel = ({ babelHelpersAsImport = true } = {}) => {
|
|
|
55
55
|
{ babelHelpersAsImport, getImportSpecifier },
|
|
56
56
|
];
|
|
57
57
|
} else {
|
|
58
|
-
|
|
58
|
+
urlInfo.dependencies.foundSideEffectFile({
|
|
59
59
|
sideEffectFileUrl: regeneratorRuntimeClientFileUrl,
|
|
60
60
|
expectedType: "js_classic",
|
|
61
61
|
specifierLine: constructableStyleSheetUsage.line,
|
|
@@ -82,7 +82,7 @@ export const jsenvPluginBabel = ({ babelHelpersAsImport = true } = {}) => {
|
|
|
82
82
|
babelPlugins,
|
|
83
83
|
options: {
|
|
84
84
|
generatorOpts: {
|
|
85
|
-
retainLines: context.dev,
|
|
85
|
+
retainLines: urlInfo.context.dev,
|
|
86
86
|
},
|
|
87
87
|
},
|
|
88
88
|
input: urlInfo.content,
|
|
@@ -5,11 +5,11 @@ export const jsenvPluginCssTranspilation = () => {
|
|
|
5
5
|
name: "jsenv:css_transpilation",
|
|
6
6
|
appliesDuring: "*",
|
|
7
7
|
transformUrlContent: {
|
|
8
|
-
css:
|
|
8
|
+
css: (urlInfo) => {
|
|
9
9
|
return applyCssTranspilation({
|
|
10
10
|
input: urlInfo.content,
|
|
11
11
|
inputUrl: urlInfo.originalUrl,
|
|
12
|
-
runtimeCompat: context.runtimeCompat,
|
|
12
|
+
runtimeCompat: urlInfo.context.runtimeCompat,
|
|
13
13
|
});
|
|
14
14
|
},
|
|
15
15
|
},
|
|
@@ -19,39 +19,45 @@ export const jsenvPluginImportAssertions = ({
|
|
|
19
19
|
text = "auto",
|
|
20
20
|
}) => {
|
|
21
21
|
const transpilations = { json, css, text };
|
|
22
|
-
const shouldTranspileImportAssertion = (
|
|
22
|
+
const shouldTranspileImportAssertion = (reference, type) => {
|
|
23
23
|
const transpilation = transpilations[type];
|
|
24
24
|
if (transpilation === true) {
|
|
25
25
|
return true;
|
|
26
26
|
}
|
|
27
27
|
if (transpilation === "auto") {
|
|
28
|
-
return !context.isSupportedOnCurrentClients(
|
|
28
|
+
return !reference.ownerUrlInfo.context.isSupportedOnCurrentClients(
|
|
29
|
+
`import_type_${type}`,
|
|
30
|
+
);
|
|
29
31
|
}
|
|
30
32
|
return false;
|
|
31
33
|
};
|
|
32
34
|
const markAsJsModuleProxy = (reference) => {
|
|
33
35
|
reference.expectedType = "js_module";
|
|
34
|
-
reference.filename
|
|
36
|
+
if (!reference.filename) {
|
|
37
|
+
reference.filename = `${urlToFilename(reference.url)}.js`;
|
|
38
|
+
}
|
|
35
39
|
};
|
|
36
40
|
const turnIntoJsModuleProxy = (reference, type) => {
|
|
37
41
|
reference.mutation = (magicSource) => {
|
|
38
|
-
const {
|
|
42
|
+
const { importTypeAttributeNode } = reference.astInfo;
|
|
39
43
|
if (reference.subtype === "import_dynamic") {
|
|
40
|
-
const assertPropertyNode = assertNode.properties.find(
|
|
41
|
-
(prop) => prop.key.name === "assert",
|
|
42
|
-
);
|
|
43
|
-
const assertPropertyValue = assertPropertyNode.value;
|
|
44
|
-
const typePropertyNode = assertPropertyValue.properties.find(
|
|
45
|
-
(prop) => prop.key.name === "type",
|
|
46
|
-
);
|
|
47
44
|
magicSource.remove({
|
|
48
|
-
start:
|
|
49
|
-
end:
|
|
45
|
+
start: importTypeAttributeNode.start,
|
|
46
|
+
end: importTypeAttributeNode.end,
|
|
50
47
|
});
|
|
51
48
|
} else {
|
|
49
|
+
const content = reference.ownerUrlInfo.content;
|
|
50
|
+
const assertKeyboardStart = content.indexOf(
|
|
51
|
+
"assert",
|
|
52
|
+
importTypeAttributeNode.start - " assert { ".length,
|
|
53
|
+
);
|
|
54
|
+
const assertKeywordEnd = content.indexOf(
|
|
55
|
+
"}",
|
|
56
|
+
importTypeAttributeNode.end,
|
|
57
|
+
);
|
|
52
58
|
magicSource.remove({
|
|
53
|
-
start:
|
|
54
|
-
end:
|
|
59
|
+
start: assertKeyboardStart,
|
|
60
|
+
end: assertKeywordEnd + 1,
|
|
55
61
|
});
|
|
56
62
|
}
|
|
57
63
|
};
|
|
@@ -77,8 +83,8 @@ export const jsenvPluginImportAssertions = ({
|
|
|
77
83
|
transpilations.text = true;
|
|
78
84
|
}
|
|
79
85
|
},
|
|
80
|
-
redirectReference: (reference
|
|
81
|
-
if (!reference.
|
|
86
|
+
redirectReference: (reference) => {
|
|
87
|
+
if (!reference.importAttributes) {
|
|
82
88
|
return null;
|
|
83
89
|
}
|
|
84
90
|
const { searchParams } = reference;
|
|
@@ -90,8 +96,8 @@ export const jsenvPluginImportAssertions = ({
|
|
|
90
96
|
markAsJsModuleProxy(reference);
|
|
91
97
|
return null;
|
|
92
98
|
}
|
|
93
|
-
const type = reference.
|
|
94
|
-
if (shouldTranspileImportAssertion(
|
|
99
|
+
const type = reference.importAttributes.type;
|
|
100
|
+
if (shouldTranspileImportAssertion(reference, type)) {
|
|
95
101
|
return turnIntoJsModuleProxy(reference, type);
|
|
96
102
|
}
|
|
97
103
|
return null;
|
|
@@ -104,29 +110,14 @@ const jsenvPluginAsModules = () => {
|
|
|
104
110
|
const asJsonModule = {
|
|
105
111
|
name: `jsenv:as_json_module`,
|
|
106
112
|
appliesDuring: "*",
|
|
107
|
-
fetchUrlContent: async (urlInfo
|
|
108
|
-
const
|
|
109
|
-
urlInfo,
|
|
110
|
-
context,
|
|
111
|
-
searchParam: "as_json_module",
|
|
113
|
+
fetchUrlContent: async (urlInfo) => {
|
|
114
|
+
const jsonUrlInfo = urlInfo.getWithoutSearchParam("as_json_module", {
|
|
112
115
|
expectedType: "json",
|
|
113
116
|
});
|
|
114
|
-
if (!
|
|
117
|
+
if (!jsonUrlInfo) {
|
|
115
118
|
return null;
|
|
116
119
|
}
|
|
117
|
-
await
|
|
118
|
-
reference: jsonReference,
|
|
119
|
-
});
|
|
120
|
-
if (context.dev) {
|
|
121
|
-
context.referenceUtils.found({
|
|
122
|
-
type: "js_import",
|
|
123
|
-
subtype: jsonReference.subtype,
|
|
124
|
-
specifier: jsonReference.url,
|
|
125
|
-
expectedType: "js_module",
|
|
126
|
-
});
|
|
127
|
-
} else if (context.build && !context.urlGraph.hasDependent(jsonUrlInfo)) {
|
|
128
|
-
context.urlGraph.deleteUrlInfo(jsonUrlInfo.url);
|
|
129
|
-
}
|
|
120
|
+
await jsonUrlInfo.fetchContent();
|
|
130
121
|
const jsonText = JSON.stringify(jsonUrlInfo.content.trim());
|
|
131
122
|
return {
|
|
132
123
|
// here we could `export default ${jsonText}`:
|
|
@@ -145,29 +136,14 @@ const jsenvPluginAsModules = () => {
|
|
|
145
136
|
const asCssModule = {
|
|
146
137
|
name: `jsenv:as_css_module`,
|
|
147
138
|
appliesDuring: "*",
|
|
148
|
-
fetchUrlContent: async (urlInfo
|
|
149
|
-
const
|
|
150
|
-
urlInfo,
|
|
151
|
-
context,
|
|
152
|
-
searchParam: "as_css_module",
|
|
139
|
+
fetchUrlContent: async (urlInfo) => {
|
|
140
|
+
const cssUrlInfo = urlInfo.getWithoutSearchParam("as_css_module", {
|
|
153
141
|
expectedType: "css",
|
|
154
142
|
});
|
|
155
|
-
if (!
|
|
143
|
+
if (!cssUrlInfo) {
|
|
156
144
|
return null;
|
|
157
145
|
}
|
|
158
|
-
await
|
|
159
|
-
reference: cssReference,
|
|
160
|
-
});
|
|
161
|
-
if (context.dev) {
|
|
162
|
-
context.referenceUtils.found({
|
|
163
|
-
type: "js_import",
|
|
164
|
-
subtype: cssReference.subtype,
|
|
165
|
-
specifier: cssReference.url,
|
|
166
|
-
expectedType: "js_module",
|
|
167
|
-
});
|
|
168
|
-
} else if (context.build && !context.urlGraph.hasDependent(cssUrlInfo)) {
|
|
169
|
-
context.urlGraph.deleteUrlInfo(cssUrlInfo.url);
|
|
170
|
-
}
|
|
146
|
+
await cssUrlInfo.fetchContent();
|
|
171
147
|
const cssText = JS_QUOTES.escapeSpecialChars(cssUrlInfo.content, {
|
|
172
148
|
// If template string is choosen and runtime do not support template literals
|
|
173
149
|
// it's ok because "jsenv:new_inline_content" plugin executes after this one
|
|
@@ -176,7 +152,7 @@ const jsenvPluginAsModules = () => {
|
|
|
176
152
|
});
|
|
177
153
|
return {
|
|
178
154
|
content: `import ${JSON.stringify(
|
|
179
|
-
context.
|
|
155
|
+
urlInfo.context.inlineContentClientFileUrl,
|
|
180
156
|
)};
|
|
181
157
|
|
|
182
158
|
const inlineContent = new __InlineContent__(${cssText}, { type: "text/css" });
|
|
@@ -195,29 +171,14 @@ export default stylesheet;`,
|
|
|
195
171
|
const asTextModule = {
|
|
196
172
|
name: `jsenv:as_text_module`,
|
|
197
173
|
appliesDuring: "*",
|
|
198
|
-
fetchUrlContent: async (urlInfo
|
|
199
|
-
const
|
|
200
|
-
urlInfo,
|
|
201
|
-
context,
|
|
202
|
-
searchParam: "as_text_module",
|
|
174
|
+
fetchUrlContent: async (urlInfo) => {
|
|
175
|
+
const textUrlInfo = urlInfo.getWithoutSearchParam("as_text_module", {
|
|
203
176
|
expectedType: "text",
|
|
204
177
|
});
|
|
205
|
-
if (!
|
|
178
|
+
if (!textUrlInfo) {
|
|
206
179
|
return null;
|
|
207
180
|
}
|
|
208
|
-
await
|
|
209
|
-
reference: textReference,
|
|
210
|
-
});
|
|
211
|
-
if (context.dev) {
|
|
212
|
-
context.referenceUtils.found({
|
|
213
|
-
type: "js_import",
|
|
214
|
-
subtype: textReference.subtype,
|
|
215
|
-
specifier: textReference.url,
|
|
216
|
-
expectedType: "js_module",
|
|
217
|
-
});
|
|
218
|
-
} else if (context.build && !context.urlGraph.hasDependent(textUrlInfo)) {
|
|
219
|
-
context.urlGraph.deleteUrlInfo(textUrlInfo.url);
|
|
220
|
-
}
|
|
181
|
+
await textUrlInfo.fetchContent();
|
|
221
182
|
const textPlain = JS_QUOTES.escapeSpecialChars(urlInfo.content, {
|
|
222
183
|
// If template string is choosen and runtime do not support template literals
|
|
223
184
|
// it's ok because "jsenv:new_inline_content" plugin executes after this one
|
|
@@ -226,7 +187,7 @@ export default stylesheet;`,
|
|
|
226
187
|
});
|
|
227
188
|
return {
|
|
228
189
|
content: `import ${JSON.stringify(
|
|
229
|
-
context.
|
|
190
|
+
urlInfo.context.inlineContentClientFileUrl,
|
|
230
191
|
)};
|
|
231
192
|
|
|
232
193
|
const inlineContent = new InlineContent(${textPlain}, { type: "text/plain" });
|
|
@@ -15,32 +15,36 @@ export const jsenvPluginImportMetaResolve = () => {
|
|
|
15
15
|
return true;
|
|
16
16
|
},
|
|
17
17
|
transformUrlContent: {
|
|
18
|
-
js_module: async (urlInfo
|
|
18
|
+
js_module: async (urlInfo) => {
|
|
19
19
|
const magicSource = createMagicSource(urlInfo.content);
|
|
20
|
-
|
|
21
|
-
if (
|
|
22
|
-
const originalSpecifierLength = Buffer.byteLength(
|
|
20
|
+
for (const referenceToOther of urlInfo.referenceToOthersSet) {
|
|
21
|
+
if (referenceToOther.subtype === "import_meta_resolve") {
|
|
22
|
+
const originalSpecifierLength = Buffer.byteLength(
|
|
23
|
+
referenceToOther.specifier,
|
|
24
|
+
);
|
|
23
25
|
const specifierLength = Buffer.byteLength(
|
|
24
|
-
|
|
26
|
+
referenceToOther.generatedSpecifier.slice(1, -1), // remove `"` around
|
|
25
27
|
);
|
|
26
28
|
const specifierLengthDiff =
|
|
27
29
|
specifierLength - originalSpecifierLength;
|
|
28
|
-
const
|
|
30
|
+
const { node } = referenceToOther.astInfo;
|
|
31
|
+
const end = node.end + specifierLengthDiff;
|
|
29
32
|
magicSource.replace({
|
|
30
|
-
start:
|
|
33
|
+
start: node.start,
|
|
31
34
|
end,
|
|
32
|
-
replacement: `new URL(${
|
|
35
|
+
replacement: `new URL(${referenceToOther.generatedSpecifier}, import.meta.url).href`,
|
|
33
36
|
});
|
|
34
37
|
const currentLengthBeforeSpecifier = "import.meta.resolve(".length;
|
|
35
38
|
const newLengthBeforeSpecifier = "new URL(".length;
|
|
36
39
|
const lengthDiff =
|
|
37
40
|
currentLengthBeforeSpecifier - newLengthBeforeSpecifier;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
referenceToOther.specifierColumn -= lengthDiff;
|
|
42
|
+
referenceToOther.specifierStart -= lengthDiff;
|
|
43
|
+
referenceToOther.specifierEnd =
|
|
44
|
+
referenceToOther.specifierStart +
|
|
45
|
+
Buffer.byteLength(referenceToOther.generatedSpecifier);
|
|
42
46
|
}
|
|
43
|
-
}
|
|
47
|
+
}
|
|
44
48
|
return magicSource.toContentAndSourcemap();
|
|
45
49
|
},
|
|
46
50
|
},
|
|
@@ -3,15 +3,13 @@
|
|
|
3
3
|
* - perform conversion from js module to js classic when url uses "?js_module_fallback"
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { injectQueryParams } from "@jsenv/urls";
|
|
6
|
+
import { urlToFilename, injectQueryParams } from "@jsenv/urls";
|
|
7
7
|
import {
|
|
8
8
|
convertJsModuleToJsClassic,
|
|
9
9
|
systemJsClientFileUrlDefault,
|
|
10
10
|
} from "@jsenv/js-module-fallback";
|
|
11
11
|
|
|
12
|
-
export const jsenvPluginJsModuleConversion = ({
|
|
13
|
-
generateJsClassicFilename,
|
|
14
|
-
}) => {
|
|
12
|
+
export const jsenvPluginJsModuleConversion = () => {
|
|
15
13
|
const isReferencingJsModule = (reference) => {
|
|
16
14
|
if (
|
|
17
15
|
reference.type === "js_import" ||
|
|
@@ -26,23 +24,20 @@ export const jsenvPluginJsModuleConversion = ({
|
|
|
26
24
|
return false;
|
|
27
25
|
};
|
|
28
26
|
|
|
29
|
-
const shouldPropagateJsModuleConversion = (reference
|
|
30
|
-
if (isReferencingJsModule(reference
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
const parentGotAsJsClassic = new URL(parentUrlInfo.url).searchParams.has(
|
|
36
|
-
"js_module_fallback",
|
|
37
|
-
);
|
|
38
|
-
return parentGotAsJsClassic;
|
|
27
|
+
const shouldPropagateJsModuleConversion = (reference) => {
|
|
28
|
+
if (isReferencingJsModule(reference)) {
|
|
29
|
+
const insideJsClassic =
|
|
30
|
+
reference.ownerUrlInfo.searchParams.has("js_module_fallback");
|
|
31
|
+
return insideJsClassic;
|
|
39
32
|
}
|
|
40
33
|
return false;
|
|
41
34
|
};
|
|
42
35
|
|
|
43
36
|
const markAsJsClassicProxy = (reference) => {
|
|
44
37
|
reference.expectedType = "js_classic";
|
|
45
|
-
|
|
38
|
+
if (!reference.filename) {
|
|
39
|
+
reference.filename = generateJsClassicFilename(reference.url);
|
|
40
|
+
}
|
|
46
41
|
};
|
|
47
42
|
|
|
48
43
|
const turnIntoJsClassicProxy = (reference) => {
|
|
@@ -56,7 +51,7 @@ export const jsenvPluginJsModuleConversion = ({
|
|
|
56
51
|
return {
|
|
57
52
|
name: "jsenv:js_module_conversion",
|
|
58
53
|
appliesDuring: "*",
|
|
59
|
-
redirectReference: (reference
|
|
54
|
+
redirectReference: (reference) => {
|
|
60
55
|
if (reference.searchParams.has("js_module_fallback")) {
|
|
61
56
|
markAsJsClassicProxy(reference);
|
|
62
57
|
return null;
|
|
@@ -67,42 +62,25 @@ export const jsenvPluginJsModuleConversion = ({
|
|
|
67
62
|
// (because it's the transpiled equivalent of static and dynamic imports)
|
|
68
63
|
// And not other references otherwise we could try to transform inline resources
|
|
69
64
|
// or specifiers inside new URL()...
|
|
70
|
-
if (shouldPropagateJsModuleConversion(reference
|
|
71
|
-
return turnIntoJsClassicProxy(reference
|
|
65
|
+
if (shouldPropagateJsModuleConversion(reference)) {
|
|
66
|
+
return turnIntoJsClassicProxy(reference);
|
|
72
67
|
}
|
|
73
68
|
return null;
|
|
74
69
|
},
|
|
75
|
-
fetchUrlContent: async (urlInfo
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
context,
|
|
80
|
-
searchParam: "js_module_fallback",
|
|
70
|
+
fetchUrlContent: async (urlInfo) => {
|
|
71
|
+
const jsModuleUrlInfo = urlInfo.getWithoutSearchParam(
|
|
72
|
+
"js_module_fallback",
|
|
73
|
+
{
|
|
81
74
|
// override the expectedType to "js_module"
|
|
82
75
|
// because when there is ?js_module_fallback it means the underlying resource
|
|
83
76
|
// is a js_module
|
|
84
77
|
expectedType: "js_module",
|
|
85
|
-
}
|
|
86
|
-
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
if (!jsModuleUrlInfo) {
|
|
87
81
|
return null;
|
|
88
82
|
}
|
|
89
|
-
await
|
|
90
|
-
reference: jsModuleReference,
|
|
91
|
-
});
|
|
92
|
-
if (context.dev) {
|
|
93
|
-
context.referenceUtils.found({
|
|
94
|
-
type: "js_import",
|
|
95
|
-
subtype: jsModuleReference.subtype,
|
|
96
|
-
specifier: jsModuleReference.url,
|
|
97
|
-
expectedType: "js_module",
|
|
98
|
-
});
|
|
99
|
-
} else if (
|
|
100
|
-
context.build &&
|
|
101
|
-
!context.urlGraph.hasDependent(jsModuleUrlInfo)
|
|
102
|
-
) {
|
|
103
|
-
context.urlGraph.deleteUrlInfo(jsModuleUrlInfo.url);
|
|
104
|
-
}
|
|
105
|
-
|
|
83
|
+
await jsModuleUrlInfo.fetchContent();
|
|
106
84
|
let outputFormat;
|
|
107
85
|
if (urlInfo.isEntryPoint && !jsModuleUrlInfo.data.usesImport) {
|
|
108
86
|
// if it's an entry point without dependency (it does not use import)
|
|
@@ -114,7 +92,7 @@ export const jsenvPluginJsModuleConversion = ({
|
|
|
114
92
|
// or to be able to import when it uses import
|
|
115
93
|
outputFormat = "system";
|
|
116
94
|
urlInfo.type = "js_classic";
|
|
117
|
-
|
|
95
|
+
urlInfo.dependencies.foundSideEffectFile({
|
|
118
96
|
sideEffectFileUrl: systemJsClientFileUrlDefault,
|
|
119
97
|
expectedType: "js_classic",
|
|
120
98
|
line: 0,
|
|
@@ -122,12 +100,12 @@ export const jsenvPluginJsModuleConversion = ({
|
|
|
122
100
|
});
|
|
123
101
|
}
|
|
124
102
|
const { content, sourcemap } = await convertJsModuleToJsClassic({
|
|
125
|
-
rootDirectoryUrl: context.rootDirectoryUrl,
|
|
103
|
+
rootDirectoryUrl: urlInfo.context.rootDirectoryUrl,
|
|
126
104
|
input: jsModuleUrlInfo.content,
|
|
127
105
|
inputIsEntryPoint: urlInfo.isEntryPoint,
|
|
128
106
|
inputSourcemap: jsModuleUrlInfo.sourcemap,
|
|
129
107
|
inputUrl: jsModuleUrlInfo.url,
|
|
130
|
-
outputUrl:
|
|
108
|
+
outputUrl: urlInfo.url,
|
|
131
109
|
outputFormat,
|
|
132
110
|
});
|
|
133
111
|
return {
|
|
@@ -142,3 +120,25 @@ export const jsenvPluginJsModuleConversion = ({
|
|
|
142
120
|
},
|
|
143
121
|
};
|
|
144
122
|
};
|
|
123
|
+
|
|
124
|
+
const generateJsClassicFilename = (url) => {
|
|
125
|
+
const filename = urlToFilename(url);
|
|
126
|
+
let [basename, extension] = splitFileExtension(filename);
|
|
127
|
+
const { searchParams } = new URL(url);
|
|
128
|
+
if (
|
|
129
|
+
searchParams.has("as_json_module") ||
|
|
130
|
+
searchParams.has("as_css_module") ||
|
|
131
|
+
searchParams.has("as_text_module")
|
|
132
|
+
) {
|
|
133
|
+
extension = ".js";
|
|
134
|
+
}
|
|
135
|
+
return `${basename}.nomodule${extension}`;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const splitFileExtension = (filename) => {
|
|
139
|
+
const dotLastIndex = filename.lastIndexOf(".");
|
|
140
|
+
if (dotLastIndex === -1) {
|
|
141
|
+
return [filename, ""];
|
|
142
|
+
}
|
|
143
|
+
return [filename.slice(0, dotLastIndex), filename.slice(dotLastIndex)];
|
|
144
|
+
};
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { urlToFilename } from "@jsenv/urls";
|
|
2
|
-
|
|
3
1
|
import { jsenvPluginJsModuleConversion } from "./jsenv_plugin_js_module_conversion.js";
|
|
4
2
|
import { jsenvPluginJsModuleFallbackInsideHtml } from "./jsenv_plugin_js_module_fallback_inside_html.js";
|
|
5
3
|
import { jsenvPluginJsModuleFallbackOnWorkers } from "./jsenv_plugin_js_module_fallback_on_workers.js";
|
|
@@ -8,30 +6,6 @@ export const jsenvPluginJsModuleFallback = () => {
|
|
|
8
6
|
return [
|
|
9
7
|
jsenvPluginJsModuleFallbackInsideHtml(),
|
|
10
8
|
jsenvPluginJsModuleFallbackOnWorkers(),
|
|
11
|
-
jsenvPluginJsModuleConversion(
|
|
12
|
-
generateJsClassicFilename,
|
|
13
|
-
}),
|
|
9
|
+
jsenvPluginJsModuleConversion(),
|
|
14
10
|
];
|
|
15
11
|
};
|
|
16
|
-
|
|
17
|
-
const generateJsClassicFilename = (url) => {
|
|
18
|
-
const filename = urlToFilename(url);
|
|
19
|
-
let [basename, extension] = splitFileExtension(filename);
|
|
20
|
-
const { searchParams } = new URL(url);
|
|
21
|
-
if (
|
|
22
|
-
searchParams.has("as_json_module") ||
|
|
23
|
-
searchParams.has("as_css_module") ||
|
|
24
|
-
searchParams.has("as_text_module")
|
|
25
|
-
) {
|
|
26
|
-
extension = ".js";
|
|
27
|
-
}
|
|
28
|
-
return `${basename}.nomodule${extension}`;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const splitFileExtension = (filename) => {
|
|
32
|
-
const dotLastIndex = filename.lastIndexOf(".");
|
|
33
|
-
if (dotLastIndex === -1) {
|
|
34
|
-
return [filename, ""];
|
|
35
|
-
}
|
|
36
|
-
return [filename.slice(0, dotLastIndex), filename.slice(dotLastIndex)];
|
|
37
|
-
};
|
|
@@ -17,6 +17,14 @@ import {
|
|
|
17
17
|
|
|
18
18
|
export const jsenvPluginJsModuleFallbackInsideHtml = () => {
|
|
19
19
|
const turnIntoJsClassicProxy = (reference) => {
|
|
20
|
+
// not needed for now: redirections are disabled
|
|
21
|
+
// for getWithoutSearchParam
|
|
22
|
+
// if (
|
|
23
|
+
// reference.prev &&
|
|
24
|
+
// reference.prev.searchParams.has("js_module_fallback")
|
|
25
|
+
// ) {
|
|
26
|
+
// return null;
|
|
27
|
+
// }
|
|
20
28
|
return injectQueryParams(reference.url, { js_module_fallback: "" });
|
|
21
29
|
};
|
|
22
30
|
|
|
@@ -24,15 +32,15 @@ export const jsenvPluginJsModuleFallbackInsideHtml = () => {
|
|
|
24
32
|
name: "jsenv:js_module_fallback_inside_html",
|
|
25
33
|
appliesDuring: "*",
|
|
26
34
|
redirectReference: {
|
|
27
|
-
link_href: (reference
|
|
35
|
+
link_href: (reference) => {
|
|
28
36
|
if (
|
|
29
|
-
context.systemJsTranspilation &&
|
|
37
|
+
reference.ownerUrlInfo.context.systemJsTranspilation &&
|
|
30
38
|
reference.subtype === "modulepreload"
|
|
31
39
|
) {
|
|
32
40
|
return turnIntoJsClassicProxy(reference);
|
|
33
41
|
}
|
|
34
42
|
if (
|
|
35
|
-
context.systemJsTranspilation &&
|
|
43
|
+
reference.ownerUrlInfo.context.systemJsTranspilation &&
|
|
36
44
|
reference.subtype === "preload" &&
|
|
37
45
|
reference.expectedType === "js_module"
|
|
38
46
|
) {
|
|
@@ -40,18 +48,18 @@ export const jsenvPluginJsModuleFallbackInsideHtml = () => {
|
|
|
40
48
|
}
|
|
41
49
|
return null;
|
|
42
50
|
},
|
|
43
|
-
script: (reference
|
|
51
|
+
script: (reference) => {
|
|
44
52
|
if (
|
|
45
|
-
context.systemJsTranspilation &&
|
|
53
|
+
reference.ownerUrlInfo.context.systemJsTranspilation &&
|
|
46
54
|
reference.expectedType === "js_module"
|
|
47
55
|
) {
|
|
48
56
|
return turnIntoJsClassicProxy(reference);
|
|
49
57
|
}
|
|
50
58
|
return null;
|
|
51
59
|
},
|
|
52
|
-
js_url: (reference
|
|
60
|
+
js_url: (reference) => {
|
|
53
61
|
if (
|
|
54
|
-
context.systemJsTranspilation &&
|
|
62
|
+
reference.ownerUrlInfo.context.systemJsTranspilation &&
|
|
55
63
|
reference.expectedType === "js_module"
|
|
56
64
|
) {
|
|
57
65
|
return turnIntoJsClassicProxy(reference);
|
|
@@ -60,7 +68,7 @@ export const jsenvPluginJsModuleFallbackInsideHtml = () => {
|
|
|
60
68
|
},
|
|
61
69
|
},
|
|
62
70
|
finalizeUrlContent: {
|
|
63
|
-
html: async (urlInfo
|
|
71
|
+
html: async (urlInfo) => {
|
|
64
72
|
const htmlAst = parseHtmlString(urlInfo.content);
|
|
65
73
|
const mutations = [];
|
|
66
74
|
visitHtmlNodes(htmlAst, {
|
|
@@ -73,13 +81,18 @@ export const jsenvPluginJsModuleFallbackInsideHtml = () => {
|
|
|
73
81
|
if (!href) {
|
|
74
82
|
return;
|
|
75
83
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
let linkHintReference = null;
|
|
85
|
+
for (const referenceToOther of urlInfo.referenceToOthersSet) {
|
|
86
|
+
if (
|
|
87
|
+
referenceToOther.generatedSpecifier === href &&
|
|
88
|
+
referenceToOther.type === "link_href" &&
|
|
89
|
+
referenceToOther.subtype === rel
|
|
90
|
+
) {
|
|
91
|
+
linkHintReference = referenceToOther;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (!wasOrWillBeConvertedToJsClassic(linkHintReference)) {
|
|
83
96
|
return;
|
|
84
97
|
}
|
|
85
98
|
if (rel === "modulepreload") {
|
|
@@ -104,21 +117,26 @@ export const jsenvPluginJsModuleFallbackInsideHtml = () => {
|
|
|
104
117
|
}
|
|
105
118
|
const src = getHtmlNodeAttribute(node, "src");
|
|
106
119
|
if (src) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
120
|
+
let scriptTypeModuleReference = null;
|
|
121
|
+
for (const referenceToOther of urlInfo.referenceToOthersSet) {
|
|
122
|
+
if (
|
|
123
|
+
referenceToOther.generatedSpecifier === src &&
|
|
124
|
+
referenceToOther.type === "script" &&
|
|
125
|
+
referenceToOther.subtype === "js_module"
|
|
126
|
+
) {
|
|
127
|
+
scriptTypeModuleReference = referenceToOther;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (!scriptTypeModuleReference) {
|
|
114
132
|
return;
|
|
115
133
|
}
|
|
116
|
-
if (
|
|
134
|
+
if (scriptTypeModuleReference.expectedType === "js_classic") {
|
|
117
135
|
mutations.push(() => {
|
|
118
136
|
setHtmlNodeAttributes(node, { type: undefined });
|
|
119
137
|
});
|
|
120
138
|
}
|
|
121
|
-
} else if (context.systemJsTranspilation) {
|
|
139
|
+
} else if (urlInfo.context.systemJsTranspilation) {
|
|
122
140
|
mutations.push(() => {
|
|
123
141
|
setHtmlNodeAttributes(node, { type: undefined });
|
|
124
142
|
});
|
|
@@ -127,7 +145,7 @@ export const jsenvPluginJsModuleFallbackInsideHtml = () => {
|
|
|
127
145
|
});
|
|
128
146
|
await Promise.all(mutations.map((mutation) => mutation()));
|
|
129
147
|
return stringifyHtmlAst(htmlAst, {
|
|
130
|
-
cleanupPositionAttributes: context.dev,
|
|
148
|
+
cleanupPositionAttributes: urlInfo.context.dev,
|
|
131
149
|
});
|
|
132
150
|
},
|
|
133
151
|
},
|
|
@@ -16,9 +16,10 @@ import { injectQueryParams } from "@jsenv/urls";
|
|
|
16
16
|
export const jsenvPluginJsModuleFallbackOnWorkers = () => {
|
|
17
17
|
const turnIntoJsClassicProxy = (reference) => {
|
|
18
18
|
reference.mutation = (magicSource) => {
|
|
19
|
+
const { typePropertyNode } = reference.astInfo;
|
|
19
20
|
magicSource.replace({
|
|
20
|
-
start:
|
|
21
|
-
end:
|
|
21
|
+
start: typePropertyNode.value.start,
|
|
22
|
+
end: typePropertyNode.value.end,
|
|
22
23
|
replacement: JSON.stringify("classic"),
|
|
23
24
|
});
|
|
24
25
|
};
|
|
@@ -29,19 +30,25 @@ export const jsenvPluginJsModuleFallbackOnWorkers = () => {
|
|
|
29
30
|
name: "jsenv:js_module_fallback_on_workers",
|
|
30
31
|
appliesDuring: "*",
|
|
31
32
|
redirectReference: {
|
|
32
|
-
js_url: (reference
|
|
33
|
+
js_url: (reference) => {
|
|
33
34
|
if (reference.expectedType !== "js_module") {
|
|
34
35
|
return null;
|
|
35
36
|
}
|
|
36
37
|
if (reference.expectedSubtype === "worker") {
|
|
37
|
-
if (
|
|
38
|
+
if (
|
|
39
|
+
reference.ownerUrlInfo.context.isSupportedOnCurrentClients(
|
|
40
|
+
"worker_type_module",
|
|
41
|
+
)
|
|
42
|
+
) {
|
|
38
43
|
return null;
|
|
39
44
|
}
|
|
40
45
|
return turnIntoJsClassicProxy(reference);
|
|
41
46
|
}
|
|
42
47
|
if (reference.expectedSubtype === "service_worker") {
|
|
43
48
|
if (
|
|
44
|
-
context.isSupportedOnCurrentClients(
|
|
49
|
+
reference.ownerUrlInfo.context.isSupportedOnCurrentClients(
|
|
50
|
+
"service_worker_type_module",
|
|
51
|
+
)
|
|
45
52
|
) {
|
|
46
53
|
return null;
|
|
47
54
|
}
|
|
@@ -49,7 +56,9 @@ export const jsenvPluginJsModuleFallbackOnWorkers = () => {
|
|
|
49
56
|
}
|
|
50
57
|
if (reference.expectedSubtype === "shared_worker") {
|
|
51
58
|
if (
|
|
52
|
-
context.isSupportedOnCurrentClients(
|
|
59
|
+
reference.ownerUrlInfo.context.isSupportedOnCurrentClients(
|
|
60
|
+
"shared_worker_type_module",
|
|
61
|
+
)
|
|
53
62
|
) {
|
|
54
63
|
return null;
|
|
55
64
|
}
|