Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add swc (@swc-node/register) support out of box #106

Merged
merged 2 commits into from Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.