@jsenv/core 25.0.0-alpha.0 → 25.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser_runtime/asset-manifest.json +2 -2
- package/dist/browser_runtime/{browser_runtime_a8097085.js → browser_runtime_91c5a3b8.js} +137 -26
- package/dist/browser_runtime/browser_runtime_91c5a3b8.js.map +1089 -0
- package/dist/build_manifest.js +5 -5
- package/dist/compile_proxy/asset-manifest.json +2 -2
- package/dist/compile_proxy/{compile_proxy_e16d7de8.html → compile_proxy_7ad5faa6.html} +119 -26
- package/dist/compile_proxy/{compile_proxy_e3b0c442_9e168143.js.map → compile_proxy_e3b0c442_809f35f7.js.map} +6 -6
- package/dist/redirector/asset-manifest.json +2 -2
- package/dist/redirector/{redirector_e3b0c442_3a34a156.js.map → redirector_e3b0c442_e391410e.js.map} +6 -6
- package/dist/redirector/{redirector_2e0c8abe.html → redirector_eb92e8a7.html} +119 -26
- package/dist/toolbar/asset-manifest.json +11 -11
- package/dist/toolbar/{toolbar.main_a5ef2c60.js.map → toolbar.main2_6c1b3d82.js.map} +8 -8
- package/dist/toolbar/{toolbar_412abb83.html → toolbar_04ba410c.html} +127 -32
- package/dist/toolbar_injector/asset-manifest.json +2 -2
- package/dist/toolbar_injector/{toolbar_injector_4f9c19e5.js → toolbar_injector_4a48bc53.js} +2 -2
- package/dist/toolbar_injector/{toolbar_injector_4f9c19e5.js.map → toolbar_injector_4a48bc53.js.map} +2 -2
- package/package.json +5 -4
- package/readme.md +22 -89
- package/src/buildProject.js +28 -15
- package/src/dev_server.js +8 -2
- package/src/execute.js +7 -1
- package/src/executeTestPlan.js +6 -0
- package/src/internal/browser_feature_detection/browser_feature_detection.js +18 -25
- package/src/internal/browser_runtime/browser_runtime.js +2 -2
- package/src/internal/browser_runtime/createBrowserRuntime.js +1 -1
- package/src/internal/browser_runtime/displayErrorInDocument.js +2 -0
- package/src/internal/browser_runtime/displayErrorNotification.js +1 -1
- package/src/internal/building/buildUsingRollup.js +3 -8
- package/src/internal/building/ressource_builder.js +35 -42
- package/src/internal/building/rollup_plugin_jsenv.js +195 -186
- package/src/internal/building/url_versioning.js +36 -42
- package/src/internal/compiling/createCompiledFileService.js +28 -40
- package/src/internal/compiling/html_source_file_service.js +66 -51
- package/src/internal/compiling/js-compilation-service/babel_plugin_systemjs_prepend.js +23 -0
- package/src/internal/compiling/js-compilation-service/jsenvTransform.js +16 -12
- package/src/internal/compiling/js-compilation-service/transformJs.js +2 -0
- package/src/internal/compiling/jsenvCompilerForHtml.js +43 -44
- package/src/internal/compiling/jsenvCompilerForImportmap.js +15 -76
- package/src/internal/compiling/jsenvCompilerForJavaScript.js +9 -0
- package/src/internal/compiling/startCompileServer.js +29 -5
- package/src/internal/dev_server/toolbar/compilation/toolbar.compilation.js +9 -9
- package/src/internal/executing/executePlan.js +6 -0
- package/src/internal/generateGroupMap/{jsenvBabelPluginCompatMap.js → babel_plugins_compatibility.js} +0 -0
- package/src/internal/generateGroupMap/{featuresCompatMap.js → features_compatibility.js} +9 -1
- package/src/internal/generateGroupMap/generateGroupMap.js +6 -35
- package/src/internal/generateGroupMap/one_runtime_compat.js +9 -12
- package/src/internal/generateGroupMap/runtime_compat.js +10 -15
- package/src/internal/generateGroupMap/runtime_compat_composition.js +2 -2
- package/src/internal/generateGroupMap/shake_babel_plugin_map.js +21 -0
- package/src/internal/import-resolution/importmap_default.js +52 -0
- package/src/internal/node_feature_detection/node_feature_detection.js +25 -19
- package/src/internal/runtime/s.js +101 -6
- package/src/internal/unevalException.js +1 -1
- package/src/jsenvServiceWorkerFinalizer.js +3 -1
- package/dist/browser_runtime/browser_runtime_a8097085.js.map +0 -1067
- package/src/internal/generateGroupMap/jsenvPluginCompatMap.js +0 -1
- package/src/internal/import-resolution/importmap-default.js +0 -34
|
@@ -7,29 +7,40 @@ import {
|
|
|
7
7
|
|
|
8
8
|
export const createUrlVersioner = ({
|
|
9
9
|
entryPointUrls,
|
|
10
|
-
workerUrls,
|
|
11
|
-
classicWorkerUrls,
|
|
12
|
-
serviceWorkerUrls,
|
|
13
|
-
classicServiceWorkerUrls,
|
|
14
10
|
asOriginalUrl,
|
|
15
11
|
lineBreakNormalization,
|
|
16
12
|
}) => {
|
|
17
|
-
const
|
|
13
|
+
const names = []
|
|
14
|
+
const getFreeName = (name) => {
|
|
15
|
+
let nameCandidate = name
|
|
16
|
+
let integer = 1
|
|
17
|
+
// eslint-disable-next-line no-constant-condition
|
|
18
|
+
while (true) {
|
|
19
|
+
if (!names.includes(nameCandidate)) {
|
|
20
|
+
names.push(nameCandidate)
|
|
21
|
+
return nameCandidate
|
|
22
|
+
}
|
|
23
|
+
integer++
|
|
24
|
+
nameCandidate = `${name}${integer}`
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const computeBuildRelativeUrl = (ressource, precomputation) => {
|
|
18
29
|
const pattern = getFilenamePattern({
|
|
19
30
|
ressource,
|
|
20
31
|
entryPointUrls,
|
|
21
|
-
workerUrls,
|
|
22
|
-
classicWorkerUrls,
|
|
23
|
-
serviceWorkerUrls,
|
|
24
|
-
classicServiceWorkerUrls,
|
|
25
32
|
asOriginalUrl,
|
|
26
33
|
precomputeBuildRelativeUrl,
|
|
27
34
|
})
|
|
35
|
+
|
|
28
36
|
const buildRelativeUrl = generateBuildRelativeUrl(
|
|
29
37
|
ressource.url,
|
|
30
38
|
ressource.bufferAfterBuild,
|
|
31
39
|
{
|
|
32
40
|
pattern,
|
|
41
|
+
getName: precomputation
|
|
42
|
+
? () => urlToBasename(ressource.url)
|
|
43
|
+
: () => getFreeName(urlToBasename(ressource.url)),
|
|
33
44
|
contentType: ressource.contentType,
|
|
34
45
|
lineBreakNormalization,
|
|
35
46
|
},
|
|
@@ -46,7 +57,7 @@ export const createUrlVersioner = ({
|
|
|
46
57
|
}
|
|
47
58
|
|
|
48
59
|
ressource.bufferAfterBuild = bufferAfterBuild
|
|
49
|
-
const precomputedBuildRelativeUrl = computeBuildRelativeUrl(ressource)
|
|
60
|
+
const precomputedBuildRelativeUrl = computeBuildRelativeUrl(ressource, true)
|
|
50
61
|
ressource.bufferAfterBuild = undefined
|
|
51
62
|
ressource.precomputedBuildRelativeUrl = precomputedBuildRelativeUrl
|
|
52
63
|
return precomputedBuildRelativeUrl
|
|
@@ -61,10 +72,6 @@ export const createUrlVersioner = ({
|
|
|
61
72
|
const getFilenamePattern = ({
|
|
62
73
|
ressource,
|
|
63
74
|
entryPointUrls,
|
|
64
|
-
workerUrls,
|
|
65
|
-
classicWorkerUrls,
|
|
66
|
-
serviceWorkerUrls,
|
|
67
|
-
classicServiceWorkerUrls,
|
|
68
75
|
asOriginalUrl,
|
|
69
76
|
precomputeBuildRelativeUrl,
|
|
70
77
|
}) => {
|
|
@@ -74,30 +81,6 @@ const getFilenamePattern = ({
|
|
|
74
81
|
return entryPointBuildRelativeUrl
|
|
75
82
|
}
|
|
76
83
|
|
|
77
|
-
// service worker:
|
|
78
|
-
// - MUST be at the root (same level than the HTML file)
|
|
79
|
-
// otherwise it might be registered for the scope "/assets/" instead of "/"
|
|
80
|
-
// - MUST not be versioned
|
|
81
|
-
if (ressource.isServiceWorker) {
|
|
82
|
-
const originalUrl = asOriginalUrl(ressource.url)
|
|
83
|
-
const serviceWorkerBuildRelativeUrl = ressource.isJsModule
|
|
84
|
-
? serviceWorkerUrls[originalUrl]
|
|
85
|
-
: classicServiceWorkerUrls[originalUrl]
|
|
86
|
-
// we could/should log a warning when service worker is not at the root
|
|
87
|
-
// we should also disable versioning for this file
|
|
88
|
-
// of the build directory
|
|
89
|
-
return serviceWorkerBuildRelativeUrl
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// it's a module worker
|
|
93
|
-
if (ressource.isWorker) {
|
|
94
|
-
const originalUrl = asOriginalUrl(ressource.url)
|
|
95
|
-
const workerBuildRelativeUrl = ressource.isJsModule
|
|
96
|
-
? workerUrls[originalUrl]
|
|
97
|
-
: classicWorkerUrls[originalUrl]
|
|
98
|
-
return workerBuildRelativeUrl
|
|
99
|
-
}
|
|
100
|
-
|
|
101
84
|
// inline ressource inherits location
|
|
102
85
|
if (ressource.isInline) {
|
|
103
86
|
// inherit parent directory location because it's an inline file
|
|
@@ -119,8 +102,19 @@ const getFilenamePattern = ({
|
|
|
119
102
|
return `${name}_[hash][extname]`
|
|
120
103
|
}
|
|
121
104
|
|
|
105
|
+
// service worker:
|
|
106
|
+
// - MUST be at the root (same level than the HTML file)
|
|
107
|
+
// otherwise it might be registered for the scope "/assets/" instead of "/"
|
|
108
|
+
// - MUST not be versioned
|
|
109
|
+
if (ressource.isServiceWorker) {
|
|
110
|
+
return "[name][extname]"
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (ressource.isWorker) {
|
|
114
|
+
return "[name]_[hash][extname]"
|
|
115
|
+
}
|
|
116
|
+
|
|
122
117
|
if (ressource.isJsModule) {
|
|
123
|
-
// it's a js module
|
|
124
118
|
return "[name]_[hash][extname]"
|
|
125
119
|
}
|
|
126
120
|
|
|
@@ -133,8 +127,8 @@ const generateBuildRelativeUrl = (
|
|
|
133
127
|
fileUrl,
|
|
134
128
|
fileContent,
|
|
135
129
|
{
|
|
136
|
-
|
|
137
|
-
pattern
|
|
130
|
+
getName,
|
|
131
|
+
pattern,
|
|
138
132
|
contentType = "application/octet-stream",
|
|
139
133
|
lineBreakNormalization = false,
|
|
140
134
|
} = {},
|
|
@@ -143,7 +137,7 @@ const generateBuildRelativeUrl = (
|
|
|
143
137
|
if (pattern.startsWith("./")) pattern = pattern.slice(2)
|
|
144
138
|
const buildRelativeUrl = renderFileNamePattern(pattern, {
|
|
145
139
|
dirname: () => urlToParentUrl(fileUrl),
|
|
146
|
-
name:
|
|
140
|
+
name: getName,
|
|
147
141
|
hash: () =>
|
|
148
142
|
generateContentHash(fileContent, {
|
|
149
143
|
contentType,
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
urlToMeta,
|
|
7
7
|
} from "@jsenv/filesystem"
|
|
8
8
|
|
|
9
|
-
import { featuresCompatMap } from "@jsenv/core/src/internal/generateGroupMap/featuresCompatMap.js"
|
|
10
9
|
import { createRuntimeCompat } from "@jsenv/core/src/internal/generateGroupMap/runtime_compat.js"
|
|
11
|
-
|
|
10
|
+
import { shakeBabelPluginMap } from "@jsenv/core/src/internal/generateGroupMap/shake_babel_plugin_map.js"
|
|
12
11
|
import { serverUrlToCompileInfo } from "@jsenv/core/src/internal/url_conversion.js"
|
|
12
|
+
|
|
13
13
|
import { setUrlExtension } from "../url_utils.js"
|
|
14
14
|
import {
|
|
15
15
|
COMPILE_ID_BUILD_GLOBAL,
|
|
@@ -45,8 +45,12 @@ export const createCompiledFileService = ({
|
|
|
45
45
|
moduleOutFormat,
|
|
46
46
|
importMetaFormat,
|
|
47
47
|
topLevelAwait,
|
|
48
|
+
prependSystemJs,
|
|
48
49
|
groupMap,
|
|
49
50
|
customCompilers,
|
|
51
|
+
workerUrls,
|
|
52
|
+
serviceWorkerUrls,
|
|
53
|
+
importMapInWebWorkers,
|
|
50
54
|
|
|
51
55
|
jsenvEventSourceClientInjection,
|
|
52
56
|
jsenvToolbarInjection,
|
|
@@ -60,6 +64,8 @@ export const createCompiledFileService = ({
|
|
|
60
64
|
Object.keys(groupMap).forEach((groupName) => {
|
|
61
65
|
compileIdModuleFormats[groupName] = canAvoidSystemJs({
|
|
62
66
|
runtimeSupport: groupMap[groupName].minRuntimeVersions,
|
|
67
|
+
workerUrls,
|
|
68
|
+
importMapInWebWorkers,
|
|
63
69
|
})
|
|
64
70
|
? "esmodule"
|
|
65
71
|
: "systemjs"
|
|
@@ -183,18 +189,20 @@ export const createCompiledFileService = ({
|
|
|
183
189
|
outDirectoryRelativeUrl,
|
|
184
190
|
compileId,
|
|
185
191
|
request,
|
|
186
|
-
|
|
187
|
-
runtimeSupport,
|
|
188
|
-
babelPluginMap: babelPluginMapFromCompileId(compileId, {
|
|
192
|
+
babelPluginMap: shakeBabelPluginMap({
|
|
189
193
|
babelPluginMap,
|
|
190
|
-
groupMap,
|
|
194
|
+
missingFeatureNames: groupMap[compileId].missingFeatureNames,
|
|
191
195
|
}),
|
|
196
|
+
runtimeSupport,
|
|
197
|
+
workerUrls,
|
|
198
|
+
serviceWorkerUrls,
|
|
192
199
|
moduleOutFormat:
|
|
193
200
|
moduleOutFormat === undefined
|
|
194
201
|
? compileIdModuleFormats[compileId]
|
|
195
202
|
: moduleOutFormat,
|
|
196
203
|
importMetaFormat,
|
|
197
204
|
topLevelAwait,
|
|
205
|
+
prependSystemJs,
|
|
198
206
|
|
|
199
207
|
sourcemapMethod,
|
|
200
208
|
sourcemapExcludeSources,
|
|
@@ -210,18 +218,23 @@ export const createCompiledFileService = ({
|
|
|
210
218
|
}
|
|
211
219
|
}
|
|
212
220
|
|
|
213
|
-
const canAvoidSystemJs = ({
|
|
221
|
+
const canAvoidSystemJs = ({
|
|
222
|
+
runtimeSupport,
|
|
223
|
+
workerUrls,
|
|
224
|
+
importMapInWebWorkers,
|
|
225
|
+
}) => {
|
|
214
226
|
const runtimeCompatMap = createRuntimeCompat({
|
|
227
|
+
featureNames: [
|
|
228
|
+
"module",
|
|
229
|
+
"importmap",
|
|
230
|
+
"import_assertion_type_json",
|
|
231
|
+
"import_assertion_type_css",
|
|
232
|
+
...(workerUrls.length > 0 ? ["worker_type_module"] : []),
|
|
233
|
+
...(importMapInWebWorkers ? ["worker_importmap"] : []),
|
|
234
|
+
],
|
|
215
235
|
runtimeSupport,
|
|
216
|
-
pluginMap: {
|
|
217
|
-
module: true,
|
|
218
|
-
importmap: true,
|
|
219
|
-
import_assertion_type_json: true,
|
|
220
|
-
import_assertion_type_css: true,
|
|
221
|
-
},
|
|
222
|
-
pluginCompatMap: featuresCompatMap,
|
|
223
236
|
})
|
|
224
|
-
return runtimeCompatMap.
|
|
237
|
+
return runtimeCompatMap.missingFeatureNames.length === 0
|
|
225
238
|
}
|
|
226
239
|
|
|
227
240
|
const getCompiler = ({ originalFileUrl, compileMeta }) => {
|
|
@@ -295,31 +308,6 @@ const contentTypeExtensions = {
|
|
|
295
308
|
// "text/css": ".css",
|
|
296
309
|
}
|
|
297
310
|
|
|
298
|
-
const babelPluginMapFromCompileId = (
|
|
299
|
-
compileId,
|
|
300
|
-
{ babelPluginMap, groupMap },
|
|
301
|
-
) => {
|
|
302
|
-
const babelPluginMapForGroup = {}
|
|
303
|
-
|
|
304
|
-
groupMap[compileId].pluginRequiredNameArray.forEach((requiredPluginName) => {
|
|
305
|
-
const babelPlugin = babelPluginMap[requiredPluginName]
|
|
306
|
-
if (babelPlugin) {
|
|
307
|
-
babelPluginMapForGroup[requiredPluginName] = babelPlugin
|
|
308
|
-
}
|
|
309
|
-
})
|
|
310
|
-
|
|
311
|
-
Object.keys(babelPluginMap).forEach((key) => {
|
|
312
|
-
if (key.startsWith("syntax-")) {
|
|
313
|
-
babelPluginMapForGroup[key] = babelPluginMap[key]
|
|
314
|
-
}
|
|
315
|
-
if (key === "transform-replace-expressions") {
|
|
316
|
-
babelPluginMapForGroup[key] = babelPluginMap[key]
|
|
317
|
-
}
|
|
318
|
-
})
|
|
319
|
-
|
|
320
|
-
return babelPluginMapForGroup
|
|
321
|
-
}
|
|
322
|
-
|
|
323
311
|
const ressourceToPathname = (ressource) => {
|
|
324
312
|
const searchSeparatorIndex = ressource.indexOf("?")
|
|
325
313
|
const pathname =
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
urlToFilename,
|
|
19
19
|
urlIsInsideOf,
|
|
20
20
|
} from "@jsenv/filesystem"
|
|
21
|
-
import { moveImportMap } from "@jsenv/importmap"
|
|
21
|
+
import { composeTwoImportMaps, moveImportMap } from "@jsenv/importmap"
|
|
22
22
|
import { createDetailedMessage } from "@jsenv/logger"
|
|
23
23
|
|
|
24
24
|
import {
|
|
@@ -28,6 +28,8 @@ import {
|
|
|
28
28
|
} from "@jsenv/core/dist/build_manifest.js"
|
|
29
29
|
import { fetchUrl } from "@jsenv/core/src/internal/fetchUrl.js"
|
|
30
30
|
import { stringifyDataUrl } from "@jsenv/core/src/internal/dataUrl.utils.js"
|
|
31
|
+
import { getDefaultImportmap } from "@jsenv/core/src/internal/import-resolution/importmap_default.js"
|
|
32
|
+
|
|
31
33
|
import {
|
|
32
34
|
parseHtmlString,
|
|
33
35
|
parseHtmlAstRessources,
|
|
@@ -155,14 +157,13 @@ const transformHTMLSourceFile = async ({
|
|
|
155
157
|
fileUrl = urlWithoutSearch(fileUrl)
|
|
156
158
|
|
|
157
159
|
const htmlAst = parseHtmlString(fileContent)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
160
|
+
await visitImportmapScripts({
|
|
161
|
+
logger,
|
|
162
|
+
htmlAst,
|
|
163
|
+
inlineImportMapIntoHTML,
|
|
164
|
+
htmlFileUrl: fileUrl,
|
|
165
|
+
projectDirectoryUrl,
|
|
166
|
+
})
|
|
166
167
|
|
|
167
168
|
const browserRuntimeBuildUrlRelativeToProject = urlToRelativeUrl(
|
|
168
169
|
BROWSER_RUNTIME_BUILD_URL,
|
|
@@ -277,59 +278,73 @@ const transformHTMLSourceFile = async ({
|
|
|
277
278
|
return stringifyHtmlAst(htmlAst)
|
|
278
279
|
}
|
|
279
280
|
|
|
280
|
-
const
|
|
281
|
+
const visitImportmapScripts = async ({
|
|
282
|
+
logger,
|
|
283
|
+
inlineImportMapIntoHTML,
|
|
284
|
+
htmlAst,
|
|
285
|
+
htmlFileUrl,
|
|
286
|
+
projectDirectoryUrl,
|
|
287
|
+
}) => {
|
|
281
288
|
const { scripts } = parseHtmlAstRessources(htmlAst)
|
|
282
|
-
const
|
|
289
|
+
const importmapScripts = scripts.filter((script) => {
|
|
283
290
|
const typeAttribute = getHtmlNodeAttributeByName(script, "type")
|
|
284
|
-
|
|
285
|
-
if (typeAttribute && typeAttribute.value === "importmap" && srcAttribute) {
|
|
291
|
+
if (typeAttribute && typeAttribute.value === "importmap") {
|
|
286
292
|
return true
|
|
287
293
|
}
|
|
288
294
|
return false
|
|
289
295
|
})
|
|
290
296
|
|
|
291
297
|
await Promise.all(
|
|
292
|
-
|
|
293
|
-
const srcAttribute = getHtmlNodeAttributeByName(
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
298
|
+
importmapScripts.map(async (importmapScript) => {
|
|
299
|
+
const srcAttribute = getHtmlNodeAttributeByName(importmapScript, "src")
|
|
300
|
+
if (srcAttribute && inlineImportMapIntoHTML) {
|
|
301
|
+
const importMapUrl = resolveUrl(srcAttribute.value, htmlFileUrl)
|
|
302
|
+
const importMapResponse = await fetchUrl(importMapUrl)
|
|
303
|
+
if (importMapResponse.status !== 200) {
|
|
304
|
+
logger.warn(
|
|
305
|
+
createDetailedMessage(
|
|
306
|
+
importMapResponse.status === 404
|
|
307
|
+
? `Cannot inline importmap script because file cannot be found.`
|
|
308
|
+
: `Cannot inline importmap script due to unexpected response status (${importMapResponse.status}).`,
|
|
309
|
+
{
|
|
310
|
+
"importmap script src": srcAttribute.value,
|
|
311
|
+
"importmap url": importMapUrl,
|
|
312
|
+
"html url": htmlFileUrl,
|
|
313
|
+
},
|
|
314
|
+
),
|
|
315
|
+
)
|
|
316
|
+
return
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const importMapContent = await importMapResponse.json()
|
|
320
|
+
const importMapInlined = moveImportMap(
|
|
321
|
+
importMapContent,
|
|
322
|
+
importMapUrl,
|
|
323
|
+
htmlFileUrl,
|
|
311
324
|
)
|
|
312
|
-
return
|
|
313
|
-
}
|
|
314
325
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
326
|
+
replaceHtmlNode(
|
|
327
|
+
importmapScript,
|
|
328
|
+
`<script type="importmap">${JSON.stringify(
|
|
329
|
+
importMapInlined,
|
|
330
|
+
null,
|
|
331
|
+
" ",
|
|
332
|
+
)}</script>`,
|
|
333
|
+
{
|
|
334
|
+
attributesToIgnore: ["src"],
|
|
335
|
+
},
|
|
336
|
+
)
|
|
337
|
+
}
|
|
321
338
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
)
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
},
|
|
332
|
-
)
|
|
339
|
+
const textNode = getHtmlNodeTextNode(importmapScript)
|
|
340
|
+
if (!srcAttribute && textNode) {
|
|
341
|
+
const jsenvImportmap = getDefaultImportmap(htmlFileUrl, {
|
|
342
|
+
projectDirectoryUrl,
|
|
343
|
+
})
|
|
344
|
+
const htmlImportmap = JSON.parse(textNode.value)
|
|
345
|
+
const importmap = composeTwoImportMaps(jsenvImportmap, htmlImportmap)
|
|
346
|
+
textNode.value = JSON.stringify(importmap, null, " ")
|
|
347
|
+
}
|
|
333
348
|
}),
|
|
334
349
|
)
|
|
335
350
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs"
|
|
2
|
+
|
|
3
|
+
import { jsenvCoreDirectoryUrl } from "@jsenv/core/src/internal/jsenvCoreDirectoryUrl.js"
|
|
4
|
+
|
|
5
|
+
export const babelPluginSystemJsPrepend = (api) => {
|
|
6
|
+
api.assertVersion(7)
|
|
7
|
+
const systemJsUrl = new URL(
|
|
8
|
+
"src/internal/runtime/s.js",
|
|
9
|
+
jsenvCoreDirectoryUrl,
|
|
10
|
+
)
|
|
11
|
+
return {
|
|
12
|
+
name: "systemjs-prepend",
|
|
13
|
+
visitor: {
|
|
14
|
+
Program: {
|
|
15
|
+
exit(path) {
|
|
16
|
+
const code = String(readFileSync(systemJsUrl))
|
|
17
|
+
const ast = api.template.ast`${code}`
|
|
18
|
+
path.node.body.unshift(ast)
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -11,6 +11,7 @@ import { babelPluginImportMetadata } from "@jsenv/core/src/internal/compiling/ba
|
|
|
11
11
|
import { ansiToHTML } from "./ansiToHTML.js"
|
|
12
12
|
import { babelPluginRegeneratorRuntimeAsJsenvImport } from "./babel_plugin_regenerator_runtime_as_jsenv_import.js"
|
|
13
13
|
import { babelPluginBabelHelpersAsJsenvImports } from "./babel_plugin_babel_helpers_as_jsenv_imports.js"
|
|
14
|
+
import { babelPluginSystemJsPrepend } from "./babel_plugin_systemjs_prepend.js"
|
|
14
15
|
import { filePathToBabelHelperName } from "./babelHelper.js"
|
|
15
16
|
|
|
16
17
|
export const jsenvTransform = async ({
|
|
@@ -26,6 +27,7 @@ export const jsenvTransform = async ({
|
|
|
26
27
|
topLevelAwait,
|
|
27
28
|
|
|
28
29
|
babelHelpersInjectionAsImport,
|
|
30
|
+
prependSystemJs,
|
|
29
31
|
transformGenerator,
|
|
30
32
|
regeneratorRuntimeImportPath,
|
|
31
33
|
sourcemapEnabled,
|
|
@@ -77,7 +79,6 @@ export const jsenvTransform = async ({
|
|
|
77
79
|
],
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
|
-
|
|
81
82
|
babelPluginMap = {
|
|
82
83
|
...getMinimalBabelPluginMap(),
|
|
83
84
|
"transform-import-meta": [
|
|
@@ -147,6 +148,19 @@ export const jsenvTransform = async ({
|
|
|
147
148
|
: {}),
|
|
148
149
|
"import-metadata": [babelPluginImportMetadata],
|
|
149
150
|
}
|
|
151
|
+
if (moduleOutFormat === "systemjs") {
|
|
152
|
+
babelPluginMap = {
|
|
153
|
+
...babelPluginMap,
|
|
154
|
+
"proposal-dynamic-import": [proposalDynamicImport],
|
|
155
|
+
"transform-modules-systemjs": [transformModulesSystemJs],
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (prependSystemJs) {
|
|
159
|
+
babelPluginMap = {
|
|
160
|
+
...babelPluginMap,
|
|
161
|
+
"systemjs-prepend": [babelPluginSystemJsPrepend],
|
|
162
|
+
}
|
|
163
|
+
}
|
|
150
164
|
|
|
151
165
|
const asyncToPromise = babelPluginMap["transform-async-to-promises"]
|
|
152
166
|
if (topLevelAwait && asyncToPromise) {
|
|
@@ -158,17 +172,7 @@ export const jsenvTransform = async ({
|
|
|
158
172
|
code,
|
|
159
173
|
options: {
|
|
160
174
|
...options,
|
|
161
|
-
plugins: babelPluginsFromBabelPluginMap(
|
|
162
|
-
...babelPluginMap,
|
|
163
|
-
...(moduleOutFormat === "systemjs"
|
|
164
|
-
? {
|
|
165
|
-
"proposal-dynamic-import": [proposalDynamicImport],
|
|
166
|
-
...(moduleOutFormat === "systemjs"
|
|
167
|
-
? { "transform-modules-systemjs": [transformModulesSystemJs] }
|
|
168
|
-
: {}),
|
|
169
|
-
}
|
|
170
|
-
: {}),
|
|
171
|
-
}),
|
|
175
|
+
plugins: babelPluginsFromBabelPluginMap(babelPluginMap),
|
|
172
176
|
},
|
|
173
177
|
})
|
|
174
178
|
code = babelTransformReturnValue.code
|
|
@@ -12,6 +12,7 @@ export const transformJs = async ({
|
|
|
12
12
|
moduleOutFormat = "esmodule",
|
|
13
13
|
importMetaFormat = moduleOutFormat,
|
|
14
14
|
babelHelpersInjectionAsImport = moduleOutFormat === "esmodule",
|
|
15
|
+
prependSystemJs,
|
|
15
16
|
topLevelAwait,
|
|
16
17
|
transformGenerator = true,
|
|
17
18
|
sourcemapEnabled = true,
|
|
@@ -51,6 +52,7 @@ export const transformJs = async ({
|
|
|
51
52
|
importMetaFormat,
|
|
52
53
|
|
|
53
54
|
babelHelpersInjectionAsImport,
|
|
55
|
+
prependSystemJs,
|
|
54
56
|
topLevelAwait,
|
|
55
57
|
transformGenerator,
|
|
56
58
|
sourcemapEnabled,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
TOOLBAR_INJECTOR_BUILD_URL,
|
|
9
9
|
} from "@jsenv/core/dist/build_manifest.js"
|
|
10
10
|
import { fetchUrl } from "@jsenv/core/src/internal/fetchUrl.js"
|
|
11
|
-
import {
|
|
11
|
+
import { getDefaultImportmap } from "@jsenv/core/src/internal/import-resolution/importmap_default.js"
|
|
12
12
|
|
|
13
13
|
import {
|
|
14
14
|
setJavaScriptSourceMappingUrl,
|
|
@@ -120,83 +120,82 @@ export const compileHtml = async ({
|
|
|
120
120
|
importmapInfo = {
|
|
121
121
|
script,
|
|
122
122
|
url: resolveUrl(src, url),
|
|
123
|
-
|
|
123
|
+
load: async () => {
|
|
124
124
|
const importMapResponse = await fetchUrl(importmapInfo.url)
|
|
125
|
-
if (importMapResponse.status
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
"importmap url": importmapInfo.url,
|
|
133
|
-
"html url": url,
|
|
134
|
-
},
|
|
135
|
-
),
|
|
125
|
+
if (importMapResponse.status === 200) {
|
|
126
|
+
const importmapAsText = await importMapResponse.text()
|
|
127
|
+
let htmlImportmap = JSON.parse(importmapAsText)
|
|
128
|
+
htmlImportmap = moveImportMap(
|
|
129
|
+
htmlImportmap,
|
|
130
|
+
importmapInfo.url,
|
|
131
|
+
url,
|
|
136
132
|
)
|
|
137
|
-
|
|
133
|
+
sources.push(importmapInfo.url)
|
|
134
|
+
sourcesContent.push(importmapAsText)
|
|
135
|
+
return htmlImportmap
|
|
138
136
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
importMapMoved,
|
|
150
|
-
null,
|
|
151
|
-
" ",
|
|
137
|
+
logger.warn(
|
|
138
|
+
createDetailedMessage(
|
|
139
|
+
importMapResponse.status === 404
|
|
140
|
+
? `importmap script file cannot be found.`
|
|
141
|
+
: `importmap script file unexpected response status (${importMapResponse.status}).`,
|
|
142
|
+
{
|
|
143
|
+
"importmap url": importmapInfo.url,
|
|
144
|
+
"html url": url,
|
|
145
|
+
},
|
|
146
|
+
),
|
|
152
147
|
)
|
|
153
|
-
return
|
|
148
|
+
return {}
|
|
154
149
|
},
|
|
155
150
|
}
|
|
156
151
|
} else {
|
|
157
152
|
importmapInfo = {
|
|
158
153
|
script,
|
|
159
154
|
url: compiledUrl,
|
|
160
|
-
|
|
155
|
+
load: () => {
|
|
156
|
+
const jsenvImportmap = getDefaultImportmap(compiledUrl, {
|
|
157
|
+
projectDirectoryUrl,
|
|
158
|
+
compileDirectoryUrl: `${projectDirectoryUrl}${compileId}/${outDirectoryRelativeUrl}`,
|
|
159
|
+
})
|
|
160
|
+
const htmlImportmap = JSON.parse(
|
|
161
|
+
getHtmlNodeTextNode(script).value,
|
|
162
|
+
)
|
|
163
|
+
const importmap = composeTwoImportMaps(
|
|
164
|
+
jsenvImportmap,
|
|
165
|
+
htmlImportmap,
|
|
166
|
+
)
|
|
167
|
+
return importmap
|
|
168
|
+
},
|
|
161
169
|
}
|
|
162
170
|
}
|
|
163
171
|
}
|
|
164
172
|
}
|
|
165
173
|
})
|
|
166
174
|
if (importmapInfo) {
|
|
167
|
-
const
|
|
168
|
-
const
|
|
169
|
-
importMapFileUrl: compiledUrl,
|
|
170
|
-
projectDirectoryUrl,
|
|
171
|
-
compileDirectoryRelativeUrl: `${outDirectoryRelativeUrl}${compileId}/`,
|
|
172
|
-
})
|
|
173
|
-
const mappings = composeTwoImportMaps(importMapFromJsenv, htmlImportMap)
|
|
174
|
-
const importmapAsText = JSON.stringify(mappings, null, " ")
|
|
175
|
+
const importmap = await importmapInfo.load()
|
|
176
|
+
const importmapAsText = JSON.stringify(importmap, null, " ")
|
|
175
177
|
replaceHtmlNode(
|
|
176
178
|
importmapInfo.script,
|
|
177
179
|
`<script type="${
|
|
178
|
-
moduleOutFormat === "systemjs" ? "
|
|
180
|
+
moduleOutFormat === "systemjs" ? "systemjs-importmap" : "importmap"
|
|
179
181
|
}">${importmapAsText}</script>`,
|
|
180
182
|
{
|
|
181
183
|
attributesToIgnore: ["src"],
|
|
182
184
|
},
|
|
183
185
|
)
|
|
184
186
|
importmapInfo.inlinedFrom = importmapInfo.url
|
|
185
|
-
importmapInfo.url = compiledUrl
|
|
186
187
|
importmapInfo.text = importmapAsText
|
|
187
188
|
} else {
|
|
188
|
-
|
|
189
|
-
const defaultImportMap = getDefaultImportMap({
|
|
190
|
-
importMapFileUrl: compiledUrl,
|
|
189
|
+
const defaultImportMap = getDefaultImportmap(compiledUrl, {
|
|
191
190
|
projectDirectoryUrl,
|
|
192
|
-
|
|
191
|
+
compileDirectoryUrl: `${projectDirectoryUrl}${outDirectoryRelativeUrl}${compileId}/`,
|
|
193
192
|
})
|
|
194
193
|
const importmapAsText = JSON.stringify(defaultImportMap, null, " ")
|
|
195
194
|
manipulateHtmlAst(htmlAst, {
|
|
196
195
|
scriptInjections: [
|
|
197
196
|
{
|
|
198
197
|
type:
|
|
199
|
-
moduleOutFormat === "systemjs" ? "
|
|
198
|
+
moduleOutFormat === "systemjs" ? "systemjs-importmap" : "importmap",
|
|
200
199
|
// in case there is no importmap, force the presence
|
|
201
200
|
// so that '@jsenv/core/' are still remapped
|
|
202
201
|
text: importmapAsText,
|