@jsenv/core 24.4.6 → 24.5.2

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 (36) hide show
  1. package/dist/build_manifest.js +4 -4
  2. package/dist/compile_proxy/asset-manifest.json +1 -2
  3. package/dist/compile_proxy/{compile_proxy-e666f204.html → compile_proxy-1dfca609.html} +254 -218
  4. package/dist/redirector/asset-manifest.json +1 -2
  5. package/dist/redirector/{redirector-bee67b92.html → redirector-d1316407.html} +254 -218
  6. package/dist/toolbar/asset-manifest.json +1 -2
  7. package/dist/toolbar/{toolbar-3e2e70d3.html → toolbar-afb71355.html} +262 -222
  8. package/dist/toolbar/{toolbar.main-b23f63e6.js.map → toolbar.main-feac7fa3.js.map} +3 -3
  9. package/dist/toolbar_injector/asset-manifest.json +1 -1
  10. package/dist/toolbar_injector/{toolbar_injector-69fc0515.js → toolbar_injector-445d3ea0.js} +2 -2
  11. package/dist/toolbar_injector/{toolbar_injector-69fc0515.js.map → toolbar_injector-445d3ea0.js.map} +3 -3
  12. package/package.json +3 -2
  13. package/readme.md +32 -36
  14. package/src/buildProject.js +2 -0
  15. package/src/internal/building/buildUsingRollup.js +16 -28
  16. package/src/internal/building/{bundleWorker.js → js/babel_plugin_inline_worker_imports.js} +25 -61
  17. package/src/internal/building/js/parseJsRessource.js +12 -13
  18. package/src/internal/building/js/transform_worker.js +55 -0
  19. package/src/internal/building/resolve_import_url_helper.js +2 -1
  20. package/src/internal/building/ressource_builder.js +59 -15
  21. package/src/internal/building/{createJsenvRollupPlugin.js → rollup_plugin_jsenv.js} +81 -9
  22. package/src/internal/building/url_loader.js +0 -2
  23. package/src/internal/compiling/createCompiledFileService.js +3 -3
  24. package/src/internal/dev_server/toolbar/toolbar.html +1 -1
  25. package/src/internal/dev_server/toolbar/toolbar.main.js +4 -0
  26. package/src/internal/dev_server/toolbar/util/dom.js +1 -1
  27. package/src/internal/executing/coverage_utils/v8_coverage_from_directory.js +9 -1
  28. package/src/internal/executing/createSummaryLog.js +4 -4
  29. package/src/internal/executing/executeConcurrently.js +1 -0
  30. package/src/internal/executing/executePlan.js +24 -10
  31. package/src/internal/executing/executionLogs.js +1 -1
  32. package/src/jsenvServiceWorkerFinalizer.js +19 -2
  33. package/dist/compile_proxy/assets/s.js-fcba0e35.map +0 -246
  34. package/dist/redirector/assets/s.js-fcba0e35.map +0 -246
  35. package/dist/toolbar/assets/s.js-fcba0e35.map +0 -246
  36. package/src/internal/building/buildServiceWorker.js +0 -75
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "24.4.6",
3
+ "version": "24.5.2",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -56,7 +56,7 @@
56
56
  "@babel/plugin-syntax-numeric-separator": "7.10.4",
57
57
  "@babel/plugin-transform-modules-systemjs": "7.16.0",
58
58
  "@c88/v8-coverage": "0.1.1",
59
- "@jsenv/abort": "4.1.1",
59
+ "@jsenv/abort": "4.1.2",
60
60
  "@jsenv/filesystem": "2.5.1",
61
61
  "@jsenv/importmap": "1.2.0",
62
62
  "@jsenv/log": "1.5.0",
@@ -99,6 +99,7 @@
99
99
  "terser": "5.10.0",
100
100
  "v8-to-istanbul": "8.1.0",
101
101
  "vm2": "3.9.5",
102
+ "why-is-node-running": "2.2.0",
102
103
  "wrap-ansi": "8.0.1"
103
104
  },
