@jsenv/core 25.1.1 → 25.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.
Files changed (57) hide show
  1. package/dist/browser_runtime/browser_runtime_91c5a3b8.js.map +2 -2
  2. package/dist/build_manifest.js +4 -4
  3. package/dist/compile_proxy/asset-manifest.json +2 -2
  4. package/dist/compile_proxy/{compile_proxy_e3b0c442_809f35f7.js.map → compile_proxy.html__inline__20_809f35f7.js.map} +0 -0
  5. package/dist/compile_proxy/{compile_proxy_7ad5faa6.html → compile_proxy_8dfaee51.html} +3 -4
  6. package/dist/redirector/asset-manifest.json +2 -2
  7. package/dist/redirector/{redirector_e3b0c442_e391410e.js.map → redirector.html__inline__15_e391410e.js.map} +0 -0
  8. package/dist/redirector/{redirector_eb92e8a7.html → redirector_3e9a97b9.html} +3 -4
  9. package/dist/toolbar/asset-manifest.json +1 -1
  10. package/dist/toolbar/{toolbar_f7b8a263.html → toolbar_361afb84.html} +2 -3
  11. package/dist/toolbar_injector/asset-manifest.json +2 -2
  12. package/dist/toolbar_injector/{toolbar_injector_49e4756e.js → toolbar_injector_fac1e995.js} +2 -2
  13. package/dist/toolbar_injector/{toolbar_injector_49e4756e.js.map → toolbar_injector_fac1e995.js.map} +2 -2
  14. package/package.json +13 -9
  15. package/readme.md +73 -79
  16. package/src/buildProject.js +21 -13
  17. package/src/commonJsToJavaScriptModule.js +8 -7
  18. package/src/dev_server.js +2 -0
  19. package/src/execute.js +2 -0
  20. package/src/executeTestPlan.js +4 -1
  21. package/src/internal/building/buildUsingRollup.js +4 -2
  22. package/src/internal/building/build_stats.js +3 -0
  23. package/src/internal/building/build_url_generator.js +153 -0
  24. package/src/internal/building/css/parseCssRessource.js +32 -26
  25. package/src/internal/building/html/parseHtmlRessource.js +93 -68
  26. package/src/internal/building/js/parseJsRessource.js +4 -7
  27. package/src/internal/building/parseRessource.js +3 -0
  28. package/src/internal/building/ressource_builder.js +64 -62
  29. package/src/internal/building/ressource_builder_util.js +17 -5
  30. package/src/internal/building/rollup_plugin_jsenv.js +259 -189
  31. package/src/internal/building/url_fetcher.js +16 -7
  32. package/src/internal/building/url_loader.js +1 -5
  33. package/src/internal/building/url_versioning.js +0 -173
  34. package/src/internal/compiling/babel_plugin_import_metadata.js +7 -11
  35. package/src/internal/compiling/babel_plugin_proxy_external_imports.js +31 -0
  36. package/src/internal/compiling/compile-directory/compile-asset.js +8 -4
  37. package/src/internal/compiling/compile-directory/getOrGenerateCompiledFile.js +43 -8
  38. package/src/internal/compiling/compile-directory/updateMeta.js +4 -8
  39. package/src/internal/compiling/compile-directory/validateCache.js +1 -2
  40. package/src/internal/compiling/compileFile.js +22 -10
  41. package/src/internal/compiling/createCompiledFileService.js +22 -24
  42. package/src/internal/compiling/html_source_file_service.js +9 -9
  43. package/src/internal/compiling/js-compilation-service/babelHelper.js +10 -13
  44. package/src/internal/compiling/js-compilation-service/babel_plugin_babel_helpers_as_jsenv_imports.js +4 -2
  45. package/src/internal/compiling/js-compilation-service/jsenvTransform.js +16 -7
  46. package/src/internal/compiling/js-compilation-service/transformJs.js +9 -5
  47. package/src/internal/compiling/jsenvCompilerForHtml.js +226 -184
  48. package/src/internal/compiling/jsenvCompilerForJavaScript.js +15 -11
  49. package/src/internal/compiling/startCompileServer.js +79 -19
  50. package/src/internal/compiling/transformResultToCompilationResult.js +47 -25
  51. package/src/internal/executing/executePlan.js +2 -0
  52. package/src/internal/fetchUrl.js +3 -2
  53. package/src/internal/jsenv_remote_directory.js +156 -0
  54. package/src/internal/origin_directory_converter.js +62 -0
  55. package/src/internal/response_validation.js +11 -24
  56. package/src/internal/sourceMappingURLUtils.js +10 -0
  57. package/src/internal/url_conversion.js +1 -0
