@jsenv/plugin-transpilation 1.2.2 → 1.3.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 +3 -3
- package/src/as_js_module/jsenv_plugin_as_js_module.js +3 -3
- package/src/import_assertions/jsenv_plugin_import_assertions.js +114 -101
- package/src/{import_meta_resolve → js_module_fallback}/jsenv_plugin_import_meta_resolve.js +3 -3
- package/src/js_module_fallback/jsenv_plugin_js_module_conversion.js +17 -7
- package/src/js_module_fallback/jsenv_plugin_js_module_fallback.js +32 -3
- package/src/js_module_fallback/jsenv_plugin_js_module_fallback_inside_html.js +62 -70
- package/src/js_module_fallback/jsenv_plugin_js_module_fallback_on_workers.js +21 -34
- package/src/{top_level_await → js_module_fallback}/jsenv_plugin_top_level_await.js +3 -3
- package/src/jsenv_plugin_transpilation.js +9 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/plugin-transpilation",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "TODO",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -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": "5.0
|
|
57
|
-
"@jsenv/runtime-compat": "1.
|
|
56
|
+
"@jsenv/ast": "5.1.0",
|
|
57
|
+
"@jsenv/runtime-compat": "1.2.0",
|
|
58
58
|
"lightningcss": "1.21.5"
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -16,10 +16,10 @@ import { convertJsClassicToJsModule } from "./convert_js_classic_to_js_module.js
|
|
|
16
16
|
export const jsenvPluginAsJsModule = () => {
|
|
17
17
|
const markAsJsModuleProxy = (reference) => {
|
|
18
18
|
reference.expectedType = "js_module";
|
|
19
|
-
if (!reference.
|
|
19
|
+
if (!reference.filenameHint) {
|
|
20
20
|
const filename = urlToFilename(reference.url);
|
|
21
21
|
const [basename] = splitFileExtension(filename);
|
|
22
|
-
reference.
|
|
22
|
+
reference.filenameHint = `${basename}.mjs`;
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
|
|
@@ -41,7 +41,7 @@ export const jsenvPluginAsJsModule = () => {
|
|
|
41
41
|
if (!jsClassicUrlInfo) {
|
|
42
42
|
return null;
|
|
43
43
|
}
|
|
44
|
-
await jsClassicUrlInfo.
|
|
44
|
+
await jsClassicUrlInfo.cook();
|
|
45
45
|
const { content, sourcemap } = await convertJsClassicToJsModule({
|
|
46
46
|
input: jsClassicUrlInfo.content,
|
|
47
47
|
inputSourcemap: jsClassicUrlInfo.sourcemap,
|
|
@@ -19,33 +19,22 @@ export const jsenvPluginImportAssertions = ({
|
|
|
19
19
|
text = "auto",
|
|
20
20
|
}) => {
|
|
21
21
|
const transpilations = { json, css, text };
|
|
22
|
-
const shouldTranspileImportAssertion = (reference, type) => {
|
|
23
|
-
const transpilation = transpilations[type];
|
|
24
|
-
if (transpilation === true) {
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
if (transpilation === "auto") {
|
|
28
|
-
return !reference.ownerUrlInfo.context.isSupportedOnCurrentClients(
|
|
29
|
-
`import_type_${type}`,
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
return false;
|
|
33
|
-
};
|
|
34
22
|
const markAsJsModuleProxy = (reference) => {
|
|
35
23
|
reference.expectedType = "js_module";
|
|
36
|
-
if (!reference.
|
|
37
|
-
reference.
|
|
24
|
+
if (!reference.filenameHint) {
|
|
25
|
+
reference.filenameHint = `${urlToFilename(reference.url)}.js`;
|
|
38
26
|
}
|
|
39
27
|
};
|
|
40
28
|
const turnIntoJsModuleProxy = (reference, type) => {
|
|
41
29
|
reference.mutation = (magicSource) => {
|
|
42
|
-
const { importTypeAttributeNode } = reference.astInfo;
|
|
43
30
|
if (reference.subtype === "import_dynamic") {
|
|
31
|
+
const { importTypeAttributeNode } = reference.astInfo;
|
|
44
32
|
magicSource.remove({
|
|
45
33
|
start: importTypeAttributeNode.start,
|
|
46
34
|
end: importTypeAttributeNode.end,
|
|
47
35
|
});
|
|
48
36
|
} else {
|
|
37
|
+
const { importTypeAttributeNode } = reference.astInfo;
|
|
49
38
|
const content = reference.ownerUrlInfo.content;
|
|
50
39
|
const assertKeyboardStart = content.indexOf(
|
|
51
40
|
"assert",
|
|
@@ -64,66 +53,86 @@ export const jsenvPluginImportAssertions = ({
|
|
|
64
53
|
const newUrl = injectQueryParams(reference.url, {
|
|
65
54
|
[`as_${type}_module`]: "",
|
|
66
55
|
});
|
|
67
|
-
markAsJsModuleProxy(reference);
|
|
56
|
+
markAsJsModuleProxy(reference, type);
|
|
68
57
|
return newUrl;
|
|
69
58
|
};
|
|
70
59
|
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
60
|
+
const createImportTypePlugin = ({ type, createUrlContent }) => {
|
|
61
|
+
return {
|
|
62
|
+
name: `jsenv:import_type_${type}`,
|
|
63
|
+
appliesDuring: "*",
|
|
64
|
+
init: (context) => {
|
|
65
|
+
// transpilation is forced during build so that
|
|
66
|
+
// - avoid rollup to see import assertions
|
|
67
|
+
// We would have to tell rollup to ignore import with assertion
|
|
68
|
+
// - means rollup can bundle more js file together
|
|
69
|
+
// - means url versioning can work for css inlined in js
|
|
70
|
+
if (context.build) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
const transpilation = transpilations[type];
|
|
74
|
+
if (transpilation === "auto") {
|
|
75
|
+
return !context.isSupportedOnCurrentClients(`import_type_${type}`);
|
|
76
|
+
}
|
|
77
|
+
return transpilation;
|
|
78
|
+
},
|
|
79
|
+
redirectReference: (reference) => {
|
|
80
|
+
if (!reference.importAttributes) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const { searchParams } = reference;
|
|
84
|
+
if (searchParams.has(`as_${type}_module`)) {
|
|
85
|
+
markAsJsModuleProxy(reference, type);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
// when search param is injected, it will be removed later
|
|
89
|
+
// by "getWithoutSearchParam". We don't want to redirect again
|
|
90
|
+
// (would create infinite recursion)
|
|
91
|
+
if (
|
|
92
|
+
reference.prev &&
|
|
93
|
+
reference.prev.searchParams.has(`as_${type}_module`)
|
|
94
|
+
) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
if (reference.importAttributes.type === type) {
|
|
98
|
+
return turnIntoJsModuleProxy(reference, type);
|
|
99
|
+
}
|
|
88
100
|
return null;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
},
|
|
101
|
+
},
|
|
102
|
+
fetchUrlContent: async (urlInfo) => {
|
|
103
|
+
const originalUrlInfo = urlInfo.getWithoutSearchParam(
|
|
104
|
+
`as_${type}_module`,
|
|
105
|
+
{
|
|
106
|
+
expectedType: "json",
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
if (!originalUrlInfo) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
await originalUrlInfo.cook();
|
|
113
|
+
return createUrlContent(originalUrlInfo);
|
|
114
|
+
},
|
|
115
|
+
};
|
|
105
116
|
};
|
|
106
|
-
return [importAssertions, ...jsenvPluginAsModules()];
|
|
107
|
-
};
|
|
108
117
|
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
appliesDuring: "*",
|
|
113
|
-
fetchUrlContent: async (urlInfo) => {
|
|
114
|
-
const jsonUrlInfo = urlInfo.getWithoutSearchParam("as_json_module", {
|
|
115
|
-
expectedType: "json",
|
|
116
|
-
});
|
|
117
|
-
if (!jsonUrlInfo) {
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
await jsonUrlInfo.fetchContent();
|
|
118
|
+
const asJsonModule = createImportTypePlugin({
|
|
119
|
+
type: "json",
|
|
120
|
+
createUrlContent: (jsonUrlInfo) => {
|
|
121
121
|
const jsonText = JSON.stringify(jsonUrlInfo.content.trim());
|
|
122
|
+
let inlineContentCall;
|
|
123
|
+
// here we could `export default ${jsonText}`:
|
|
124
|
+
// but js engine are optimized to recognize JSON.parse
|
|
125
|
+
// and use a faster parsing strategy
|
|
126
|
+
if (jsonUrlInfo.context.dev) {
|
|
127
|
+
inlineContentCall = `JSON.parse(
|
|
128
|
+
${jsonText},
|
|
129
|
+
//# inlinedFromUrl=${jsonUrlInfo.url}
|
|
130
|
+
)`;
|
|
131
|
+
} else {
|
|
132
|
+
inlineContentCall = `JSON.parse(${jsonText})`;
|
|
133
|
+
}
|
|
122
134
|
return {
|
|
123
|
-
|
|
124
|
-
// but js engine are optimized to recognize JSON.parse
|
|
125
|
-
// and use a faster parsing strategy
|
|
126
|
-
content: `export default JSON.parse(${jsonText})`,
|
|
135
|
+
content: `export default ${inlineContentCall};`,
|
|
127
136
|
contentType: "text/javascript",
|
|
128
137
|
type: "js_module",
|
|
129
138
|
originalUrl: jsonUrlInfo.originalUrl,
|
|
@@ -131,33 +140,35 @@ const jsenvPluginAsModules = () => {
|
|
|
131
140
|
data: jsonUrlInfo.data,
|
|
132
141
|
};
|
|
133
142
|
},
|
|
134
|
-
};
|
|
143
|
+
});
|
|
135
144
|
|
|
136
|
-
const asCssModule = {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
fetchUrlContent: async (urlInfo) => {
|
|
140
|
-
const cssUrlInfo = urlInfo.getWithoutSearchParam("as_css_module", {
|
|
141
|
-
expectedType: "css",
|
|
142
|
-
});
|
|
143
|
-
if (!cssUrlInfo) {
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
await cssUrlInfo.fetchContent();
|
|
145
|
+
const asCssModule = createImportTypePlugin({
|
|
146
|
+
type: "css",
|
|
147
|
+
createUrlContent: (cssUrlInfo) => {
|
|
147
148
|
const cssText = JS_QUOTES.escapeSpecialChars(cssUrlInfo.content, {
|
|
148
149
|
// If template string is choosen and runtime do not support template literals
|
|
149
150
|
// it's ok because "jsenv:new_inline_content" plugin executes after this one
|
|
150
151
|
// and convert template strings into raw strings
|
|
151
152
|
canUseTemplateString: true,
|
|
152
153
|
});
|
|
154
|
+
let inlineContentCall;
|
|
155
|
+
if (cssUrlInfo.context.dev) {
|
|
156
|
+
inlineContentCall = `new __InlineContent__(
|
|
157
|
+
${cssText},
|
|
158
|
+
{ type: "text/css" },
|
|
159
|
+
//# inlinedFromUrl=${cssUrlInfo.url}
|
|
160
|
+
)`;
|
|
161
|
+
} else {
|
|
162
|
+
inlineContentCall = `new __InlineContent__(${cssText}, { type: "text/css" })`;
|
|
163
|
+
}
|
|
153
164
|
return {
|
|
154
|
-
content: `
|
|
155
|
-
|
|
156
|
-
)};
|
|
165
|
+
content: `
|
|
166
|
+
import ${JSON.stringify(cssUrlInfo.context.inlineContentClientFileUrl)};
|
|
157
167
|
|
|
158
|
-
const inlineContent =
|
|
168
|
+
const inlineContent = ${inlineContentCall};
|
|
159
169
|
const stylesheet = new CSSStyleSheet();
|
|
160
170
|
stylesheet.replaceSync(inlineContent.text);
|
|
171
|
+
|
|
161
172
|
export default stylesheet;`,
|
|
162
173
|
contentType: "text/javascript",
|
|
163
174
|
type: "js_module",
|
|
@@ -166,31 +177,33 @@ export default stylesheet;`,
|
|
|
166
177
|
data: cssUrlInfo.data,
|
|
167
178
|
};
|
|
168
179
|
},
|
|
169
|
-
};
|
|
180
|
+
});
|
|
170
181
|
|
|
171
|
-
const asTextModule = {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const textUrlInfo = urlInfo.getWithoutSearchParam("as_text_module", {
|
|
176
|
-
expectedType: "text",
|
|
177
|
-
});
|
|
178
|
-
if (!textUrlInfo) {
|
|
179
|
-
return null;
|
|
180
|
-
}
|
|
181
|
-
await textUrlInfo.fetchContent();
|
|
182
|
-
const textPlain = JS_QUOTES.escapeSpecialChars(urlInfo.content, {
|
|
182
|
+
const asTextModule = createImportTypePlugin({
|
|
183
|
+
type: "text",
|
|
184
|
+
createUrlContent: (textUrlInfo) => {
|
|
185
|
+
const textPlain = JS_QUOTES.escapeSpecialChars(textUrlInfo.content, {
|
|
183
186
|
// If template string is choosen and runtime do not support template literals
|
|
184
187
|
// it's ok because "jsenv:new_inline_content" plugin executes after this one
|
|
185
188
|
// and convert template strings into raw strings
|
|
186
189
|
canUseTemplateString: true,
|
|
187
190
|
});
|
|
191
|
+
let inlineContentCall;
|
|
192
|
+
if (textUrlInfo.context.dev) {
|
|
193
|
+
inlineContentCall = `new __InlineContent__(
|
|
194
|
+
${textPlain},
|
|
195
|
+
{ type: "text/plain"},
|
|
196
|
+
//# inlinedFromUrl=${textUrlInfo.url}
|
|
197
|
+
)`;
|
|
198
|
+
} else {
|
|
199
|
+
inlineContentCall = `new __InlineContent__(${textPlain}, { type: "text/plain"})`;
|
|
200
|
+
}
|
|
188
201
|
return {
|
|
189
|
-
content: `
|
|
190
|
-
|
|
191
|
-
|
|
202
|
+
content: `
|
|
203
|
+
import ${JSON.stringify(textUrlInfo.context.inlineContentClientFileUrl)};
|
|
204
|
+
|
|
205
|
+
const inlineContent = ${inlineContentCall};
|
|
192
206
|
|
|
193
|
-
const inlineContent = new InlineContent(${textPlain}, { type: "text/plain" });
|
|
194
207
|
export default inlineContent.text;`,
|
|
195
208
|
contentType: "text/javascript",
|
|
196
209
|
type: "js_module",
|
|
@@ -199,7 +212,7 @@ export default inlineContent.text;`,
|
|
|
199
212
|
data: textUrlInfo.data,
|
|
200
213
|
};
|
|
201
214
|
},
|
|
202
|
-
};
|
|
215
|
+
});
|
|
203
216
|
|
|
204
217
|
return [asJsonModule, asCssModule, asTextModule];
|
|
205
218
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createMagicSource } from "@jsenv/sourcemap";
|
|
2
2
|
|
|
3
|
-
export const jsenvPluginImportMetaResolve = () => {
|
|
3
|
+
export const jsenvPluginImportMetaResolve = ({ needJsModuleFallback }) => {
|
|
4
4
|
return {
|
|
5
5
|
name: "jsenv:import_meta_resolve",
|
|
6
6
|
appliesDuring: "*",
|
|
@@ -8,8 +8,8 @@ export const jsenvPluginImportMetaResolve = () => {
|
|
|
8
8
|
if (context.isSupportedOnCurrentClients("import_meta_resolve")) {
|
|
9
9
|
return false;
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
if (needJsModuleFallback(context)) {
|
|
12
|
+
// will be handled by systemjs, keep it untouched
|
|
13
13
|
return false;
|
|
14
14
|
}
|
|
15
15
|
return true;
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
systemJsClientFileUrlDefault,
|
|
10
10
|
} from "@jsenv/js-module-fallback";
|
|
11
11
|
|
|
12
|
-
export const jsenvPluginJsModuleConversion = () => {
|
|
12
|
+
export const jsenvPluginJsModuleConversion = ({ remapImportSpecifier }) => {
|
|
13
13
|
const isReferencingJsModule = (reference) => {
|
|
14
14
|
if (
|
|
15
15
|
reference.type === "js_import" ||
|
|
@@ -35,17 +35,16 @@ export const jsenvPluginJsModuleConversion = () => {
|
|
|
35
35
|
|
|
36
36
|
const markAsJsClassicProxy = (reference) => {
|
|
37
37
|
reference.expectedType = "js_classic";
|
|
38
|
-
if (!reference.
|
|
39
|
-
reference.
|
|
38
|
+
if (!reference.filenameHint) {
|
|
39
|
+
reference.filenameHint = generateJsClassicFilename(reference.url);
|
|
40
40
|
}
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
const turnIntoJsClassicProxy = (reference) => {
|
|
44
|
-
|
|
44
|
+
markAsJsClassicProxy(reference);
|
|
45
|
+
return injectQueryParams(reference.url, {
|
|
45
46
|
js_module_fallback: "",
|
|
46
47
|
});
|
|
47
|
-
markAsJsClassicProxy(reference);
|
|
48
|
-
return urlTransformed;
|
|
49
48
|
};
|
|
50
49
|
|
|
51
50
|
return {
|
|
@@ -56,6 +55,15 @@ export const jsenvPluginJsModuleConversion = () => {
|
|
|
56
55
|
markAsJsClassicProxy(reference);
|
|
57
56
|
return null;
|
|
58
57
|
}
|
|
58
|
+
// when search param is injected, it will be removed later
|
|
59
|
+
// by "getWithoutSearchParam". We don't want to redirect again
|
|
60
|
+
// (would create infinite recursion)
|
|
61
|
+
if (
|
|
62
|
+
reference.prev &&
|
|
63
|
+
reference.prev.searchParams.has(`js_module_fallback`)
|
|
64
|
+
) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
59
67
|
// We want to propagate transformation of js module to js classic to:
|
|
60
68
|
// - import specifier (static/dynamic import + re-export)
|
|
61
69
|
// - url specifier when inside System.register/_context.import()
|
|
@@ -80,7 +88,7 @@ export const jsenvPluginJsModuleConversion = () => {
|
|
|
80
88
|
if (!jsModuleUrlInfo) {
|
|
81
89
|
return null;
|
|
82
90
|
}
|
|
83
|
-
await jsModuleUrlInfo.
|
|
91
|
+
await jsModuleUrlInfo.cook();
|
|
84
92
|
let outputFormat;
|
|
85
93
|
if (urlInfo.isEntryPoint && !jsModuleUrlInfo.data.usesImport) {
|
|
86
94
|
// if it's an entry point without dependency (it does not use import)
|
|
@@ -107,6 +115,7 @@ export const jsenvPluginJsModuleConversion = () => {
|
|
|
107
115
|
inputUrl: jsModuleUrlInfo.url,
|
|
108
116
|
outputUrl: urlInfo.url,
|
|
109
117
|
outputFormat,
|
|
118
|
+
remapImportSpecifier,
|
|
110
119
|
});
|
|
111
120
|
return {
|
|
112
121
|
content,
|
|
@@ -130,6 +139,7 @@ const generateJsClassicFilename = (url) => {
|
|
|
130
139
|
searchParams.has("as_css_module") ||
|
|
131
140
|
searchParams.has("as_text_module")
|
|
132
141
|
) {
|
|
142
|
+
basename += extension;
|
|
133
143
|
extension = ".js";
|
|
134
144
|
}
|
|
135
145
|
return `${basename}.nomodule${extension}`;
|
|
@@ -1,11 +1,40 @@
|
|
|
1
1
|
import { jsenvPluginJsModuleConversion } from "./jsenv_plugin_js_module_conversion.js";
|
|
2
2
|
import { jsenvPluginJsModuleFallbackInsideHtml } from "./jsenv_plugin_js_module_fallback_inside_html.js";
|
|
3
3
|
import { jsenvPluginJsModuleFallbackOnWorkers } from "./jsenv_plugin_js_module_fallback_on_workers.js";
|
|
4
|
+
import { jsenvPluginImportMetaResolve } from "./jsenv_plugin_import_meta_resolve.js";
|
|
5
|
+
import { jsenvPluginTopLevelAwait } from "./jsenv_plugin_top_level_await.js";
|
|
6
|
+
|
|
7
|
+
export const jsenvPluginJsModuleFallback = ({ remapImportSpecifier } = {}) => {
|
|
8
|
+
const needJsModuleFallback = (context) => {
|
|
9
|
+
if (Object.keys(context.clientRuntimeCompat).includes("node")) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
if (
|
|
13
|
+
context.versioning &&
|
|
14
|
+
context.versioningViaImportmap &&
|
|
15
|
+
!context.isSupportedOnCurrentClients("importmap")
|
|
16
|
+
) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (
|
|
20
|
+
!context.isSupportedOnCurrentClients("script_type_module") ||
|
|
21
|
+
!context.isSupportedOnCurrentClients("import_dynamic") ||
|
|
22
|
+
!context.isSupportedOnCurrentClients("import_meta")
|
|
23
|
+
) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
};
|
|
4
28
|
|
|
5
|
-
export const jsenvPluginJsModuleFallback = () => {
|
|
6
29
|
return [
|
|
7
|
-
jsenvPluginJsModuleFallbackInsideHtml(),
|
|
30
|
+
jsenvPluginJsModuleFallbackInsideHtml({ needJsModuleFallback }),
|
|
8
31
|
jsenvPluginJsModuleFallbackOnWorkers(),
|
|
9
|
-
jsenvPluginJsModuleConversion(),
|
|
32
|
+
jsenvPluginJsModuleConversion({ remapImportSpecifier }),
|
|
33
|
+
// must come after jsModuleFallback because it's related to the module format
|
|
34
|
+
// so we want to want to know the module format before transforming things
|
|
35
|
+
// - top level await
|
|
36
|
+
// - import.meta.resolve()
|
|
37
|
+
jsenvPluginImportMetaResolve({ needJsModuleFallback }),
|
|
38
|
+
jsenvPluginTopLevelAwait({ needJsModuleFallback }),
|
|
10
39
|
];
|
|
11
40
|
};
|
|
@@ -13,34 +13,32 @@ import {
|
|
|
13
13
|
getHtmlNodeAttribute,
|
|
14
14
|
setHtmlNodeAttributes,
|
|
15
15
|
analyzeScriptNode,
|
|
16
|
+
getHtmlNodeText,
|
|
16
17
|
} from "@jsenv/ast";
|
|
17
18
|
|
|
18
|
-
export const jsenvPluginJsModuleFallbackInsideHtml = (
|
|
19
|
+
export const jsenvPluginJsModuleFallbackInsideHtml = ({
|
|
20
|
+
needJsModuleFallback,
|
|
21
|
+
}) => {
|
|
19
22
|
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
|
-
// }
|
|
28
23
|
return injectQueryParams(reference.url, { js_module_fallback: "" });
|
|
29
24
|
};
|
|
30
25
|
|
|
31
26
|
return {
|
|
32
27
|
name: "jsenv:js_module_fallback_inside_html",
|
|
33
28
|
appliesDuring: "*",
|
|
29
|
+
init: needJsModuleFallback,
|
|
34
30
|
redirectReference: {
|
|
35
31
|
link_href: (reference) => {
|
|
36
32
|
if (
|
|
37
|
-
reference.
|
|
38
|
-
reference.
|
|
33
|
+
reference.prev &&
|
|
34
|
+
reference.prev.searchParams.has(`js_module_fallback`)
|
|
39
35
|
) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
if (reference.subtype === "modulepreload") {
|
|
40
39
|
return turnIntoJsClassicProxy(reference);
|
|
41
40
|
}
|
|
42
41
|
if (
|
|
43
|
-
reference.ownerUrlInfo.context.systemJsTranspilation &&
|
|
44
42
|
reference.subtype === "preload" &&
|
|
45
43
|
reference.expectedType === "js_module"
|
|
46
44
|
) {
|
|
@@ -50,18 +48,24 @@ export const jsenvPluginJsModuleFallbackInsideHtml = () => {
|
|
|
50
48
|
},
|
|
51
49
|
script: (reference) => {
|
|
52
50
|
if (
|
|
53
|
-
reference.
|
|
54
|
-
reference.
|
|
51
|
+
reference.prev &&
|
|
52
|
+
reference.prev.searchParams.has(`js_module_fallback`)
|
|
55
53
|
) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
if (reference.expectedType === "js_module") {
|
|
56
57
|
return turnIntoJsClassicProxy(reference);
|
|
57
58
|
}
|
|
58
59
|
return null;
|
|
59
60
|
},
|
|
60
61
|
js_url: (reference) => {
|
|
61
62
|
if (
|
|
62
|
-
reference.
|
|
63
|
-
reference.
|
|
63
|
+
reference.prev &&
|
|
64
|
+
reference.prev.searchParams.has(`js_module_fallback`)
|
|
64
65
|
) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
if (reference.expectedType === "js_module") {
|
|
65
69
|
return turnIntoJsClassicProxy(reference);
|
|
66
70
|
}
|
|
67
71
|
return null;
|
|
@@ -92,19 +96,21 @@ export const jsenvPluginJsModuleFallbackInsideHtml = () => {
|
|
|
92
96
|
break;
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
|
-
if (!wasOrWillBeConvertedToJsClassic(linkHintReference)) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
99
|
if (rel === "modulepreload") {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
if (linkHintReference.expectedType === "js_classic") {
|
|
101
|
+
mutations.push(() => {
|
|
102
|
+
setHtmlNodeAttributes(node, {
|
|
103
|
+
rel: "preload",
|
|
104
|
+
as: "script",
|
|
105
|
+
crossorigin: undefined,
|
|
106
|
+
});
|
|
104
107
|
});
|
|
105
|
-
}
|
|
108
|
+
}
|
|
106
109
|
}
|
|
107
|
-
if (
|
|
110
|
+
if (
|
|
111
|
+
rel === "preload" &&
|
|
112
|
+
wasConvertedFromJsModule(linkHintReference)
|
|
113
|
+
) {
|
|
108
114
|
mutations.push(() => {
|
|
109
115
|
setHtmlNodeAttributes(node, { crossorigin: undefined });
|
|
110
116
|
});
|
|
@@ -116,31 +122,33 @@ export const jsenvPluginJsModuleFallbackInsideHtml = () => {
|
|
|
116
122
|
return;
|
|
117
123
|
}
|
|
118
124
|
const src = getHtmlNodeAttribute(node, "src");
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
referenceToOther.type === "script" &&
|
|
125
|
-
referenceToOther.subtype === "js_module"
|
|
126
|
-
) {
|
|
127
|
-
scriptTypeModuleReference = referenceToOther;
|
|
128
|
-
break;
|
|
129
|
-
}
|
|
125
|
+
const text = getHtmlNodeText(node);
|
|
126
|
+
let scriptReference = null;
|
|
127
|
+
for (const referenceToOther of urlInfo.referenceToOthersSet) {
|
|
128
|
+
if (referenceToOther.type !== "script") {
|
|
129
|
+
continue;
|
|
130
130
|
}
|
|
131
|
-
if (
|
|
132
|
-
|
|
131
|
+
if (src && referenceToOther.generatedSpecifier === src) {
|
|
132
|
+
scriptReference = referenceToOther;
|
|
133
|
+
break;
|
|
133
134
|
}
|
|
134
|
-
if (
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
if (text) {
|
|
136
|
+
if (referenceToOther.content === text) {
|
|
137
|
+
scriptReference = referenceToOther;
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
if (referenceToOther.urlInfo.content === text) {
|
|
141
|
+
scriptReference = referenceToOther;
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
138
144
|
}
|
|
139
|
-
} else if (urlInfo.context.systemJsTranspilation) {
|
|
140
|
-
mutations.push(() => {
|
|
141
|
-
setHtmlNodeAttributes(node, { type: undefined });
|
|
142
|
-
});
|
|
143
145
|
}
|
|
146
|
+
if (!wasConvertedFromJsModule(scriptReference)) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
mutations.push(() => {
|
|
150
|
+
setHtmlNodeAttributes(node, { type: undefined });
|
|
151
|
+
});
|
|
144
152
|
},
|
|
145
153
|
});
|
|
146
154
|
await Promise.all(mutations.map((mutation) => mutation()));
|
|
@@ -152,30 +160,14 @@ export const jsenvPluginJsModuleFallbackInsideHtml = () => {
|
|
|
152
160
|
};
|
|
153
161
|
};
|
|
154
162
|
|
|
155
|
-
const
|
|
156
|
-
if (reference.expectedType
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
let prev = reference.prev;
|
|
163
|
-
while (prev) {
|
|
164
|
-
if (prev.expectedType === "js_classic") {
|
|
165
|
-
return true;
|
|
166
|
-
}
|
|
167
|
-
if (willBeConvertedToJsClassic(prev)) {
|
|
168
|
-
return true;
|
|
163
|
+
const wasConvertedFromJsModule = (reference) => {
|
|
164
|
+
if (reference.expectedType === "js_classic") {
|
|
165
|
+
// check if a prev version was using js module
|
|
166
|
+
if (reference.original) {
|
|
167
|
+
if (reference.original.expectedType === "js_module") {
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
169
170
|
}
|
|
170
|
-
prev = prev.prev;
|
|
171
171
|
}
|
|
172
|
-
|
|
173
172
|
return false;
|
|
174
173
|
};
|
|
175
|
-
|
|
176
|
-
const willBeConvertedToJsClassic = (reference) => {
|
|
177
|
-
return (
|
|
178
|
-
reference.searchParams.has("js_module_fallback") ||
|
|
179
|
-
reference.searchParams.has("as_js_classic")
|
|
180
|
-
);
|
|
181
|
-
};
|
|
@@ -26,46 +26,33 @@ export const jsenvPluginJsModuleFallbackOnWorkers = () => {
|
|
|
26
26
|
return injectQueryParams(reference.url, { js_module_fallback: "" });
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (
|
|
35
|
-
return
|
|
29
|
+
const createWorkerPlugin = (subtype) => {
|
|
30
|
+
return {
|
|
31
|
+
name: `jsenv:js_module_fallback_on_${subtype}`,
|
|
32
|
+
appliesDuring: "*",
|
|
33
|
+
init: (context) => {
|
|
34
|
+
if (context.isSupportedOnCurrentClients(`${subtype}_type_module`)) {
|
|
35
|
+
return false;
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
) {
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
return turnIntoJsClassicProxy(reference);
|
|
46
|
-
}
|
|
47
|
-
if (reference.expectedSubtype === "service_worker") {
|
|
48
|
-
if (
|
|
49
|
-
reference.ownerUrlInfo.context.isSupportedOnCurrentClients(
|
|
50
|
-
"service_worker_type_module",
|
|
51
|
-
)
|
|
52
|
-
) {
|
|
37
|
+
return true;
|
|
38
|
+
},
|
|
39
|
+
redirectReference: {
|
|
40
|
+
js_url: (reference) => {
|
|
41
|
+
if (reference.expectedType !== "js_module") {
|
|
53
42
|
return null;
|
|
54
43
|
}
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
if (reference.expectedSubtype === "shared_worker") {
|
|
58
|
-
if (
|
|
59
|
-
reference.ownerUrlInfo.context.isSupportedOnCurrentClients(
|
|
60
|
-
"shared_worker_type_module",
|
|
61
|
-
)
|
|
62
|
-
) {
|
|
44
|
+
if (reference.expectedSubtype !== subtype) {
|
|
63
45
|
return null;
|
|
64
46
|
}
|
|
65
47
|
return turnIntoJsClassicProxy(reference);
|
|
66
|
-
}
|
|
67
|
-
return null;
|
|
48
|
+
},
|
|
68
49
|
},
|
|
69
|
-
}
|
|
50
|
+
};
|
|
70
51
|
};
|
|
52
|
+
|
|
53
|
+
return [
|
|
54
|
+
createWorkerPlugin("worker"),
|
|
55
|
+
createWorkerPlugin("service_worker"),
|
|
56
|
+
createWorkerPlugin("shared_worker"),
|
|
57
|
+
];
|
|
71
58
|
};
|
|
@@ -3,7 +3,7 @@ import { applyBabelPlugins } from "@jsenv/ast";
|
|
|
3
3
|
|
|
4
4
|
const require = createRequire(import.meta.url);
|
|
5
5
|
|
|
6
|
-
export const jsenvPluginTopLevelAwait = () => {
|
|
6
|
+
export const jsenvPluginTopLevelAwait = ({ needJsModuleFallback }) => {
|
|
7
7
|
return {
|
|
8
8
|
name: "jsenv:top_level_await",
|
|
9
9
|
appliesDuring: "*",
|
|
@@ -11,8 +11,8 @@ export const jsenvPluginTopLevelAwait = () => {
|
|
|
11
11
|
if (context.isSupportedOnCurrentClients("top_level_await")) {
|
|
12
12
|
return false;
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
if (needJsModuleFallback(context)) {
|
|
15
|
+
// will be handled by systemjs, keep it untouched
|
|
16
16
|
return false;
|
|
17
17
|
}
|
|
18
18
|
return true;
|
|
@@ -11,44 +11,34 @@ import { jsenvPluginImportAssertions } from "./import_assertions/jsenv_plugin_im
|
|
|
11
11
|
import { jsenvPluginBabel } from "./babel/jsenv_plugin_babel.js";
|
|
12
12
|
import { jsenvPluginJsModuleFallback } from "./js_module_fallback/jsenv_plugin_js_module_fallback.js";
|
|
13
13
|
import { jsenvPluginAsJsModule } from "./as_js_module/jsenv_plugin_as_js_module.js";
|
|
14
|
-
import { jsenvPluginTopLevelAwait } from "./top_level_await/jsenv_plugin_top_level_await.js";
|
|
15
|
-
import { jsenvPluginImportMetaResolve } from "./import_meta_resolve/jsenv_plugin_import_meta_resolve.js";
|
|
16
14
|
import { jsenvPluginCssTranspilation } from "./css/jsenv_plugin_css_transpilation.js";
|
|
17
15
|
|
|
18
16
|
export const jsenvPluginTranspilation = ({
|
|
19
17
|
importAssertions = true,
|
|
20
18
|
css = true, // TODO
|
|
21
|
-
// build sets
|
|
19
|
+
// build sets jsModuleFallback: false during first step of the build
|
|
22
20
|
// and re-enable it in the second phase (when performing the bundling)
|
|
23
21
|
// so that bundling is applied on js modules THEN it is converted to js classic if needed
|
|
24
|
-
|
|
25
|
-
topLevelAwait = true,
|
|
26
|
-
importMetaResolve = true,
|
|
22
|
+
jsModuleFallback = true,
|
|
27
23
|
babelHelpersAsImport = true,
|
|
28
24
|
}) => {
|
|
29
25
|
if (importAssertions === true) {
|
|
30
26
|
importAssertions = {};
|
|
31
27
|
}
|
|
32
|
-
if (
|
|
33
|
-
|
|
28
|
+
if (jsModuleFallback === true) {
|
|
29
|
+
jsModuleFallback = {};
|
|
34
30
|
}
|
|
35
31
|
return [
|
|
36
|
-
...(importMetaResolve ? [jsenvPluginImportMetaResolve()] : []),
|
|
37
|
-
...(importAssertions
|
|
38
|
-
? [jsenvPluginImportAssertions(importAssertions)]
|
|
39
|
-
: []),
|
|
40
32
|
// babel also so that rollup can bundle babel helpers for instance
|
|
41
33
|
jsenvPluginBabel({
|
|
42
|
-
topLevelAwait,
|
|
43
34
|
babelHelpersAsImport,
|
|
44
35
|
}),
|
|
45
|
-
...(jsModuleFallbackOnJsClassic
|
|
46
|
-
? [jsenvPluginJsModuleFallback(jsModuleFallbackOnJsClassic)]
|
|
47
|
-
: []),
|
|
48
36
|
jsenvPluginAsJsModule(),
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
37
|
+
...(jsModuleFallback ? [jsenvPluginJsModuleFallback()] : []),
|
|
38
|
+
...(importAssertions
|
|
39
|
+
? [jsenvPluginImportAssertions(importAssertions)]
|
|
40
|
+
: []),
|
|
41
|
+
|
|
52
42
|
...(css ? [jsenvPluginCssTranspilation()] : []),
|
|
53
43
|
];
|
|
54
44
|
};
|