feat: publish both CJS and ESM files

This way, users can pick whichever one works for their needs
This commit is contained in:
Amaan Qureshi 2025-01-19 23:07:26 -05:00
parent 10e6ecf162
commit a4b20c1c56
10 changed files with 225 additions and 55 deletions

View file

@ -186,7 +186,14 @@ jobs:
- name: Build wasm library
# No reason to build on the same Github runner hosts many times
if: ${{ !matrix.no-run && !matrix.use-cross }}
run: $BUILD_CMD run -p xtask -- build-wasm
shell: bash
run: |
cd lib/binding_web
npm ci
CJS=true npm run build
CJS=true npm run build:debug
npm run build
npm run build:debug
- name: Build target
run: $BUILD_CMD build --release --target=${{ matrix.target }} --features=${{ matrix.features }}
@ -236,6 +243,16 @@ jobs:
name: tree-sitter.wasm
path: |
lib/binding_web/tree-sitter.js
lib/binding_web/tree-sitter.js.map
lib/binding_web/tree-sitter.cjs
lib/binding_web/tree-sitter.cjs.map
lib/binding_web/tree-sitter.wasm
lib/binding_web/tree-sitter.wasm.map
lib/binding_web/debug/tree-sitter.cjs
lib/binding_web/debug/tree-sitter.cjs.map
lib/binding_web/debug/tree-sitter.js
lib/binding_web/debug/tree-sitter.js.map
lib/binding_web/debug/tree-sitter.wasm
lib/binding_web/debug/tree-sitter.wasm.map
if-no-files-found: error
retention-days: 7

View file

