@jsenv/core 27.0.0-alpha.6 → 27.0.0-alpha.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "27.0.0-alpha.6",
3
+ "version": "27.0.0-alpha.9",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -185,28 +185,38 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
185
185
  }
186
186
  Object.keys(rawGraph.urlInfos).forEach((rawUrl) => {
187
187
  const rawUrlInfo = rawGraph.getUrlInfo(rawUrl)
188
- if (!rawUrlInfo.data.isEntryPoint) {
189
- return
190
- }
191
- addToBundlerIfAny(rawUrlInfo)
192
- if (rawUrlInfo.type === "html") {
193
- rawUrlInfo.dependencies.forEach((dependencyUrl) => {
194
- const dependencyUrlInfo = rawGraph.getUrlInfo(dependencyUrl)
195
- if (dependencyUrlInfo.isInline) {
196
- if (dependencyUrlInfo.type === "js_module") {
197
- // bundle inline script type module deps
198
- dependencyUrlInfo.references.forEach((inlineScriptRef) => {
199
- if (inlineScriptRef.type === "js_import_export") {
200
- addToBundlerIfAny(rawGraph.getUrlInfo(inlineScriptRef.url))
201
- }
202
- })
188
+ if (rawUrlInfo.data.isEntryPoint) {
189
+ addToBundlerIfAny(rawUrlInfo)
190
+ if (rawUrlInfo.type === "html") {
191
+ rawUrlInfo.dependencies.forEach((dependencyUrl) => {
192
+ const dependencyUrlInfo = rawGraph.getUrlInfo(dependencyUrl)
193
+ if (dependencyUrlInfo.isInline) {
194
+ if (dependencyUrlInfo.type === "js_module") {
195
+ // bundle inline script type module deps
196
+ dependencyUrlInfo.references.forEach((inlineScriptRef) => {
197
+ if (inlineScriptRef.type === "js_import_export") {
198
+ addToBundlerIfAny(rawGraph.getUrlInfo(inlineScriptRef.url))
199
+ }
200
+ })
201
+ }
202
+ // inline content cannot be bundled
203
+ return
203
204
  }
204
- // inline content cannot be bundled
205
- return
205
+ addToBundlerIfAny(dependencyUrlInfo)
206
+ })
207
+ return
208
+ }
209
+ }
210
+ // File referenced with new URL('./file.js', import.meta.url)
211
+ // are entry points that can be bundled
212
+ // For instance we will bundle service worker/workers detected like this
213
+ if (rawUrlInfo.type === "js_module") {
214
+ rawUrlInfo.references.forEach((reference) => {
215
+ if (reference.type === "js_import_meta_url_pattern") {
216
+ const urlInfo = rawGraph.getUrlInfo(reference.url)
217
+ addToBundlerIfAny(urlInfo)
206
218
  }
207
- addToBundlerIfAny(dependencyUrlInfo)
208
219
  })
209
- return
210
220
  }
211
221
  })
212
222
  await Object.keys(bundlers).reduce(async (previous, type) => {
@@ -131,15 +131,6 @@ const rollupPluginJsenv = ({
131
131
  const rollupFileInfo = rollupResult[fileName]
132
132
  // there is 3 types of file: "placeholder", "asset", "chunk"
133
133
  if (rollupFileInfo.type === "chunk") {
134
- const { facadeModuleId } = rollupFileInfo
135
- let url
136
- if (facadeModuleId) {
137
- url = fileUrlConverter.asFileUrl(facadeModuleId)
138
- } else {
139
- const { sources } = rollupFileInfo.map
140
- const sourcePath = sources[sources.length - 1]
141
- url = fileUrlConverter.asFileUrl(sourcePath)
142
- }
143
134
  const jsModuleBundleUrlInfo = {
144
135
  // buildRelativeUrl: rollupFileInfo.fileName,
145
136
  data: {
@@ -149,6 +140,12 @@ const rollupPluginJsenv = ({
149
140
  content: rollupFileInfo.code,
150
141
  sourcemap: rollupFileInfo.map,
151
142
  }
143
+ let url
144
+ if (rollupFileInfo.facadeModuleId) {
145
+ url = fileUrlConverter.asFileUrl(rollupFileInfo.facadeModuleId)
146
+ } else {
147
+ url = new URL(rollupFileInfo.fileName, rootDirectoryUrl).href
148
+ }
152
149
  jsModuleBundleUrlInfos[url] = jsModuleBundleUrlInfo
153
150
  }
154
151
  })
@@ -171,13 +168,18 @@ const rollupPluginJsenv = ({
171
168
  },
172
169
  chunkFileNames: (chunkInfo) => {
173
170
  // preserves relative path parts:
174
- // the goal is to mantain the original relative path (relative to the root directory)
171
+ // the goal is to maintain the original relative path (relative to the root directory)
175
172
  // so that later in the build process, when resolving these urls, we are able to
176
173
  // re-resolve the specifier againt the original parent url and find the original url
177
- const { facadeModuleId } = chunkInfo
178
- const fileUrl = fileUrlConverter.asFileUrl(facadeModuleId)
179
- const relativePath = urlToRelativeUrl(fileUrl, rootDirectoryUrl)
180
- return relativePath
174
+ if (chunkInfo.facadeModuleId) {
175
+ const fileUrl = fileUrlConverter.asFileUrl(chunkInfo.facadeModuleId)
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`
181
183
  },
182
184
  // https://rollupjs.org/guide/en/#outputpaths
183
185
  // paths: (id) => {
@@ -10,10 +10,7 @@ export const getBaseBabelPluginStructure = ({
10
10
  isJsModule,
11
11
  }) => {
12
12
  const isBabelPluginNeeded = (babelPluginName) => {
13
- return !isSupportedOnRuntime(
14
- babelPluginName,
15
- babelPluginCompatMap[babelPluginName],
16
- )
13
+ return !isSupportedOnRuntime(babelPluginCompatMap[babelPluginName])
17
14
  }
18
15
 
19
16
  const babelPluginStructure = {}
@@ -1,5 +1,6 @@
1
1
  import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
2
2
 
3
+ import { RUNTIME_SUPPORT } from "@jsenv/core/src/omega/runtime_support/runtime_support.js"
3
4
  import { getBaseBabelPluginStructure } from "./helpers/babel_plugin_structure.js"
4
5
  import { babelPluginBabelHelpersAsJsenvImports } from "./helpers/babel_plugin_babel_helpers_as_jsenv_imports.js"
5
6
  import { babelPluginNewStylesheetAsJsenvImport } from "./new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js"
@@ -12,16 +13,29 @@ export const jsenvPluginBabel = ({
12
13
  } = {}) => {
13
14
  const transformWithBabel = async (urlInfo, context) => {
14
15
  const isJsModule = urlInfo.type === "js_module"
15
- const isWorker =
16
- urlInfo.subtype === "worker" || urlInfo.subtype === "service_worker"
17
- const { isSupportedOnRuntime, referenceUtils } = context
16
+ const isWorker = urlInfo.subtype === "worker"
17
+ const isServiceWorker = urlInfo.subtype === "service_worker"
18
+ const isWorkerContext = isWorker || isServiceWorker
19
+ let { runtimeSupport } = context
20
+ if (isServiceWorker) {
21
+ // when code is executed by a service worker we can assume
22
+ // the execution context supports more than the default one
23
+ // for instance arrow function are supported
24
+ runtimeSupport = RUNTIME_SUPPORT.add(runtimeSupport, "service_worker")
25
+ }
26
+ if (isWorker) {
27
+ runtimeSupport = RUNTIME_SUPPORT.add(runtimeSupport, "worker")
28
+ }
29
+ const { referenceUtils } = context
30
+ const isSupportedOnRuntime = (feature) =>
31
+ RUNTIME_SUPPORT.isSupported(runtimeSupport, feature)
18
32
  const babelPluginStructure = getBaseBabelPluginStructure({
19
33
  url: urlInfo.url,
20
34
  isSupportedOnRuntime,
21
35
  topLevelAwait,
22
36
  usesTopLevelAwait: urlInfo.data.usesTopLevelAwait,
23
37
  isJsModule,
24
- isWorker,
38
+ isWorkerContext,
25
39
  })
26
40
  if (getCustomBabelPlugins) {
27
41
  Object.assign(babelPluginStructure, getCustomBabelPlugins(context))
@@ -52,10 +52,7 @@ export const jsenvPluginNewInlineContent = ({ allowEscapeForVersioning }) => {
52
52
  columnEnd: inlineContentCall.columnEnd,
53
53
  })
54
54
  let { quote } = inlineContentCall
55
- if (
56
- quote === "`" &&
57
- !isSupportedOnRuntime("transform-template-literals")
58
- ) {
55
+ if (quote === "`" && !isSupportedOnRuntime("template_literals")) {
59
56
  // if quote is "`" and template literals are not supported
60
57
  // we'll use a regular string (single or double quote)
61
58
  // when rendering the string
@@ -10,8 +10,7 @@ import {
10
10
  import { stringifyUrlSite } from "@jsenv/utils/urls/url_trace.js"
11
11
 
12
12
  import { createUrlInfoTransformer } from "./url_graph/url_info_transformations.js"
13
- import { featuresCompatMap } from "./runtime_support/features_compatibility.js"
14
- import { isFeatureSupportedOnRuntimes } from "./runtime_support/runtime_support.js"
13
+ import { RUNTIME_SUPPORT } from "./runtime_support/runtime_support.js"
15
14
  import { fileUrlConverter } from "./file_url_converter.js"
16
15
  import { parseUrlMentions } from "./url_mentions/parse_url_mentions.js"
17
16
  import {
@@ -185,14 +184,6 @@ export const createKitchen = ({
185
184
  },
186
185
  })
187
186
 
188
- const isSupported = ({
189
- runtimeSupport,
190
- featureName,
191
- featureCompat = featuresCompatMap[featureName],
192
- }) => {
193
- return isFeatureSupportedOnRuntimes(runtimeSupport, featureCompat)
194
- }
195
-
196
187
  const load = async ({ reference, urlInfo, context }) => {
197
188
  try {
198
189
  const loadReturnValue = urlInfo.isInline
@@ -274,8 +265,8 @@ export const createKitchen = ({
274
265
  reference,
275
266
  outDirectoryUrl,
276
267
  runtimeSupport,
277
- isSupportedOnRuntime: (featureName, featureCompat) => {
278
- return isSupported({ runtimeSupport, featureName, featureCompat })
268
+ isSupportedOnRuntime: (feature) => {
269
+ return RUNTIME_SUPPORT.isSupported(runtimeSupport, feature)
279
270
  },
280
271
  cook: (params) => {
281
272
  return cookDuringCook({
@@ -585,7 +576,6 @@ export const createKitchen = ({
585
576
  urlInfoTransformer,
586
577
  rootDirectoryUrl,
587
578
  jsenvDirectoryUrl,
588
- isSupported,
589
579
  createReference,
590
580
  resolveReference,
591
581
  cook,
@@ -1,4 +1,4 @@
1
- export const featuresCompatMap = {
1
+ export const featureCompats = {
2
2
  script_type_module: {
3
3
  edge: "16",
4
4
  firefox: "60",
@@ -52,6 +52,7 @@ export const featuresCompatMap = {
52
52
  chrome: "93",
53
53
  edge: "93",
54
54
  },
55
+ import_type_text: {},
55
56
  // https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet#browser_compatibility
56
57
  new_stylesheet: {
57
58
  chrome: "73",
@@ -59,6 +60,33 @@ export const featuresCompatMap = {
59
60
  opera: "53",
60
61
  android: "73",
61
62
  },
63
+ // https://caniuse.com/?search=worker
64
+ worker: {
65
+ ie: "10",
66
+ edge: "12",
67
+ firefox: "3.5",
68
+ chrome: "4",
69
+ opera: "11.5",
70
+ safari: "4",
71
+ ios: "5",
72
+ android: "4.4",
73
+ },
74
+ service_worker: {
75
+ edge: "17",
76
+ firefox: "44",
77
+ chrome: "40",
78
+ safari: "11.1",
79
+ opera: "27",
80
+ ios: "11.3",
81
+ android: "12.12",
82
+ },
83
+ service_worker_type_module: {
84
+ chrome: "80",
85
+ edge: "80",
86
+ opera: "67",
87
+ android: "80",
88
+ },
89
+ // https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker#browser_compatibility
62
90
  worker_type_module: {
63
91
  chrome: "80",
64
92
  edge: "80",
@@ -88,4 +116,15 @@ export const featuresCompatMap = {
88
116
  samsung: "8",
89
117
  electron: "3",
90
118
  },
119
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#browser_compatibility
120
+ template_literals: {
121
+ chrome: "41",
122
+ edge: "12",
123
+ firefox: "34",
124
+ opera: "28",
125
+ safari: "9",
126
+ ios: "9",
127
+ android: "4",
128
+ node: "4",
129
+ },
91
130
  }
@@ -1,20 +1,52 @@
1
1
  import { findHighestVersion } from "@jsenv/utils/semantic_versioning/highest_version.js"
2
+ import { featureCompats } from "./features_compatibility.js"
2
3
 
3
- export const isFeatureSupportedOnRuntimes = (
4
- runtimeSupport,
5
- featureCompat = {},
6
- ) => {
7
- const runtimeNames = Object.keys(runtimeSupport)
8
- return runtimeNames.every((runtimeName) => {
9
- const runtimeVersion = runtimeSupport[runtimeName]
10
- const runtimeVersionCompatible = featureCompat[runtimeName] || "Infinity"
11
- const highestVersion = findHighestVersion(
12
- runtimeVersion,
13
- runtimeVersionCompatible,
14
- )
15
- if (highestVersion !== runtimeVersion) {
16
- return false
4
+ export const RUNTIME_SUPPORT = {
5
+ featureCompats,
6
+
7
+ add: (originalRuntimeSupport, feature) => {
8
+ const featureCompat = getFeatureCompat(feature)
9
+ const runtimeSupport = {
10
+ ...originalRuntimeSupport,
11
+ }
12
+ Object.keys(featureCompat).forEach((runtimeName) => {
13
+ const firstVersion = originalRuntimeSupport[runtimeName]
14
+ const secondVersion = featureCompat[runtimeName]
15
+ runtimeSupport[runtimeName] = firstVersion
16
+ ? findHighestVersion(firstVersion, secondVersion)
17
+ : secondVersion
18
+ })
19
+ return runtimeSupport
20
+ },
21
+
22
+ isSupported: (runtimeSupport, feature) => {
23
+ const featureCompat = getFeatureCompat(feature)
24
+ const runtimeNames = Object.keys(runtimeSupport)
25
+ return runtimeNames.every((runtimeName) => {
26
+ const runtimeVersion = runtimeSupport[runtimeName]
27
+ const runtimeVersionCompatible = featureCompat[runtimeName] || "Infinity"
28
+ const highestVersion = findHighestVersion(
29
+ runtimeVersion,
30
+ runtimeVersionCompatible,
31
+ )
32
+ if (highestVersion !== runtimeVersion) {
33
+ return false
34
+ }
35
+ return true
36
+ })
37
+ },
38
+ }
39
+
40
+ const getFeatureCompat = (feature) => {
41
+ if (typeof feature === "string") {
42
+ const compat = featureCompats[feature]
43
+ if (!compat) {
44
+ throw new Error(`"${feature}" feature is unknown`)
17
45
  }
18
- return true
19
- })
46
+ return compat
47
+ }
48
+ if (typeof feature !== "object") {
49
+ throw new TypeError(`feature must be a string or an object, got ${feature}`)
50
+ }
51
+ return feature
20
52
  }