Skip to content

Commit

Permalink
Unify code-base as ts and transpile to cjs for publish
Browse files Browse the repository at this point in the history
  • Loading branch information
jdalton committed Jul 25, 2024
1 parent da75762 commit ac9b621
Show file tree
Hide file tree
Showing 122 changed files with 15,495 additions and 10,134 deletions.
39 changes: 39 additions & 0 deletions .config/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict'

const { isEsmId } = require('../scripts/packages')

module.exports = {
plugins: [
'@babel/plugin-proposal-export-default-from',
'@babel/plugin-transform-export-namespace-from',
[
'@babel/plugin-transform-runtime',
{
absoluteRuntime: false,
corejs: false,
helpers: true,
regenerator: false,
version: '^7.24.6'
}
],
[
'@babel/plugin-transform-modules-commonjs',
{
allowTopLevelThis: true,
importInterop: (specifier, requestingFilename) => {
if (requestingFilename) {
const specIsEsm = isEsmId(specifier, requestingFilename)
const parentIsEsm = isEsmId(requestingFilename)
if (specIsEsm && parentIsEsm) {
return 'none'
}
if (specIsEsm) {
return 'babel'
}
}
return 'node'
}
}
]
]
}
205 changes: 205 additions & 0 deletions .config/rollup.base.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
'use strict'

const { builtinModules } = require('node:module')
const path = require('node:path')

const commonjs = require('@rollup/plugin-commonjs')
const replace = require('@rollup/plugin-replace')
const { nodeResolve } = require('@rollup/plugin-node-resolve')
const rangesIntersect = require('semver/ranges/intersects')
const ts = require('rollup-plugin-ts')

const { loadJSON } = require('../scripts/files')
const {
getPackageName,
getPackageNameEnd,
isEsmId,
normalizeId,
isPackageName,
isBuiltin,
resolveId
} = require('../scripts/packages')
const { escapeRegExp } = require('../scripts/strings')
const socketModifyPlugin = require('../scripts/rollup/socket-modify-plugin')

const ENTRY_SUFFIX = '?commonjs-entry'
const EXTERNAL_SUFFIX = '?commonjs-external'

const builtinAliases = builtinModules.reduce((o, n) => {
o[n] = `node:${n}`
return o
}, {})

const rootPath = path.resolve(__dirname, '..')
const babelConfigPath = path.join(__dirname, 'babel.config.js')
const tsconfigPath = path.join(__dirname, 'tsconfig.rollup.json')

const babelConfig = require(babelConfigPath)
const { dependencies: pkgDeps, devDependencies: pkgDevDeps } = loadJSON(path.resolve(rootPath, 'package.json'))

const customResolver = nodeResolve({
exportConditions: ['node'],
preferBuiltins: true
})

