Skip to content

Commit 213962f

Browse files
committed
Add ESM build
1 parent 76d2e3c commit 213962f

File tree

4 files changed

+65
-1
lines changed

4 files changed

+65
-1
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,7 @@ dist
128128
.yarn/build-state.yml
129129
.yarn/install-state.gz
130130
.pnp.*
131+
132+
# Generated files
133+
index.mjs
134+
index.d.mts

.npmignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.github
2+
.gitattributes
3+
scripts
4+
test
5+
**/*.test-d.ts

package.json

+16-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,27 @@
55
"main": "index.js",
66
"type": "commonjs",
77
"types": "types/index.d.ts",
8+
"exports": {
9+
".": {
10+
"import": {
11+
"default": "./index.mjs",
12+
"types": "./types/index.d.mts"
13+
},
14+
"default": {
15+
"default": "./index.js",
16+
"types": "./types/index.d.ts"
17+
}
18+
},
19+
"./*": "./*"
20+
},
821
"scripts": {
922
"lint": "eslint",
1023
"lint:fix": "eslint --fix",
1124
"test:unit": "c8 --100 node --test",
1225
"test:typescript": "tsd",
13-
"test": "npm run lint && npm run test:unit && npm run test:typescript"
26+
"test": "npm run lint && npm run test:unit && npm run test:typescript",
27+
"build": "node ./scripts/generate-esm.mjs",
28+
"version": "npm run build"
1429
},
1530
"precommit": [
1631
"lint",

scripts/generate-esm.mjs

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import fs from 'node:fs'
2+
3+
const CWD = new URL('../', import.meta.url)
4+
5+
// list of all inputs/outputs, with replacements
6+
const SOURCE_FILES = [
7+
{
8+
source: './index.js',
9+
types: './types/index.d.ts',
10+
replacements: [
11+
[/const\s+([^=]+)=\s*require\(([^)]+)\)/g, (_, spec, moduleName) => {
12+
return `import ${spec.trim().replace(/:\s*/g, ' as ')} from ${moduleName.trim()}`
13+
}],
14+
[/module\.exports\s*=\s*({[^}]+})/, 'export $1'],
15+
]
16+
}
17+
]
18+
19+
// Build script
20+
for (const { source, types, replacements } of SOURCE_FILES) {
21+
// replace
22+
let output = fs.readFileSync(new URL(source, CWD), 'utf8')
23+
for (const [search, replaceValue] of replacements) {
24+
output = output.replace(search, replaceValue)
25+
}
26+
27+
// verify
28+
if (output.includes('require(')) {
29+
throw new Error('Could not convert all require() statements')
30+
}
31+
if (output.includes('module.exports')) {
32+
throw new Error('Could not convert module.exports statement')
33+
}
34+
35+
// write source
36+
fs.writeFileSync(new URL(source.replace(/\.js$/, '.mjs'), CWD), output)
37+
38+
// write types
39+
fs.copyFileSync(new URL(types, CWD), new URL(types.replace(/\.d\.ts$/, '.d.mts'), CWD))
40+
}

0 commit comments

Comments
 (0)