@jsenv/core 29.1.6 → 29.1.8
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/js/s.js.map +12 -1
- package/dist/js/supervisor.js +1 -1
- package/dist/main.js +170 -78
- package/package.json +9 -9
- package/src/build/build.js +39 -19
- package/src/build/start_build_server.js +4 -0
- package/src/dev/file_service.js +31 -22
- package/src/kitchen/kitchen.js +14 -4
- package/src/kitchen/url_graph/url_info_transformations.js +3 -3
- package/src/plugins/bundling/js_module/bundle_js_modules.js +15 -4
- package/src/plugins/supervisor/client/supervisor.js +4 -1
- package/src/plugins/transpilation/as_js_classic/convert_js_module_to_js_classic.js +22 -3
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_conversion.js +45 -18
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +18 -2
package/src/build/build.js
CHANGED
|
@@ -242,8 +242,8 @@ build ${entryPointKeys.length} entry points`)
|
|
|
242
242
|
const buildUrlsGenerator = createBuilUrlsGenerator({
|
|
243
243
|
buildDirectoryUrl,
|
|
244
244
|
})
|
|
245
|
-
const
|
|
246
|
-
|
|
245
|
+
const buildDirectoryRedirections = new Map()
|
|
246
|
+
|
|
247
247
|
const associateBuildUrlAndRawUrl = (buildUrl, rawUrl, reason) => {
|
|
248
248
|
if (urlIsInsideOf(rawUrl, buildDirectoryUrl)) {
|
|
249
249
|
throw new Error(`raw url must be inside rawGraph, got ${rawUrl}`)
|
|
@@ -252,7 +252,7 @@ build ${entryPointKeys.length} entry points`)
|
|
|
252
252
|
${ANSI.color(rawUrl, ANSI.GREY)} ->
|
|
253
253
|
${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
254
254
|
`)
|
|
255
|
-
|
|
255
|
+
buildDirectoryRedirections.set(buildUrl, rawUrl)
|
|
256
256
|
}
|
|
257
257
|
const buildUrls = new Map()
|
|
258
258
|
const bundleUrlInfos = {}
|
|
@@ -284,7 +284,9 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
284
284
|
resolveUrl: (reference) => {
|
|
285
285
|
const getUrl = () => {
|
|
286
286
|
if (reference.type === "filesystem") {
|
|
287
|
-
const parentRawUrl =
|
|
287
|
+
const parentRawUrl = buildDirectoryRedirections.get(
|
|
288
|
+
reference.parentUrl,
|
|
289
|
+
)
|
|
288
290
|
const baseUrl = ensurePathnameTrailingSlash(parentRawUrl)
|
|
289
291
|
return new URL(reference.specifier, baseUrl).href
|
|
290
292
|
}
|
|
@@ -314,7 +316,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
314
316
|
return reference.original ? reference.original.url : null
|
|
315
317
|
}
|
|
316
318
|
// already a build url
|
|
317
|
-
const rawUrl =
|
|
319
|
+
const rawUrl = buildDirectoryRedirections.get(reference.url)
|
|
318
320
|
if (rawUrl) {
|
|
319
321
|
return reference.url
|
|
320
322
|
}
|
|
@@ -493,14 +495,14 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
493
495
|
// logger.debug(`fetching from bundle ${url}`)
|
|
494
496
|
return bundleUrlInfo
|
|
495
497
|
}
|
|
496
|
-
const rawUrl =
|
|
498
|
+
const rawUrl = buildDirectoryRedirections.get(url) || url
|
|
497
499
|
const rawUrlInfo = rawGraph.getUrlInfo(rawUrl)
|
|
498
500
|
if (!rawUrlInfo) {
|
|
499
501
|
throw new Error(
|
|
500
502
|
createDetailedMessage(`Cannot find url`, {
|
|
501
503
|
url,
|
|
502
|
-
"raw urls":
|
|
503
|
-
"build urls":
|
|
504
|
+
"raw urls": Array.from(buildDirectoryRedirections.values()),
|
|
505
|
+
"build urls": Array.from(buildDirectoryRedirections.keys()),
|
|
504
506
|
}),
|
|
505
507
|
)
|
|
506
508
|
}
|
|
@@ -526,7 +528,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
526
528
|
if (reference.injected) {
|
|
527
529
|
const [ref, rawUrlInfo] = rawGraphKitchen.injectReference({
|
|
528
530
|
...reference,
|
|
529
|
-
parentUrl:
|
|
531
|
+
parentUrl: buildDirectoryRedirections.get(reference.parentUrl),
|
|
530
532
|
})
|
|
531
533
|
await rawGraphKitchen.cook(rawUrlInfo, { reference: ref })
|
|
532
534
|
return rawUrlInfo
|
|
@@ -562,7 +564,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
562
564
|
],
|
|
563
565
|
sourcemaps,
|
|
564
566
|
sourcemapsSourcesContent,
|
|
565
|
-
|
|
567
|
+
sourcemapsSourcesRelative: !versioning,
|
|
566
568
|
writeGeneratedFiles,
|
|
567
569
|
outDirectoryUrl: new URL(".jsenv/postbuild/", rootDirectoryUrl),
|
|
568
570
|
})
|
|
@@ -740,9 +742,9 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
740
742
|
}
|
|
741
743
|
if (bundlerGeneratedUrlInfo.sourceUrls) {
|
|
742
744
|
bundlerGeneratedUrlInfo.sourceUrls.forEach((sourceUrl) => {
|
|
743
|
-
const
|
|
744
|
-
if (
|
|
745
|
-
|
|
745
|
+
const sourceRawUrlInfo = rawGraph.getUrlInfo(sourceUrl)
|
|
746
|
+
if (sourceRawUrlInfo) {
|
|
747
|
+
sourceRawUrlInfo.data.bundled = true
|
|
746
748
|
}
|
|
747
749
|
})
|
|
748
750
|
}
|
|
@@ -751,7 +753,23 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
751
753
|
})
|
|
752
754
|
bundleRedirections.set(url, buildUrl)
|
|
753
755
|
if (urlIsInsideOf(url, buildDirectoryUrl)) {
|
|
754
|
-
|
|
756
|
+
if (bundlerGeneratedUrlInfo.data.isDynamicEntry) {
|
|
757
|
+
const rawUrlInfo = rawGraph.getUrlInfo(
|
|
758
|
+
bundlerGeneratedUrlInfo.originalUrl,
|
|
759
|
+
)
|
|
760
|
+
rawUrlInfo.data.bundled = false
|
|
761
|
+
bundleRedirections.set(
|
|
762
|
+
bundlerGeneratedUrlInfo.originalUrl,
|
|
763
|
+
buildUrl,
|
|
764
|
+
)
|
|
765
|
+
associateBuildUrlAndRawUrl(
|
|
766
|
+
buildUrl,
|
|
767
|
+
bundlerGeneratedUrlInfo.originalUrl,
|
|
768
|
+
"bundle",
|
|
769
|
+
)
|
|
770
|
+
} else {
|
|
771
|
+
// chunk generated by rollup to share code
|
|
772
|
+
}
|
|
755
773
|
} else {
|
|
756
774
|
associateBuildUrlAndRawUrl(buildUrl, url, "bundle")
|
|
757
775
|
}
|
|
@@ -1018,7 +1036,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1018
1036
|
fetchUrlContent: (versionedUrlInfo) => {
|
|
1019
1037
|
if (versionedUrlInfo.isInline) {
|
|
1020
1038
|
const rawUrlInfo = rawGraph.getUrlInfo(
|
|
1021
|
-
|
|
1039
|
+
buildDirectoryRedirections.get(versionedUrlInfo.url),
|
|
1022
1040
|
)
|
|
1023
1041
|
const finalUrlInfo = finalGraph.getUrlInfo(
|
|
1024
1042
|
versionedUrlInfo.url,
|
|
@@ -1040,7 +1058,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1040
1058
|
],
|
|
1041
1059
|
sourcemaps,
|
|
1042
1060
|
sourcemapsSourcesContent,
|
|
1043
|
-
|
|
1061
|
+
sourcemapsSourcesRelative: true,
|
|
1044
1062
|
writeGeneratedFiles,
|
|
1045
1063
|
outDirectoryUrl: new URL(
|
|
1046
1064
|
".jsenv/postbuild/",
|
|
@@ -1109,7 +1127,8 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1109
1127
|
/*
|
|
1110
1128
|
* Update <link rel="preload"> and friends after build (once we know everything)
|
|
1111
1129
|
* - Used to remove resource hint targeting an url that is no longer used:
|
|
1112
|
-
* -
|
|
1130
|
+
* - because of bundlings
|
|
1131
|
+
* - because of import assertions transpilation (file is inlined into JS)
|
|
1113
1132
|
*/
|
|
1114
1133
|
resync_resource_hints: {
|
|
1115
1134
|
const actions = []
|
|
@@ -1153,7 +1172,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1153
1172
|
return
|
|
1154
1173
|
}
|
|
1155
1174
|
if (buildUrlInfo.dependents.size === 0) {
|
|
1156
|
-
logger.
|
|
1175
|
+
logger.warn(
|
|
1157
1176
|
`remove resource hint because "${href}" not used anymore`,
|
|
1158
1177
|
)
|
|
1159
1178
|
mutations.push(() => {
|
|
@@ -1180,7 +1199,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1180
1199
|
url = rawRedirections.get(url) || url
|
|
1181
1200
|
const rawUrlInfo = rawGraph.getUrlInfo(url)
|
|
1182
1201
|
if (rawUrlInfo && rawUrlInfo.data.bundled) {
|
|
1183
|
-
logger.
|
|
1202
|
+
logger.warn(
|
|
1184
1203
|
`remove resource hint on "${href}" because it was bundled`,
|
|
1185
1204
|
)
|
|
1186
1205
|
mutations.push(() => {
|
|
@@ -1190,6 +1209,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1190
1209
|
url = bundleRedirections.get(url) || url
|
|
1191
1210
|
url = bundleInternalRedirections.get(url) || url
|
|
1192
1211
|
url = finalRedirections.get(url) || url
|
|
1212
|
+
url = findKey(buildDirectoryRedirections, url) || url
|
|
1193
1213
|
onBuildUrl(url)
|
|
1194
1214
|
}
|
|
1195
1215
|
} else {
|
|
@@ -190,6 +190,10 @@ export const startBuildServer = async ({
|
|
|
190
190
|
],
|
|
191
191
|
})
|
|
192
192
|
startBuildServerTask.done()
|
|
193
|
+
if (hostname) {
|
|
194
|
+
delete server.origins.localip
|
|
195
|
+
delete server.origins.externalip
|
|
196
|
+
}
|
|
193
197
|
logger.info(``)
|
|
194
198
|
Object.keys(server.origins).forEach((key) => {
|
|
195
199
|
logger.info(`- ${server.origins[key]}`)
|
package/src/dev/file_service.js
CHANGED
|
@@ -167,7 +167,15 @@ export const createFileService = ({
|
|
|
167
167
|
return false
|
|
168
168
|
}
|
|
169
169
|
if (!watch) {
|
|
170
|
-
|
|
170
|
+
let fileContentAsBuffer
|
|
171
|
+
try {
|
|
172
|
+
fileContentAsBuffer = readFileSync(new URL(urlInfo.url))
|
|
173
|
+
} catch (e) {
|
|
174
|
+
if (e.code === "ENOENT") {
|
|
175
|
+
return false
|
|
176
|
+
}
|
|
177
|
+
return false
|
|
178
|
+
}
|
|
171
179
|
const fileContentEtag = bufferToEtag(fileContentAsBuffer)
|
|
172
180
|
if (fileContentEtag !== urlInfo.originalContentEtag) {
|
|
173
181
|
return false
|
|
@@ -273,30 +281,31 @@ export const createFileService = ({
|
|
|
273
281
|
const ifNoneMatch = request.headers["if-none-match"]
|
|
274
282
|
const urlInfoTargetedByCache = urlGraph.getParentIfInline(urlInfo)
|
|
275
283
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
284
|
+
try {
|
|
285
|
+
if (ifNoneMatch) {
|
|
286
|
+
const [clientOriginalContentEtag, clientContentEtag] =
|
|
287
|
+
ifNoneMatch.split("_")
|
|
288
|
+
if (
|
|
289
|
+
urlInfoTargetedByCache.originalContentEtag ===
|
|
290
|
+
clientOriginalContentEtag &&
|
|
291
|
+
urlInfoTargetedByCache.contentEtag === clientContentEtag &&
|
|
292
|
+
urlInfoTargetedByCache.isValid()
|
|
293
|
+
) {
|
|
294
|
+
const headers = {
|
|
295
|
+
"cache-control": `private,max-age=0,must-revalidate`,
|
|
296
|
+
}
|
|
297
|
+
Object.keys(urlInfo.headers).forEach((key) => {
|
|
298
|
+
if (key !== "content-length") {
|
|
299
|
+
headers[key] = urlInfo.headers[key]
|
|
300
|
+
}
|
|
301
|
+
})
|
|
302
|
+
return {
|
|
303
|
+
status: 304,
|
|
304
|
+
headers,
|
|
291
305
|
}
|
|
292
|
-
})
|
|
293
|
-
return {
|
|
294
|
-
status: 304,
|
|
295
|
-
headers,
|
|
296
306
|
}
|
|
297
307
|
}
|
|
298
|
-
|
|
299
|
-
try {
|
|
308
|
+
|
|
300
309
|
// urlInfo objects are reused, they must be "reset" before cooking them again
|
|
301
310
|
if (
|
|
302
311
|
(urlInfo.error || urlInfo.contentEtag) &&
|
package/src/kitchen/kitchen.js
CHANGED
|
@@ -38,7 +38,7 @@ export const createKitchen = ({
|
|
|
38
38
|
sourcemaps = scenarios.dev ? "inline" : "none", // "programmatic" and "file" also allowed
|
|
39
39
|
sourcemapsSourcesProtocol,
|
|
40
40
|
sourcemapsSourcesContent,
|
|
41
|
-
|
|
41
|
+
sourcemapsSourcesRelative,
|
|
42
42
|
writeGeneratedFiles,
|
|
43
43
|
outDirectoryUrl,
|
|
44
44
|
}) => {
|
|
@@ -263,7 +263,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
263
263
|
sourcemaps,
|
|
264
264
|
sourcemapsSourcesProtocol,
|
|
265
265
|
sourcemapsSourcesContent,
|
|
266
|
-
|
|
266
|
+
sourcemapsSourcesRelative,
|
|
267
267
|
clientRuntimeCompat,
|
|
268
268
|
injectSourcemapPlaceholder: ({ urlInfo, specifier }) => {
|
|
269
269
|
const [sourcemapReference, sourcemapUrlInfo] = resolveReference(
|
|
@@ -652,6 +652,10 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
652
652
|
if (generatedUrl && generatedUrl.startsWith("file:")) {
|
|
653
653
|
if (urlInfo.type === "directory") {
|
|
654
654
|
// no need to write the directory
|
|
655
|
+
} else if (urlInfo.content === null) {
|
|
656
|
+
// Some error might lead to urlInfo.content to be null
|
|
657
|
+
// (error hapenning before urlInfo.content can be set, or 404 for instance)
|
|
658
|
+
// in that case we can't write anything
|
|
655
659
|
} else {
|
|
656
660
|
writeFileSync(new URL(generatedUrl), urlInfo.content)
|
|
657
661
|
const { sourcemapGeneratedUrl, sourcemap } = urlInfo
|
|
@@ -847,8 +851,14 @@ const adjustUrlSite = (urlInfo, { urlGraph, url, line, column }) => {
|
|
|
847
851
|
isOriginal: true,
|
|
848
852
|
url: inlineUrlSite.url,
|
|
849
853
|
content: inlineUrlSite.content,
|
|
850
|
-
line:
|
|
851
|
-
|
|
854
|
+
line:
|
|
855
|
+
inlineUrlSite.line === undefined
|
|
856
|
+
? urlSite.line
|
|
857
|
+
: inlineUrlSite.line + urlSite.line,
|
|
858
|
+
column:
|
|
859
|
+
inlineUrlSite.column === undefined
|
|
860
|
+
? urlSite.column
|
|
861
|
+
: inlineUrlSite.column + urlSite.column,
|
|
852
862
|
},
|
|
853
863
|
parentUrlInfo,
|
|
854
864
|
)
|
|
@@ -13,7 +13,7 @@ export const createUrlInfoTransformer = ({
|
|
|
13
13
|
sourcemaps,
|
|
14
14
|
sourcemapsSourcesProtocol,
|
|
15
15
|
sourcemapsSourcesContent,
|
|
16
|
-
|
|
16
|
+
sourcemapsSourcesRelative,
|
|
17
17
|
urlGraph,
|
|
18
18
|
injectSourcemapPlaceholder,
|
|
19
19
|
foundSourcemap,
|
|
@@ -187,7 +187,7 @@ export const createUrlInfoTransformer = ({
|
|
|
187
187
|
const sourcemapUrlInfo = urlGraph.getUrlInfo(sourcemapReference.url)
|
|
188
188
|
sourcemapUrlInfo.contentType = "application/json"
|
|
189
189
|
const sourcemap = urlInfo.sourcemap
|
|
190
|
-
if (
|
|
190
|
+
if (sourcemapsSourcesRelative) {
|
|
191
191
|
sourcemap.sources = sourcemap.sources.map((source) => {
|
|
192
192
|
const sourceRelative = urlToRelativeUrl(source, urlInfo.url)
|
|
193
193
|
return sourceRelative || "."
|
|
@@ -214,7 +214,7 @@ export const createUrlInfoTransformer = ({
|
|
|
214
214
|
contentType: urlInfo.contentType,
|
|
215
215
|
content: urlInfo.content,
|
|
216
216
|
specifier:
|
|
217
|
-
sourcemaps === "file" &&
|
|
217
|
+
sourcemaps === "file" && sourcemapsSourcesRelative
|
|
218
218
|
? urlToRelativeUrl(sourcemapReference.url, urlInfo.url)
|
|
219
219
|
: sourcemapReference.generatedSpecifier,
|
|
220
220
|
})
|
|
@@ -136,15 +136,27 @@ const rollupPluginJsenv = ({
|
|
|
136
136
|
const rollupFileInfo = rollupResult[fileName]
|
|
137
137
|
// there is 3 types of file: "placeholder", "asset", "chunk"
|
|
138
138
|
if (rollupFileInfo.type === "chunk") {
|
|
139
|
+
const sourceUrls = Object.keys(rollupFileInfo.modules).map((id) =>
|
|
140
|
+
fileUrlConverter.asFileUrl(id),
|
|
141
|
+
)
|
|
142
|
+
|
|
139
143
|
let url
|
|
144
|
+
let originalUrl
|
|
140
145
|
if (rollupFileInfo.facadeModuleId) {
|
|
141
146
|
url = fileUrlConverter.asFileUrl(rollupFileInfo.facadeModuleId)
|
|
147
|
+
originalUrl = url
|
|
142
148
|
} else {
|
|
143
149
|
url = new URL(rollupFileInfo.fileName, buildDirectoryUrl).href
|
|
150
|
+
if (rollupFileInfo.isDynamicEntry) {
|
|
151
|
+
originalUrl = sourceUrls[sourceUrls.length - 1]
|
|
152
|
+
} else {
|
|
153
|
+
originalUrl = url
|
|
154
|
+
}
|
|
144
155
|
}
|
|
156
|
+
|
|
145
157
|
const jsModuleBundleUrlInfo = {
|
|
146
158
|
url,
|
|
147
|
-
originalUrl
|
|
159
|
+
originalUrl,
|
|
148
160
|
type: format === "esm" ? "js_module" : "common_js",
|
|
149
161
|
data: {
|
|
150
162
|
generatedBy: "rollup",
|
|
@@ -152,10 +164,9 @@ const rollupPluginJsenv = ({
|
|
|
152
164
|
usesImport:
|
|
153
165
|
rollupFileInfo.imports.length > 0 ||
|
|
154
166
|
rollupFileInfo.dynamicImports.length > 0,
|
|
167
|
+
isDynamicEntry: rollupFileInfo.isDynamicEntry,
|
|
155
168
|
},
|
|
156
|
-
sourceUrls
|
|
157
|
-
fileUrlConverter.asFileUrl(id),
|
|
158
|
-
),
|
|
169
|
+
sourceUrls,
|
|
159
170
|
contentType: "text/javascript",
|
|
160
171
|
content: rollupFileInfo.code,
|
|
161
172
|
sourcemap: rollupFileInfo.map,
|
|
@@ -101,7 +101,10 @@ window.__supervisor__ = (() => {
|
|
|
101
101
|
return
|
|
102
102
|
}
|
|
103
103
|
// firefox
|
|
104
|
-
if (
|
|
104
|
+
if (
|
|
105
|
+
message.startsWith("import not found:") ||
|
|
106
|
+
message.startsWith("ambiguous indirect export:")
|
|
107
|
+
) {
|
|
105
108
|
exception.code = DYNAMIC_IMPORT_EXPORT_MISSING
|
|
106
109
|
return
|
|
107
110
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { readFileSync } from "@jsenv/filesystem"
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
createMagicSource,
|
|
4
|
+
composeTwoSourcemaps,
|
|
5
|
+
SOURCEMAP,
|
|
6
|
+
} from "@jsenv/sourcemap"
|
|
3
7
|
import { applyBabelPlugins } from "@jsenv/ast"
|
|
4
8
|
|
|
5
9
|
import { requireFromJsenv } from "@jsenv/core/src/require_from_jsenv.js"
|
|
@@ -67,8 +71,23 @@ export const convertJsModuleToJsClassic = async ({
|
|
|
67
71
|
urlInfo.isEntryPoint
|
|
68
72
|
) {
|
|
69
73
|
const magicSource = createMagicSource(code)
|
|
70
|
-
|
|
71
|
-
|
|
74
|
+
let systemJsFileContent = readFileSync(systemJsClientFileUrl, {
|
|
75
|
+
as: "string",
|
|
76
|
+
})
|
|
77
|
+
const sourcemapFound = SOURCEMAP.readComment({
|
|
78
|
+
contentType: "text/javascript",
|
|
79
|
+
content: systemJsFileContent,
|
|
80
|
+
})
|
|
81
|
+
if (sourcemapFound) {
|
|
82
|
+
// for now let's remove s.js sourcemap
|
|
83
|
+
// because it would likely mess the sourcemap of the entry point itself
|
|
84
|
+
systemJsFileContent = SOURCEMAP.writeComment({
|
|
85
|
+
contentType: "text/javascript",
|
|
86
|
+
content: systemJsFileContent,
|
|
87
|
+
specifier: "",
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
magicSource.prepend(`${systemJsFileContent}\n\n`)
|
|
72
91
|
const magicResult = magicSource.toContentAndSourcemap()
|
|
73
92
|
sourcemap = await composeTwoSourcemaps(sourcemap, magicResult.sourcemap)
|
|
74
93
|
return {
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { injectQueryParams } from "@jsenv/urls"
|
|
7
|
+
import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js"
|
|
7
8
|
import { convertJsModuleToJsClassic } from "./convert_js_module_to_js_classic.js"
|
|
8
9
|
|
|
9
10
|
export const jsenvPluginAsJsClassicConversion = ({
|
|
@@ -11,12 +12,44 @@ export const jsenvPluginAsJsClassicConversion = ({
|
|
|
11
12
|
systemJsClientFileUrl,
|
|
12
13
|
generateJsClassicFilename,
|
|
13
14
|
}) => {
|
|
15
|
+
const isReferencingJsModule = (reference) => {
|
|
16
|
+
if (
|
|
17
|
+
reference.type === "js_import_export" ||
|
|
18
|
+
reference.subtype === "system_register_arg" ||
|
|
19
|
+
reference.subtype === "system_import_arg"
|
|
20
|
+
) {
|
|
21
|
+
return true
|
|
22
|
+
}
|
|
23
|
+
if (reference.type === "js_url_specifier") {
|
|
24
|
+
if (reference.expectedType === "js_classic") {
|
|
25
|
+
return false
|
|
26
|
+
}
|
|
27
|
+
if (
|
|
28
|
+
reference.expectedType === undefined &&
|
|
29
|
+
CONTENT_TYPE.fromUrlExtension(reference.url) === "text/javascript"
|
|
30
|
+
) {
|
|
31
|
+
// by default, js referenced by new URL is considered as "js_module"
|
|
32
|
+
// in case this is not desired code must use "?js_classic" like
|
|
33
|
+
// new URL('./file.js?js_classic', import.meta.url)
|
|
34
|
+
return true
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return false
|
|
38
|
+
}
|
|
39
|
+
|
|
14
40
|
const shouldPropagateJsClassic = (reference, context) => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
41
|
+
if (isReferencingJsModule(reference, context)) {
|
|
42
|
+
const parentUrlInfo = context.urlGraph.getUrlInfo(reference.parentUrl)
|
|
43
|
+
if (!parentUrlInfo) {
|
|
44
|
+
return false
|
|
45
|
+
}
|
|
46
|
+
// if (parentUrlInfo.isEntryPoint) {
|
|
47
|
+
// return true
|
|
48
|
+
// }
|
|
49
|
+
return new URL(parentUrlInfo.url).searchParams.has("as_js_classic")
|
|
18
50
|
}
|
|
19
|
-
|
|
51
|
+
|
|
52
|
+
return false
|
|
20
53
|
}
|
|
21
54
|
const markAsJsClassicProxy = (reference) => {
|
|
22
55
|
reference.expectedType = "js_classic"
|
|
@@ -38,20 +71,14 @@ export const jsenvPluginAsJsClassicConversion = ({
|
|
|
38
71
|
markAsJsClassicProxy(reference)
|
|
39
72
|
return null
|
|
40
73
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
// (because it's the transpiled equivalent of static and dynamic imports)
|
|
50
|
-
// And not other references otherwise we could try to transform inline resources
|
|
51
|
-
// or specifiers inside new URL()...
|
|
52
|
-
if (shouldPropagateJsClassic(reference, context)) {
|
|
53
|
-
return turnIntoJsClassicProxy(reference, context)
|
|
54
|
-
}
|
|
74
|
+
// We want to propagate transformation of js module to js classic to:
|
|
75
|
+
// - import specifier (static/dynamic import + re-export)
|
|
76
|
+
// - url specifier when inside System.register/_context.import()
|
|
77
|
+
// (because it's the transpiled equivalent of static and dynamic imports)
|
|
78
|
+
// And not other references otherwise we could try to transform inline resources
|
|
79
|
+
// or specifiers inside new URL()...
|
|
80
|
+
if (shouldPropagateJsClassic(reference, context)) {
|
|
81
|
+
return turnIntoJsClassicProxy(reference, context)
|
|
55
82
|
}
|
|
56
83
|
return null
|
|
57
84
|
},
|
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
injectScriptNodeAsEarlyAsPossible,
|
|
17
17
|
createHtmlNode,
|
|
18
18
|
} from "@jsenv/ast"
|
|
19
|
-
import { injectQueryParams } from "@jsenv/urls"
|
|
19
|
+
import { injectQueryParams, urlToRelativeUrl } from "@jsenv/urls"
|
|
20
|
+
import { SOURCEMAP } from "@jsenv/sourcemap"
|
|
20
21
|
|
|
21
22
|
export const jsenvPluginAsJsClassicHtml = ({
|
|
22
23
|
systemJsInjection,
|
|
@@ -162,10 +163,25 @@ export const jsenvPluginAsJsClassicHtml = ({
|
|
|
162
163
|
}
|
|
163
164
|
if (needsSystemJs) {
|
|
164
165
|
mutations.push(async () => {
|
|
165
|
-
|
|
166
|
+
let systemJsFileContent = readFileSync(
|
|
166
167
|
new URL(systemJsClientFileUrl),
|
|
167
168
|
{ encoding: "utf8" },
|
|
168
169
|
)
|
|
170
|
+
const sourcemapFound = SOURCEMAP.readComment({
|
|
171
|
+
contentType: "text/javascript",
|
|
172
|
+
content: systemJsFileContent,
|
|
173
|
+
})
|
|
174
|
+
if (sourcemapFound) {
|
|
175
|
+
const sourcemapFileUrl = new URL(
|
|
176
|
+
sourcemapFound.specifier,
|
|
177
|
+
systemJsClientFileUrl,
|
|
178
|
+
)
|
|
179
|
+
systemJsFileContent = SOURCEMAP.writeComment({
|
|
180
|
+
contentType: "text/javascript",
|
|
181
|
+
content: systemJsFileContent,
|
|
182
|
+
specifier: urlToRelativeUrl(sourcemapFileUrl, urlInfo.url),
|
|
183
|
+
})
|
|
184
|
+
}
|
|
169
185
|
const [systemJsReference, systemJsUrlInfo] =
|
|
170
186
|
context.referenceUtils.inject({
|
|
171
187
|
type: "script_src",
|