Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: provide cjs pkg entrypoints #793

Merged
merged 8 commits into from
May 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,24 @@ jobs:
timeout-minutes: 1
env:
FORCE_COLOR: 3

smoke-node:
runs-on: ubuntu-latest
needs: build
strategy:
matrix:
node-version: [12, 14, 16, 18, 20]
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- uses: actions/download-artifact@v4
with:
name: build
- name: cjs smoke test
run: npm run test:smoke:cjs
- name: mjs smoke test
if: matrix.node-version != '12'
run: npm run test:smoke:mjs
69 changes: 58 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 40 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,55 @@
}
},
"exports": {
".": "./build/index.js",
"./globals": "./build/globals.js",
"./cli": "./build/cli.js",
"./core": "./build/core.js",
".": {
"import": "./build/index.js",
"require": "./build/index.cjs",
"types": "./build/index.d.ts",
"default": "./build/index.js"
},
"./globals": {
"import": "./build/globals.js",
"require": "./build/globals.cjs",
"types": "./build/globals.d.ts",
"default": "./build/globals.js"
},
"./cli": {
"import": "./build/cli.js",
"require": "./build/cli.cjs",
"types": "./build/cli.d.ts",
"default": "./build/cli.js"
},
"./core": {
"import": "./build/core.js",
"require": "./build/core.cjs",
"types": "./build/core.d.ts",
"default": "./build/core.js"
},
"./package.json": "./package.json"
},
"bin": {
"zx": "./build/cli.js"
},
"engines": {
"node": ">= 16.0.0"
"node": ">= 12.0.0"
},
"scripts": {
"fmt": "prettier --write .",
"fmt:check": "prettier --check .",
"build": "npm run build:js && npm run build:dts",
"build:check": "tsc",
"build:js": "node scripts/build-js.mjs --format=esm --entry=src/*.ts && npm run build:vendor",
"build:vendor": "node scripts/build-js.mjs --format=esm --entry=src/vendor.ts --bundle=all --banner",
"build:js": "node scripts/build-js.mjs --format=cjs --hybrid --entry=src/*.ts && npm run build:vendor",
"build:vendor": "node scripts/build-js.mjs --format=cjs --entry=src/vendor.ts --bundle=all",
"build:dts": "tsc --project tsconfig.prod.json && node scripts/build-dts.mjs",
"test": "npm run build && npm run test:unit && npm run test:types",
"test": "npm run build && npm run test:unit && npm run test:types && npm run test:license",
"test:unit": "node ./test/all.test.js",
"test:types": "tsd",
"test:license": "node ./test/extra.test.js",
"test:smoke:bun": "bun test ./test/smoke/bun.test.js",
"test:smoke:win32": "node ./test/smoke/win32.test.js",
"coverage": "c8 -x build/vendor.js -x 'test/**' -x scripts --check-coverage npm test",
"test:smoke:cjs": "node ./test/smoke/node.test.cjs",
"test:smoke:mjs": "node ./test/smoke/node.test.mjs",
"coverage": "c8 -x build/vendor.cjs -x build/esblib.cjs -x 'test/**' -x scripts --check-coverage npm test",
"circular": "madge --circular src/*",
"version": "cat package.json | fx .version"
},
Expand All @@ -60,27 +83,32 @@
"@types/minimist": "^1.2.5",
"@types/node": ">=20.11.30",
"@types/which": "^3.0.3",
"@webpod/ps": "^0.0.0-beta.3",
"@webpod/ingrid": "^0.0.0-beta.3",
"@webpod/ps": "^0.0.0-beta.3",
"c8": "^9.1.0",
"chalk": "^5.3.0",
"create-require": "^1.1.1",
"depseek": "^0.4.1",
"dts-bundle-generator": "^9.3.1",
"dts-bundle-generator": "^9.5.1",
"esbuild": "^0.20.2",
"esbuild-node-externals": "^1.13.0",
"esbuild-plugin-entry-chunks": "^0.1.12",
"esbuild-plugin-hybrid-export": "^0.2.1",
"esbuild-plugin-transform-hook": "^0.0.1",
"esbuild-plugin-extract-helpers": "^0.0.3",
"fs-extra": "^11.2.0",
"fx": "*",
"globby": "^14.0.1",
"madge": "^6.1.0",
"minimist": "^1.2.8",
"node-abort-controller": "^3.1.1",
"node-fetch-native": "^1.6.4",
"prettier": "^3.2.5",
"tsd": "^0.31.0",
"typescript": "^5.4.4",
"which": "^4.0.0",
"yaml": "^2.4.1",
"zurk": "^0.1.2"
"zurk": "^0.1.4"
},
"publishConfig": {
"registry": "https://wombat-dressing-room.appspot.com"
Expand Down
63 changes: 57 additions & 6 deletions scripts/build-js.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import path from 'node:path'
import esbuild from 'esbuild'
import { nodeExternalsPlugin } from 'esbuild-node-externals'
import { entryChunksPlugin } from 'esbuild-plugin-entry-chunks'
import { hybridExportPlugin } from 'esbuild-plugin-hybrid-export'
import { transformHookPlugin } from 'esbuild-plugin-transform-hook'
import { extractHelpersPlugin } from 'esbuild-plugin-extract-helpers'
import minimist from 'minimist'
import glob from 'fast-glob'

Expand All @@ -33,7 +36,7 @@ const argv = minimist(process.argv.slice(2), {
target: 'node12',
cwd: process.cwd(),
},
boolean: ['minify', 'sourcemap', 'banner'],
boolean: ['minify', 'sourcemap', 'banner', 'hybrid'],
string: ['entry', 'external', 'bundle', 'license', 'format', 'map', 'cwd'],
})
const {
Expand All @@ -44,6 +47,7 @@ const {
sourcemap,
license,
format,
hybrid,
cwd: _cwd,
} = argv

Expand All @@ -54,9 +58,6 @@ const entryPoints = entry.includes('*')
? await glob(entries, { absolute: false, onlyFiles: true, cwd, root: cwd })
: entries.map((p) => path.relative(cwd, path.resolve(cwd, p)))

console.log('cwd=', cwd)
console.log('entryPoints=', entryPoints)

const _bundle = bundle !== 'none' && !process.argv.includes('--no-bundle')
const _external = _bundle ? external.split(',') : undefined // https://github.com/evanw/esbuild/issues/1466

Expand All @@ -70,6 +71,50 @@ if (bundle === 'src') {
plugins.push(nodeExternalsPlugin())
}

if (hybrid) {
plugins.push(
hybridExportPlugin({
loader: 'import',
to: 'build',
toExt: '.js',
})
)
}

plugins.push(
transformHookPlugin({
hooks: [
{
on: 'end',
pattern: new RegExp(
'(' +
entryPoints.map((e) => path.parse(e).name).join('|') +
')\\.cjs$'
),
transform(contents) {
return contents
.toString()
.replaceAll('"node:', '"')
.replaceAll(
'require("stream/promises")',
'require("stream").promises'
)
.replaceAll('require("fs/promises")', 'require("fs").promises')
.replaceAll('}).prototype', '}).prototype || {}')
.replace(
/\/\/ Annotate the CommonJS export names for ESM import in node:/,
($0) => `/* c8 ignore next 100 */\n${$0}`
)
},
},
],
}),
extractHelpersPlugin({
cwd: 'build',
include: /\.cjs/,
})
)

const formats = format.split(',')
const banner =
argv.banner && bundle === 'all'
Expand All @@ -95,7 +140,7 @@ const esmConfig = {
target: 'esnext',
format: 'esm',
outExtension: {
// '.js': '.mjs'
'.js': '.mjs',
},
plugins,
legalComments: license,
Expand All @@ -111,12 +156,18 @@ const cjsConfig = {
format: 'cjs',
banner: {},
outExtension: {
// '.js': '.cjs'
'.js': '.cjs',
},
// https://github.com/evanw/esbuild/issues/1633
define: {
'import.meta.url': 'import_meta_url',
},
inject: ['./scripts/import.meta.url-polyfill.js'],
}

for (const format of formats) {
const config = format === 'cjs' ? cjsConfig : esmConfig
console.log('config=', config)

await esbuild.build(config).catch(() => process.exit(1))
}
Expand Down
5 changes: 5 additions & 0 deletions scripts/import.meta.url-polyfill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const import_meta_url =
typeof document === 'undefined'
? new (require('url'.replace('', '')).URL)('file:' + __filename).href
: (document.currentScript && document.currentScript.src) ||
new URL('main.js', document.baseURI).href
Loading