@jsenv/core 20.3.2 → 21.0.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 (29) hide show
  1. package/dist/.DS_Store +0 -0
  2. package/dist/jsenv_compile_proxy.js +4 -6
  3. package/dist/jsenv_compile_proxy.js.map +3 -4
  4. package/dist/jsenv_exploring_redirector.js +4 -6
  5. package/dist/jsenv_exploring_redirector.js.map +3 -4
  6. package/dist/jsenv_toolbar.js +7 -16
  7. package/dist/jsenv_toolbar.js.map +4 -6
  8. package/{LICENSE → license} +0 -0
  9. package/main.js +2 -1
  10. package/package.json +3 -7
  11. package/readme.md +8 -8
  12. package/src/{convertCommonJsWithRollup.js → commonJsToJavaScriptModule.js} +23 -5
  13. package/src/execute.js +2 -2
  14. package/src/executeTestPlan.js +2 -2
  15. package/src/internal/compiling/compile-directory/getOrGenerateCompiledFile.js +17 -14
  16. package/src/internal/compiling/createCompiledFileService.js +125 -64
  17. package/src/internal/compiling/js-compilation-service/jsenvTransform.js +1 -1
  18. package/src/internal/compiling/js-compilation-service/transformJs.js +1 -71
  19. package/src/internal/compiling/jsenvCompilerForHtml.js +146 -187
  20. package/src/internal/compiling/jsenvCompilerForImportmap.js +79 -13
  21. package/src/internal/compiling/jsenvCompilerForJavaScript.js +33 -70
  22. package/src/internal/compiling/startCompileServer.js +1 -7
  23. package/src/internal/compiling/transformResultToCompilationResult.js +7 -2
  24. package/src/internal/executing/executePlan.js +2 -2
  25. package/src/internal/runtime/createBrowserRuntime/scanBrowserRuntimeFeatures.js +4 -7
  26. package/src/internal/toolbar/compilation/toolbar.compilation.js +3 -11
  27. package/src/startExploring.js +0 -2
  28. package/src/textToJavaScriptModule.js +10 -0
  29. package/src/internal/compiling/transformImportmap.js +0 -94
package/readme.md CHANGED
@@ -355,10 +355,10 @@ CommonJS module format rely on `module.exports` and `require`. It was invented b
355
355
  _jsenv.config.mjs to use code written in CommonJS_:
356
356
 
357
357
  ```js
358
- import { jsenvBabelPluginMap, convertCommonJsWithRollup } from "@jsenv/core"
358
+ import { jsenvBabelPluginMap, commonJsToJavaScriptModule } from "@jsenv/core"
359
359
 
360
- export const convertMap = {
361
- "./node_modules/whatever/index.js": convertCommonJsWithRollup,
360
+ export const customCompilers = {
361
+ "./node_modules/whatever/index.js": commonJsToJavaScriptModule,
362
362
  }
363
363
  ```
364
364
 
@@ -370,7 +370,7 @@ _jsenv.config.mjs for react and jsx:_
370
370
 
371
371
  ```js
372
372
  import { createRequire } from "module"
373
- import { jsenvBabelPluginMap, convertCommonJsWithRollup } from "@jsenv/core"
373
+ import { jsenvBabelPluginMap, commonJsToJavaScriptModule } from "@jsenv/core"
374
374
 
375
375
  const require = createRequire(import.meta.url)
376
376
  const transformReactJSX = require("@babel/plugin-transform-react-jsx")
@@ -383,10 +383,10 @@ export const babelPluginMap = {
383
383
  ],
384
384
  }
385
385
 
386
- export const convertMap = {
387
- "./node_modules/react/index.js": convertCommonJsWithRollup,
386
+ export const customCompilers = {
387
+ "./node_modules/react/index.js": commonJsToJavaScriptModule,
388
388
  "./node_modules/react-dom/index.js": (options) => {
389
- return convertCommonJsWithRollup({ ...options, external: ["react"] })
389
+ return commonJsToJavaScriptModule({ ...options, external: ["react"] })
390
390
  },
391
391
  }
392
392
  ```
@@ -408,7 +408,7 @@ See also
408
408
 