module.exports = (extendConfig = {}) => {
const depStats = {
esm: { __proto__: null },
external: { __proto__: null },
topLevel: { __proto__: null },
topLevelDev: { __proto__: null }
}

const config = {
__proto__: {
meta: {
depStats
}
},
external(id_, parentId_) {
if (
id_.endsWith(EXTERNAL_SUFFIX) ||
isBuiltin(id_)
) {
return true
}
const id = normalizeId(id_)
if (
id.endsWith('.cjs') ||
id.endsWith('.json')
) {
return true
}
if (
id.endsWith('.mjs') ||
id.endsWith('.mts') ||
id.endsWith('.ts') ||
!isPackageName(id)
) {
return false
}
const name = getPackageName(id)
const parentId = parentId_ ? resolveId(parentId_) : undefined
const resolvedId = resolveId(id, parentId)
if (isEsmId(resolvedId, parentId)) {
depStats.esm[name] = pkgDeps[name] ?? pkgDevDeps[name] ?? ''
return false
}
const parentNodeModulesIndex = parentId.lastIndexOf('/node_modules/')
if (parentNodeModulesIndex !== -1) {
const parentNameStart = parentNodeModulesIndex + 14
const parentNameEnd = getPackageNameEnd(parentId, parentNameStart)
const {
version,
dependencies = {},
optionalDependencies = {},
peerDependencies = {}
} = loadJSON(`${parentId.slice(0, parentNameEnd)}/package.json`)
const curRange =
dependencies[name] ?? optionalDependencies[name] ?? peerDependencies[name] ?? version
const seenRange = pkgDeps[name] ?? depStats.external[name]
if (seenRange) {
return rangesIntersect(seenRange, curRange)
}
depStats.external[name] = curRange
} else if (pkgDeps[name]) {
depStats.external[name] = pkgDeps[name]
depStats.topLevel[name] = pkgDeps[name]
} else if (pkgDevDeps[name]) {
depStats.topLevelDev[name] = pkgDevDeps[name]
}
return true
},
...extendConfig,
plugins: [
customResolver,
ts({
transpiler: 'babel',
browserslist: false,
transpileOnly: true,
exclude: ['**/*.json'],
babelConfig,
tsconfig: tsconfigPath
}),
// Convert un-prefixed built-in imports into "node:"" prefixed forms.
replace({
delimiters: ['(?<=(?:require\\(|from\\s*)["\'])', '(?=["\'])'],
preventAssignment: false,
values: builtinAliases
}),
// Convert `require('u' + 'rl')` into something like `require$$2$3`.
socketModifyPlugin({
find: /require\('u' \+ 'rl'\)/g,
replace(match) {
return /(?<=var +)[$\w]+(?= *= *require\('node:url'\))/.exec(this.input)?.[0] ?? match
}
}),
// Remove bare require calls, e.g. require calls not associated with an
// import binding:
// require('node:util')
// require('graceful-fs')
socketModifyPlugin({
find: /^\s*require\(["'].+?["']\);?\r?\n/gm,
replace: ''
}),
// Fix incorrectly set "spinners" binding caused by a transpilation bug
// https://github.com/sindresorhus/ora/blob/main/index.js#L416C2-L416C50
// export {default as spinners} from 'cli-spinners'
socketModifyPlugin({
find: /(?<=ora[^.]+\.spinners\s*=\s*)[$\w]+/g,
replace(match) {
return new RegExp(`(?<=${escapeRegExp(match)}\\s*=\\s*)[$\\w]+`).exec(this.input)?.[0] ?? match
}
}),
commonjs({
ignoreDynamicRequires: true,
ignoreGlobal: true,
ignoreTryCatch: true,
defaultIsModuleExports: true,
transformMixedEsModules: true,
extensions: ['.cjs', '.js', '.ts', `.ts${ENTRY_SUFFIX}`]
}),
...(extendConfig.plugins ?? [])
]
}

const output = (
Array.isArray(config.output)
? config.output
: (config.output ? [config.output] : [])
).map((o) =>
({
...o,
chunkFileNames: '[name].js',
manualChunks(id) {
if (id.includes('/node_modules/')) {
return 'vendor'
}
}
})
)

// Replace hard-coded absolute paths in source with hard-coded relative paths.
const replacePlugin = replace({
delimiters: ['(?<=["\'])', '/'],
preventAssignment: false,
values: {
[rootPath]: '../'
}
})

const replaceOutputPlugin = {
name: replacePlugin.name,
renderChunk: replacePlugin.renderChunk
}

for (const o of output) {
o.plugins = [
...(Array.isArray(o.plugins) ? o.plugins : []),
replaceOutputPlugin
]
}

config.output = output
return config
}
60 changes: 60 additions & 0 deletions .config/rollup.dist.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use strict'

const { chmodSync, readFileSync, writeFileSync } = require('node:fs')
const path = require('node:path')

const { loadJSON } = require('../scripts/files')
const { formatObject } = require('../scripts/strings')

const baseConfig = require('./rollup.base.config.js')

const rootPath = path.resolve(__dirname, '..')
const distPath = path.join(rootPath, 'dist')
const srcPath = path.join(rootPath, 'src')

const pkgJSONPath = path.resolve(rootPath, 'package.json')
const pkgJSON = loadJSON(pkgJSONPath)

module.exports = () => {
const config = baseConfig({
input: {
cli: `${srcPath}/cli.ts`,
'npm-cli': `${srcPath}/shadow/npm-cli.ts`,
'npx-cli': `${srcPath}/shadow/npx-cli.ts`,
'npm-injection': `${srcPath}/shadow/npm-injection.ts`
},
output: [
{
dir: 'dist',
entryFileNames: '[name].js',
format: 'cjs',
exports: 'auto',
externalLiveBindings : false,
freeze: false
}
],
plugins: [
{
writeBundle() {
// Make dist files chmod +x
chmodSync(path.join(distPath, 'cli.js'), 0o755)
chmodSync(path.join(distPath, 'npm-cli.js'), 0o755)
chmodSync(path.join(distPath, 'npx-cli.js'), 0o755)
// Update dependencies with additional inlined modules
const dependencies = { ...pkgJSON.dependencies }
for (const { 0: id, 1: range } of Object.entries(config.meta.depStats.external)) {
dependencies[id] = range
}
writeFileSync(
pkgJSONPath,
readFileSync(pkgJSONPath, 'utf8')
.replace(/(?<="dependencies":\s*)\{[^\}]*\}/, () => formatObject(dependencies)),
'utf8'
)
}
}
]
})

return config
}
24 changes: 24 additions & 0 deletions .config/rollup.test.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict'

const path = require('node:path')

const baseConfig = require('./rollup.base.config.js')

const rootPath = path.resolve(__dirname, '..')
const srcPath = path.join(rootPath, 'src')

module.exports = () => baseConfig({
input: {
'path-resolve': `${srcPath}/utils/path-resolve.ts`
},
output: [
{
dir: 'test/dist',
entryFileNames: '[name].js',
format: 'cjs',
exports: 'auto',
externalLiveBindings : false,
freeze: false
}
]
})
32 changes: 32 additions & 0 deletions .config/tsconfig.base.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"compilerOptions": {
"allowJs": false,
"composite": true,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"incremental": true,
"isolatedModules": true,
"lib": ["esnext"],
"noEmit": true,
"noEmitOnError": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"strictNullChecks": true,
"target": "esnext",

/* New checks being tried out */
"exactOptionalPropertyTypes": true,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noUncheckedIndexedAccess": true,

/* Additional checks */
"noUnusedLocals": true,
"noUnusedParameters": true
}
}
7 changes: 7 additions & 0 deletions .config/tsconfig.rollup.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"module": "preserve",
"moduleResolution": "bundler",
}
}
6 changes: 6 additions & 0 deletions .config/tsconfig.tap.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"module": "commonjs"
}
}
4 changes: 3 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/coverage/**/*
/lib/types/api.d.ts
**/dist/**/*
/src/types/api.d.ts
rollup.config.js
Loading

0 comments on commit ac9b621

Please sign in to comment.