@ -35,6 +35,23 @@ jobs:
run: |
mkdir -p target
mv artifacts/tree-sitter.wasm/* target/
# Rename files
mv target/tree-sitter.js target/web-tree-sitter.js
mv target/tree-sitter.js.map target/web-tree-sitter.js.map
mv target/tree-sitter.cjs target/web-tree-sitter.cjs
mv target/tree-sitter.cjs.map target/web-tree-sitter.cjs.map
mv target/tree-sitter.wasm target/web-tree-sitter.wasm
mv target/tree-sitter.wasm.map target/web-tree-sitter.wasm.map
mv target/debug/tree-sitter.js target/web-tree-sitter-debug.js
mv target/debug/tree-sitter.js.map target/web-tree-sitter-debug.js.map
mv target/debug/tree-sitter.cjs target/web-tree-sitter-debug.cjs
mv target/debug/tree-sitter.cjs.map target/web-tree-sitter-debug.cjs.map
mv target/debug/tree-sitter.wasm target/web-tree-sitter-debug.wasm
mv target/debug/tree-sitter.wasm.map target/web-tree-sitter-debug.wasm.map
rm -rf target/debug
rm -r artifacts/tree-sitter.wasm
for platform in $(cd artifacts; ls | sed 's/^tree-sitter\.//'); do
exe=$(ls artifacts/tree-sitter.$platform/tree-sitter*)
@ -47,8 +64,18 @@ jobs:
run: |-
gh release create ${{ github.ref_name }} \
target/tree-sitter-*.gz \
target/tree-sitter.wasm \
target/tree-sitter.js
target/web-tree-sitter.js \
target/web-tree-sitter.js.map \
target/web-tree-sitter.cjs \
target/web-tree-sitter.cjs.map \
target/web-tree-sitter.wasm \
target/web-tree-sitter.wasm.map \
target/web-tree-sitter-debug.js \
target/web-tree-sitter-debug.js.map \
target/web-tree-sitter-debug.cjs \
target/web-tree-sitter-debug.cjs.map \
target/web-tree-sitter-debug.wasm \
target/web-tree-sitter-debug.wasm.map
env:
GH_TOKEN: ${{ github.token }}
@ -91,7 +118,11 @@ jobs:
- name: Build wasm
if: matrix.directory == 'lib/binding_web'
run: cargo xtask build-wasm
run: |
npm run build
npm run build:debug
CJS=true npm run build
CJS=true npm run build:debug
- name: Publish to npmjs.com
working-directory: ${{ matrix.directory }}

View file

@ -1,12 +1,9 @@
debug/
dist/
/lib/tree-sitter.js
/lib/tree-sitter.wasm
/lib/tree-sitter.wasm.map
/tree-sitter.js
/tree-sitter.js.map
/tree-sitter.wasm
/tree-sitter.wasm.map
tree-sitter*
lib/tree-sitter*
!lib/tree-sitter.c
!lib/tree-sitter.d.ts
node_modules
*.tgz
LICENSE

View file

@ -14,6 +14,7 @@
"@types/emscripten": "^1.39.13",
"@types/node": "^22.10.7",
"@vitest/coverage-v8": "^3.0.2",
"dts-buddy": "^0.5.4",
"esbuild": "^0.24.2",
"eslint": "^9.18.0",
"source-map": "^0.7.4",
@ -779,6 +780,17 @@
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
@ -1786,6 +1798,43 @@
"dev": true,
"license": "MIT"
},
"node_modules/dts-buddy": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/dts-buddy/-/dts-buddy-0.5.4.tgz",
"integrity": "sha512-a3jJYbMXK98aJvhdV/v+tEKTTEJXXWtMjrl5L8jJL7rnZzGtPA6JNHJZ5//NVRw4JiB5T10Ie5T7h/QsP3aaYw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/source-map": "^0.3.5",
"@jridgewell/sourcemap-codec": "^1.4.15",
"globrex": "^0.1.2",
"kleur": "^4.1.5",
"locate-character": "^3.0.0",
"magic-string": "^0.30.4",
"sade": "^1.8.1",
"tiny-glob": "^0.2.9",
"ts-api-utils": "^1.0.3"
},
"bin": {
"dts-buddy": "src/cli.js"
},
"peerDependencies": {
"typescript": ">=5.0.4 <5.8"
}
},
"node_modules/dts-buddy/node_modules/ts-api-utils": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
"integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=16"
},
"peerDependencies": {
"typescript": ">=4.2.0"
}
},
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@ -2304,6 +2353,20 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/globalyzer": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz",
"integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==",
"dev": true,
"license": "MIT"
},
"node_modules/globrex": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz",
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
"dev": true,
"license": "MIT"
},
"node_modules/graphemer": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
@ -2529,6 +2592,16 @@
"json-buffer": "3.0.1"
}
},
"node_modules/kleur": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
"integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -2543,6 +2616,13 @@
"node": ">= 0.8.0"
}
},
"node_modules/locate-character": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
"dev": true,
"license": "MIT"
},
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@ -2678,6 +2758,16 @@
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/mri": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
"integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/mrmime": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz",
@ -3033,6 +3123,19 @@
"queue-microtask": "^1.2.2"
}
},
"node_modules/sade": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
"integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
"dev": true,
"license": "MIT",
"dependencies": {
"mri": "^1.1.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/semver": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
@ -3311,6 +3414,17 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/tiny-glob": {
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz",
"integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==",
"dev": true,
"license": "MIT",
"dependencies": {
"globalyzer": "0.1.0",
"globrex": "^0.1.2"
}
},
"node_modules/tinybench": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",

View file

@ -15,8 +15,17 @@
"email": "amaanq12@gmail.com"
}
],
"main": "tree-sitter.js",
"type": "module",
"exports": {
".": {
"import": "./tree-sitter.js",
"require": "./tree-sitter.cjs"
},
"./debug": {
"import": "./debug/tree-sitter.js",
"require": "./debug/tree-sitter.cjs"
}
},
"types": "web-tree-sitter.d.ts",
"keywords": [
"incremental",
@ -26,15 +35,21 @@
],
"files": [
"README.md",
"tree-sitter.cjs",
"tree-sitter.cjs.map",
"tree-sitter.js",
"tree-sitter.js.map",
"tree-sitter.wasm",
"tree-sitter.wasm.map",
"tree-sitter-web.d.ts",
"debug/tree-sitter.js",
"debug/tree-sitter.js.map",
"debug/tree-sitter.wasm",
"debug/tree-sitter.wasm.map"
"tree-sitter-debug.cjs",
"tree-sitter-debug.cjs.map",
"tree-sitter-debug.js",
"tree-sitter-debug.js.map",
"tree-sitter-debug.wasm",
"tree-sitter-debug.wasm.map",
"web-tree-sitter.d.ts",
"web-tree-sitter.d.ts.map",
"src/**/*.ts"
],
"devDependencies": {
"@eslint/js": "^9.18.0",
@ -51,18 +66,17 @@
"vitest": "^3.0.2"
},
"scripts": {
"build:ts": "esbuild src/index.ts --bundle --format=esm --platform=node --global-name=TreeSitterImpl --outfile=tree-sitter.js --external:fs/* --external:fs/promises --sourcemap --sources-content=true --keep-names && cp lib/*wasm* .",
"build:ts": "node script/build.js",
"build:wasm": "cd ../../ && cargo xtask build-wasm",
"build:wasm:debug": "cd ../../ && cargo xtask build-wasm --debug",
"build": "npm run build:wasm && npm run build:ts",
"build:debug": "npm run build:wasm:debug && npm run build:ts && cp debug/* .",
"lint": "eslint src/*.ts script/*.ts",
"lint:fix": "eslint src/*.ts script/*.ts --fix",
"build:debug": "npm run build:wasm:debug && npm run build:ts -- --debug",
"build:dts": "node script/generate-dts.js",
"lint": "eslint src/*.ts script/*.ts test/*.ts",
"lint:fix": "eslint src/*.ts script/*.ts test/*.ts --fix",
"test": "vitest run",
"test:watch": "vitest",
"prepack": "cp ../../LICENSE .",
"prepublishOnly": "tsx script/check-artifacts-fresh.ts",
"postinstall": "node script/postinstall.js"
"prepublishOnly": "tsx script/check-artifacts-fresh.ts"
}
}

