@jsenv/core 27.0.0-alpha.12 → 27.0.0-alpha.13
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/main.js +4 -0
- package/package.json +13 -7
- package/readme.md +4 -12
- package/src/build/build.js +438 -387
- package/src/build/build_urls_generator.js +23 -20
- package/src/build/graph_utils.js +31 -0
- package/src/build/{inject_version_mappings.js → inject_global_version_mappings.js} +31 -14
- package/src/build/inject_service_worker_urls.js +66 -12
- package/src/build/resync_ressource_hints.js +83 -0
- package/src/dev/plugins/autoreload/babel_plugin_metadata_import_meta_hot.js +1 -1
- package/src/dev/plugins/autoreload/client/import_meta_hot.js +3 -1
- package/src/dev/plugins/autoreload/html_hot_dependencies.js +2 -2
- package/src/dev/plugins/autoreload/jsenv_plugin_autoreload.js +61 -51
- package/src/dev/plugins/autoreload/sse_service.js +23 -3
- package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -2
- package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -1
- package/src/dev/start_dev_server.js +10 -5
- package/src/execute/execute.js +10 -4
- package/src/execute/run.js +17 -54
- package/src/execute/runtimes/browsers/from_playwright.js +167 -146
- package/src/execute/runtimes/node/node_process.js +281 -37
- package/src/omega/{runtime_support/default_runtime_support.js → compat/default_runtime_compat.js} +3 -5
- package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +30 -7
- package/src/omega/{runtime_support/runtime_support.js → compat/runtime_compat.js} +14 -16
- package/src/omega/errors.js +51 -58
- package/src/omega/fetched_content_compliance.js +24 -0
- package/src/omega/kitchen.js +396 -280
- package/src/omega/server/file_service.js +9 -11
- package/src/omega/url_graph/url_graph_load.js +13 -7
- package/src/omega/url_graph/url_graph_report.js +7 -5
- package/src/omega/url_graph.js +22 -10
- package/src/omega/web_workers.js +42 -0
- package/src/plugins/bundling/css/bundle_css.js +17 -0
- package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
- package/src/{build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js → plugins/bundling/js_module/bundle_js_module.js} +100 -75
- package/src/plugins/bundling/jsenv_plugin_bundling.js +51 -0
- package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +48 -41
- package/src/plugins/file_urls/jsenv_plugin_file_urls.js +66 -0
- package/src/{omega/core_plugins → plugins}/filesystem_magic/jsenv_plugin_filesystem_magic.js +7 -4
- package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
- package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
- package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_installer.js +3 -2
- package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_setup.js +0 -0
- package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
- package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
- package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +38 -46
- package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
- package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +26 -8
- package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
- package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
- package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +37 -31
- package/src/{omega/core_plugins → plugins}/inject_globals/jsenv_plugin_inject_globals.js +4 -6
- package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
- package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +18 -14
- package/src/{omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js → plugins/inline/jsenv_plugin_html_inline_content.js} +61 -40
- package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
- package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +6 -6
- package/src/plugins/inline/jsenv_plugin_js_inline_content.js +263 -0
- package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
- package/src/plugins/minification/css/minify_css.js +9 -0
- package/src/plugins/minification/html/minify_html.js +15 -0
- package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
- package/src/plugins/minification/jsenv_plugin_minification.js +77 -0
- package/src/plugins/minification/json/minify_json.js +8 -0
- package/src/{omega/core_plugins → plugins}/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +15 -15
- package/src/{omega → plugins}/plugin_controller.js +18 -10
- package/src/plugins/plugins.js +50 -0
- package/src/plugins/transpilation/as_js_classic/client/s.js +808 -0
- package/src/plugins/transpilation/as_js_classic/client/s.js.md +1 -0
- package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
- package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +178 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +156 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_top_level_await.js +37 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_workers_type_module_as_classic.js +133 -0
- package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
- package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
- package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +0 -0
- package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_structure.js +3 -21
- package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
- package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +29 -27
- package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +0 -0
- package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/.eslintrc.cjs +0 -0
- package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
- package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
- package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
- package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
- package/src/{omega/core_plugins → plugins/transpilation}/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -0
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +243 -0
- package/src/plugins/transpilation/jsenv_plugin_transpilation.js +40 -0
- package/src/plugins/url_references/css/css_urls.js +49 -0
- package/src/plugins/url_references/html/html_urls.js +273 -0
- package/src/plugins/url_references/js/js_urls.js +170 -0
- package/src/plugins/url_references/jsenv_plugin_url_references.js +18 -0
- package/src/plugins/url_references/webmanifest/webmanifest_urls.js +17 -0
- package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +12 -5
- package/src/{omega/core_plugins → plugins}/url_version/jsenv_plugin_url_version.js +8 -8
- package/src/preview/preview.js +3 -0
- package/src/test/execute_plan.js +18 -11
- package/src/test/execute_test_plan.js +5 -6
- package/src/test/logs_file_execution.js +8 -7
- package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
- package/src/execute/runtimes/node/controlled_process.js +0 -316
- package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
- package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
- package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
- package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
- package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
- package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -207
- package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
- package/src/omega/core_plugins.js +0 -42
- package/src/omega/url_mentions/css_url_mentions.js +0 -63
- package/src/omega/url_mentions/html_url_mentions.js +0 -185
- package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
- package/src/omega/url_mentions/parse_url_mentions.js +0 -37
- package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
|
@@ -42,15 +42,11 @@ export const createFileService = ({
|
|
|
42
42
|
const { runtimeName, runtimeVersion } = parseUserAgentHeader(
|
|
43
43
|
request.headers["user-agent"],
|
|
44
44
|
)
|
|
45
|
-
const
|
|
46
|
-
[runtimeName]: runtimeVersion,
|
|
47
|
-
}
|
|
48
|
-
const reference = kitchen.createReference({
|
|
45
|
+
const [reference, urlInfo] = kitchen.prepareEntryPoint({
|
|
49
46
|
parentUrl: inferParentFromRequest(request, rootDirectoryUrl),
|
|
50
47
|
type: "entry_point",
|
|
51
48
|
specifier: request.ressource,
|
|
52
49
|
})
|
|
53
|
-
const requestedUrlInfo = kitchen.resolveReference(reference)
|
|
54
50
|
const referenceFromGraph = urlGraph.inferReference(
|
|
55
51
|
reference.url,
|
|
56
52
|
reference.parentUrl,
|
|
@@ -58,11 +54,13 @@ export const createFileService = ({
|
|
|
58
54
|
try {
|
|
59
55
|
await kitchen.cook({
|
|
60
56
|
reference: referenceFromGraph || reference,
|
|
61
|
-
urlInfo
|
|
57
|
+
urlInfo,
|
|
62
58
|
outDirectoryUrl: `${rootDirectoryUrl}.jsenv/${scenario}/${runtimeName}@${runtimeVersion}/`,
|
|
63
|
-
|
|
59
|
+
clientRuntimeCompat: {
|
|
60
|
+
[runtimeName]: runtimeVersion,
|
|
61
|
+
},
|
|
64
62
|
})
|
|
65
|
-
const { response, contentType, content } =
|
|
63
|
+
const { response, contentType, content } = urlInfo
|
|
66
64
|
if (response) {
|
|
67
65
|
return response
|
|
68
66
|
}
|
|
@@ -86,11 +84,11 @@ export const createFileService = ({
|
|
|
86
84
|
statusText: e.reason,
|
|
87
85
|
statusMessage: e.message,
|
|
88
86
|
headers: {
|
|
89
|
-
"content-type":
|
|
90
|
-
"content-length": Buffer.byteLength(
|
|
87
|
+
"content-type": urlInfo.contentType,
|
|
88
|
+
"content-length": Buffer.byteLength(urlInfo.content),
|
|
91
89
|
"cache-control": "no-store",
|
|
92
90
|
},
|
|
93
|
-
body:
|
|
91
|
+
body: urlInfo.content,
|
|
94
92
|
}
|
|
95
93
|
}
|
|
96
94
|
if (code === "EISDIR") {
|
|
@@ -5,23 +5,24 @@ export const loadUrlGraph = async ({
|
|
|
5
5
|
kitchen,
|
|
6
6
|
startLoading,
|
|
7
7
|
outDirectoryUrl,
|
|
8
|
-
|
|
8
|
+
clientRuntimeCompat,
|
|
9
9
|
}) => {
|
|
10
10
|
if (outDirectoryUrl) {
|
|
11
11
|
await ensureEmptyDirectory(outDirectoryUrl)
|
|
12
12
|
}
|
|
13
13
|
const promises = []
|
|
14
|
+
const promiseMap = new Map()
|
|
14
15
|
const cook = ({ urlInfo, ...rest }) => {
|
|
15
|
-
const promiseFromData = urlInfo
|
|
16
|
+
const promiseFromData = promiseMap.get(urlInfo)
|
|
16
17
|
if (promiseFromData) return promiseFromData
|
|
17
18
|
const promise = _cook({
|
|
18
19
|
urlInfo,
|
|
19
20
|
outDirectoryUrl,
|
|
20
|
-
|
|
21
|
+
clientRuntimeCompat,
|
|
21
22
|
...rest,
|
|
22
23
|
})
|
|
23
24
|
promises.push(promise)
|
|
24
|
-
urlInfo
|
|
25
|
+
promiseMap.set(urlInfo, promise)
|
|
25
26
|
return promise
|
|
26
27
|
}
|
|
27
28
|
const _cook = async ({ urlInfo, ...rest }) => {
|
|
@@ -32,21 +33,25 @@ export const loadUrlGraph = async ({
|
|
|
32
33
|
})
|
|
33
34
|
const { references } = urlInfo
|
|
34
35
|
references.forEach((reference) => {
|
|
36
|
+
// we use reference.generatedUrl to mimic what a browser would do:
|
|
37
|
+
// do a fetch to the specifier as found in the file
|
|
38
|
+
const referencedUrlInfo = urlGraph.reuseOrCreateUrlInfo(
|
|
39
|
+
reference.generatedUrl,
|
|
40
|
+
)
|
|
35
41
|
cook({
|
|
36
42
|
reference,
|
|
37
|
-
urlInfo:
|
|
43
|
+
urlInfo: referencedUrlInfo,
|
|
38
44
|
})
|
|
39
45
|
})
|
|
40
46
|
}
|
|
41
47
|
startLoading(
|
|
42
48
|
({ trace, parentUrl = kitchen.rootDirectoryUrl, type, specifier }) => {
|
|
43
|
-
const entryReference = kitchen.
|
|
49
|
+
const [entryReference, entryUrlInfo] = kitchen.prepareEntryPoint({
|
|
44
50
|
trace,
|
|
45
51
|
parentUrl,
|
|
46
52
|
type,
|
|
47
53
|
specifier,
|
|
48
54
|
})
|
|
49
|
-
const entryUrlInfo = kitchen.resolveReference(entryReference)
|
|
50
55
|
entryUrlInfo.data.isEntryPoint = true
|
|
51
56
|
cook({
|
|
52
57
|
reference: entryReference,
|
|
@@ -66,4 +71,5 @@ export const loadUrlGraph = async ({
|
|
|
66
71
|
await waitAll()
|
|
67
72
|
}
|
|
68
73
|
await waitAll()
|
|
74
|
+
promiseMap.clear()
|
|
69
75
|
}
|
|
@@ -39,8 +39,10 @@ const createUrlGraphReport = (urlGraph) => {
|
|
|
39
39
|
return
|
|
40
40
|
}
|
|
41
41
|
const urlInfo = urlInfos[url]
|
|
42
|
-
// ignore
|
|
43
|
-
|
|
42
|
+
// ignore:
|
|
43
|
+
// - inline files: they are already taken into account in the file where they appear
|
|
44
|
+
// - external files: we don't know their content
|
|
45
|
+
if (urlInfo.isInline || urlInfo.external) {
|
|
44
46
|
return
|
|
45
47
|
}
|
|
46
48
|
// file loaded via import assertion are already inside the graph
|
|
@@ -49,9 +51,9 @@ const createUrlGraphReport = (urlGraph) => {
|
|
|
49
51
|
// and only the js module remain (likely bundled)
|
|
50
52
|
const urlObject = new URL(urlInfo.url)
|
|
51
53
|
if (
|
|
52
|
-
urlObject.searchParams.has("
|
|
53
|
-
urlObject.searchParams.has("
|
|
54
|
-
urlObject.searchParams.has("
|
|
54
|
+
urlObject.searchParams.has("as_json_module") ||
|
|
55
|
+
urlObject.searchParams.has("as_css_module") ||
|
|
56
|
+
urlObject.searchParams.has("as_text_module")
|
|
55
57
|
) {
|
|
56
58
|
return
|
|
57
59
|
}
|
package/src/omega/url_graph.js
CHANGED
|
@@ -44,9 +44,19 @@ export const createUrlGraph = () => {
|
|
|
44
44
|
const updateReferences = (urlInfo, references) => {
|
|
45
45
|
const dependencyUrls = []
|
|
46
46
|
references.forEach((reference) => {
|
|
47
|
-
if (
|
|
48
|
-
|
|
47
|
+
if (reference.isRessourceHint) {
|
|
48
|
+
// ressource hint are a special kind of reference.
|
|
49
|
+
// They are a sort of weak reference to an url.
|
|
50
|
+
// We ignore them so that url referenced only by ressource hints
|
|
51
|
+
// have url.dependents.size === 0 and can be considered as not used
|
|
52
|
+
// It means html won't consider url referenced solely
|
|
53
|
+
// by <link> as dependency and it's fine
|
|
54
|
+
return
|
|
49
55
|
}
|
|
56
|
+
if (dependencyUrls.includes(reference.url)) {
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
dependencyUrls.push(reference.url)
|
|
50
60
|
})
|
|
51
61
|
pruneDependencies(
|
|
52
62
|
urlInfo,
|
|
@@ -115,19 +125,21 @@ export const createUrlGraph = () => {
|
|
|
115
125
|
const createUrlInfo = (url) => {
|
|
116
126
|
return {
|
|
117
127
|
data: {}, // plugins can put whatever they want here
|
|
128
|
+
references: [],
|
|
129
|
+
dependencies: new Set(),
|
|
130
|
+
dependents: new Set(),
|
|
131
|
+
type: undefined, // "html", "css", "js_classic", "js_module", "importmap", "json", "webmanifest", ...
|
|
132
|
+
subtype: undefined, // "worker", "service_worker", "shared_worker" for js, otherwise undefined
|
|
133
|
+
contentType: "", // "text/html", "text/css", "text/javascript", "application/json", ...
|
|
118
134
|
url,
|
|
135
|
+
filename: "",
|
|
119
136
|
generatedUrl: null,
|
|
120
137
|
isInline: false,
|
|
121
138
|
inlineUrlSite: null,
|
|
122
|
-
|
|
123
|
-
originalContent:
|
|
124
|
-
content:
|
|
139
|
+
external: false,
|
|
140
|
+
originalContent: undefined,
|
|
141
|
+
content: undefined,
|
|
125
142
|
sourcemap: null,
|
|
126
143
|
sourcemapReference: null,
|
|
127
|
-
type: "",
|
|
128
|
-
subtype: "",
|
|
129
|
-
references: [],
|
|
130
|
-
dependencies: new Set(),
|
|
131
|
-
dependents: new Set(),
|
|
132
144
|
}
|
|
133
145
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// the following apis are creating js entry points:
|
|
2
|
+
// - new Worker()
|
|
3
|
+
// - new SharedWorker()
|
|
4
|
+
// - navigator.serviceWorker.register()
|
|
5
|
+
export const isWebWorkerEntryPointReference = (reference) => {
|
|
6
|
+
if (reference.subtype === "new_url_first_arg") {
|
|
7
|
+
return ["worker", "service_worker", "shared_worker"].includes(
|
|
8
|
+
reference.expectedSubtype,
|
|
9
|
+
)
|
|
10
|
+
}
|
|
11
|
+
return [
|
|
12
|
+
"new_worker_first_arg",
|
|
13
|
+
"new_shared_worker_first_arg",
|
|
14
|
+
"service_worker_register_first_arg",
|
|
15
|
+
].includes(reference.subtype)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const isWebWorkerUrlInfo = (urlInfo) => {
|
|
19
|
+
return (
|
|
20
|
+
urlInfo.subtype === "worker" ||
|
|
21
|
+
urlInfo.subtype === "service_worker" ||
|
|
22
|
+
urlInfo.subtype === "shared_worker"
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// export const isEntryPoint = (urlInfo, urlGraph) => {
|
|
27
|
+
// if (urlInfo.data.isEntryPoint) {
|
|
28
|
+
// return true
|
|
29
|
+
// }
|
|
30
|
+
// if (isWebWorker(urlInfo)) {
|
|
31
|
+
// // - new Worker("a.js") -> "a.js" is an entry point
|
|
32
|
+
// // - self.importScripts("b.js") -> "b.js" is not an entry point
|
|
33
|
+
// // So the following logic applies to infer if the file is a web worker entry point
|
|
34
|
+
// // "When a non-webworker file references a worker file, the worker file is an entry point"
|
|
35
|
+
// const dependents = Array.from(urlInfo.dependents)
|
|
36
|
+
// return dependents.some((dependentUrl) => {
|
|
37
|
+
// const dependentUrlInfo = urlGraph.getUrlInfo(dependentUrl)
|
|
38
|
+
// return !isWebWorker(dependentUrlInfo)
|
|
39
|
+
// })
|
|
40
|
+
// }
|
|
41
|
+
// return false
|
|
42
|
+
// }
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { bundleWithParcel } from "@jsenv/utils/css_ast/parcel_css.js"
|
|
2
|
+
|
|
3
|
+
export const bundleCss = ({ cssUrlInfos, context }) => {
|
|
4
|
+
const bundledCssUrlInfos = {}
|
|
5
|
+
cssUrlInfos.forEach((cssUrlInfo) => {
|
|
6
|
+
const { code, map } = bundleWithParcel(cssUrlInfo, context)
|
|
7
|
+
bundledCssUrlInfos[cssUrlInfo.url] = {
|
|
8
|
+
data: {
|
|
9
|
+
generatedBy: "parcel",
|
|
10
|
+
},
|
|
11
|
+
contentType: "text/css",
|
|
12
|
+
content: String(code),
|
|
13
|
+
sourcemap: map,
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
return bundledCssUrlInfos
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* TODO:
|
|
3
|
+
* for each js_classic where subtype is a worker
|
|
4
|
+
* take the url info and find importScripts calls
|
|
5
|
+
* and replace them with the corresponding url info file content
|
|
6
|
+
* we'll ikely need to save the importScripts node location to be able to do that
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
|
|
10
|
+
|
|
11
|
+
export const bundleJsClassicWorkers = () => {
|
|
12
|
+
return {}
|
|
13
|
+
}
|
|
@@ -1,43 +1,32 @@
|
|
|
1
|
-
import { isFileSystemPath
|
|
1
|
+
import { isFileSystemPath } from "@jsenv/filesystem"
|
|
2
|
+
import { createDetailedMessage } from "@jsenv/logger"
|
|
2
3
|
|
|
3
4
|
import { applyRollupPlugins } from "@jsenv/utils/js_ast/apply_rollup_plugins.js"
|
|
4
5
|
import { sourcemapConverter } from "@jsenv/utils/sourcemap/sourcemap_converter.js"
|
|
5
6
|
import { fileUrlConverter } from "@jsenv/core/src/omega/file_url_converter.js"
|
|
6
7
|
|
|
7
|
-
export const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
},
|
|
25
|
-
) => {
|
|
26
|
-
const { jsModuleBundleUrlInfos } = await buildWithRollup({
|
|
27
|
-
signal,
|
|
28
|
-
logger,
|
|
29
|
-
rootDirectoryUrl,
|
|
30
|
-
buildDirectoryUrl,
|
|
31
|
-
urlGraph,
|
|
32
|
-
jsModuleUrlInfos,
|
|
8
|
+
export const bundleJsModule = async ({ jsModuleUrlInfos, context }) => {
|
|
9
|
+
const {
|
|
10
|
+
signal,
|
|
11
|
+
logger,
|
|
12
|
+
rootDirectoryUrl,
|
|
13
|
+
buildDirectoryUrl,
|
|
14
|
+
urlGraph,
|
|
15
|
+
runtimeCompat,
|
|
16
|
+
sourcemaps,
|
|
17
|
+
} = context
|
|
18
|
+
const { jsModuleBundleUrlInfos } = await buildWithRollup({
|
|
19
|
+
signal,
|
|
20
|
+
logger,
|
|
21
|
+
rootDirectoryUrl,
|
|
22
|
+
buildDirectoryUrl,
|
|
23
|
+
urlGraph,
|
|
24
|
+
jsModuleUrlInfos,
|
|
33
25
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
}
|
|
26
|
+
runtimeCompat,
|
|
27
|
+
sourcemaps,
|
|
28
|
+
})
|
|
29
|
+
return jsModuleBundleUrlInfos
|
|
41
30
|
}
|
|
42
31
|
|
|
43
32
|
export const buildWithRollup = async ({
|
|
@@ -48,36 +37,46 @@ export const buildWithRollup = async ({
|
|
|
48
37
|
urlGraph,
|
|
49
38
|
jsModuleUrlInfos,
|
|
50
39
|
|
|
51
|
-
|
|
40
|
+
runtimeCompat,
|
|
52
41
|
sourcemaps,
|
|
53
42
|
}) => {
|
|
54
43
|
const resultRef = { current: null }
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
44
|
+
try {
|
|
45
|
+
await applyRollupPlugins({
|
|
46
|
+
rollupPlugins: [
|
|
47
|
+
rollupPluginJsenv({
|
|
48
|
+
signal,
|
|
49
|
+
logger,
|
|
50
|
+
rootDirectoryUrl,
|
|
51
|
+
buildDirectoryUrl,
|
|
52
|
+
urlGraph,
|
|
53
|
+
jsModuleUrlInfos,
|
|
64
54
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
55
|
+
runtimeCompat,
|
|
56
|
+
sourcemaps,
|
|
57
|
+
resultRef,
|
|
58
|
+
}),
|
|
59
|
+
],
|
|
60
|
+
inputOptions: {
|
|
61
|
+
input: [],
|
|
62
|
+
onwarn: (warning) => {
|
|
63
|
+
if (warning.code === "CIRCULAR_DEPENDENCY") {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
logger.warn(String(warning))
|
|
67
|
+
},
|
|
77
68
|
},
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
69
|
+
})
|
|
70
|
+
return resultRef.current
|
|
71
|
+
} catch (e) {
|
|
72
|
+
if (e.code === "MISSING_EXPORT") {
|
|
73
|
+
const detailedMessage = createDetailedMessage(e.message, {
|
|
74
|
+
frame: e.frame,
|
|
75
|
+
})
|
|
76
|
+
throw new Error(detailedMessage, { cause: e })
|
|
77
|
+
}
|
|
78
|
+
throw e
|
|
79
|
+
}
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
const rollupPluginJsenv = ({
|
|
@@ -119,6 +118,7 @@ const rollupPluginJsenv = ({
|
|
|
119
118
|
implicitlyLoadedAfterOneOf: previousNonEntryPointModuleId
|
|
120
119
|
? [previousNonEntryPointModuleId]
|
|
121
120
|
: null,
|
|
121
|
+
preserveSignature: "allow-extension",
|
|
122
122
|
})
|
|
123
123
|
previousNonEntryPointModuleId = id
|
|
124
124
|
})
|
|
@@ -135,8 +135,12 @@ const rollupPluginJsenv = ({
|
|
|
135
135
|
// buildRelativeUrl: rollupFileInfo.fileName,
|
|
136
136
|
data: {
|
|
137
137
|
generatedBy: "rollup",
|
|
138
|
+
usesImport:
|
|
139
|
+
rollupFileInfo.imports.length > 0 ||
|
|
140
|
+
rollupFileInfo.dynamicImports.length > 0,
|
|
141
|
+
usesExport: rollupFileInfo.exports.length > 0,
|
|
138
142
|
},
|
|
139
|
-
contentType: "
|
|
143
|
+
contentType: "text/javascript",
|
|
140
144
|
content: rollupFileInfo.code,
|
|
141
145
|
sourcemap: rollupFileInfo.map,
|
|
142
146
|
}
|
|
@@ -144,7 +148,7 @@ const rollupPluginJsenv = ({
|
|
|
144
148
|
if (rollupFileInfo.facadeModuleId) {
|
|
145
149
|
url = fileUrlConverter.asFileUrl(rollupFileInfo.facadeModuleId)
|
|
146
150
|
} else {
|
|
147
|
-
url = new URL(rollupFileInfo.fileName,
|
|
151
|
+
url = new URL(rollupFileInfo.fileName, buildDirectoryUrl).href
|
|
148
152
|
}
|
|
149
153
|
jsModuleBundleUrlInfos[url] = jsModuleBundleUrlInfo
|
|
150
154
|
}
|
|
@@ -167,19 +171,12 @@ const rollupPluginJsenv = ({
|
|
|
167
171
|
return `[name].js`
|
|
168
172
|
},
|
|
169
173
|
chunkFileNames: (chunkInfo) => {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const relativePath = urlToRelativeUrl(fileUrl, rootDirectoryUrl)
|
|
177
|
-
return relativePath
|
|
178
|
-
}
|
|
179
|
-
// chunk generated dynamically by rollup to share code.
|
|
180
|
-
// we prefix with "__rollup__/" to avoid potential conflict of filename
|
|
181
|
-
// between this one and a file with the same name existing in the root directory
|
|
182
|
-
return `__rollup__/${chunkInfo.name}.js`
|
|
174
|
+
const insideJs = willBeInsideJsDirectory({
|
|
175
|
+
chunkInfo,
|
|
176
|
+
fileUrlConverter,
|
|
177
|
+
jsModuleUrlInfos,
|
|
178
|
+
})
|
|
179
|
+
return insideJs ? `js/${chunkInfo.name}.js` : `${chunkInfo.name}.js`
|
|
183
180
|
},
|
|
184
181
|
// https://rollupjs.org/guide/en/#outputpaths
|
|
185
182
|
// paths: (id) => {
|
|
@@ -197,7 +194,7 @@ const rollupPluginJsenv = ({
|
|
|
197
194
|
urlImporters[url] = importer
|
|
198
195
|
}
|
|
199
196
|
if (!url.startsWith("file:")) {
|
|
200
|
-
return { url, external: true }
|
|
197
|
+
return { id: url, external: true }
|
|
201
198
|
}
|
|
202
199
|
const filePath = fileUrlConverter.asFilePath(url)
|
|
203
200
|
return filePath
|
|
@@ -225,3 +222,31 @@ const rollupPluginJsenv = ({
|
|
|
225
222
|
},
|
|
226
223
|
}
|
|
227
224
|
}
|
|
225
|
+
|
|
226
|
+
const willBeInsideJsDirectory = ({
|
|
227
|
+
chunkInfo,
|
|
228
|
+
fileUrlConverter,
|
|
229
|
+
jsModuleUrlInfos,
|
|
230
|
+
}) => {
|
|
231
|
+
// if the chunk is generated dynamically by rollup
|
|
232
|
+
// for an entry point jsenv will put that file inside js/ directory
|
|
233
|
+
// if it's generated dynamically for a file already in js/ directory
|
|
234
|
+
// both will be inside the js/ directory
|
|
235
|
+
if (!chunkInfo.facadeModuleId) {
|
|
236
|
+
// generated by rollup
|
|
237
|
+
return true
|
|
238
|
+
}
|
|
239
|
+
const url = fileUrlConverter.asFileUrl(chunkInfo.facadeModuleId)
|
|
240
|
+
const jsModuleUrlInfo = jsModuleUrlInfos.find(
|
|
241
|
+
(jsModuleUrlInfo) => jsModuleUrlInfo.url === url,
|
|
242
|
+
)
|
|
243
|
+
if (!jsModuleUrlInfo) {
|
|
244
|
+
// generated by rollup
|
|
245
|
+
return true
|
|
246
|
+
}
|
|
247
|
+
if (!jsModuleUrlInfo.data.isEntryPoint) {
|
|
248
|
+
// not an entry point, jsenv will put it inside js/ directory
|
|
249
|
+
return true
|
|
250
|
+
}
|
|
251
|
+
return false
|
|
252
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { bundleCss } from "./css/bundle_css.js"
|
|
2
|
+
import { bundleJsClassicWorkers } from "./js_classic_workers/bundle_js_classic_workers.js"
|
|
3
|
+
import { bundleJsModule } from "./js_module/bundle_js_module.js"
|
|
4
|
+
|
|
5
|
+
export const jsenvPluginBundling = (bundling) => {
|
|
6
|
+
if (typeof bundling === "boolean") {
|
|
7
|
+
bundling = {
|
|
8
|
+
css: bundling,
|
|
9
|
+
js_classic_workers: bundling,
|
|
10
|
+
js_module: bundling,
|
|
11
|
+
}
|
|
12
|
+
} else if (typeof bundling !== "object") {
|
|
13
|
+
throw new Error(`bundling must be a boolean or an object, got ${bundling}`)
|
|
14
|
+
}
|
|
15
|
+
Object.keys(bundling).forEach((key) => {
|
|
16
|
+
if (bundling[key] === true) bundling[key] = {}
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
name: "jsenv:bundling",
|
|
21
|
+
appliesDuring: {
|
|
22
|
+
build: true,
|
|
23
|
+
},
|
|
24
|
+
bundle: {
|
|
25
|
+
css: bundling.css
|
|
26
|
+
? (cssUrlInfos, context) =>
|
|
27
|
+
bundleCss({
|
|
28
|
+
cssUrlInfos,
|
|
29
|
+
context,
|
|
30
|
+
options: bundling.css,
|
|
31
|
+
})
|
|
32
|
+
: undefined,
|
|
33
|
+
js_classic: bundling.js_classic
|
|
34
|
+
? (jsClassicUrlInfos, context) =>
|
|
35
|
+
bundleJsClassicWorkers({
|
|
36
|
+
jsClassicUrlInfos,
|
|
37
|
+
context,
|
|
38
|
+
options: bundling.js_classic_workers,
|
|
39
|
+
})
|
|
40
|
+
: undefined,
|
|
41
|
+
js_module: bundling.js_module
|
|
42
|
+
? (jsModuleUrlInfos, context) =>
|
|
43
|
+
bundleJsModule({
|
|
44
|
+
jsModuleUrlInfos,
|
|
45
|
+
context,
|
|
46
|
+
options: bundling.js_module,
|
|
47
|
+
})
|
|
48
|
+
: undefined,
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
}
|
package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js
RENAMED
|
@@ -11,50 +11,57 @@ import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
|
|
|
11
11
|
import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
|
|
12
12
|
|
|
13
13
|
export const jsenvPluginCommonJsGlobals = () => {
|
|
14
|
+
const transformCommonJsGlobals = async (urlInfo, { scenario }) => {
|
|
15
|
+
const isJsModule = urlInfo.type === "js_module"
|
|
16
|
+
|
|
17
|
+
const replaceMap = {
|
|
18
|
+
"process.env.NODE_ENV": `("${
|
|
19
|
+
scenario === "dev" || scenario === "test" ? "dev" : "prod"
|
|
20
|
+
}")`,
|
|
21
|
+
"global": "globalThis",
|
|
22
|
+
"__filename": isJsModule
|
|
23
|
+
? `import.meta.url.slice('file:///'.length)`
|
|
24
|
+
: `document.currentScript.src`,
|
|
25
|
+
"__dirname": isJsModule
|
|
26
|
+
? `import.meta.url.slice('file:///'.length).replace(/[\\\/\\\\][^\\\/\\\\]*$/, '')`
|
|
27
|
+
: `new URL('./', document.currentScript.src).href`,
|
|
28
|
+
}
|
|
29
|
+
const { metadata } = await applyBabelPlugins({
|
|
30
|
+
babelPlugins: [
|
|
31
|
+
[
|
|
32
|
+
babelPluginMetadataExpressionPaths,
|
|
33
|
+
{
|
|
34
|
+
replaceMap,
|
|
35
|
+
allowConflictingReplacements: true,
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
],
|
|
39
|
+
urlInfo,
|
|
40
|
+
})
|
|
41
|
+
const { expressionPaths } = metadata
|
|
42
|
+
const keys = Object.keys(expressionPaths)
|
|
43
|
+
if (keys.length === 0) {
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
46
|
+
const magicSource = createMagicSource(urlInfo.content)
|
|
47
|
+
keys.forEach((key) => {
|
|
48
|
+
expressionPaths[key].forEach((path) => {
|
|
49
|
+
magicSource.replace({
|
|
50
|
+
start: path.node.start,
|
|
51
|
+
end: path.node.end,
|
|
52
|
+
replacement: replaceMap[key],
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
return magicSource.toContentAndSourcemap()
|
|
57
|
+
}
|
|
58
|
+
|
|
14
59
|
return {
|
|
15
60
|
name: "jsenv:commonjs_globals",
|
|
16
61
|
appliesDuring: "*",
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"process.env.NODE_ENV": `("${
|
|
21
|
-
scenario === "dev" || scenario === "test" ? "dev" : "prod"
|
|
22
|
-
}")`,
|
|
23
|
-
"global": "globalThis",
|
|
24
|
-
"__filename": `import.meta.url.slice('file:///'.length)`,
|
|
25
|
-
"__dirname": `import.meta.url.slice('file:///'.length).replace(/[\\\/\\\\][^\\\/\\\\]*$/, '')`,
|
|
26
|
-
}
|
|
27
|
-
const { metadata } = await applyBabelPlugins({
|
|
28
|
-
babelPlugins: [
|
|
29
|
-
[
|
|
30
|
-
babelPluginMetadataExpressionPaths,
|
|
31
|
-
{
|
|
32
|
-
replaceMap,
|
|
33
|
-
allowConflictingReplacements: true,
|
|
34
|
-
},
|
|
35
|
-
],
|
|
36
|
-
],
|
|
37
|
-
url,
|
|
38
|
-
generatedUrl,
|
|
39
|
-
content,
|
|
40
|
-
})
|
|
41
|
-
const { expressionPaths } = metadata
|
|
42
|
-
const keys = Object.keys(expressionPaths)
|
|
43
|
-
if (keys.length === 0) {
|
|
44
|
-
return null
|
|
45
|
-
}
|
|
46
|
-
const magicSource = createMagicSource(content)
|
|
47
|
-
keys.forEach((key) => {
|
|
48
|
-
expressionPaths[key].forEach((path) => {
|
|
49
|
-
magicSource.replace({
|
|
50
|
-
start: path.node.start,
|
|
51
|
-
end: path.node.end,
|
|
52
|
-
replacement: replaceMap[key],
|
|
53
|
-
})
|
|
54
|
-
})
|
|
55
|
-
})
|
|
56
|
-
return magicSource.toContentAndSourcemap()
|
|
57
|
-
},
|
|
62
|
+
transformUrlContent: {
|
|
63
|
+
js_classic: transformCommonJsGlobals,
|
|
64
|
+
js_module: transformCommonJsGlobals,
|
|
58
65
|
},
|
|
59
66
|
}
|
|
60
67
|
}
|