Skip to content

Commit 9ced9ad

Browse files
committed
feat(oxlint2): bundle
with tsdown
1 parent c6792b0 commit 9ced9ad

File tree

7 files changed

+635
-139
lines changed

7 files changed

+635
-139
lines changed

napi/oxlint2/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dist/

napi/oxlint2/package.json

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
{
22
"name": "oxlint2",
33
"version": "0.1.0",
4-
"main": "src-js/index.js",
4+
"main": "dist/index.js",
55
"type": "module",
66
"scripts": {
7-
"build-dev": "napi build --platform --js ./bindings.js --dts ./bindings.d.ts --output-dir src-js --no-dts-cache --esm",
8-
"build-test": "pnpm run build-dev --profile coverage --features force_test_reporter",
9-
"build": "pnpm run build-dev --release",
7+
"build-napi": "napi build --platform --js ./bindings.js --dts ./bindings.d.ts --output-dir src-js --no-dts-cache --esm",
8+
"build-napi-test": "pnpm run build-napi --profile coverage --features force_test_reporter",
9+
"build-napi-release": "pnpm run build-napi --release",
10+
"build-js": "node scripts/build.js",
11+
"build-dev": "pnpm run build-napi && pnpm run build-js",
12+
"build-test": "pnpm run build-napi-test && pnpm run build-js",
13+
"build": "pnpm run build-napi-release && pnpm run build-js",
1014
"test": "vitest"
1115
},
1216
"engines": {
@@ -26,8 +30,12 @@
2630
"registry": "https://registry.npmjs.org/",
2731
"access": "public"
2832
},
33+
"files": [
34+
"dist"
35+
],
2936
"devDependencies": {
3037
"execa": "^9.6.0",
38+
"tsdown": "^0.13.0",
3139
"typescript": "catalog:",
3240
"vitest": "catalog:"
3341
},

napi/oxlint2/scripts/build.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#!/usr/bin/env node
2+
3+
import { execSync } from 'child_process';
4+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
5+
import { dirname, join } from 'path';
6+
import { fileURLToPath } from 'url';
7+
8+
const __dirname = dirname(fileURLToPath(import.meta.url));
9+
const rootDir = join(__dirname, '..');
10+
11+
console.log('Building with tsdown...');
12+
try {
13+
execSync('pnpm tsdown', { stdio: 'inherit', cwd: rootDir });
14+
} catch (error) {
15+
console.error('Build failed:', error);
16+
process.exit(1);
17+
}
18+
19+
// Create directories after tsdown build.
20+
const distDir = join(rootDir, 'dist');
21+
const distGeneratedDir = join(distDir, 'generated');
22+
const parserRawTransferDir = join(distDir, 'parser', 'raw-transfer');
23+
const parserGeneratedDir = join(distDir, 'parser', 'generated', 'lazy');
24+
25+
// Create all necessary directories
26+
if (!existsSync(distGeneratedDir)) {
27+
mkdirSync(distGeneratedDir, { recursive: true });
28+
}
29+
if (!existsSync(parserRawTransferDir)) {
30+
mkdirSync(parserRawTransferDir, { recursive: true });
31+
}
32+
if (!existsSync(parserGeneratedDir)) {
33+
mkdirSync(parserGeneratedDir, { recursive: true });
34+
}
35+
36+
console.log('Copying generated files...');
37+
// Copy generated constants file
38+
const constantsPath = join(rootDir, 'src-js/generated/constants.cjs');
39+
if (existsSync(constantsPath)) {
40+
copyFileSync(constantsPath, join(distGeneratedDir, 'constants.cjs'));
41+
console.log('Copied constants.cjs');
42+
} else {
43+
console.error(
44+
'Warning: generated/constants.cjs not found. Make sure to run napi build first.',
45+
);
46+
}
47+
48+
// Copy parser files
49+
const parserFiles = [
50+
{
51+
src: join(rootDir, '../parser/raw-transfer/lazy-common.js'),
52+
dest: join(parserRawTransferDir, 'lazy-common.cjs'),
53+
},
54+
{
55+
src: join(rootDir, '../parser/raw-transfer/node-array.js'),
56+
dest: join(parserRawTransferDir, 'node-array.cjs'),
57+
},
58+
{
59+
src: join(rootDir, '../parser/generated/lazy/walk.js'),
60+
dest: join(parserGeneratedDir, 'walk.cjs'),
61+
},
62+
{
63+
src: join(rootDir, '../parser/generated/lazy/constructors.js'),
64+
dest: join(parserGeneratedDir, 'constructors.cjs'),
65+
},
66+
];
67+
68+
for (const { src, dest } of parserFiles) {
69+
if (existsSync(src)) {
70+
// replace a any `require(`*.js`)` with `require(`*`.cjs`)`
71+
const content = String(readFileSync(src));
72+
const updatedContent = content.replace(
73+
/require\((['"])(.*?)(\.js)(['"])\)/g,
74+
(match, p1, p2, p3, p4) => {
75+
return `require(${p1}${p2}.cjs${p4})`;
76+
},
77+
);
78+
writeFileSync(dest, updatedContent);
79+
80+
//
81+
// copyFileSync(src, dest);
82+
console.log(`Copied ${src.split('/').pop()}`);
83+
} else {
84+
console.error(`Warning: parser file not found: ${src}`);
85+
}
86+
}
87+
88+
// Copy native .node files that might exist in src-js
89+
const nodeFiles = [
90+
'oxlint.darwin-arm64.node',
91+
'oxlint.darwin-x64.node',
92+
'oxlint.linux-x64-gnu.node',
93+
'oxlint.linux-arm64-gnu.node',
94+
'oxlint.linux-x64-musl.node',
95+
'oxlint.linux-arm64-musl.node',
96+
'oxlint.win32-x64-msvc.node',
97+
'oxlint.win32-arm64-msvc.node',
98+
];
99+
100+
for (const nodeFile of nodeFiles) {
101+
const srcPath = join(rootDir, 'src-js', nodeFile);
102+
if (existsSync(srcPath)) {
103+
copyFileSync(srcPath, join(distDir, nodeFile));
104+
console.log(`Copied ${nodeFile}`);
105+
}
106+
}
107+
108+
console.log('Build complete!');

napi/oxlint2/src-js/index.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import { addVisitorToCompiled, compiledVisitor, finalizeCompiledVisitor, initCom
99
// and need to make sure get same instance of modules as it uses internally,
1010
// otherwise `TOKEN` here won't be same `TOKEN` as used within `oxc-parser`.
1111
const require = createRequire(import.meta.url);
12-
const { TOKEN } = require('../../parser/raw-transfer/lazy-common.js'),
13-
walkProgram = require('../../parser/generated/lazy/walk.js');
12+
const { TOKEN } = require('../dist/parser/raw-transfer/lazy-common.cjs'),
13+
walkProgram = require('../dist/parser/generated/lazy/walk.cjs');
1414

1515
// --------------------
1616
// Plugin loading
@@ -42,7 +42,9 @@ async function loadPlugin(path) {
4242

4343
async function loadPluginImpl(path) {
4444
if (registeredPluginPaths.has(path)) {
45-
return JSON.stringify({ Failure: 'This plugin has already been registered' });
45+
return JSON.stringify({
46+
Failure: 'This plugin has already been registered',
47+
});
4648
}
4749

4850
const { default: plugin } = await import(path);
@@ -56,7 +58,10 @@ async function loadPluginImpl(path) {
5658

5759
for (const [ruleName, rule] of Object.entries(plugin.rules)) {
5860
ruleNames.push(ruleName);
59-
registeredRules.push({ rule, context: new Context(`${pluginName}/${ruleName}`) });
61+
registeredRules.push({
62+
rule,
63+
context: new Context(`${pluginName}/${ruleName}`),
64+
});
6065
}
6166

6267
return JSON.stringify({ Success: { name: pluginName, offset, ruleNames } });
@@ -194,7 +199,14 @@ function lintFile([filePath, bufferId, buffer, ruleIds]) {
194199

195200
const sourceText = textDecoder.decode(buffer.subarray(0, sourceByteLen));
196201
const sourceIsAscii = sourceText.length === sourceByteLen;
197-
const ast = { buffer, sourceText, sourceByteLen, sourceIsAscii, nodes: new Map(), token: TOKEN };
202+
const ast = {
203+
buffer,
204+
sourceText,
205+
sourceByteLen,
206+
sourceIsAscii,
207+
nodes: new Map(),
208+
token: TOKEN,
209+
};
198210

199211
walkProgram(programPos, ast, compiledVisitor);
200212
}

napi/oxlint2/test/e2e.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { describe, expect, it } from 'vitest';
55
import { execa } from 'execa';
66

77
const PACKAGE_ROOT_PATH = path.dirname(import.meta.dirname);
8-
const ENTRY_POINT_PATH = path.join(PACKAGE_ROOT_PATH, 'src-js/index.js');
8+
const ENTRY_POINT_PATH = path.join(PACKAGE_ROOT_PATH, 'dist/index.js');
99

1010
async function runOxlint(cwd: string, args: string[] = []) {
1111
return await execa('node', [ENTRY_POINT_PATH, ...args], {

napi/oxlint2/tsdown.config.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { defineConfig } from 'tsdown';
2+
3+
export default defineConfig({
4+
entry: ['src-js/index.js'],
5+
format: ['esm'],
6+
platform: 'node',
7+
target: 'node20',
8+
outDir: 'dist',
9+
clean: true,
10+
bundle: true,
11+
external: [
12+
// External native bindings
13+
'./oxlint.*.node',
14+
'oxlint2-*',
15+
// External the generated constants file - we'll copy it separately
16+
'./generated/constants.cjs',
17+
// These are generated (also used by oxc-parser, so we'll copy them separately)
18+
/..\/parser\/.*/,
19+
],
20+
});

0 commit comments

Comments
 (0)