Skip to content

Commit

Permalink
feat: add swc (@swc-node/register) support out of box (#106)
Browse files Browse the repository at this point in the history
close #102
  • Loading branch information
JounQin committed Aug 10, 2022
1 parent b1308ac commit 9f27ff9
Show file tree
Hide file tree
Showing 11 changed files with 233 additions and 64 deletions.
5 changes: 5 additions & 0 deletions .changeset/clean-walls-trade.md
@@ -0,0 +1,5 @@
---
"synckit": patch
---

feat: add `swc` (`@swc-node/register`) support out of box
17 changes: 13 additions & 4 deletions README.md
Expand Up @@ -25,6 +25,7 @@ Perform async work synchronously in Node.js using `worker_threads` with first-cl
- [`ts-node`](#ts-node)
- [`esbuild-register`](#esbuild-register)
- [`esbuild-runner`](#esbuild-runner)
- [`swc`](#swc)
- [`tsx`](#tsx)
- [Benchmark](#benchmark)
- [Sponsors](#sponsors)
Expand Down Expand Up @@ -83,7 +84,7 @@ You must make sure, the `result` is serializable by [`Structured Clone Algorithm
1. `SYNCKIT_BUFFER_SIZE`: `bufferSize` to create `SharedArrayBuffer` for `worker_threads` (default as `1024`)
2. `SYNCKIT_TIMEOUT`: `timeout` for performing the async job (no default)
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)
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
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

### TypeScript

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

#### `esbuild-register`

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

#### `esbuild-runner`

Please view <https://github.com/folke/esbuild-runner> for its document
Please view [`esbuild-runner`][] for its document

#### `swc`

Please view [`@swc-node/register`][] for its document

#### `tsx`

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

## Benchmark

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

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

[`esbuild-register`]: https://github.com/egoist/esbuild-register
[`esbuild-runner`]: https://github.com/folke/esbuild-runner
[`@swc-node/register`]: https://github.com/swc-project/swc-node/tree/master/packages/register
[`tsx`]: https://github.com/esbuild-kit/tsx
[1stg.me]: https://www.1stg.me
[jounqin]: https://GitHub.com/JounQin
[mit]: http://opensource.org/licenses/MIT
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -91,6 +91,7 @@
"@1stg/lib-config": "^9.0.2",
"@changesets/changelog-github": "^0.4.6",
"@changesets/cli": "^2.23.2",
"@swc-node/register": "^1.5.1",
"@types/jest": "^28.1.5",
"@types/node": "^18.0.4",
"deasync": "^0.1.27",
Expand Down
10 changes: 10 additions & 0 deletions src/index.ts
Expand Up @@ -32,6 +32,8 @@ export const TsRunner = {
EsbuildRegister: 'esbuild-register',
// https://github.com/folke/esbuild-runner
EsbuildRunner: 'esbuild-runner',
// https://github.com/swc-project/swc-node/tree/master/packages/register
SWC: 'swc',
// https://github.com/esbuild-kit/tsx
TSX: 'tsx',
} as const
Expand Down Expand Up @@ -207,6 +209,12 @@ const setupTsRunner = (
}
break
}
case TsRunner.SWC: {
if (!execArgv.includes('-r')) {
execArgv = ['-r', `@${TsRunner.SWC}-node/register`, ...execArgv]
}
break
}
case TsRunner.TSX: {
if (!execArgv.includes('--loader')) {
execArgv = ['--loader', TsRunner.TSX, ...execArgv]
Expand Down Expand Up @@ -282,6 +290,8 @@ function startWorkerThread<R, T extends AnyAsyncFn<R>>(
TsRunner.EsbuildRegister,
// https://github.com/folke/esbuild-runner/issues/67
TsRunner.EsbuildRunner,
// https://github.com/swc-project/swc-node/issues/667
TsRunner.SWC,
.../* istanbul ignore next */ (isTsxSupported ? [] : [TsRunner.TSX]),
] as TsRunner[]
).includes(tsRunner)
Expand Down
6 changes: 0 additions & 6 deletions test/esbuild-register.worker.mjs

This file was deleted.

6 changes: 0 additions & 6 deletions test/esbuild-runner-error.worker.mts

This file was deleted.

6 changes: 0 additions & 6 deletions test/esbuild-runner.worker.mjs

This file was deleted.

106 changes: 71 additions & 35 deletions test/ts-runner.spec.ts
Expand Up @@ -13,75 +13,111 @@ beforeEach(() => {
jest.resetModules()
})

it(TsRunner.EsbuildRegister, async () => {
const workerJsPath = path.resolve(_dirname, 'worker-js')
const workerMjsPath = path.resolve(_dirname, 'worker.mjs')
const workerMtsPath = path.resolve(_dirname, 'worker-mts.mjs')

test(TsRunner.EsbuildRegister, async () => {
const { createSyncFn } = await import('synckit')
const syncFn = createSyncFn<AsyncWorkerFn>(
path.resolve(_dirname, 'esbuild-register.worker.mjs'),
{
tsRunner: TsRunner.EsbuildRegister,
},
)

let syncFn = createSyncFn<AsyncWorkerFn>(workerJsPath, {
tsRunner: TsRunner.EsbuildRegister,
})
expect(syncFn(1)).toBe(1)
expect(syncFn(2)).toBe(2)
expect(syncFn(5)).toBe(5)

syncFn = createSyncFn<AsyncWorkerFn>(workerMjsPath, {
tsRunner: TsRunner.EsbuildRegister,
})
expect(syncFn(1)).toBe(1)
expect(syncFn(2)).toBe(2)
expect(syncFn(5)).toBe(5)

expect(() =>
createSyncFn<AsyncWorkerFn>(
path.resolve(_dirname, 'esbuild-register-error.worker.mjs'),
{
tsRunner: TsRunner.EsbuildRegister,
},
),
createSyncFn<AsyncWorkerFn>(workerMtsPath, {
tsRunner: TsRunner.EsbuildRegister,
}),
).toThrowError('esbuild-register is not supported for .mts files yet')
})

it(TsRunner.EsbuildRunner, async () => {
test(TsRunner.EsbuildRunner, async () => {
const { createSyncFn } = await import('synckit')
const syncFn = createSyncFn<AsyncWorkerFn>(
path.resolve(_dirname, 'esbuild-runner.worker.mjs'),
{
tsRunner: TsRunner.EsbuildRunner,
},
)

let syncFn = createSyncFn<AsyncWorkerFn>(workerJsPath, {
tsRunner: TsRunner.EsbuildRunner,
})
expect(syncFn(1)).toBe(1)
expect(syncFn(2)).toBe(2)
expect(syncFn(5)).toBe(5)

syncFn = createSyncFn<AsyncWorkerFn>(workerMjsPath, {
tsRunner: TsRunner.EsbuildRunner,
})
expect(syncFn(1)).toBe(1)
expect(syncFn(2)).toBe(2)
expect(syncFn(5)).toBe(5)

expect(() =>
createSyncFn<AsyncWorkerFn>(
path.resolve(_dirname, 'esbuild-runner-error.worker.mjs'),
{
tsRunner: TsRunner.EsbuildRunner,
},
),
createSyncFn<AsyncWorkerFn>(workerMtsPath, {
tsRunner: TsRunner.EsbuildRunner,
}),
).toThrowError('esbuild-runner is not supported for .mts files yet')
})

it(TsRunner.TSX, async () => {
test(TsRunner.SWC, async () => {
const { createSyncFn } = await import('synckit')

let syncFn = createSyncFn<AsyncWorkerFn>(workerJsPath, {
tsRunner: TsRunner.SWC,
})
expect(syncFn(1)).toBe(1)
expect(syncFn(2)).toBe(2)
expect(syncFn(5)).toBe(5)

syncFn = createSyncFn<AsyncWorkerFn>(workerMjsPath, {
tsRunner: TsRunner.SWC,
})
expect(syncFn(1)).toBe(1)
expect(syncFn(2)).toBe(2)
expect(syncFn(5)).toBe(5)

expect(() =>
createSyncFn<AsyncWorkerFn>(workerMtsPath, {
tsRunner: TsRunner.SWC,
}),
).toThrowError('swc is not supported for .mts files yet')
})

test(TsRunner.TSX, async () => {
const { createSyncFn } = await import('synckit')

let syncFn = createSyncFn<AsyncWorkerFn>(workerJsPath, {
tsRunner: TsRunner.TSX,
})
expect(syncFn(1)).toBe(1)
expect(syncFn(2)).toBe(2)
expect(syncFn(5)).toBe(5)

if (Number.parseFloat(process.versions.node) < MTS_SUPPORTED_NODE_VERSION) {
// eslint-disable-next-line jest/no-conditional-expect
expect(() =>
createSyncFn<AsyncWorkerFn>(path.resolve(_dirname, 'tsx.worker.mjs'), {
createSyncFn<AsyncWorkerFn>(workerMtsPath, {
tsRunner: TsRunner.TSX,
}),
).toThrowError('tsx is not supported for .mts files yet')
return
}

const syncFn = createSyncFn<AsyncWorkerFn>(
path.resolve(_dirname, 'tsx.worker.mjs'),
{
tsRunner: TsRunner.TSX,
},
)
syncFn = createSyncFn<AsyncWorkerFn>(workerMjsPath, {
tsRunner: TsRunner.TSX,
})
expect(syncFn(1)).toBe(1)
expect(syncFn(2)).toBe(2)
expect(syncFn(5)).toBe(5)
})

it('unknown ts runner', async () => {
test('unknown ts runner', async () => {
const { createSyncFn } = await import('synckit')

expect(() =>
Expand Down
6 changes: 0 additions & 6 deletions test/tsx.worker.mts

This file was deleted.

File renamed without changes.

0 comments on commit 9f27ff9

Please sign in to comment.