@jcoreio/toolchain-esnext 1.0.0-beta.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/.babelrc.cjs +8 -0
- package/bin/babel +5 -0
- package/bin/babel-node +5 -0
- package/bin/resolveBin.cjs +8 -0
- package/eslint.extends.cjs +9 -0
- package/package.json +43 -0
- package/plugins/babelPlugins.cjs +11 -0
- package/plugins/babelPresets.cjs +23 -0
- package/plugins/bootstrapProjectPackageJson.cjs +7 -0
- package/plugins/buildDistPackageJson.cjs +46 -0
- package/plugins/compile.cjs +62 -0
- package/plugins/configureMocha.cjs +11 -0
- package/plugins/getConfigFiles.cjs +25 -0
- package/plugins/getEslintExtends.cjs +1 -0
- package/util/getImportSources.cjs +30 -0
- package/util/resolveImportSource.cjs +35 -0
- package/util/resolveImportsCodemod.cjs +18 -0
- package/util/transformImportSources.cjs +35 -0
package/.babelrc.cjs
ADDED
package/bin/babel
ADDED
package/bin/babel-node
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jcoreio/toolchain-esnext",
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
|
+
"description": "ESNext JS build toolchain",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/jcoreio/toolchains.git",
|
|
8
|
+
"directory": "packages/esnext"
|
|
9
|
+
},
|
|
10
|
+
"author": "Andy Edwards",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/jcoreio/toolchains/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/jcoreio/toolchains/tree/beta/packages/esnext",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@babel/cli": "^7.16.0",
|
|
18
|
+
"@babel/core": "^7.16.5",
|
|
19
|
+
"@babel/eslint-parser": "^7.16.5",
|
|
20
|
+
"@babel/node": "^7.16.5",
|
|
21
|
+
"@babel/plugin-transform-runtime": "^7.16.5",
|
|
22
|
+
"@babel/preset-env": "^7.16.5",
|
|
23
|
+
"@babel/register": "^7.16.5",
|
|
24
|
+
"@babel/runtime": "^7.18.6",
|
|
25
|
+
"@babel/traverse": "^7.22.1",
|
|
26
|
+
"babel-parse-wild-code": "^2.1.3",
|
|
27
|
+
"babel-plugin-add-module-exports": "^1.0.4",
|
|
28
|
+
"babel-plugin-istanbul": "^6.1.1",
|
|
29
|
+
"dedent-js": "^1.0.1",
|
|
30
|
+
"eslint": "^8.5.0",
|
|
31
|
+
"fs-extra": "^10.0.0",
|
|
32
|
+
"glob": "^7.2.0",
|
|
33
|
+
"resolve": "^1.22.2",
|
|
34
|
+
"resolve-bin": "^1.0.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"@jcoreio/toolchain": "1.0.0-beta.1"
|
|
38
|
+
},
|
|
39
|
+
"bin": {
|
|
40
|
+
"babel": "./bin/babel",
|
|
41
|
+
"babel-node": "./bin/babel-node"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module.exports = [
|
|
2
|
+
(api) => {
|
|
3
|
+
const { JCOREIO_TOOLCHAIN_MJS } = process.env
|
|
4
|
+
api.cache.using(() => JCOREIO_TOOLCHAIN_MJS)
|
|
5
|
+
return [
|
|
6
|
+
require.resolve('@babel/plugin-transform-runtime'),
|
|
7
|
+
!JCOREIO_TOOLCHAIN_MJS &&
|
|
8
|
+
require.resolve('babel-plugin-add-module-exports'),
|
|
9
|
+
].filter(Boolean)
|
|
10
|
+
},
|
|
11
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const { toolchainConfig } = require('@jcoreio/toolchain/util/findUps.cjs')
|
|
2
|
+
|
|
3
|
+
module.exports = [
|
|
4
|
+
(api) => {
|
|
5
|
+
const { JCOREIO_TOOLCHAIN_MJS } = process.env
|
|
6
|
+
api.cache.using(() => JCOREIO_TOOLCHAIN_MJS)
|
|
7
|
+
return [
|
|
8
|
+
[
|
|
9
|
+
require.resolve('@babel/preset-env'),
|
|
10
|
+
{
|
|
11
|
+
...(JCOREIO_TOOLCHAIN_MJS
|
|
12
|
+
? toolchainConfig.mjsBabelEnv || {
|
|
13
|
+
targets: {
|
|
14
|
+
node: 16,
|
|
15
|
+
},
|
|
16
|
+
}
|
|
17
|
+
: toolchainConfig.cjsBabelEnv || { forceAllTransforms: true }),
|
|
18
|
+
modules: JCOREIO_TOOLCHAIN_MJS ? false : 'auto',
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const glob = require('@jcoreio/toolchain/util/glob.cjs')
|
|
2
|
+
const Path = require('path')
|
|
3
|
+
const fs = require('@jcoreio/toolchain/util/projectFs.cjs')
|
|
4
|
+
|
|
5
|
+
module.exports = [
|
|
6
|
+
[
|
|
7
|
+
async function buildDistPackageJson(packageJson) {
|
|
8
|
+
const files = await glob(Path.join('dist', '**', '*.{js,cjs,mjs,d.ts}'))
|
|
9
|
+
const exportMap = { './package.json': './package.json' }
|
|
10
|
+
let usesBabelRuntime = false
|
|
11
|
+
for (const file of files) {
|
|
12
|
+
const key = `./${Path.relative('dist', file).replace(
|
|
13
|
+
/(\.[^/.]*)*$/,
|
|
14
|
+
''
|
|
15
|
+
)}`.replace(/\/index$/, '')
|
|
16
|
+
const forFile = exportMap[key] || (exportMap[key] = {})
|
|
17
|
+
forFile[
|
|
18
|
+
/\.d\.ts$/.test(file)
|
|
19
|
+
? 'types'
|
|
20
|
+
: /\.c?js$/.test(file)
|
|
21
|
+
? 'require'
|
|
22
|
+
: 'import'
|
|
23
|
+
] = `./${file}`
|
|
24
|
+
usesBabelRuntime =
|
|
25
|
+
usesBabelRuntime ||
|
|
26
|
+
// this could return false positives in rare cases, but keeps the test simple
|
|
27
|
+
(await fs.readFile(file)).includes('@babel/runtime')
|
|
28
|
+
}
|
|
29
|
+
if (!packageJson.exports) {
|
|
30
|
+
packageJson.exports = exportMap
|
|
31
|
+
}
|
|
32
|
+
const indexExport = exportMap['.']
|
|
33
|
+
if (indexExport) {
|
|
34
|
+
if (indexExport.require) packageJson.main = indexExport.require
|
|
35
|
+
if (indexExport.import) packageJson.module = indexExport.import
|
|
36
|
+
if (indexExport.types) packageJson.types = indexExport.types
|
|
37
|
+
}
|
|
38
|
+
packageJson.main = indexExport.require
|
|
39
|
+
if (!usesBabelRuntime) {
|
|
40
|
+
const { dependencies } = packageJson
|
|
41
|
+
if (dependencies) delete dependencies['@babel/runtime']
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
{ after: '@jcoreio/toolchain' },
|
|
45
|
+
],
|
|
46
|
+
]
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const execa = require('@jcoreio/toolchain/util/execa.cjs')
|
|
2
|
+
const fs = require('@jcoreio/toolchain/util/projectFs.cjs')
|
|
3
|
+
const glob = require('@jcoreio/toolchain/util/glob.cjs')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const dedent = require('dedent-js')
|
|
6
|
+
const { packageJson } = require('@jcoreio/toolchain/util/findUps.cjs')
|
|
7
|
+
const getPluginsArraySync = require('@jcoreio/toolchain/util/getPluginsArraySync.cjs')
|
|
8
|
+
const resolveImportsCodemod = require('../util/resolveImportsCodemod.cjs')
|
|
9
|
+
|
|
10
|
+
module.exports = [
|
|
11
|
+
[
|
|
12
|
+
async function compile(args = []) {
|
|
13
|
+
const config = packageJson['@jcoreio/toolchain']
|
|
14
|
+
const extensions = getPluginsArraySync('babelExtensions')
|
|
15
|
+
|
|
16
|
+
await execa('babel', [
|
|
17
|
+
'src',
|
|
18
|
+
...(extensions.length ? ['--extensions', extensions.join(',')] : []),
|
|
19
|
+
'--out-dir',
|
|
20
|
+
'dist',
|
|
21
|
+
'--out-file-extension',
|
|
22
|
+
'.js',
|
|
23
|
+
])
|
|
24
|
+
const jsFiles = await glob(path.join('dist', '**', '*.js'))
|
|
25
|
+
await resolveImportsCodemod(jsFiles)
|
|
26
|
+
if (config && config.esWrapper) {
|
|
27
|
+
await Promise.all(
|
|
28
|
+
jsFiles.map((file) =>
|
|
29
|
+
fs.writeFile(
|
|
30
|
+
file.replace(/\.js$/, '.mjs'),
|
|
31
|
+
dedent`
|
|
32
|
+
export * from './${path.basename(file)}'
|
|
33
|
+
import root from './${path.basename(file)}'
|
|
34
|
+
export default root
|
|
35
|
+
|
|
36
|
+
`,
|
|
37
|
+
'utf8'
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
} else {
|
|
42
|
+
await execa(
|
|
43
|
+
'babel',
|
|
44
|
+
[
|
|
45
|
+
'src',
|
|
46
|
+
...(extensions.length
|
|
47
|
+
? ['--extensions', extensions.join(',')]
|
|
48
|
+
: []),
|
|
49
|
+
'--out-dir',
|
|
50
|
+
'dist',
|
|
51
|
+
'--out-file-extension',
|
|
52
|
+
'.mjs',
|
|
53
|
+
],
|
|
54
|
+
{ env: { ...process.env, JCOREIO_TOOLCHAIN_MJS: '1' } }
|
|
55
|
+
)
|
|
56
|
+
const mjsFiles = await glob(path.join('dist', '**', '*.mjs'))
|
|
57
|
+
await resolveImportsCodemod(mjsFiles)
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
{ insteadOf: '@jcoreio/toolchain' },
|
|
61
|
+
],
|
|
62
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const { name } = require('../package.json')
|
|
2
|
+
const dedent = require('dedent-js')
|
|
3
|
+
|
|
4
|
+
module.exports = [
|
|
5
|
+
async function getConfigFiles() {
|
|
6
|
+
return {
|
|
7
|
+
'toolchain.config.cjs': dedent`
|
|
8
|
+
/* eslint-env node, es2018 */
|
|
9
|
+
module.exports = {
|
|
10
|
+
cjsBabelEnv: { forceAllTransforms: true },
|
|
11
|
+
mjsBabelEnv: { targets: { node: 16 } },
|
|
12
|
+
}
|
|
13
|
+
`,
|
|
14
|
+
'.babelrc.cjs': dedent`
|
|
15
|
+
/* eslint-env node, es2018 */
|
|
16
|
+
module.exports = function (api) {
|
|
17
|
+
const base = require('${name}/.babelrc.cjs')(api)
|
|
18
|
+
return {
|
|
19
|
+
...base,
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
`,
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = [() => [require.resolve('../eslint.extends.cjs')]]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const { default: traverse } = require('@babel/traverse')
|
|
2
|
+
|
|
3
|
+
module.exports = function getImportSources(ast) {
|
|
4
|
+
const sources = []
|
|
5
|
+
traverse(ast, {
|
|
6
|
+
ImportDeclaration(path) {
|
|
7
|
+
sources.push(path.node.source)
|
|
8
|
+
path.skip()
|
|
9
|
+
},
|
|
10
|
+
ExportNamedDeclaration(path) {
|
|
11
|
+
sources.push(path.node.source)
|
|
12
|
+
path.skip()
|
|
13
|
+
},
|
|
14
|
+
ExportAllDeclaration(path) {
|
|
15
|
+
sources.push(path.node.source)
|
|
16
|
+
path.skip()
|
|
17
|
+
},
|
|
18
|
+
CallExpression(path) {
|
|
19
|
+
if (
|
|
20
|
+
path.get('callee').isImport() ||
|
|
21
|
+
(path.get('callee').isIdentifier() &&
|
|
22
|
+
path.node.callee.name === 'require')
|
|
23
|
+
) {
|
|
24
|
+
sources.push(path.node.arguments[0])
|
|
25
|
+
path.skip()
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
return sources.filter((n) => n && n.type === 'StringLiteral')
|
|
30
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const { promisify } = require('util')
|
|
2
|
+
const _resolve = require('resolve')
|
|
3
|
+
const resolve = promisify(_resolve)
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const fs = require('fs-extra')
|
|
6
|
+
|
|
7
|
+
module.exports = async function resolveImportSource({ file, source }) {
|
|
8
|
+
const basedir = path.dirname(file)
|
|
9
|
+
if (source.startsWith('.')) {
|
|
10
|
+
const resolved = await resolve(source, {
|
|
11
|
+
basedir,
|
|
12
|
+
extensions: [
|
|
13
|
+
path.extname(file.replace(/\.flow$/, '')),
|
|
14
|
+
'.mjs',
|
|
15
|
+
'.cjs',
|
|
16
|
+
'.js',
|
|
17
|
+
],
|
|
18
|
+
})
|
|
19
|
+
const result = path.relative(basedir, resolved)
|
|
20
|
+
return result.startsWith('.') ? result : `./${result}`
|
|
21
|
+
}
|
|
22
|
+
const match = /^((?:@[^/]+\/)?[^/]+)(?:\/(.+))?$/.exec(source)
|
|
23
|
+
if (!match) return source
|
|
24
|
+
const [, pkg, subpath] = match
|
|
25
|
+
if (!subpath) return source
|
|
26
|
+
const packageJsonFile = await resolve(`${pkg}/package.json`)
|
|
27
|
+
const packageJson = await fs.readJson(packageJsonFile)
|
|
28
|
+
const exportMap = packageJson ? packageJson.exports : undefined
|
|
29
|
+
if (exportMap && exportMap[`./${subpath}`]) return source
|
|
30
|
+
const resolved = await resolve(source, {
|
|
31
|
+
basedir,
|
|
32
|
+
extensions: [path.extname(file), '.mjs', '.cjs', '.js'],
|
|
33
|
+
})
|
|
34
|
+
return `${pkg}/${path.relative(path.dirname(packageJsonFile), resolved)}`
|
|
35
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const fs = require('@jcoreio/toolchain/util/projectFs.cjs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const { projectDir } = require('@jcoreio/toolchain/util/findUps.cjs')
|
|
4
|
+
const transformImportSources = require('./transformImportSources.cjs')
|
|
5
|
+
const resolveImportSource = require('./resolveImportSource.cjs')
|
|
6
|
+
|
|
7
|
+
module.exports = async function resolveImportsCodemod(files) {
|
|
8
|
+
await Promise.all(
|
|
9
|
+
files.map(async (file) => {
|
|
10
|
+
file = path.resolve(projectDir, file)
|
|
11
|
+
const transformed = await transformImportSources({
|
|
12
|
+
file,
|
|
13
|
+
transform: resolveImportSource,
|
|
14
|
+
})
|
|
15
|
+
await fs.writeFile(file, transformed, 'utf8')
|
|
16
|
+
})
|
|
17
|
+
)
|
|
18
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const fs = require('fs-extra')
|
|
2
|
+
const { parseAsync } = require('babel-parse-wild-code')
|
|
3
|
+
const getImportSources = require('./getImportSources.cjs')
|
|
4
|
+
|
|
5
|
+
async function transformImportSources({ file, source, ast, transform }) {
|
|
6
|
+
if (!source) source = await fs.readFile(file, 'utf8')
|
|
7
|
+
if (!ast) ast = await parseAsync(file, { sourceType: 'unambiguous' })
|
|
8
|
+
const sources = getImportSources(ast)
|
|
9
|
+
const replacements = []
|
|
10
|
+
for (const { value, start, end } of sources) {
|
|
11
|
+
const replacement = await transform({
|
|
12
|
+
file,
|
|
13
|
+
source: value,
|
|
14
|
+
})
|
|
15
|
+
if (replacement === value) continue
|
|
16
|
+
replacements.push({ value: replacement, start, end })
|
|
17
|
+
}
|
|
18
|
+
replacements.sort((a, b) => a.start - b.start)
|
|
19
|
+
|
|
20
|
+
const parts = []
|
|
21
|
+
let end = 0
|
|
22
|
+
for (const r of replacements) {
|
|
23
|
+
if (r.start > end) {
|
|
24
|
+
parts.push(source.substring(end, r.start))
|
|
25
|
+
}
|
|
26
|
+
parts.push(JSON.stringify(r.value))
|
|
27
|
+
end = r.end
|
|
28
|
+
}
|
|
29
|
+
if (end < source.length) {
|
|
30
|
+
parts.push(source.substring(end))
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return parts.join('')
|
|
34
|
+
}
|
|
35
|
+
module.exports = transformImportSources
|