Skip to content

Commit

Permalink
feat: provide cjs pkg entrypoints (#793)
Browse files Browse the repository at this point in the history
* feat: provide cjs pkg entrypoints

relates #340 #399 #282 #197

* chore: linting

* build: extract esbuild helpers

* chore: up some dev deps

* test: check licenses once

* test: ignore esblib.cjs coverage

* test: omit annotations coverage

* style: linting
  • Loading branch information
antongolub authored May 4, 2024
1 parent bc2a08c commit 086b500
Show file tree
Hide file tree
Showing 12 changed files with 237 additions and 40 deletions.
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

0 comments on commit 086b500

Please sign in to comment.