swc-project / swc-node Goto Github PK
View Code? Open in Web Editor NEWFaster ts-node without typecheck
License: MIT License
Faster ts-node without typecheck
License: MIT License
Problem
I intended to leverage @swc-node/jest
with Preact and @testing-library/preact
. To support Preact with TS, I had to add "jsxFactory": "h"
to my tsconfig.json
or /** @jsx h **/
at the top of every Preact component file. The former allows me to configure the entire project once. However, I noticed with this library I'm not able to leverage the power of that TS configuration setting.
Solution
Add support for the TS configuration property jsxFactory
export class CreateCategoryDto {
@IsNotEmpty({ groups: ['create'] })
@IsOptional({ groups: ['update'] })
name!: string;
}
It always throw exception that name not exist
config
const { register } = require('@swc-node/register/register');
register({
extends: tsconfig,
target: 99,
module: 1,
experimentalDecorators: true,
emitDecoratorMetadata: true,
esModuleInterop: true,
jsx: false,
});
ts-node
worked fine
It seems like the custom TypeScript paths are not being recognized:
● Test suite failed to run
Cannot find module '~/test/with-test-database' from 'src/modules/foo/repos/profile.test.ts'
The tsconfig
file:
{
"extends": "tsconfigs/nodejs-executable",
"compilerOptions": {
"lib": [
"ES2019",
"ES2020.BigInt"
],
"target": "ES2019",
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"experimentalDecorators": true,
"baseUrl": "./src",
"paths": {
"~/test/*": ["../test/*"],
"~/*": ["./*"]
}
},
"include": [
"src/**/*.ts",
"test/**/*.ts"
]
}
In ts-jest
there is a pathsToModuleNameMapper
that helps with that.
The following construct seems to confuse the compiler:
export class Base<C extends SharedDomainContainer = SharedDomainContainer> {
public constructor(protected readonly container: C) {}
/**
* Pino logger instance.
*/
protected readonly log = this.container.logger.child({ component: this.constructor.name })
}
TypeError: Cannot read property 'logger' of undefined
Added in swc 1.2.50: swc-project/swc@a310542
Original issue: swc-project/swc#1279
This would fix a lot of typeorm setups.
It seems when using swc-node/jest
that newlines are potentially being double escaped as they show up in snapshot output as raw characters where they were simply interpreted as newlines under the typical jest process.
to: FAKE1-744-894-6541 x3436
- body: |-
- Thanks. We will text you when a dose is available in your area.
- Questions? hidrb.com/faq
- Share? hidrb.com/#share
+ body: >-
+ \n Thanks. We will text you when a dose is available in your area.\n
+ Questions? hidrb.com/faq\n Share? hidrb.com/#share\n
↵
swc
now supports transpiling dynamic imports to CommonJS: swc-project/swc#1028
@swc-node/register
however only sets the jsc.parser.dynamicImport
option for ES2020 modules and newer.
Using @swc-node/register
leads to the following error:
error: import(...) expressions requires `jsc.parser.dynamicImport` to be true
--> /...(file path)...
|
51 | const { GraphQLSchema, GraphQLObjectType } = await import(/* webpackChunkName: "graphql" */ 'graphql');
|
My compilerOptions
:
"allowJs": true,
"target": "esnext",
"lib": ["es6", "dom", "esnext"],
"module": "commonjs",
"moduleResolution": "node",
"strict": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"jsx": "react",
"resolveJsonModule": true,
Could this also be enabled when targeting CommonJS, or made configurable in the API?
Thanks a lot!
Something wrong happen when run jest with @swc-node/jest in Jenkins pipeline.
But the same operation is working on local mac machine.
Here is the error message posted by Jenkins pipeline.
TypeError: Not compatible with your platform. Error message: Error loading shared library ld-linux-x86-64.so.2: No such file or directory
After the last update, I have a pretty odd failure, which I cannot repro on a smaller codebase.
Essentially, I am importing a const that defines a key of the object.
import {
ADVERTISING_AUTHORIZATION_CREDENTIALS,
ADVERTISING_AUTHORIZATION_REDIRECT_FINAL_URI,
} from '../../infra/constants'
Then, I am using it to construct an object:
console.log(
'ADVERTISING_AUTHORIZATION_REDIRECT_FINAL_URI',
ADVERTISING_AUTHORIZATION_REDIRECT_FINAL_URI,
)
const enviro = {
[ADVERTISING_AUTHORIZATION_REDIRECT_FINAL_URI]: 'http://example.com',
}
console.log('enviro', enviro)
This produces the following output:
console.log
ADVERTISING_AUTHORIZATION_REDIRECT_FINAL_URI ADVERTISING_AUTHORIZATION_REDIRECT_FINAL_URI
at Object.<anonymous> (...test.ts:39:1)
console.log
enviro { undefined: 'http://example.com' }
at Object.<anonymous> (...test.ts:47:1)
Notice that ADVERTISING_AUTHORIZATION_REDIRECT_FINAL_URI
does have a value, as evident from the first console log.
Yet when using in the context of object key, it seems to be undefined
.
Any tips on how to repro this better are appreciated!
Cheers!
About tagline says
Faster ts-node without typecheck
AFAIK ts-node
is a CLI utility that lets you run TypeScript files directly in a manner similar to how node cli lets you do that
I can't seem to figure out how to use swc-node
the same way?
I'm not sure about this, but it provides almost identical api to @swc/core
Related to #333
My setup:
transform: {
'^.+\\.(t|j)sx?$': [
'@swc-node/jest',
{
target: 'es2019',
experimentalDecorators: true,
emitDecoratorMetadata: true,
keepClassNames: true,
},
],
},
"@swc-node/jest": "1.1.1",
"@swc/cli": "0.1.35",
"@swc/core": "1.2.50",
Still seems to be adding extra 1
to typeorm models:
RepositoryNotFoundError: No repository for "User1" was found. Looks like this entity is not registered in current "default" connection?
Hey,
I'm trying to figure out how to use @swc-node/core
, but not sure how I would use it. This tool provides 2 functions that receive an input string only.
Is there a way I can define an entry file, and from there, it will automatically transpile everything that this file needs (recursively)?
Maybe write some custom code for it?
Thanks
Within @swc-node/jest, you're caching the previous transformation result, which is something that jest does internally already. We have a relatively large code base with 17,000 tests and we were finding that memory usage was quite high. Upon looking at the heap usage, we found that the same transformation strings were in memory multiple times.
Jest already caches transformations. You provide a getCacheKey function to handle changes in config. I noticed that @swc/jest has the same issue, but someone has created a PR that adds the getCacheKey function see - #32. Removing the cache from this lib and adding getCacheKey reduces the memory usage significantly and subsequently reduced the total time by 10seconds for us.
If you also return a createTransformer function, you get the config for transformations directly, and do not have to handle the differences between jest 26 and 27. The PR above also uses that. It can pretty much be changed to this:
import { Options, transformJest } from '@swc-node/core'
import createCacheKeyFunction from '@jest/create-cache-key-function'
export const createTransformer = (config: Options) => ({
process: (src: string, path: string) => {
if (/\.(tsx?|jsx?|mjs)$/.test(path)) {
return transformJest(src, path, config)
}
return src
},
getCacheKey: createCacheKeyFunction([], [JSON.stringify(config)])
})
I want to set dynamicImport
to true
.
I tried using the .swcrc
file in the root, but that did not work.
Any clues?
Thanks!
Hello, @Brooooooklyn.
I'm found a difference between README.md
and read-default-config.ts
in @swc-node/register
package:
README.md
@swc-node/register
respect the following option intsconfig
:
compilerOptions.target
switch (target) { // ... case ts.ScriptTarget.ES2019: return 'es2019' case ts.ScriptTarget.ES2020: case ts.ScriptTarget.ESNext: case ts.ScriptTarget.Latest: return 'es2020' case ts.ScriptTarget.JSON: return 'es5' }
read-default-tsconfig.ts
function toTsTarget(target: ts.ScriptTarget) { switch (target) { // ... case ts.ScriptTarget.ES2019: case ts.ScriptTarget.ES2020: case ts.ScriptTarget.ES2021: case ts.ScriptTarget.ESNext: case ts.ScriptTarget.Latest: return 'es2019' case ts.ScriptTarget.JSON: return 'es5' } }
Best wishes,
Sergey.
If two test files import a common TS file, this package is transpiling the common file twice.
This means the package is very fast for small repos but perf advantage over ts-jest rapidly drops off as more test files are added.
I think you need to maintain a cache of paths and their transpile output, either in memory or on disk.
Hi,
I am experimenting with swc-node as a faster replacement for ts-node on a side project of mine.
It works create on macOS, however, the specific project is supposed to run on my local Raspberry PI.
On there I get the following error message:
TypeError: Can not find node binding files from @swc/core-linux-arm-gnueabi, @swc/core-linux-arm-gnueabihf, @swc/core-linux-arm-musleabi, @swc/core-linux-arm-musleabihf, @swc/core-linux-arm-gnueabi, @swc/core-linux-arm-gnueabihf, @swc/core-linux-arm-musleabi, @swc/core-linux-arm-musleabihf and [... some node_modules paths]
originating in @node-rs/helper/lib/loader.js:27:11
I did follow the "register / CLI" approach described here: https://github.com/Brooooooklyn/swc-node/tree/master/packages/register
Maybe helpful information:
$ arch
armv7l
$ uname -a
Linux homepi 5.10.17-v7l+ #1421 SMP Thu May 27 14:00:13 BST 2021 armv7l GNU/Linux
Let me know if there is anything I can help with.
Best,
Michael
If I have a file that contains
// myFile.ts
export const addOne = (x: number): string => `${x + 1}`
export const someFunc = (x: number): string => `The answer is : ${addOne(x)}`
And I want to test the two functions separately and therefore mock addOne
:
import * as myFile from './myFile'
describe('someFunc', () => {
const expected = '2';
const addOneSpy = jest.spyOn(myFile, 'addOne').mockResolvedValue(expected);
it('should call addOne', () => {
expect(addOneSpy).toHaveBeenCalledWith(1);
});
});
with ts-jest
, this code snippet provided works. With @swc-node/jest
, it seems any jest spies from the same file cannot be spied on, and if they are, result in the error:
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: 1
Number of calls: 0
Note that I have tried the exact same scenario but exporting them as actual functions (i.e. export function someFunc(x: number): string {
), but still run into the same problem.
My macos version is 10.13.6 , when I run yarn test
which is a script of 'jest'.
dyld: lazy symbol binding failed: Symbol not found: ____chkstk_darwin
Referenced from: /Users/luxueyan/mine/vue-next-demo/element-plus/node_modules/@swc-node/core-darwin/swc.darwin.node (which was built for Mac OS X 10.15)
Expected in: /usr/lib/libSystem.B.dylib
node -r @swc-node/register index.ts
seems to work, but only if "type": "module"
isn't in package.json. I would give more details, but I don't know what the problem is myself.
The compiler in @swc-node/core
supports the option "inline"
for the sourcemap
option, but @swc-node/register
doesn't provide a configuration option for it.
When debugging node code using Chrome Dev Tools, it would be nice to be able to inline the source map in order to debug using the original source maps. Would it be possible to pass through the option to the underlying transformer somehow?
See cloudevents/sdk-javascript#323
This is the code: https://github.com/cloudevents/sdk-javascript/blob/73f0becc2b8e4f10ae40e23b77e4161d9b5ff611/src/event/cloudevent.ts#L19-L22
It works with ts-jest
, does not work with @swc-node/[email protected]
.
When emitDecoratorMetadata is enabled, property decorators is being called with property descriptors but tsc dont do this only return property descriptor when is set or is a function
lastest swc/core supported,swc-project/swc#1834
Hi, awesome project!
I'm trying to adopt @swc-node/jest
to replace ts-jest
in our project but found the jest transform phase won't report any syntaxes error if the test cases written in ts have any.
create a empty folder and run
yarn add -D jest @swc-node/jest
Add jest.config.js
module.exports = {
transform: {
'^.+\\.(t|j)sx?$': [
'@swc-node/jest',
{ jsc: { minify: false } },
],
},
}
Create a simple jest test case index.test.ts
in wrong ts syntax
test('should say hello', () => {
let x: string = 123
console.log('hello' as number)
})
Run it yarn jest index.test.ts
It should display type checking errors
Only passed without any type checking errors reported
Though ts-jest can cover the type checking but I'm not sure if the type checking is not included here for speed or it's sth missed in swc. Feel free to close if it's not the issue of this project. Thanks!
I use top-level await
in TS, and it works fine, however, Jest tests importing modules with top-level await
don't work. If they are supposed to work, let me know and I'll prepare a minimal broken demo, which works with TS but modules can't be tested with Jest, either with @swc-node/jest
or with other methods. It is not clear where the problem lies, as of now. It could be swc, Jest or somewhere else. It may be related to #120 or not.
error: Unexpected token `@`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, ` for template literal, (, or an identifier
--> my.ts:31:1
|
31 | @injectable()
FAIL my.test.ts
● Test suite failed to run
GenericFailure: failed to process js file
Caused by:
failed to parse module
at Compiler.transformSync (node_modules/@swc/core/index.js:116:25)
at Object.transformSync (node_modules/@swc/core/index.js:196:21)
at Object.transformJest (node_modules/@swc-node/core/index.ts:59:10)
at Object.process (node_modules/@swc-node/jest/index.ts:8:14)
at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:464:35)
at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:569:40)
at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:607:25)
injectable is from InversifyJS
getting this error when testing React with Jest.
jest.config.js
transform: {
'^.+\\.(t|j)sx?$': [
'@swc-node/jest',
{
dynamicImport: true,
jsx: true,
},
],
},
this causes the error
export const complexGen = new FixtureGenerator({ size: 25, count: 1000 })
It's unclear to me what the motivation is for the @swc-node/jest project as a distinct project from @swc/jest.
Perhaps this could be documented somewhere?
using @swc-node/register to compile monorepo type projects, it seems that packages referenced by typescript's paths do not compile.
node -r @swc-node/register .\source\entry\src\index.ts
import * as ccc from "@pro/aaa"
the aaa package does not seem to compile
Instead, it looks for the main path in the packages configuration(aaa/package.json) of the aaa package
Just installed @swc-node/jest 1.3.4 with npm install @swc-node/jest
and changed my jest transform to use it.
When I run jest
though, I get the error:
> jest
Error: Cannot find module '@node-rs/xxhash'
Require stack:
- ../dir/node_modules/@swc-node/jest/lib/index.js
- ../dir/node_modules/jest-util/build/requireOrImportModule.js
- ../dir/node_modules/jest-util/build/index.js
- ../dir/node_modules/@jest/core/build/cli/index.js
- ../dir/node_modules/@jest/core/build/jest.js
- ../dir/node_modules/jest-cli/build/cli/index.js
- ../dir/node_modules/jest-cli/bin/jest.js
- ../dir/node_modules/jest/bin/jest.js
It seems like @node-rs/xxhash
was specified as a devDependency, should it have been specified as a regular dependency instead?
I use a optional call. It throw error.
TypeError: Illegal invocation
95 | // Remove the old try catch block since there will be no error to be thrown
96 | // console.log(element.focus)
> 97 | element.focus?.()
| ^
98 | // let _a
99 | // (_a = element.focus) === null || _a === void 0 ? void 0 : _a.call(element)
100 | Utils.IgnoreUtilFocusChanges = false
at Function.focus (node_modules/jsdom/lib/jsdom/living/generated/HTMLElement.js:114:15)
at attemptFocus (packages/utils/aria.ts:97:1)
at Object.focusFirstDescendant (packages/utils/aria.ts:159:1)
at Object.focusFirstDescendant (packages/utils/aria.ts:159:1)
at packages/drawer/src/index.vue:147:1
It looks like the focus method missed right context. The transformed code may be different with the below 'es5' statement which is transformed by tsc.
var _a
(_a = element.focus) === null || _a === void 0 ? void 0 : _a.call(element)
`
Error: Cannot find module 'x/t'
Getting the following error for every test file when running all jest tests:
TypeError: Cannot set property 'filename' of null
But if I run a single jest test, by passing in a filename, it runs just fine.
Any ideas?
Source Code
test('given no DIContainerContext.Provider then an error is thrown', () => {
const { result } = renderHook(() => useDIContainer());
expect(result.error?.message).toMatchInlineSnapshot();
});
Output
Test suite failed to run
Jest: Couldn't locate all inline snapshots.
at Object.parse (node_modules/jest-snapshot/build/InlineSnapshots.js:267:11)
at Object.parse (node_modules/prettier/index.js:13625:19)
at coreFormat (node_modules/prettier/index.js:14899:14)
at format (node_modules/prettier/index.js:15131:14)
at node_modules/prettier/index.js:57542:12
at Object.format (node_modules/prettier/index.js:57562:12)
In our TypeScript + React Native project I'm trying to switch our jest tests to swc. It's working great for the part of my codebase that does not use mobx, however, as soon as the transformer comes accross mobx decorators (observer, observable, action etc) the following error is thrown:
TypeError: decorator is not a function
20 | }
21 |
> 22 | @observable
| ^
23 | public width = 0;
24 |
25 | @observable
at src/styles/dimension-store.tsx:22:16
at Array.reduce (<anonymous>)
at _applyDecoratedDescriptor (src/styles/dimension-store.tsx:21:41)
at Object.<anonymous> (src/styles/dimension-store.tsx:134:258)
at Object.<anonymous> (src/styles/style-constants.base.ts:3:51)TypeError: decorator is not a function
I tried to patch it by including reflect-metadata
or core-js
in my test setups, it does remove the error but it causes mobx to fail (properties that are decorated are no longer initialized). Can't seem to figure out what the problem is.
I have the following jest config:
transform: {
"^.+\\.tsx?$": [
"@swc-node/jest",
// configuration
{
esModuleInterop: true,
dynamicImport: true,
experimentalDecorators: true,
emitDecoratorMetadata: true,
},
],
"^.+\\.js$": `${packageRoot}/node_modules/react-native/jest/preprocessor.js`,
}
What makes this so much faster than the native @swc/core?
And does is also provide minification?
I'm using @swc-node/register
to run tests via uvu
in a Preact project and ran into this issue. It looks like @swc-node/register
automatically passes the jsx
option, but doesn't pass along any configured jsxFactory
or jsxFragmentFactory
values which makes it difficult to use any non-React JSX engines.
Could you please provide a minimal example which caused the compile error?
Originally posted by @Brooooooklyn in #51 (comment)
Here is an error I've received:
● Test suite failed to run
error: Expected '>', got 'style'
|
2 | return <span style={{ display: "block", width: "10px", height: "10px", backgroundColor: "#ffffff" }} />
| ^^^^^
Caused by:
0: failed to process js file
1: Syntax Error
at Compiler.transformSync (node_modules/@swc/core/index.js:135:25)
at transformSync (node_modules/@swc/core/index.js:215:21)
at transformJest (node_modules/@swc-node/core/index.ts:72:26)
at Object.process (node_modules/@swc-node/jest/index.ts:30:27)
at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:612:31)
at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:758:40)
at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:815:19)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 0.38 s
Ran all test suites related to changed files.
Watch Usage: Press w to show more.
Here is my config for jest.config.js:
module.exports = {
globalSetup: "<rootDir>/setupTestEnv.js",
setupFilesAfterEnv: ["./setupTests.js"],
testPathIgnorePatterns: ["<rootDir>/node_modules", "<rootDir>/cypress"],
moduleNameMapper: {
"^~/components(.*)$": "<rootDir>/src/components$1",
"^~/containers(.*)$": "<rootDir>/src/containers$1",
"^~/api(.*)$": "<rootDir>/src/api$1",
"^~(.*)$": "<rootDir>/src$1",
"^@/public(.*)$": "<rootDir>/public$1",
"^@/local(.*)$": "<rootDir>/local$1",
".+\\.(css|sass|less|scss)$": "<rootDir>/mocks/styles.js"
},
transform: {
"^.+\\.(js|jsx|ts|tsx)$": "@swc-node/jest",
".+\\.(jpg|png|jpeg|gif)$": "jest-transform-stub",
".+.svg": "<rootDir>/mocks/svgs.js"
}
};
Is there a missing package in configuration or this feature is not iplemented yet?
EDIT
I also noticed that if I remove the style attribute it works fine, but then appears another error:
src/components/Test/index.test.js
● Test suite failed to run
error: Expression expected
|
11 | render(<TestComponent />);
| ^
error: Expression expected
|
11 | render(<TestComponent />);
| ^
error: Unexpected token `)`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, ` for template literal, (, or an identifier
|
11 | render(<TestComponent />);
| ^
Caused by:
0: failed to process js file
1: Syntax Error
at Compiler.transformSync (node_modules/@swc/core/index.js:135:25)
at transformSync (node_modules/@swc/core/index.js:215:21)
at transformJest (node_modules/@swc-node/core/index.ts:72:26)
at Object.process (node_modules/@swc-node/jest/index.ts:30:27)
```
and test be like:
```
describe("Test component", () => {
it("Displays fetched data", async () => {
render(<TestComponent />);
const author = await screen.findByTestId("result");
expect(author).toHaveTextContent("Author: John Maverick");
});
});
The transformer would be even faster, if it would not need to rerun every file transformation on each test run. I guess we just need to add something like
getCacheKey() {
return crypto
.createHash('md5')
.update(fs.readFileSync(__filename))
.digest('hex');
},
to the transform's exports.
Support angular
Hi,
I tried several things, but nothing worked, so I come directly ask the question :
I want to be able to debug my jest tests, so put a break point in my IDE, and be able to stop on it, like with ts-jest. but with swc, it fails. I supposed that the source-maps were missing, but event with the option
{
"sourceMaps": true
}
in my .swcrc file it fails. Does someone has the same issue or have a solution please?
If user installs @swc-node/jest
and @swc/core
at the same time it might result into duplicated versions of @swc/core
which will increase the installation size a lot.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.