409
409
  - [@jsenv/importmap-node-module](https://github.com/jsenv/importmap-node-module#import-map-node-module)
410
410
  - [babelPluginMap](./docs/shared-parameters.md#babelPluginMap)
411
- - [convertMap](./docs/shared-parameters.md#convertMap)
411
+ - [customCompilers](./docs/shared-parameters.md#customCompilers)
412
412
  - [transform-react-jsx on babel](https://babeljs.io/docs/en/next/babel-plugin-transform-react-jsx.html)
413
413
  - [importmap spec](https://github.com/WICG/import-maps#import-maps)
414
414
 
@@ -1,10 +1,14 @@
1
1
  import { urlToFileSystemPath, resolveUrl } from "@jsenv/filesystem"
2
2
 
3
3
  import { require } from "./internal/require.js"
4
+ import { transformResultToCompilationResult } from "./internal/compiling/transformResultToCompilationResult.js"
4
5
 
5
- export const convertCommonJsWithRollup = async ({
6
+ export const commonJsToJavaScriptModule = async ({
6
7
  url,
7
- urlAfterTransform,
8
+ compiledUrl,
9
+ projectDirectoryUrl,
10
+
11
+ sourcemapExcludeSources,
8
12
 
9
13
  replaceGlobalObject = true,
10
14
  replaceGlobalFilename = true,
@@ -92,15 +96,29 @@ export const convertCommonJsWithRollup = async ({
92
96
  // https://rollupjs.org/guide/en#output-sourcemap
93
97
  sourcemap: true,
94
98
  sourcemapExcludeSources: true,
95
- ...(urlAfterTransform
96
- ? { dir: urlToFileSystemPath(resolveUrl("./", urlAfterTransform)) }
99
+ ...(compiledUrl
100
+ ? { dir: urlToFileSystemPath(resolveUrl("./", compiledUrl)) }
97
101
  : {}),
98
102
  }
99
103
 
100
104
  const { output } = await rollupBuild.generate(generateOptions)
101
105
  const { code, map } = output[0]
102
106
 
103
- return { code, map }
107
+ return transformResultToCompilationResult(
108
+ {
109
+ contentType: "application/javascript",
110
+ code,
111
+ map,
112
+ },
113
+ {
114
+ projectDirectoryUrl,
115
+ originalFileContent: code,
116
+ originalFileUrl: url,
117
+ compiledFileUrl: compiledUrl,
118
+ sourcemapFileUrl: `${compiledUrl}.map`,
119
+ sourcemapExcludeSources,
120
+ },
121
+ )
104
122
  }
105
123
 
106
124
  const __filenameReplacement = `import.meta.url.slice('file:///'.length)`
package/src/execute.js CHANGED
@@ -50,7 +50,7 @@ export const execute = async ({
50
50
  compileServerIp,
51
51
  compileServerPort,
52
52
  babelPluginMap,
53
- convertMap,
53
+ customCompilers,
54
54
  compileServerCanReadFromFilesystem,
55
55
  compileServerCanWriteOnFilesystem,
56
56
  runtimeSupportDuringDev = jsenvRuntimeSupportDuringDev,
@@ -95,7 +95,7 @@ export const execute = async ({
95
95
  compileServerIp,
96
96
  compileServerPort,
97
97
  babelPluginMap,
98
- convertMap,
98
+ customCompilers,
99
99
  runtimeSupport: runtimeSupportDuringDev,
100
100
  compileServerCanReadFromFilesystem,
101
101
  compileServerCanWriteOnFilesystem,
@@ -77,7 +77,7 @@ export const executeTestPlan = async ({
77
77
  compileServerCanReadFromFilesystem,
78
78
  compileServerCanWriteOnFilesystem,
79
79
  babelPluginMap,
80
- convertMap,
80
+ customCompilers,
81
81
  // we could even affine depending on testPlan
82
82
  runtimeSupportDuringDev = jsenvRuntimeSupportDuringDev,
83
83
  jsenvDirectoryClean,
@@ -185,7 +185,7 @@ export const executeTestPlan = async ({
185
185
  compileServerCanReadFromFilesystem,
186
186
  compileServerCanWriteOnFilesystem,
187
187
  babelPluginMap,
188
- convertMap,
188
+ customCompilers,
189
189
  runtimeSupport: runtimeSupportDuringDev,
190
190
  })
191
191
 
@@ -215,21 +215,28 @@ const callCompile = async ({
215
215
  }) => {
216
216
  logger.debug(`compile ${originalFileUrl}`)
217
217
 
218
- const compileArgs =
218
+ const codeBeforeCompile =
219
219
  compile.length === 0
220
- ? []
221
- : await getArgumentsForCompile({ originalFileUrl, fileContentFallback })
220
+ ? ""
221
+ : await getCodeToCompile({ originalFileUrl, fileContentFallback })
222
222
 
223
+ const compileReturnValue = await compile({
224
+ code: codeBeforeCompile,
225
+ map: undefined,
226
+ })
227
+ if (typeof compileReturnValue !== "object" || compileReturnValue === null) {
228
+ throw new TypeError(
229
+ `compile must return an object, got ${compileReturnValue}`,
230
+ )
231
+ }
223
232
  const {
233
+ contentType,
234
+ compiledSource,
224
235
  sources = [],
225
236
  sourcesContent = [],
226
237
  assets = [],
227
238
  assetsContent = [],
228
- contentType,
229
- compiledSource,
230
- ...rest
231
- } = await compile(...compileArgs)
232
-
239
+ } = compileReturnValue
233
240
  if (typeof contentType !== "string") {
234
241
  throw new TypeError(
235
242
  `compile must return a contentType string, got ${contentType}`,
@@ -248,14 +255,10 @@ const callCompile = async ({
248
255
  sourcesContent,
249
256
  assets,
250
257
  assetsContent,
251
- ...rest,
252
258
  }
253
259
  }
254
260
 
255
- const getArgumentsForCompile = async ({
256
- originalFileUrl,
257
- fileContentFallback,
258
- }) => {
261
+ const getCodeToCompile = async ({ originalFileUrl, fileContentFallback }) => {
259
262
  let fileContent
260
263
  if (fileContentFallback) {
261
264
  try {
@@ -270,7 +273,7 @@ const getArgumentsForCompile = async ({
270
273
  } else {
271
274
  fileContent = await readFileContent(originalFileUrl)
272
275
  }
273
- return [fileContent]
276
+ return fileContent
274
277
  }
275
278
 
276
279
  const startAsap = async (fn, { logger, compiledFileUrl }) => {
@@ -1,5 +1,10 @@
1
1
  import { serveFile } from "@jsenv/server"
2
- import { resolveUrl, resolveDirectoryUrl } from "@jsenv/filesystem"
2
+ import {
3
+ resolveUrl,
4
+ resolveDirectoryUrl,
5
+ normalizeStructuredMetaMap,
6
+ urlToMeta,
7
+ } from "@jsenv/filesystem"
3
8
 
4
9
  import { serverUrlToCompileInfo } from "@jsenv/core/src/internal/url_conversion.js"
5
10
  import {
@@ -9,14 +14,19 @@ import {
9
14
  COMPILE_ID_BUILD_COMMONJS_FILES,
10
15
  } from "../CONSTANTS.js"
11
16
  import { compileFile } from "./compileFile.js"
12
- import { jsenvCompilerForHtml } from "./jsenvCompilerForHtml.js"
13
- import { jsenvCompilerForImportmap } from "./jsenvCompilerForImportmap.js"
14
- import { jsenvCompilerForJavaScript } from "./jsenvCompilerForJavaScript.js"
17
+ import { compileHtml } from "./jsenvCompilerForHtml.js"
18
+ import { compileImportmap } from "./jsenvCompilerForImportmap.js"
19
+ import { compileJavascript } from "./jsenvCompilerForJavaScript.js"
15
20
 
16
21
  const jsenvCompilers = {
17
- ...jsenvCompilerForJavaScript,
18
- ...jsenvCompilerForHtml,
19
- ...jsenvCompilerForImportmap,
22
+ "**/*.js": compileJavascript,
23
+ "**/*.jsx": compileJavascript,
24
+ "**/*.ts": compileJavascript,
25
+ "**/*.tsx": compileJavascript,
26
+ "**/*.mjs": compileJavascript,
27
+
28
+ "**/*.html": compileHtml,
29
+ "**/*.importmap": compileImportmap,
20
30
  }
21
31
 
22
32
  export const createCompiledFileService = ({
@@ -33,18 +43,31 @@ export const createCompiledFileService = ({
33
43
  importMetaFormat,
34
44
  babelPluginMap,
35
45
  groupMap,
36
- convertMap,
37
46
  customCompilers,
38
- urlMappings,
39
47
 
40
48
  jsenvToolbarInjection,
41
49
 
42
50
  projectFileRequestedCallback,
43
51
  useFilesystemAsCache,
44
- writeOnFilesystem,
45
52
  compileCacheStrategy,
46
53
  sourcemapExcludeSources,
47
54
  }) => {
55
+ Object.keys(customCompilers).forEach((key) => {
56
+ const value = customCompilers[key]
57
+ if (typeof value !== "function") {
58
+ throw new TypeError(
59
+ `Compiler must be a function, found ${value} for "${key}"`,
60
+ )
61
+ }
62
+ })
63
+ const compileMeta = normalizeStructuredMetaMap(
64
+ {
65
+ jsenvCompiler: jsenvCompilers,
66
+ customCompiler: customCompilers,
67
+ },
68
+ projectDirectoryUrl,
69
+ )
70
+
48
71
  return (request) => {
49
72
  const { origin, ressource } = request
50
73
  const requestUrl = `${origin}${ressource}`
@@ -103,73 +126,111 @@ export const createCompiledFileService = ({
103
126
  compileDirectoryUrl,
104
127
  )
105
128
 
106
- let compilerOptions = null
107
- const compilerCandidateParams = {
129
+ const compiler = getCompiler({ originalFileUrl, compileMeta })
130
+ // no compiler -> serve original file
131
+ // we don't redirect otherwise it complexify ressource tracking
132
+ // and url resolution
133
+ if (!compiler) {
134
+ return sourceFileService({
135
+ ...request,
136
+ ressource: `/${originalFileRelativeUrl}`,
137
+ })
138
+ }
139
+
140
+ // compile this if needed
141
+ const compileResponsePromise = compileFile({
108
142
  cancellationToken,
109
143
  logger,
110
144
 
111
- compileServerOrigin: request.origin,
112
145
  projectDirectoryUrl,
113
146
  originalFileUrl,
114
147
  compiledFileUrl,
115
- compileId,
116
- outDirectoryRelativeUrl,
117
-
118
- urlMappings,
119
-
120
- moduleOutFormat,
121
- importMetaFormat,
122
- groupMap,
123
- babelPluginMap,
124
- convertMap,
125
- transformTopLevelAwait,
126
- runtimeSupport,
127
148
 
128
- writeOnFilesystem,
129
- sourcemapExcludeSources,
130
- jsenvToolbarInjection,
131
- }
132
- const compilerCandidates = { ...jsenvCompilers, ...customCompilers }
133
- Object.keys(compilerCandidates).find((compilerCandidateName) => {
134
- const compilerCandidate = compilerCandidates[compilerCandidateName]
135
- if (typeof compilerCandidate !== "function") {
136
- throw new TypeError(
137
- `"${compilerCandidateName}" compiler is not a function, got ${compilerCandidate}`,
138
- )
139
- }
140
- const returnValue = compilerCandidate(compilerCandidateParams)
141
- if (returnValue && typeof returnValue === "object") {
142
- compilerOptions = returnValue
143
- return true
144
- }
145
- return false
149
+ writeOnFilesystem: true, // we always need them
150
+ useFilesystemAsCache,
151
+ compileCacheStrategy,
152
+ projectFileRequestedCallback,
153
+ request,
154
+ compile: ({ code, map }) => {
155
+ return compiler({
156
+ cancellationToken,
157
+ logger,
158
+
159
+ code,
160
+ map,
161
+ url: originalFileUrl,
162
+ compiledUrl: compiledFileUrl,
163
+ projectDirectoryUrl,
164
+ compileServerOrigin: request.origin,
165
+ outDirectoryRelativeUrl,
166
+ compileId,
167
+
168
+ runtimeSupport,
169
+ moduleOutFormat,
170
+ importMetaFormat,
171
+ transformTopLevelAwait,
172
+ babelPluginMap: compileIdToBabelPluginMap(compileId, {
173
+ babelPluginMap,
174
+ groupMap,
175
+ }),
176
+
177
+ sourcemapMethod: "comment", // "inline" is also possible
178
+ sourcemapExcludeSources,
179
+ jsenvToolbarInjection,
180
+ })
181
+ },
146
182
  })
183
+ return compileResponsePromise
184
+ }
185
+ }
147
186
 
148
- if (compilerOptions) {
149
- return compileFile({
150
- cancellationToken,
151
- logger,
187
+ const getCompiler = ({ originalFileUrl, compileMeta }) => {
188
+ const { jsenvCompiler, customCompiler } = urlToMeta({
189
+ url: originalFileUrl,
190
+ structuredMetaMap: compileMeta,
191
+ })
152
192
 
153
- projectDirectoryUrl,
154
- originalFileUrl,
155
- compiledFileUrl,
193
+ if (!jsenvCompiler && !customCompiler) {
194
+ return null
195
+ }
156
196
 
157
- writeOnFilesystem: true, // we always need them
158
- useFilesystemAsCache,
159
- compileCacheStrategy,
160
- projectFileRequestedCallback,
161
- request,
197
+ if (!jsenvCompiler && customCompiler) {
198
+ return customCompiler
199
+ }
162
200
 
163
- ...compilerOptions,
164
- })
165
- }
201
+ // there is only a jsenvCompiler
202
+ if (jsenvCompiler && !customCompiler) {
203
+ return jsenvCompiler
204
+ }
166
205
 
167
- // no compiler -> serve original file
168
- // we don't redirect otherwise it complexify ressource tracking
169
- // and url resolution
170
- return sourceFileService({
171
- ...request,
172
- ressource: `/${originalFileRelativeUrl}`,
206
+ // both project and jsenv wants to compile the file
207
+ // we'll do the custom compilation first, then jsenv compilation
208
+ return async (params) => {
209
+ const customResult = await customCompiler(params)
210
+ const jsenvResult = await jsenvCompiler({
211
+ ...params,
212
+ code: customResult.compiledSource,
213
+ map: customResult.sourcemap,
173
214
  })
215
+ return jsenvResult
216
+ }
217
+ }
218
+
219
+ const compileIdToBabelPluginMap = (compileId, { babelPluginMap, groupMap }) => {
220
+ const babelPluginMapForGroupMap = {}
221
+
222
+ const groupBabelPluginMap = {}
223
+ groupMap[compileId].babelPluginRequiredNameArray.forEach(
224
+ (babelPluginRequiredName) => {
225
+ if (babelPluginRequiredName in babelPluginMap) {
226
+ groupBabelPluginMap[babelPluginRequiredName] =
227
+ babelPluginMap[babelPluginRequiredName]
228
+ }
229
+ },
230
+ )
231
+
232
+ return {
233
+ ...groupBabelPluginMap,
234
+ ...babelPluginMapForGroupMap,
174
235
  }
175
236
  }
@@ -14,7 +14,7 @@ import { filePathToBabelHelperName } from "./babelHelper.js"
14
14
 
15
15
  export const jsenvTransform = async ({
16
16
  code,
17
- map,
17
+ map, // optional
18
18
  ast, // optional
19
19
  url,
20
20
  relativeUrl, // optional
@@ -1,8 +1,4 @@
1
- import {
2
- urlToRelativeUrl,
3
- normalizeStructuredMetaMap,
4
- urlToMeta,
5
- } from "@jsenv/filesystem"
1
+ import { urlToRelativeUrl } from "@jsenv/filesystem"
6
2
 
7
3
  import { jsenvTransform } from "./jsenvTransform.js"
8
4
 
@@ -10,11 +6,9 @@ export const transformJs = async ({
10
6
  code,
11
7
  map,
12
8
  url,
13
- urlAfterTransform,
14
9
  projectDirectoryUrl,
15
10
 
16
11
  babelPluginMap,
17
- convertMap = {},
18
12
  moduleOutFormat = "esmodule",
19
13
  importMetaFormat = moduleOutFormat,
20
14
  babelHelpersInjectionAsImport = true,
@@ -41,20 +35,6 @@ export const transformJs = async ({
41
35
  throw new TypeError(`url must be a string, got ${url}`)
42
36
  }
43
37
 
44
- const conversionResult = await applyConvertMap({
45
- code,
46
- map,
47
- url,
48
- urlAfterTransform,
49
- projectDirectoryUrl,
50
-
51
- convertMap,
52
- sourcemapEnabled,
53
- allowTopLevelAwait,
54
- })
55
- code = conversionResult.code
56
- map = conversionResult.map
57
-
58
38
  const transformResult = await jsenvTransform({
59
39
  code,
60
40
  map,
@@ -79,53 +59,3 @@ export const transformJs = async ({
79
59
  const { metadata } = transformResult
80
60
  return { code, map, metadata }
81
61
  }
82
-
83
- const applyConvertMap = async ({
84
- code,
85
- map,
86
- url,
87
- urlAfterTransform,
88
- projectDirectoryUrl,
89
-
90
- convertMap,
91
- remap,
92
- allowTopLevelAwait,
93
- }) => {
94
- const structuredMetaMap = normalizeStructuredMetaMap(
95
- {
96
- convert: convertMap,
97
- },
98
- projectDirectoryUrl,
99
- )
100
- const { convert } = urlToMeta({ url, structuredMetaMap })
101
- if (!convert) {
102
- return { code, map }
103
- }
104
-
105
- if (typeof convert !== "function") {
106
- throw new TypeError(`convert must be a function, got ${convert}`)
107
- }
108
- const convertReturnValue = await convert({
109
- code,
110
- map,
111
- url,
112
- urlAfterTransform,
113
- projectDirectoryUrl,
114
-
115
- remap,
116
- allowTopLevelAwait,
117
- })
118
- if (typeof convertReturnValue !== "object") {
119
- throw new TypeError(
120
- `convert must return an object, got ${convertReturnValue}`,
121
- )
122
- }
123
- code = convertReturnValue.code
124
- map = convertReturnValue.map
125
- if (typeof code !== "string") {
126
- throw new TypeError(
127
- `convert return value "code" property must be a string, got ${code}`,
128
- )
129
- }
130
- return { code, map }
131
- }