@@ -49,6 +49,7 @@ export const executeTestPlan = async ({
49
49
  completedExecutionLogMerging = false,
50
50
  logSummary = true,
51
51
  updateProcessExitCode = true,
52
+ windowsProcessExitFix = true,
52
53
 
53
54
  maxExecutionsInParallel = 1,
54
55
  defaultMsAllocatedPerExecution = 30000,
@@ -90,6 +91,7 @@ export const executeTestPlan = async ({
90
91
  compileServerCanWriteOnFilesystem,
91
92
  babelPluginMap,
92
93
  babelConfigFileUrl,
94
+ preservedUrls,
93
95
  workers,
94
96
  serviceWorkers,
95
97
  importMapInWebWorkers,
@@ -193,6 +195,7 @@ export const executeTestPlan = async ({
193
195
  compileServerCanWriteOnFilesystem,
194
196
  babelPluginMap,
195
197
  babelConfigFileUrl,
198
+ preservedUrls,
196
199
  workers,
197
200
  serviceWorkers,
198
201
  importMapInWebWorkers,
@@ -259,7 +262,7 @@ export const executeTestPlan = async ({
259
262
  // because not properly killed for some reason.
260
263
  // (It can be reproduced on @jsenv/importmap-node-module where playwright is not involved)
261
264
  // The hotfix for now is to manually call process.exit() in on windows
262
- if (process.platform === "win32") {
265
+ if (process.platform === "win32" && windowsProcessExitFix) {
263
266
  setTimeout(() => {
264
267
  process.exit()
265
268
  }, 2000).unref()
@@ -24,6 +24,7 @@ export const buildUsingRollup = async ({
24
24
  entryPoints,
25
25
  compileServerOrigin,
26
26
  compileDirectoryRelativeUrl,
27
+ jsenvDirectoryRelativeUrl,
27
28
  buildDirectoryUrl,
28
29
  buildDirectoryClean,
29
30
  assetManifestFile = false,
@@ -43,8 +44,8 @@ export const buildUsingRollup = async ({
43
44
  importMapFileRelativeUrl,
44
45
  importDefaultExtension,
45
46
  externalImportSpecifiers,
46
- externalImportUrlPatterns,
47
47
  importPaths,
48
+ preservedUrls,
48
49
  workers,
49
50
  serviceWorkers,
50
51
  serviceWorkerFinalizer,
@@ -98,6 +99,7 @@ export const buildUsingRollup = async ({
98
99
  entryPoints,
99
100
  compileServerOrigin,
100
101
  compileDirectoryRelativeUrl,
102
+ jsenvDirectoryRelativeUrl,
101
103
  buildDirectoryUrl,
102
104
 
103
105
  format,
@@ -112,8 +114,8 @@ export const buildUsingRollup = async ({
112
114
  importMapFileRelativeUrl,
113
115
  importDefaultExtension,
114
116
  externalImportSpecifiers,
115
- externalImportUrlPatterns,
116
117
  importPaths,
118
+ preservedUrls,
117
119
  workers,
118
120
  serviceWorkers,
119
121
  serviceWorkerFinalizer,
@@ -90,6 +90,9 @@ const getProjectFileContents = (ressourceBuilder) => {
90
90
  // sourcemap generated by rollup do not have bufferBeforeBuild
91
91
  return
92
92
  }
93
+ if (!bufferBeforeBuild) {
94
+ throw new Error(`bufferBeforeBuild missing for ${url}`)
95
+ }
93
96
  projectFileContents[url] = bufferBeforeBuild
94
97
  })
95
98
  return projectFileContents
@@ -0,0 +1,153 @@
1
+ import { urlToBasename, urlToExtension } from "@jsenv/filesystem"
2
+
3
+ import { generateContentHash } from "./url_versioning.js"
4
+
5
+ export const createBuildUrlGenerator = ({
6
+ entryPointUrls,
7
+ asOriginalUrl,
8
+ lineBreakNormalization,
9
+ }) => {
10
+ const availableNameGenerator = createAvailableNameGenerator()
11
+
12
+ const prepareBuildUrlForRessource = (ressource) => {
13
+ const buildRelativeUrlPattern = getBuildRelativeUrlPattern({
14
+ entryPointUrls,
15
+ asOriginalUrl,
16
+ availableNameGenerator,
17
+ ressource,
18
+ })
19
+ const buildRelativeUrlWithoutHash = buildRelativeUrlPattern.replace(
20
+ "_[hash]",
21
+ "",
22
+ )
23
+ return {
24
+ buildRelativeUrlPattern,
25
+ buildRelativeUrlWithoutHash,
26
+ }
27
+ }
28
+
29
+ const computeBuildRelativeUrl = (ressource) => {
30
+ const buildRelativeUrl = renderFileNamePattern(
31
+ ressource.buildRelativeUrlPattern,
32
+ {
33
+ hash: () =>
34
+ generateContentHash(ressource.bufferAfterBuild, {
35
+ contentType: ressource.contentType,
36
+ lineBreakNormalization,
37
+ }),
38
+ },
39
+ )
40
+ return buildRelativeUrl
41
+ }
42
+
43
+ return { prepareBuildUrlForRessource, computeBuildRelativeUrl }
44
+ }
45
+
46
+ const getBuildRelativeUrlPattern = ({
47
+ entryPointUrls,
48
+ asOriginalUrl,
49
+ availableNameGenerator,
50
+ ressource,
51
+ }) => {
52
+ if (ressource.isEntryPoint) {
53
+ const originalUrl = asOriginalUrl(ressource.url)
54
+ const entryPointBuildRelativeUrlPattern = entryPointUrls[originalUrl]
55
+ return entryPointBuildRelativeUrlPattern
56
+ }
57
+
58
+ // inline ressource
59
+ // TODO: should inherit importer directory location because inline
60
+ if (ressource.isInline) {
61
+ // const importerBuildRelativeUrlWithoutHash =
62
+ // ressource.importer.buildRelativeUrlWithoutHash
63
+ const name = urlToBasename(ressource.url)
64
+ const extension = urlToExtension(ressource.url)
65
+ // no need to ensure name is unique because it's already done
66
+ return `${name}_[hash]${extension}`
67
+ }
68
+
69
+ // importmap.
70
+ // the goal is to put the importmap at the same relative path
71
+ // than in the project to avoid having to re-resolve mappings
72
+ if (ressource.contentType === "application/importmap+json") {
73
+ const name = availableNameGenerator.getAvailableNameInDirectory(
74
+ urlToBasename(ressource.url),
75
+ "/",
76
+ )
77
+ const extension = urlToExtension(ressource.url)
78
+ return `${name}_[hash]${extension}`
79
+ }
80
+
81
+ // service worker:
82
+ // - MUST be at the root (same level than the HTML file)
83
+ // otherwise it might be registered for the scope "/assets/" instead of "/"
84
+ // - MUST not be versioned
85
+ if (ressource.isServiceWorker) {
86
+ const name = availableNameGenerator.getAvailableNameInDirectory(
87
+ urlToBasename(ressource.url),
88
+ "/",
89
+ )
90
+ const extension = urlToExtension(ressource.url)
91
+ return `${name}${extension}`
92
+ }
93
+
94
+ if (ressource.isWorker) {
95
+ const name = availableNameGenerator.getAvailableNameInDirectory(
96
+ urlToBasename(ressource.url),
97
+ "/",
98
+ )
99
+ const extension = urlToExtension(ressource.url)
100
+ return `${name}_[hash]${extension}`
101
+ }
102
+
103
+ if (ressource.isJsModule) {
104
+ const name = availableNameGenerator.getAvailableNameInDirectory(
105
+ urlToBasename(ressource.url),
106
+ "/",
107
+ )
108
+ return `${name}_[hash].js`
109
+ }
110
+
111
+ const name = availableNameGenerator.getAvailableNameInDirectory(
112
+ urlToBasename(ressource.url),
113
+ "assets/",
114
+ )
115
+ const extension = urlToExtension(ressource.url)
116
+ return ressource.urlVersioningDisabled
117
+ ? `assets/${name}${extension}`
118
+ : `assets/${name}_[hash]${extension}`
119
+ }
120
+
121
+ const createAvailableNameGenerator = () => {
122
+ const cache = {}
123
+ const getAvailableNameInDirectory = (name, directory) => {
124
+ let names = cache[directory]
125
+ if (!names) {
126
+ names = []
127
+ cache[directory] = names
128
+ }
129
+
130
+ let nameCandidate = name
131
+ let integer = 1
132
+ // eslint-disable-next-line no-constant-condition
133
+ while (true) {
134
+ if (!names.includes(nameCandidate)) {
135
+ names.push(nameCandidate)
136
+ return nameCandidate
137
+ }
138
+ integer++
139
+ nameCandidate = `${name}${integer}`
140
+ }
141
+ }
142
+
143
+ return {
144
+ getAvailableNameInDirectory,
145
+ }
146
+ }
147
+
148
+ const renderFileNamePattern = (pattern, replacements) => {
149
+ return pattern.replace(/\[(\w+)\]/g, (_match, type) => {
150
+ const replacement = replacements[type](_match)
151
+ return replacement
152
+ })
153
+ }
@@ -6,6 +6,7 @@ import {
6
6
  } from "@jsenv/filesystem"
7
7
 
8
8
  import {
9
+ generateSourcemapUrl,
9
10
  getCssSourceMappingUrl,
10
11
  setCssSourceMappingUrl,
11
12
  } from "@jsenv/core/src/internal/sourceMappingURLUtils.js"
@@ -17,11 +18,18 @@ import { moveCssUrls } from "./moveCssUrls.js"
17
18
  export const parseCssRessource = async (
18
19
  cssRessource,
19
20
  { notifyReferenceFound },
20
- { asProjectUrl, asOriginalUrl, minify, minifyCssOptions, cssConcatenation },
21
+ {
22
+ jsenvRemoteDirectory,
23
+ asProjectUrl,
24
+ asOriginalUrl,
25
+ minify,
26
+ minifyCssOptions,
27
+ cssConcatenation,
28
+ },
21
29
  ) => {
22
30
  const cssString = String(cssRessource.bufferBeforeBuild)
23
31
  const cssSourcemapUrl = getCssSourceMappingUrl(cssString)
24
- const url = cssRessource.url
32
+ const cssUrl = cssRessource.url
25
33
  let code = cssString
26
34
  let map
27
35
  let sourcemapReference
@@ -42,7 +50,10 @@ export const parseCssRessource = async (
42
50
  sourcemapReference = notifyReferenceFound({
43
51
  referenceLabel: "css sourcemaping comment",
44
52
  contentType: "application/octet-stream",
45
- ressourceSpecifier: `${urlToFilename(cssRessource.url)}.map`,
53
+ ressourceSpecifier: urlToRelativeUrl(
54
+ generateSourcemapUrl(cssUrl),
55
+ cssUrl,
56
+ ),
46
57
  isPlaceholder: true,
47
58
  isSourcemap: true,
48
59
  })
@@ -50,7 +61,7 @@ export const parseCssRessource = async (
50
61
 
51
62
  const { atImports, urlDeclarations } = await parseCssUrls({
52
63
  code,
53
- url,
64
+ url: cssUrl,
54
65
  })
55
66
  const urlNodeReferenceMapping = new Map()
56
67
  const atImportReferences = []
@@ -75,11 +86,7 @@ export const parseCssRessource = async (
75
86
  urlNodeReferenceMapping.set(urlDeclaration.urlNode, urlReference)
76
87
  })
77
88
 
78
- return async ({
79
- getUrlRelativeToImporter,
80
- precomputeBuildRelativeUrl,
81
- buildDirectoryUrl,
82
- }) => {
89
+ return async ({ getUrlRelativeToImporter, buildDirectoryUrl }) => {
83
90
  const sourcemapRessource = sourcemapReference.ressource
84
91
  const cssCompiledUrl = cssRessource.url
85
92
  const cssOriginalUrl = asOriginalUrl(cssCompiledUrl)
@@ -96,16 +103,13 @@ export const parseCssRessource = async (
96
103
  if (!urlNodeFound) {
97
104
  return urlNode.value
98
105
  }
99
-
100
106
  // url node nous dit quel référence y correspond
101
107
  const urlNodeReference = urlNodeReferenceMapping.get(urlNodeFound)
102
108
  const cssUrlRessource = urlNodeReference.ressource
103
-
104
109
  const { isExternal } = cssUrlRessource
105
110
  if (isExternal) {
106
111
  return urlNode.value
107
112
  }
108
-
109
113
  const { isInline } = cssUrlRessource
110
114
  if (isInline) {
111
115
  return getRessourceAsBase64Url(cssUrlRessource)
@@ -126,16 +130,18 @@ export const parseCssRessource = async (
126
130
  )
127
131
  atImportReference.inlinedCallback()
128
132
  let code = String(atImportReference.ressource.bufferAfterBuild)
133
+ const from = resolveUrl(
134
+ atImportReference.ressource.buildRelativeUrl,
135
+ buildDirectoryUrl,
136
+ )
137
+ const to = resolveUrl(
138
+ cssRessource.buildRelativeUrlWithoutHash,
139
+ buildDirectoryUrl,
140
+ )
129
141
  const moveResult = await moveCssUrls({
130
142
  code,
131
- from: resolveUrl(
132
- atImportReference.ressource.buildRelativeUrl,
133
- buildDirectoryUrl,
134
- ),
135
- to: resolveUrl(
136
- precomputeBuildRelativeUrl(cssRessource),
137
- buildDirectoryUrl,
138
- ),
143
+ from,
144
+ to,
139
145
  // moveCssUrls will change the css source code
140
146
  // Ideally we should update the sourcemap referenced by css
141
147
  // to target the one after css urls are moved.
@@ -153,7 +159,6 @@ export const parseCssRessource = async (
153
159
  })
154
160
  code = replaceCssResult.code
155
161
  map = replaceCssResult.map
156
-
157
162
  cssRessource.buildEnd(code)
158
163
 
159
164
  // In theory code should never be modified once buildEnd() is called
@@ -168,15 +173,16 @@ export const parseCssRessource = async (
168
173
  cssRessource.buildRelativeUrl,
169
174
  buildDirectoryUrl,
170
175
  )
171
- const sourcemapPrecomputedBuildUrl = resolveUrl(
172
- `${urlToFilename(cssBuildUrl)}.map`,
173
- cssBuildUrl,
174
- )
175
-
176
+ const sourcemapPrecomputedBuildUrl = generateSourcemapUrl(cssBuildUrl)
176
177
  map.file = urlToFilename(cssBuildUrl)
177
178
  if (map.sources) {
178
179
  map.sources = map.sources.map((source) => {
179
180
  const sourceUrl = resolveUrl(source, cssOriginalUrl)
181
+ if (jsenvRemoteDirectory.isFileUrlForRemoteUrl(sourceUrl)) {
182
+ const sourceRemoteUrl =
183
+ jsenvRemoteDirectory.remoteUrlFromFileUrl(sourceUrl)
184
+ return sourceRemoteUrl
185
+ }
180
186
  const sourceUrlRelativeToSourceMap = urlToRelativeUrl(
181
187
  sourceUrl,
182
188
  sourcemapPrecomputedBuildUrl,