Skip to content

Commit 9f27ff9

Browse files
authored
feat: add swc (@swc-node/register) support out of box (#106)
close #102
1 parent b1308ac commit 9f27ff9

11 files changed

+233
-64
lines changed

.changeset/clean-walls-trade.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"synckit": patch
3+
---
4+
5+
feat: add `swc` (`@swc-node/register`) support out of box

README.md

+13-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Perform async work synchronously in Node.js using `worker_threads` with first-cl
2525
- [`ts-node`](#ts-node)
2626
- [`esbuild-register`](#esbuild-register)
2727
- [`esbuild-runner`](#esbuild-runner)
28+
- [`swc`](#swc)
2829
- [`tsx`](#tsx)
2930
- [Benchmark](#benchmark)
3031
- [Sponsors](#sponsors)
@@ -83,7 +84,7 @@ You must make sure, the `result` is serializable by [`Structured Clone Algorithm
8384
1. `SYNCKIT_BUFFER_SIZE`: `bufferSize` to create `SharedArrayBuffer` for `worker_threads` (default as `1024`)
8485
2. `SYNCKIT_TIMEOUT`: `timeout` for performing the async job (no default)
8586
3. `SYNCKIT_EXEC_ARGV`: List of node CLI options passed to the worker, split with comma `,`. (default as `[]`), see also [`node` docs](https://nodejs.org/api/worker_threads.html)
86-
4. `SYNCKIT_TS_RUNNER`: Which TypeScript runner to be used, it could be very useful for development, could be `'ts-node' | 'esbuild-register' | 'esbuild-runner' | 'tsx'`, `'ts-node'` is used by default, make sure you have installed them already
87+
4. `SYNCKIT_TS_RUNNER`: Which TypeScript runner to be used, it could be very useful for development, could be `'ts-node' | 'esbuild-register' | 'esbuild-runner' | 'swc' | 'tsx'`, `'ts-node'` is used by default, make sure you have installed them already
8788

8889
### TypeScript
8990

@@ -97,15 +98,19 @@ If you want to integrate with [tsconfig-paths](https://www.npmjs.com/package/tsc
9798

9899
#### `esbuild-register`
99100

100-
Please view <https://github.com/egoist/esbuild-register> for its document
101+
Please view [`esbuild-register`][] for its document
101102

102103
#### `esbuild-runner`
103104

104-
Please view <https://github.com/folke/esbuild-runner> for its document
105+
Please view [`esbuild-runner`][] for its document
106+
107+
#### `swc`
108+
109+
Please view [`@swc-node/register`][] for its document
105110

106111
#### `tsx`
107112

108-
Please view <https://github.com/esbuild-kit/tsx> for its document
113+
Please view [`tsx`][] for its document
109114

110115
## Benchmark
111116

@@ -137,6 +142,10 @@ Detailed changes for each release are documented in [CHANGELOG.md](./CHANGELOG.m
137142

138143
[MIT][] © [JounQin][]@[1stG.me][]
139144

145+
[`esbuild-register`]: https://github.com/egoist/esbuild-register
146+
[`esbuild-runner`]: https://github.com/folke/esbuild-runner
147+
[`@swc-node/register`]: https://github.com/swc-project/swc-node/tree/master/packages/register
148+
[`tsx`]: https://github.com/esbuild-kit/tsx
140149
[1stg.me]: https://www.1stg.me
141150
[jounqin]: https://github.com/JounQin
142151
[mit]: http://opensource.org/licenses/MIT

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
"@1stg/lib-config": "^9.0.2",
9292
"@changesets/changelog-github": "^0.4.6",
9393
"@changesets/cli": "^2.23.2",
94+
"@swc-node/register": "^1.5.1",
9495
"@types/jest": "^28.1.5",
9596
"@types/node": "^18.0.4",
9697
"deasync": "^0.1.27",

src/index.ts

+10
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export const TsRunner = {
3232
EsbuildRegister: 'esbuild-register',
3333
// https://github.com/folke/esbuild-runner
3434
EsbuildRunner: 'esbuild-runner',
35+
// https://github.com/swc-project/swc-node/tree/master/packages/register
36+
SWC: 'swc',
3537
// https://github.com/esbuild-kit/tsx
3638
TSX: 'tsx',
3739
} as const
@@ -207,6 +209,12 @@ const setupTsRunner = (
207209
}
208210
break
209211
}
212+
case TsRunner.SWC: {
213+
if (!execArgv.includes('-r')) {
214+
execArgv = ['-r', `@${TsRunner.SWC}-node/register`, ...execArgv]
215+
}
216+
break
217+
}
210218
case TsRunner.TSX: {
211219
if (!execArgv.includes('--loader')) {
212220
execArgv = ['--loader', TsRunner.TSX, ...execArgv]
@@ -282,6 +290,8 @@ function startWorkerThread<R, T extends AnyAsyncFn<R>>(
282290
TsRunner.EsbuildRegister,
283291
// https://github.com/folke/esbuild-runner/issues/67
284292
TsRunner.EsbuildRunner,
293+
// https://github.com/swc-project/swc-node/issues/667
294+
TsRunner.SWC,
285295
.../* istanbul ignore next */ (isTsxSupported ? [] : [TsRunner.TSX]),
286296
] as TsRunner[]
287297
).includes(tsRunner)

test/esbuild-register.worker.mjs

-6
This file was deleted.

test/esbuild-runner-error.worker.mts

-6
This file was deleted.

test/esbuild-runner.worker.mjs

-6
This file was deleted.

test/ts-runner.spec.ts

+71-35
Original file line numberDiff line numberDiff line change
@@ -13,75 +13,111 @@ beforeEach(() => {
1313
jest.resetModules()
1414
})
1515

16-
it(TsRunner.EsbuildRegister, async () => {
16+
const workerJsPath = path.resolve(_dirname, 'worker-js')
17+
const workerMjsPath = path.resolve(_dirname, 'worker.mjs')
18+
const workerMtsPath = path.resolve(_dirname, 'worker-mts.mjs')
19+
20+
test(TsRunner.EsbuildRegister, async () => {
1721
const { createSyncFn } = await import('synckit')
18-
const syncFn = createSyncFn<AsyncWorkerFn>(
19-
path.resolve(_dirname, 'esbuild-register.worker.mjs'),
20-
{
21-
tsRunner: TsRunner.EsbuildRegister,
22-
},
23-
)
22+
23+
let syncFn = createSyncFn<AsyncWorkerFn>(workerJsPath, {
24+
tsRunner: TsRunner.EsbuildRegister,
25+
})
26+
expect(syncFn(1)).toBe(1)
27+
expect(syncFn(2)).toBe(2)
28+
expect(syncFn(5)).toBe(5)
29+
30+
syncFn = createSyncFn<AsyncWorkerFn>(workerMjsPath, {
31+
tsRunner: TsRunner.EsbuildRegister,
32+
})
2433
expect(syncFn(1)).toBe(1)
2534
expect(syncFn(2)).toBe(2)
2635
expect(syncFn(5)).toBe(5)
2736

2837
expect(() =>
29-
createSyncFn<AsyncWorkerFn>(
30-
path.resolve(_dirname, 'esbuild-register-error.worker.mjs'),
31-
{
32-
tsRunner: TsRunner.EsbuildRegister,
33-
},
34-
),
38+
createSyncFn<AsyncWorkerFn>(workerMtsPath, {
39+
tsRunner: TsRunner.EsbuildRegister,
40+
}),
3541
).toThrowError('esbuild-register is not supported for .mts files yet')
3642
})
3743

38-
it(TsRunner.EsbuildRunner, async () => {
44+
test(TsRunner.EsbuildRunner, async () => {
3945
const { createSyncFn } = await import('synckit')
40-
const syncFn = createSyncFn<AsyncWorkerFn>(
41-
path.resolve(_dirname, 'esbuild-runner.worker.mjs'),
42-
{
43-
tsRunner: TsRunner.EsbuildRunner,
44-
},
45-
)
46+
47+
let syncFn = createSyncFn<AsyncWorkerFn>(workerJsPath, {
48+
tsRunner: TsRunner.EsbuildRunner,
49+
})
50+
expect(syncFn(1)).toBe(1)
51+
expect(syncFn(2)).toBe(2)
52+
expect(syncFn(5)).toBe(5)
53+
54+
syncFn = createSyncFn<AsyncWorkerFn>(workerMjsPath, {
55+
tsRunner: TsRunner.EsbuildRunner,
56+
})
4657
expect(syncFn(1)).toBe(1)
4758
expect(syncFn(2)).toBe(2)
4859
expect(syncFn(5)).toBe(5)
4960

5061
expect(() =>
51-
createSyncFn<AsyncWorkerFn>(
52-
path.resolve(_dirname, 'esbuild-runner-error.worker.mjs'),
53-
{
54-
tsRunner: TsRunner.EsbuildRunner,
55-
},
56-
),
62+
createSyncFn<AsyncWorkerFn>(workerMtsPath, {
63+
tsRunner: TsRunner.EsbuildRunner,
64+
}),
5765
).toThrowError('esbuild-runner is not supported for .mts files yet')
5866
})
5967

60-
it(TsRunner.TSX, async () => {
68+
test(TsRunner.SWC, async () => {
6169
const { createSyncFn } = await import('synckit')
6270

71+
let syncFn = createSyncFn<AsyncWorkerFn>(workerJsPath, {
72+
tsRunner: TsRunner.SWC,
73+
})
74+
expect(syncFn(1)).toBe(1)
75+
expect(syncFn(2)).toBe(2)
76+
expect(syncFn(5)).toBe(5)
77+
78+
syncFn = createSyncFn<AsyncWorkerFn>(workerMjsPath, {
79+
tsRunner: TsRunner.SWC,
80+
})
81+
expect(syncFn(1)).toBe(1)
82+
expect(syncFn(2)).toBe(2)
83+
expect(syncFn(5)).toBe(5)
84+
85+
expect(() =>
86+
createSyncFn<AsyncWorkerFn>(workerMtsPath, {
87+
tsRunner: TsRunner.SWC,
88+
}),
89+
).toThrowError('swc is not supported for .mts files yet')
90+
})
91+
92+
test(TsRunner.TSX, async () => {
93+
const { createSyncFn } = await import('synckit')
94+
95+
let syncFn = createSyncFn<AsyncWorkerFn>(workerJsPath, {
96+
tsRunner: TsRunner.TSX,
97+
})
98+
expect(syncFn(1)).toBe(1)
99+
expect(syncFn(2)).toBe(2)
100+
expect(syncFn(5)).toBe(5)
101+
63102
if (Number.parseFloat(process.versions.node) < MTS_SUPPORTED_NODE_VERSION) {
64103
// eslint-disable-next-line jest/no-conditional-expect
65104
expect(() =>
66-
createSyncFn<AsyncWorkerFn>(path.resolve(_dirname, 'tsx.worker.mjs'), {
105+
createSyncFn<AsyncWorkerFn>(workerMtsPath, {
67106
tsRunner: TsRunner.TSX,
68107
}),
69108
).toThrowError('tsx is not supported for .mts files yet')
70109
return
71110
}
72111

73-
const syncFn = createSyncFn<AsyncWorkerFn>(
74-
path.resolve(_dirname, 'tsx.worker.mjs'),
75-
{
76-
tsRunner: TsRunner.TSX,
77-
},
78-
)
112+
syncFn = createSyncFn<AsyncWorkerFn>(workerMjsPath, {
113+
tsRunner: TsRunner.TSX,
114+
})
79115
expect(syncFn(1)).toBe(1)
80116
expect(syncFn(2)).toBe(2)
81117
expect(syncFn(5)).toBe(5)
82118
})
83119

84-
it('unknown ts runner', async () => {
120+
test('unknown ts runner', async () => {
85121
const { createSyncFn } = await import('synckit')
86122

87123
expect(() =>

test/tsx.worker.mts

-6
This file was deleted.
File renamed without changes.

0 commit comments

Comments
 (0)