104
105
  "devDependencies": {
package/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # jsenv [![npm package](https://img.shields.io/npm/v/@jsenv/core.svg?logo=npm&label=package)](https://www.npmjs.com/package/@jsenv/core) [![github main worflow](https://github.com/jsenv/jsenv-core/workflows/main/badge.svg)](https://github.com/jsenv/jsenv-core/actions?workflow=main) [![codecov coverage](https://codecov.io/gh/jsenv/jsenv-core/branch/master/graph/badge.svg)](https://codecov.io/gh/jsenv/jsenv-core)
2
2
 
3
- `@jsenv/core` was first created to write tests that could be executed in different browsers AND Node.js. In the end it became a tool covering the core needs of a JavaScript project:
3
+ _@jsenv/core_ was first created to write tests that could be executed in different browsers AND Node.js. In the end it became a tool covering the core needs of a JavaScript project:
4
4
 
5
5
  - A test runner to execute test files
6
6
  - A development server
@@ -29,7 +29,7 @@ Each standard listed in this section is potentially supported natively by the br
29
29
 
30
30
  # Test runner overview
31
31
 
32
- Let's assume you want to test `countDogs` exported by `animals.js` file.
32
+ Let's assume you want to test `countDogs` exported by _animals.js_ file.
33
33
 
34
34
  ```js
35
35
  export const countDogs = (animals) => {
@@ -37,7 +37,7 @@ export const countDogs = (animals) => {
37
37
  }
38
38
  ```
39
39
 
40
- 1 - Create `animals.test.html`
40
+ 1 - Create _animals.test.html_
41
41
 
42
42
  ```html
43
43
  <!DOCTYPE html>
@@ -61,7 +61,7 @@ export const countDogs = (animals) => {
61
61
  </html>
62
62
  ```
63
63
 
64
- 2 - Create `execute_test_plan.mjs`
64
+ 2 - Create _execute_test_plan.mjs_
65
65
 
66
66
  ```js
67
67
  import {
@@ -85,7 +85,7 @@ executeTestPlan({
85
85
  })
86
86
  ```
87
87
 
88
- 3 - Add `"@jsenv/core"` and `playwright`
88
+ 3 - Add _@jsenv/core_ and _playwright_
89
89
 
90
90
  ```console
91
91
  npm install --save-dev @jsenv/core
@@ -94,7 +94,7 @@ npx playwright install-deps
94
94
  npx playwright install
95
95
  ```
96
96
 
97
- 4 - Run `execute_test_plan.mjs` with Node.js
97
+ 4 - Run _execute_test_plan.mjs_ with Node.js
98
98
 
99
99
  ```console
100
100
  > node ./execute_test_plan.mjs
@@ -134,13 +134,13 @@ You have an html file that you want to open in a browser on your machine.
134
134
  </html>
135
135
  ```
136
136
 
137
- 1 - Add `"@jsenv/core"` to your _devDependencies_
137
+ 1 - Add _@jsenv/core_ to your _devDependencies_
138
138
 
139
139
  ```console
140
140
  npm install --save-dev @jsenv/core
141
141
  ```
142
142
 
143
- 2 - Create `start_dev_server.mjs`
143
+ 2 - Create _start_dev_server.mjs_
144
144
 
145
145
  ```js
146
146
  import { startDevServer } from "@jsenv/core"
@@ -156,23 +156,23 @@ startDevServer({
156
156
  })
157
157
  ```
158
158
 
159
- 3 - Run `start_dev_server.mjs` with Node.js
159
+ 3 - Run _start_dev_server.mjs_ with Node.js
160
160
 
161
161
  ```console
162
162
  > node ./start_dev_server.mjs
163
163
 
164
- server started at https://localhost:3456
164
+ server started at http://localhost:3456
165
165
  ```
166
166
 
167
- 4 - Open a browser and navigate to `https://localhost:3456`
167
+ 4 - Open a browser and navigate to `http://localhost:3456`
168
168
 
169
- When you open `https://localhost:3456` in a browser, a page called jsenv exploring index is shown. It displays a list of links to your html files.
169
+ When you open `http://localhost:3456` in a browser, a page called jsenv exploring index is shown. It displays a list of links to your html files.
170
170
 
171
171
  ![dev server index screenshot](./docs/demo_exploring_index.png)
172
172
 
173
- 5 - Click `main.html`
173
+ 5 - Click _main.html_
174
174
 
175
- Browser navigates to `main.html` and execute the file. Hello world is displayed in the browser.
175
+ Browser navigates to _main.html_ and execute the file. Hello world is displayed in the browser.
176
176
 
177
177
  ![dev server hello world screenshot](./docs/demo_exploring_hello_world.png)
178
178
 
@@ -180,7 +180,7 @@ To read more about jsenv dev server, check [jsenv dev server documentation](./do
180
180
 
181
181
  # Build overview
182
182
 
183
- Following the steps below turns an `index.html` into an optimized `dist/main.html`.
183
+ Following the steps below turns a `main.html` into an optimized `dist/main.prod.html`.
184
184
  Only the content of html files is shown below because the content of non-html files is trivial.
185
185
 
186
186
  ```html
@@ -201,13 +201,13 @@ Only the content of html files is shown below because the content of non-html fi
201
201
  </html>
202
202
  ```
203
203
 
204
- 1 - Add `"@jsenv/core"` to your _devDependencies_
204
+ 1 - Add _@jsenv/core_ to your _devDependencies_
205
205
 
206
206
  ```console
207
207
  npm install --save-dev @jsenv/core
208
208
  ```
209
209
 
210
- 2 - Create `build.mjs`
210
+ 2 - Create _build.mjs_
211
211
 
212
212
  ```js
213
213
  import { buildProject } from "@jsenv/core"
@@ -223,7 +223,7 @@ await buildProject({
223
223
  })
224
224
  ```
225
225
 
226
- 3 - Run `build.mjs` with Node.js
226
+ 3 - Run _build.mjs_ with Node.js
227
227
 
228
228
  ```console
229
229
  > node ./build.mjs
@@ -246,7 +246,7 @@ build duration: 1.85 seconds
246
246
  ✔ build end
247
247
  ```
248
248
 
249
- 4 - Open `dist/main.prod.html`
249
+ 4 - Open _dist/main.prod.html_
250
250
 
251
251
  ```html
252
252
  <!DOCTYPE html>
@@ -282,7 +282,7 @@ To sum up, jsenv focuses on simplicity and flexibility making it a perfect candi
282
282
 
283
283
  ## Main dependencies
284
284
 
285
- An overview of the main dependencies used by `@jsenv/core`.
285
+ An overview of the main dependencies used by _@jsenv/core_.
286
286
 
287
287
  | Dependency | How it is used by jsenv |
288
288
  | ----------------------------------------------------- | ------------------------------------------- |
@@ -296,16 +296,16 @@ An overview of the main dependencies used by `@jsenv/core`.
296
296
 
297
297
  ## Name
298
298
 
299
- The name `jsenv` stands for JavaScript environments. This is because the original purpose of `jsenv` was to bring closer two JavaScript runtimes: web browsers and Node.js. This aspect of `jsenv` is not highlighted in the documentation but it exists.
299
+ The name "jsenv" stands for JavaScript environments. This is because the original purpose of jsenv was to bring closer two JavaScript runtimes: web browsers and Node.js. This aspect is not highlighted in the documentation but it exists.
300
300
 
301
- Maybe `jsenv` should be written `JSEnv`? That makes typing the name too complex:
301
+ Maybe "jsenv" should be written "JSEnv"? That makes typing the name too complex:
302
302
 
303
303
  1. Hold `shift` on keyboard
304
304
  2. While holding `shift`, type `JSE`
305
305
  3. Release `shift`
306
306
  4. Finally, type `nv`.
307
307
 
308
- No one should have to do that, the prefered syntax is `jsenv`.
308
+ No one wants to do that: the prefered syntax is "jsenv".
309
309
 
310
310
  ## Logo
311
311
 
@@ -328,17 +328,17 @@ The logo is composed by the name at the center and two circles orbiting around i
328
328
  npm install --save-dev @jsenv/core
329
329
  ```
330
330
 
331
- `@jsenv/core` is tested on Mac, Windows, Linux on Node.js 14.17.0. Other operating systems and Node.js versions are not tested.
331
+ _@jsenv/core_ is tested on Mac, Windows, Linux on Node.js 16.13.0. Other operating systems and Node.js versions are not tested.
332
332
 
333
333
  # Configuration
334
334
 
335
- Jsenv configuration is done in [jsenv.config.mjs](https://github.com/jsenv/jsenv-core#jsenvconfigmjs) and [babel.config.cjs](https://github.com/jsenv/jsenv-core#babelconfigcjs).
335
+ Jsenv configuration is done in [jsenv.config.mjs](#jsenvconfigmjs) and [babel.config.cjs](#babelconfigcjs).
336
336
 
337
337
  ## jsenv.config.mjs
338
338
 
339
- Jsenv codebase usually puts configuration in a top level file named `jsenv.config.mjs`.
339
+ Jsenv codebase usually puts configuration in a top level file named _jsenv.config.mjs_.
340
340
 
341
- It's recommended to use the following `jsenv.config.mjs`
341
+ It's recommended to use the following _jsenv.config.mjs_
342
342
 
343
343
  ```js
344
344
  /*
@@ -350,22 +350,16 @@ It's recommended to use the following `jsenv.config.mjs`
350
350
  * Read more at https://github.com/jsenv/jsenv-core#jsenvconfigmjs
351
351
  */
352
352
 
353
- export const projectDirectoryUrl = String(new URL("./", import.meta.url))
353
+ export const projectDirectoryUrl = new URL("./", import.meta.url)
354
354
  ```
355
355
 
356
- The file is meant to be imported and passed using the spread operator.
357
-
358
- ![screenshot about jsenv config import and spread operator](./docs/jsenv-config-spread.png)
359
-
360
- — See [script/test/test.js](https://github.com/jsenv/jsenv-core/blob/8da56c4aeb70891be1245f388bfe5d3088145ec6/script/test/test.js#L3)
361
-
362
- This technic helps to see jsenv custom configuration quickly and share it between files. That being said you are free to organize your configuration as you want.
356
+ This file helps to see jsenv configuration quickly and share it between files. That being said you are free to organize your configuration as you want.
363
357
 
364
358
  ## babel.config.cjs
365
359
 
366
360
  When code needs to be transformed, the project must contain a [babel config file](https://babeljs.io/docs/en/config-files).
367
361
 
368
- It's recommended to use the following `babel.config.cjs`
362
+ It's recommended to use the following _babel.config.cjs_
369
363
 
370
364
  ```js
371
365
  /*
@@ -427,6 +421,8 @@ You must also add an [importmap](https://github.com/WICG/import-maps#import-maps
427
421
  </script>
428
422
  ```
429
423
 
424
+ The import mappings can be generated programmatically, you can use https://github.com/jsenv/importmap-node-module to do that.
425
+
430
426
  ## JSX
431
427
 
432
428
  If you want to use jsx, you need [@babel/plugin-transform-react-jsx](https://babeljs.io/docs/en/next/babel-plugin-transform-react-jsx.html) in your babel config file.
@@ -79,6 +79,7 @@ export const buildProject = async ({
79
79
  // https://github.com/cssnano/cssnano/tree/master/packages/cssnano-preset-default
80
80
  minifyCssOptions,
81
81
 
82
+ workers = {},
82
83
  serviceWorkers = {},
83
84
  serviceWorkerFinalizer,
84
85
 
@@ -237,6 +238,7 @@ export const buildProject = async ({
237
238
  minifyJsOptions,
238
239
  minifyCssOptions,
239
240
 
241
+ workers,
240
242
  serviceWorkers,
241
243
  serviceWorkerFinalizer,
242
244
 
@@ -8,7 +8,6 @@ import {
8
8
  } from "@jsenv/filesystem"
9
9
  import { createDetailedMessage } from "@jsenv/logger"
10
10
 
11
- import { buildServiceWorker } from "@jsenv/core/src/internal/building/buildServiceWorker.js"
12
11
  import { humanizeUrl } from "@jsenv/core/src/internal/building/url_trace.js"
13
12
  import {
14
13
  isNodePartOfSupportedRuntimes,
@@ -16,7 +15,7 @@ import {
16
15
  } from "@jsenv/core/src/internal/generateGroupMap/runtime_support.js"
17
16
  import { featuresCompatMap } from "@jsenv/core/src/internal/generateGroupMap/featuresCompatMap.js"
18
17
  import { createRuntimeCompat } from "@jsenv/core/src/internal/generateGroupMap/runtime_compat.js"
19
- import { createJsenvRollupPlugin } from "./createJsenvRollupPlugin.js"
18
+ import { createJsenvRollupPlugin } from "./rollup_plugin_jsenv.js"
20
19
 
21
20
  export const buildUsingRollup = async ({
22
21
  buildOperation,
@@ -48,6 +47,9 @@ export const buildUsingRollup = async ({
48
47
  externalImportSpecifiers,
49
48
  externalImportUrlPatterns,
50
49
  importPaths,
50
+ workers,
51
+ serviceWorkers,
52
+ serviceWorkerFinalizer,
51
53
 
52
54
  urlVersioning,
53
55
  urlVersionningForEntryPoints,
@@ -62,9 +64,6 @@ export const buildUsingRollup = async ({
62
64
  minifyJsOptions,
63
65
  minifyCssOptions,
64
66
  minifyHtmlOptions,
65
-
66
- serviceWorkers,
67
- serviceWorkerFinalizer,
68
67
  }) => {
69
68
  const node = isNodePartOfSupportedRuntimes(runtimeSupport)
70
69
  const browser = isBrowserPartOfSupportedRuntimes(runtimeSupport)
@@ -121,6 +120,9 @@ export const buildUsingRollup = async ({
121
120
  externalImportSpecifiers,
122
121
  externalImportUrlPatterns,
123
122
  importPaths,
123
+ workers,
124
+ serviceWorkers,
125
+ serviceWorkerFinalizer,
124
126
 
125
127
  urlVersioning,
126
128
  urlVersionningForEntryPoints,
@@ -157,7 +159,16 @@ export const buildUsingRollup = async ({
157
159
  if (e.plugin === "jsenv") {
158
160
  const jsenvPluginErrorMessage = getLastErrorMessage()
159
161
  if (jsenvPluginErrorMessage) {
162
+ // rollup is adding properties to the original error
163
+ // making it a bit harder to read
164
+ // It does not add useful information so we restore the error
165
+ delete e.code
166
+ delete e.hook
167
+ delete e.id
168
+ delete e.watchFiles
169
+ delete e.plugin
160
170
  e.message = jsenvPluginErrorMessage
171
+ throw e
161
172
  }
162
173
  throw e
163
174
  }
@@ -219,29 +230,6 @@ export const buildUsingRollup = async ({
219
230
  await writeFile(fileBuildUrl, buildFileContents[buildRelativeUrl])
220
231
  }),
221
232
  )
222
-
223
- await Promise.all(
224
- Object.keys(serviceWorkers).map(
225
- async (serviceWorkerProjectRelativeUrl) => {
226
- const serviceWorkerBuildRelativeUrl =
227
- serviceWorkers[serviceWorkerProjectRelativeUrl]
228
- await buildServiceWorker({
229
- projectDirectoryUrl,
230
- buildDirectoryUrl,
231
- serviceWorkerProjectRelativeUrl,
232
- serviceWorkerBuildRelativeUrl,
233
- serviceWorkerTransformer: (code) =>
234
- serviceWorkerFinalizer(code, {
235
- buildManifest,
236
- rollupBuild,
237
- lineBreakNormalization,
238
- }),
239
-
240
- minify,
241
- })
242
- },
243
- ),
244
- )
245
233
  }
246
234
 
247
235
  return {
@@ -1,73 +1,24 @@
1
- import { readFileSync } from "fs"
2
1
  import {
3
2
  resolveUrl,
4
- urlToFileSystemPath,
5
3
  fileSystemPathToUrl,
4
+ urlToFileSystemPath,
6
5
  } from "@jsenv/filesystem"
7
- import { createDetailedMessage } from "@jsenv/logger"
8
- import { require } from "@jsenv/core/src/internal/require.js"
9
-
10
- export const bundleWorker = ({ workerScriptUrl, workerScriptSourceMap }) => {
11
- const { code, map } = transformWorkerScript(workerScriptUrl, {
12
- workerScriptSourceMap,
13
- })
14
- return { code, map }
15
- }
16
6
 
17
- const transformWorkerScript = (
18
- scriptUrl,
19
- { workerScriptSourceMap, importerUrl },
7
+ export const babelPluginInlineWorkerImports = (
8
+ babel,
9
+ { readImportedScript },
20
10
  ) => {
21
- const scriptPath = urlToFileSystemPath(scriptUrl)
22
- let scriptContent
23
- try {
24
- scriptContent = String(readFileSync(scriptPath))
25
- } catch (e) {
26
- if (e.code === "ENOENT") {
27
- if (importerUrl) {
28
- throw new Error(
29
- createDetailedMessage(`no file found for an import in a worker.`, {
30
- ["worker url"]: importerUrl,
31
- ["imported url"]: scriptUrl,
32
- }),
33
- )
34
- }
35
- throw new Error(`no worker file at ${scriptUrl}`)
36
- }
37
- throw e
38
- }
39
-
40
- const { transformSync } = require("@babel/core")
41
- const { code, map } = transformSync(scriptContent, {
42
- filename: scriptPath,
43
- configFile: false,
44
- babelrc: false, // trust only these options, do not read any babelrc config file
45
- ast: false,
46
- inputSourceMap: workerScriptSourceMap,
47
- sourceMaps: true,
48
- // sourceFileName: scriptPath,
49
- plugins: [[babelPluginInlineImportScripts, {}]],
50
- })
51
- return { code, map }
52
- }
11
+ const { types } = babel
53
12
 
54
- const babelPluginInlineImportScripts = (api) => {
55
- const { types, parse } = api
56
13
  return {
57
- name: "transform-inline-import-scripts",
14
+ name: "transform-inline-worker-imports",
58
15
 
59
16
  visitor: {
60
- CallExpression: (
61
- path,
62
- {
63
- file: {
64
- opts: { filename },
65
- },
66
- },
67
- ) => {
17
+ CallExpression: (path, opts) => {
68
18
  const calleePath = path.get("callee")
69
19
 
70
20
  const replaceImportScriptsWithFileContents = () => {
21
+ const filename = opts.filename
71
22
  const fileUrl = fileSystemPathToUrl(filename)
72
23
 
73
24
  let previousArgType = ""
@@ -97,11 +48,24 @@ const babelPluginInlineImportScripts = (api) => {
97
48
 
98
49
  if (previousArgType === "local") {
99
50
  const nodes = importedUrls.reduce((previous, importedUrl) => {
100
- const importedScriptResult = transformWorkerScript(importedUrl, {
101
- importerUrl: fileUrl,
51
+ const importedScriptCode = readImportedScript(importedUrl)
52
+ const { ast } = babel.transformSync(importedScriptCode, {
53
+ filename: urlToFileSystemPath(importedUrl),
54
+ configFile: false,
55
+ babelrc: false, // trust only these options, do not read any babelrc config file
56
+ ast: true,
57
+ sourceMaps: true,
58
+ // sourceFileName: scriptPath,
59
+ plugins: [
60
+ [
61
+ babelPluginInlineWorkerImports,
62
+ {
63
+ readImportedScript,
64
+ },
65
+ ],
66
+ ],
102
67
  })
103
- const importedSourceAst = parse(importedScriptResult.code)
104
- return [...previous, ...importedSourceAst.program.body]
68
+ return [...previous, ...ast.program.body]
105
69
  }, [])
106
70
 
107
71
  calleePath.parentPath.replaceWithMultiple(nodes)
@@ -4,7 +4,7 @@ import {
4
4
  getJavaScriptSourceMappingUrl,
5
5
  setJavaScriptSourceMappingUrl,
6
6
  } from "@jsenv/core/src/internal/sourceMappingURLUtils.js"
7
- import { bundleWorker } from "@jsenv/core/src/internal/building/bundleWorker.js"
7
+ import { transformWorker } from "./transform_worker.js"
8
8
 
9
9
  export const parseJsRessource = async (
10
10
  jsRessource,
@@ -47,19 +47,18 @@ export const parseJsRessource = async (
47
47
  map = JSON.parse(String(sourcemapRessource.bufferBeforeBuild))
48
48
  }
49
49
 
50
- // in case this js asset is a worker, bundle it so that:
51
- // importScripts are inlined which is good for:
52
- // - not breaking things (otherwise we would have to copy imported files in the build directory)
53
- // - perf (one less http request)
54
- const mightBeAWorkerScript = !jsRessource.isInline
55
- if (mightBeAWorkerScript) {
56
- const workerScriptUrl = asOriginalUrl(jsUrl)
57
- const workerBundle = await bundleWorker({
58
- workerScriptUrl,
59
- workerScriptSourceMap: map,
50
+ // in case this js asset is a worker, we transform it so that
51
+ // importScripts() calls are inlined
52
+ // We could also parse each importScripts call and decide to inline
53
+ // or not. For now inlining/concatenation is forced
54
+ if (jsRessource.isWorker || jsRessource.isServiceWorker) {
55
+ const transformResult = await transformWorker({
56
+ url: asOriginalUrl(jsUrl),
57
+ code: String(jsRessource.bufferBeforeBuild),
58
+ map,
60
59
  })
61
- code = workerBundle.code
62
- map = workerBundle.map
60
+ code = transformResult.code
61
+ map = transformResult.map
63
62
  } else {
64
63
  code = jsString
65
64
  }
@@ -0,0 +1,55 @@
1
+ // we could inline a worker by doing
2
+ // var blob = new Blob(code, { type: 'text/javascript' })
3
+ // window.URL.createObjectURL(blob)
4
+
5
+ import { readFileSync } from "fs"
6
+ import { urlToFileSystemPath } from "@jsenv/filesystem"
7
+ import { createDetailedMessage } from "@jsenv/logger"
8
+
9
+ import { babelPluginInlineWorkerImports } from "./babel_plugin_inline_worker_imports.js"
10
+
11
+ export const transformWorker = async ({ url, code, map }) => {
12
+ const { transformSync } = await import("@babel/core")
13
+
14
+ const transformResult = transformSync(code, {
15
+ filename: urlToFileSystemPath(url),
16
+ configFile: false,
17
+ babelrc: false, // trust only these options, do not read any babelrc config file
18
+ ast: false,
19
+ inputSourceMap: map,
20
+ sourceMaps: true,
21
+ // sourceFileName: scriptPath,
22
+ plugins: [
23
+ [
24
+ babelPluginInlineWorkerImports,
25
+ {
26
+ readImportedScript: readWorkerFile,
27
+ },
28
+ ],
29
+ ],
30
+ })
31
+ code = transformResult.code
32
+ map = transformResult.map
33
+ return { code, map }
34
+ }
35
+
36
+ export const readWorkerFile = (url, importerUrl) => {
37
+ const filePath = urlToFileSystemPath(url)
38
+ try {
39
+ const code = String(readFileSync(filePath))
40
+ return code
41
+ } catch (e) {
42
+ if (e.code === "ENOENT") {
43
+ if (importerUrl) {
44
+ throw new Error(
45
+ createDetailedMessage(`no file found for an import in a worker.`, {
46
+ ["worker url"]: importerUrl,
47
+ ["imported url"]: url,
48
+ }),
49
+ )
50
+ }
51
+ throw new Error(`no worker file at ${url}`)
52
+ }
53
+ throw e
54
+ }
55
+ }
@@ -4,7 +4,8 @@ window.__resolveImportUrl__ = (url, baseUrl) => {
4
4
 
5
5
  if (importmapNode) {
6
6
  const importmap = JSON.parse(importmapNode.textContent)
7
- return new URL(importmap.imports[url], baseUrl)
7
+ const specifier = importmap.imports[url] || url
8
+ return new URL(specifier, baseUrl)
8
9
  }
9
10
 
10
11
  return new URL(url, baseUrl)