View file

@ -0,0 +1,23 @@
import esbuild from 'esbuild';
import fs from 'fs/promises';
const format = process.env.CJS ? 'cjs' : 'esm';
const debug = process.argv.includes('--debug');
const outfile = `${debug ? 'debug/' : ''}tree-sitter.${format === 'esm' ? 'js' : 'cjs'}`;
await esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
platform: 'node',
format,
outfile,
sourcemap: true,
sourcesContent: true,
keepNames: true,
external: ['fs/*', 'fs/promises'],
});
// Copy the generated WASM files to the appropriate spot, as esbuild doesn't "bundle" WASM files
const outputWasmName = `${debug ? 'debug/' : ''}tree-sitter.wasm`;
await fs.copyFile(`lib/tree-sitter.wasm`, outputWasmName);
await fs.copyFile(`lib/tree-sitter.wasm.map`, `${outputWasmName}.map`);

View file

@ -1,24 +0,0 @@
import fs from 'fs';
import path from 'path';
const isDebug = process.env.npm_config_debug === 'true';
if (isDebug) {
// Copy debug versions to root
fs.copyFileSync(
path.join(__dirname, '../debug/tree-sitter.js'),
path.join(__dirname, '../tree-sitter.js'),
);
fs.copyFileSync(
path.join(__dirname, '../debug/tree-sitter.wasm'),
path.join(__dirname, '../tree-sitter.wasm'),
);
fs.copyFileSync(
path.join(__dirname, '../debug/tree-sitter.js.map'),
path.join(__dirname, '../tree-sitter.js.map'),
);
fs.copyFileSync(
path.join(__dirname, '../debug/tree-sitter.wasm.map'),
path.join(__dirname, '../tree-sitter.wasm.map'),
);
}

View file

@ -143,7 +143,7 @@ pub fn run_wasm(args: &BuildWasm) -> Result<()> {
"-fno-exceptions",
"-std=c11",
"-s", "WASM=1",
"-s", "EXPORT_ES6",
"-s", "EXPORT_ES6=1",
"-s", "MODULARIZE=1",
"-s", "INITIAL_MEMORY=33554432",
"-s", "ALLOW_MEMORY_GROWTH=1",

View file

@ -71,7 +71,7 @@ fn check_wasm_exports() -> Result<()> {
let wasm_objdump = Command::new("wasm-objdump")
.args([
"--details",
"lib/binding_web/tree-sitter.wasm",
"lib/binding_web/debug/tree-sitter.wasm",
"--section",
"Name",
])

View file

@ -314,12 +314,10 @@ macro_rules! watch_wasm {
}
let watch_files = [
"binding.c",
"binding.js",
"exports.txt",
"imports.js",
"prefix.js",
"suffix.js",
"lib/tree-sitter.c",
"lib/exports.txt",
"lib/imports.js",
"lib/prefix.js",
]
.iter()
.map(PathBuf::from)