Skip to content

Commit 941ae0c

Browse files
authored
build: add file extensions to ESM imports (#139)
- Replace TypeScript compiler with esbuild for ESM build - Add esbuild-plugin-file-path-extensions to generate proper .mjs imports - Fix "Cannot find module" errors in Node.js ESM resolution - Ensure published packages work correctly in production environments resolves: trufnetwork/truf-network#1205
1 parent 1ba7a98 commit 941ae0c

File tree

3 files changed

+520
-6
lines changed

3 files changed

+520
-6
lines changed

build-esm.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
const esbuild = require('esbuild');
2+
const { esbuildPluginFilePathExtensions } = require('esbuild-plugin-file-path-extensions');
3+
const fs = require('fs');
4+
5+
async function buildESM() {
6+
try {
7+
// Clean and create dist-esm directory
8+
if (fs.existsSync('./dist-esm')) {
9+
fs.rmSync('./dist-esm', { recursive: true, force: true });
10+
}
11+
fs.mkdirSync('./dist-esm', { recursive: true });
12+
13+
// Get all TypeScript files
14+
const glob = require('glob');
15+
const entryPoints = glob.sync('./src/**/*.ts');
16+
17+
// Build ESM with file path extensions
18+
await esbuild.build({
19+
entryPoints,
20+
bundle: false, // Don't bundle - keep separate files
21+
outdir: './dist-esm',
22+
format: 'esm',
23+
target: 'es2021',
24+
platform: 'neutral',
25+
sourcemap: false,
26+
outExtension: { '.js': '.mjs' },
27+
plugins: [esbuildPluginFilePathExtensions({
28+
esmExtension: '.mjs',
29+
filter: /\.ts$/
30+
})],
31+
});
32+
33+
// Create package.json for ESM
34+
fs.writeFileSync('./dist-esm/package.json', '{"type":"module"}\n');
35+
36+
// Post-process to fix import extensions
37+
const fixImportExtensions = (dir) => {
38+
const files = fs.readdirSync(dir);
39+
for (const file of files) {
40+
const filePath = `${dir}/${file}`;
41+
const stat = fs.statSync(filePath);
42+
43+
if (stat.isDirectory()) {
44+
fixImportExtensions(filePath);
45+
} else if (file.endsWith('.mjs')) {
46+
let content = fs.readFileSync(filePath, 'utf8');
47+
48+
// Fix relative imports that don't have .mjs extension
49+
content = content.replace(
50+
/from\s+["'](\.[^"']+)["']/g,
51+
(match, importPath) => {
52+
if (!importPath.endsWith('.mjs') && !importPath.endsWith('.js')) {
53+
return match.replace(importPath, importPath + '.mjs');
54+
}
55+
return match;
56+
}
57+
);
58+
59+
// Fix import statements too
60+
content = content.replace(
61+
/import\s+[^"']*from\s+["'](\.[^"']+)["']/g,
62+
(match, importPath) => {
63+
if (!importPath.endsWith('.mjs') && !importPath.endsWith('.js')) {
64+
return match.replace(importPath, importPath + '.mjs');
65+
}
66+
return match;
67+
}
68+
);
69+
70+
fs.writeFileSync(filePath, content);
71+
}
72+
}
73+
};
74+
75+
fixImportExtensions('./dist-esm');
76+
77+
console.log('✅ ESM build completed with file extensions');
78+
} catch (error) {
79+
console.error('❌ ESM build failed:', error);
80+
process.exit(1);
81+
}
82+
}
83+
84+
buildESM();

package.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{
22
"name": "@trufnetwork/kwil-js",
3-
"version": "0.9.7",
3+
"version": "0.9.8",
44
"description": "",
55
"main": "./dist/index.js",
6-
"module": "./dist-esm/index.js",
6+
"module": "./dist-esm/index.mjs",
77
"types": "./dist/index.d.ts",
88
"sideEffects": false,
99
"exports": {
1010
".": {
11-
"import": "./dist-esm/index.js",
11+
"import": "./dist-esm/index.mjs",
1212
"require": "./dist/index.js",
1313
"types": "./dist/index.d.ts"
1414
},
@@ -22,6 +22,7 @@
2222
"dist/**/*.js",
2323
"dist/**/*.d.ts",
2424
"dist-esm/**/*.js",
25+
"dist-esm/**/*.mjs",
2526
"dist-esm/**/*.d.ts",
2627
"dist-esm/package.json",
2728
"!dist/**/*.map",
@@ -34,7 +35,7 @@
3435
],
3536
"scripts": {
3637
"clean": "rimraf dist/* dist-esm/*",
37-
"build": "pnpm run clean && tsc && tsc -p tsconfig.esm.json && node -e \"const fs=require('fs');fs.mkdirSync('dist-esm',{recursive:true});fs.writeFileSync('dist-esm/package.json','{\\\"type\\\":\\\"module\\\"}\\n');\"",
38+
"build": "pnpm run clean && tsc && node build-esm.js",
3839
"type-check:esm": "tsc -p tsconfig.esm.json --noEmit",
3940
"commit": "git add . && git-cz",
4041
"prepare": "husky install",
@@ -62,9 +63,12 @@
6263
"copyfiles": "^2.4.1",
6364
"cz-conventional-changelog": "^3.3.0",
6465
"dotenv": "^16.4.5",
66+
"esbuild": "^0.25.10",
67+
"esbuild-plugin-file-path-extensions": "^2.1.4",
6568
"eslint": "^8.23.1",
6669
"eslint-config-prettier": "^8.5.0",
6770
"eslint-plugin-prettier": "^4.2.1",
71+
"glob": "^11.0.3",
6872
"husky": "^8.0.3",
6973
"jest": "^29.7.0",
7074
"near-api-js": "^2.1.4",

0 commit comments

Comments
 (0)