@jcoreio/toolchain-esnext 5.7.0 → 5.8.1

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": "@jcoreio/toolchain-esnext",
3
- "version": "5.7.0",
3
+ "version": "5.8.1",
4
4
  "description": "ESNext JS build toolchain",
5
5
  "repository": {
6
6
  "type": "git",
@@ -32,7 +32,8 @@
32
32
  "globals": "^16.0.0",
33
33
  "resolve": "^1.22.2",
34
34
  "resolve-bin": "^1.0.0",
35
- "@jcoreio/toolchain": "5.7.0"
35
+ "semver": "^7.5.3",
36
+ "@jcoreio/toolchain": "5.8.1"
36
37
  },
37
38
  "toolchainManaged": {
38
39
  "dependencies": {
@@ -17,16 +17,12 @@ module.exports = [
17
17
 
18
18
  return [
19
19
  require.resolve('@babel/plugin-transform-runtime'),
20
- // for CJS tests, we leave off import extensions, since @babel/register resolves them.
21
- // for ESM tests, we resolve to .js for babel-register-esm.
22
- // for CJS build, we resolve to .js.
23
- // for ESM build, we resolve to .mjs.
24
- ((JCOREIO_TOOLCHAIN_CJS && !JCOREIO_TOOLCHAIN_TEST) ||
25
- JCOREIO_TOOLCHAIN_ESM) && [
20
+ (JCOREIO_TOOLCHAIN_CJS || JCOREIO_TOOLCHAIN_ESM) && [
26
21
  require.resolve('../util/babelPluginResolveImports.cjs'),
27
22
  {
28
23
  outputExtension:
29
- JCOREIO_TOOLCHAIN_ESM && !JCOREIO_TOOLCHAIN_TEST ? esmExtension
24
+ JCOREIO_TOOLCHAIN_TEST ? undefined
25
+ : JCOREIO_TOOLCHAIN_ESM ? esmExtension
30
26
  : JCOREIO_TOOLCHAIN_CJS ? cjsExtension
31
27
  : packageJson.type === 'module' ? esmExtension
32
28
  : cjsExtension,
@@ -1,6 +1,6 @@
1
1
  const execa = require('@jcoreio/toolchain/util/execa.cjs')
2
2
  const fs = require('@jcoreio/toolchain/util/projectFs.cjs')
3
- const { glob } = require('@jcoreio/toolchain/util/glob.cjs')
3
+ const { glob, globIterate } = require('@jcoreio/toolchain/util/glob.cjs')
4
4
  const buildGlobOpts = require('@jcoreio/toolchain/util/buildGlobOpts.cjs')
5
5
  const path = require('path')
6
6
  const dedent = require('dedent-js')
@@ -12,32 +12,56 @@ const {
12
12
  const getPluginsArraySync = require('@jcoreio/toolchain/util/getPluginsArraySync.cjs')
13
13
  const fixSourceMaps = require('../util/fixSourceMaps.cjs')
14
14
 
15
+ async function hasSourceFilesForExtension(extension) {
16
+ const ignore = [
17
+ ...(toolchainConfig.buildIgnore || []),
18
+ ...(/\.[cm]?ts$/i.test(extension) ? [`**/*.d${extension}`] : []),
19
+ ]
20
+ for await (const file of globIterate(`src/**/*${extension}`, {
21
+ ignore: ignore.length ? ignore : undefined,
22
+ })) {
23
+ return true
24
+ }
25
+ return false
26
+ }
27
+
15
28
  module.exports = [
16
29
  [
17
30
  async function compile(args = []) {
18
- const extensions = getPluginsArraySync('babelExtensions')
19
-
20
- await execa(
21
- 'babel',
22
- [
23
- 'src',
24
- ...(extensions.length ? ['--extensions', extensions.join(',')] : []),
25
- ...(extensions.includes('.ts') ? ['--ignore', '**/*.d.ts'] : []),
26
- ...(toolchainConfig.buildIgnore || []).flatMap((pattern) => [
27
- '--ignore',
28
- pattern,
29
- ]),
30
- '--out-dir',
31
- 'dist',
32
- '--out-file-extension',
33
- packageJson.type === 'module' ? '.cjs' : '.js',
34
- ...(toolchainConfig.sourceMaps ?
35
- ['--source-maps', toolchainConfig.sourceMaps]
36
- : []),
37
- ],
38
- { env: { ...process.env, JCOREIO_TOOLCHAIN_CJS: '1' } }
31
+ const extensions = getPluginsArraySync('sourceExtensions').map(
32
+ (ext) => `.${ext}`
39
33
  )
40
34
 
35
+ for (const extension of extensions) {
36
+ if (extension.startsWith('.m')) continue
37
+ if (!(await hasSourceFilesForExtension(extension))) continue
38
+ await execa(
39
+ 'babel',
40
+ [
41
+ 'src',
42
+ '--extensions',
43
+ extension,
44
+ ...(/\.[cm]?ts$/i.test(extension) ?
45
+ ['--ignore', '**/*.d' + extension]
46
+ : []),
47
+ ...(toolchainConfig.buildIgnore || []).flatMap((pattern) => [
48
+ '--ignore',
49
+ pattern,
50
+ ]),
51
+ '--out-dir',
52
+ 'dist',
53
+ '--out-file-extension',
54
+ /\.c[tj]sx?$/i.test(extension) || packageJson.type === 'module' ?
55
+ '.cjs'
56
+ : '.js',
57
+ ...(toolchainConfig.sourceMaps ?
58
+ ['--source-maps', toolchainConfig.sourceMaps]
59
+ : []),
60
+ ],
61
+ { env: { ...process.env, JCOREIO_TOOLCHAIN_CJS: '1' } }
62
+ )
63
+ }
64
+
41
65
  const jsFiles = await glob(path.join('dist', '**', '*.js'))
42
66
  if (toolchainConfig.outputEsm !== false) {
43
67
  if (toolchainConfig.esWrapper) {
@@ -56,27 +80,35 @@ module.exports = [
56
80
  )
57
81
  )
58
82
  } else {
59
- await execa(
60
- 'babel',
61
- [
62
- 'src',
63
- ...(extensions.length ?
64
- ['--extensions', extensions.join(',')]
65
- : []),
66
- ...(toolchainConfig.buildIgnore || []).flatMap((pattern) => [
67
- '--ignore',
68
- pattern,
69
- ]),
70
- '--out-dir',
71
- 'dist',
72
- '--out-file-extension',
73
- packageJson.type === 'module' ? '.js' : '.mjs',
74
- ...(toolchainConfig.sourceMaps ?
75
- ['--source-maps', toolchainConfig.sourceMaps]
76
- : []),
77
- ],
78
- { env: { ...process.env, JCOREIO_TOOLCHAIN_ESM: '1' } }
79
- )
83
+ for (const extension of extensions) {
84
+ if (extension.startsWith('.c')) continue
85
+ if (!(await hasSourceFilesForExtension(extension))) continue
86
+ await execa(
87
+ 'babel',
88
+ [
89
+ 'src',
90
+ '--extensions',
91
+ extension,
92
+ ...(/\.[cm]?ts$/i.test(extension) ?
93
+ ['--ignore', '**/*.d' + extension]
94
+ : []),
95
+ ...(toolchainConfig.buildIgnore || []).flatMap((pattern) => [
96
+ '--ignore',
97
+ pattern,
98
+ ]),
99
+ '--out-dir',
100
+ 'dist',
101
+ '--out-file-extension',
102
+ /\.m[tj]sx?$/.test(extension) || packageJson.type !== 'module' ?
103
+ '.mjs'
104
+ : '.js',
105
+ ...(toolchainConfig.sourceMaps ?
106
+ ['--source-maps', toolchainConfig.sourceMaps]
107
+ : []),
108
+ ],
109
+ { env: { ...process.env, JCOREIO_TOOLCHAIN_ESM: '1' } }
110
+ )
111
+ }
80
112
  }
81
113
  }
82
114
 
@@ -1,48 +1,51 @@
1
1
  import path from 'path'
2
2
  import { fileURLToPath, pathToFileURL } from 'url'
3
- import { resolve, load as wrappedLoad } from 'babel-register-esm'
4
- import fs from 'fs-extra'
5
- import { packageJson, projectDir } from '@jcoreio/toolchain/util/findUps.cjs'
6
- import hasTSSources from '@jcoreio/toolchain/util/hasTSSources.cjs'
3
+ import { resolve as baseResolve, load as wrappedLoad } from 'babel-register-esm'
4
+ import { projectDir } from '@jcoreio/toolchain/util/findUps.cjs'
5
+ import resolveAltType from './resolveAltType.cjs'
7
6
 
8
7
  const projectDirPrefix = pathToFileURL(projectDir) + '/'
9
8
 
10
- export { resolve }
9
+ export async function resolve(specifier, context, nextResolve) {
10
+ if (
11
+ specifier.startsWith('.') &&
12
+ context.parentURL.startsWith('file:') &&
13
+ !context.parentURL.includes('/node_modules/')
14
+ ) {
15
+ const basedir = path.dirname(fileURLToPath(context.parentURL))
16
+ const altTypeResolved = resolveAltType(specifier, basedir)
17
+ if (altTypeResolved) {
18
+ return {
19
+ url: new URL(altTypeResolved, context.parentURL).toString(),
20
+ shortCircuit: true,
21
+ format:
22
+ process.env.JCOREIO_TOOLCHAIN_CJS ? 'commonjs'
23
+ : process.env.JCOREIO_TOOLCHAIN_ESM ? 'module'
24
+ : context.format,
25
+ }
26
+ }
27
+ }
28
+ return await baseResolve(specifier, context, nextResolve)
29
+ }
11
30
 
12
31
  export async function load(url, context, nextLoad) {
13
32
  if (!url.startsWith('file:') || url.includes('/node_modules/')) {
14
33
  return await nextLoad(url, context)
15
34
  }
16
- const file = fileURLToPath(url)
17
- // some versions of node support --experimental-default-type, but it was removed in Node 23.
18
- // Since we allow the project to omit `type` in `package.json` and transpile the same source
19
- // code to CJS and ESM, we need to set the module type based upon the mode the toolchain is
20
- // running in here for Node >=23.
21
- if (context.format == null && url.startsWith(projectDirPrefix)) {
22
- const extension = path.extname(file)
23
- if (
24
- extension === '.ts' ||
25
- extension === '.tsx' ||
26
- (!(await hasTSSources()) && (extension === '.js' || extension === '.jsx'))
27
- ) {
28
- return await wrappedLoad(
29
- url,
30
- {
31
- ...context,
32
- format:
33
- (
34
- extension.startsWith('.js') &&
35
- packageJson.type !== 'module' &&
36
- (await fs.pathExists(file)) &&
37
- !(await hasTSSources())
38
- ) ?
39
- 'commonjs'
40
- : process.env.JCOREIO_TOOLCHAIN_ESM ? 'module'
41
- : 'commonjs',
42
- },
43
- nextLoad
44
- )
45
- }
35
+ const extension = path.extname(url)
36
+ if (
37
+ process.env.JCOREIO_TOOLCHAIN_ESM &&
38
+ url.startsWith(projectDirPrefix) &&
39
+ (!extension || /\.m?[jt]sx?$/i.test(extension))
40
+ ) {
41
+ context = { ...context, format: 'module' }
42
+ }
43
+ if (
44
+ process.env.JCOREIO_TOOLCHAIN_CJS &&
45
+ url.startsWith(projectDirPrefix) &&
46
+ (!extension || /\.c?[jt]sx?$/i.test(extension))
47
+ ) {
48
+ context = { ...context, format: 'commonjs' }
46
49
  }
47
50
  return await wrappedLoad(url, context, nextLoad)
48
51
  }
@@ -9,13 +9,17 @@ module.exports = async function fixSourceMaps() {
9
9
  await Promise.all(
10
10
  mapFiles.map(async (file) => {
11
11
  const content = await fs.readJson(file)
12
- const { sources } = content
12
+ const { sources, sourcesContent } = content
13
13
  let changed = false
14
14
  for (let i = 0; i < sources.length; i++) {
15
15
  if (sources[i].startsWith('../src/')) {
16
16
  changed = true
17
17
  sources[i] = sources[i].substring('../'.length)
18
18
  }
19
+ if (sourcesContent && sourcesContent[i] != null) {
20
+ changed = true
21
+ sourcesContent[i] = null
22
+ }
19
23
  }
20
24
  if (changed) await fs.writeJson(file, content)
21
25
  })
@@ -0,0 +1,41 @@
1
+ const path = require('path')
2
+ const fs = require('fs-extra')
3
+ const { packageJson } = require('@jcoreio/toolchain/util/findUps.cjs')
4
+ const hasTSSourcesSync = require('@jcoreio/toolchain/util/hasTSSourcesSync.cjs')
5
+
6
+ const isActive =
7
+ (packageJson.type === 'module' && process.env.JCOREIO_TOOLCHAIN_CJS) ||
8
+ (packageJson.type !== 'module' && process.env.JCOREIO_TOOLCHAIN_ESM)
9
+
10
+ module.exports = function resolveAltType(specifier, basedir) {
11
+ if (
12
+ !isActive ||
13
+ !specifier.startsWith('.') ||
14
+ !/\.[tj]sx?$/i.test(specifier)
15
+ ) {
16
+ return undefined
17
+ }
18
+ // if .js/.ts, project is CJS and output mode is ESM, see if there's a .mjs/.mts file.
19
+ // if .js/.ts, project is ESM and output mode is CJS, see if there's a .cjs/.cts file.
20
+ // same for tsx/jsx
21
+ const otherTypeSpecifier = specifier.replace(
22
+ /\.([^.]+)$/,
23
+ packageJson.type === 'module' ? '.c$1' : '.m$1'
24
+ )
25
+ if (fs.pathExistsSync(path.resolve(basedir, otherTypeSpecifier))) {
26
+ return otherTypeSpecifier
27
+ }
28
+ if (hasTSSourcesSync() && /\.tsx?$/i.test(specifier)) {
29
+ // if .ts, project is CJS and output mode is ESM, see if there's a .mjs file.
30
+ // if .ts, project is ESM and output mode is CJS, see if there's a .cjs file.
31
+ // same for tsx/jsx
32
+ const otherTypeSpecifier = specifier.replace(
33
+ /\.t([^.]+)$/,
34
+ packageJson.type === 'module' ? '.cj$1' : '.mj$1'
35
+ )
36
+ if (fs.pathExistsSync(path.resolve(basedir, otherTypeSpecifier))) {
37
+ return otherTypeSpecifier
38
+ }
39
+ }
40
+ return undefined
41
+ }
@@ -2,12 +2,18 @@ const resolve = require('resolve/sync')
2
2
  const path = require('path')
3
3
  const fs = require('fs-extra')
4
4
  const builtinModules = new Set(require('module').builtinModules)
5
+ const resolveAltType = require('./resolveAltType.cjs')
5
6
 
6
7
  module.exports = function resolveImportSource({
7
8
  file,
8
9
  source,
9
10
  outputExtension,
10
11
  }) {
12
+ const basedir = path.dirname(file)
13
+
14
+ const altTypeResolved = resolveAltType(source, basedir)
15
+ if (altTypeResolved) return altTypeResolved
16
+
11
17
  if (
12
18
  /(\.d\.ts|\.[cm]?jsx?)$/i.test(source) ||
13
19
  source.startsWith('node:') ||
@@ -16,7 +22,6 @@ module.exports = function resolveImportSource({
16
22
  return source
17
23
  }
18
24
 
19
- const basedir = path.dirname(file)
20
25
  if (source.startsWith('.')) {
21
26
  if (/\.[cm]?tsx?$/i.test(source) && /\.d\.[cm]?ts$/i.test(file)) {
22
27
  source = source.replace(/\.[^.]+$/, '')