swc-project / jest Goto Github PK
View Code? Open in Web Editor NEWSuper-fast alternative for babel-jest or ts-jest without type checking. Please use main repository for issues
Super-fast alternative for babel-jest or ts-jest without type checking. Please use main repository for issues
Tried the "drop-in replacement" for ts-jest, but ran into problems with a node_module that resolved to a flowtype file. It was not able to parse the file (perhaps not surprising), and the test fails.
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/workspace/node_modules/react-select/src/types.js:2
import type { Ref } from 'react';
^^^^^^
SyntaxError: Cannot use import statement outside a module
I'm not sure how using this plugin instead of ts-jest
causes this issue. i.e. I'm not sure how ts-jest
is able to resolve to a different file.
Note: for [email protected], the package.json file has these as its module resolutions:
{
"main": "dist/react-select.cjs.js",
"module": "dist/react-select.esm.js",
}
I think it's resolving to the "module", whereas ts-jest
is resolving from "main". Does that make sense? Is there some way to configure swc/jest
to work like this?
I just found @swc/jest can not be found in the registry: https://www.npmjs.com/search?q=%40swc%2Fjest
The package.json has the name @swc/ject
which is indeed in the registry. Is this intended?
Thank you
The project doesn't include a LICENSE file at the root, which creates some extra noise/red tape to use it for my company's projects. package.json
specifies MIT
; it would be helpful if a copy of the license could be included at the root.
I'm trying to move from react-scripts
to SWC.
The building part is fine with webpack but I'm struggling a bit with jest.
this is the config that I've tried so far in the package.json
:
{
"jest": {
"rootDir": "./src",
"testMatch": ["<rootDir>/**/*.test.{ts,tsx,js,jsx}"],
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
"transform": {
"^.+\\.tsx?$": ["@swc/ject"]
},
"testEnvironment": "node",
"collectCoverageFrom": [
"src/components/**/*.{ts,tsx}"
]
},
}
Any clue how to configure it properly?
The error I get in every test is:
SyntaxError: Cannot use import statement outside a module
Thank you
When I used the example config in the readme, I got an error:
SyntaxError: Cannot use import statement outside a module
It turned out this was because it wasn't reading the config file. If I add the configFile
option, then it works:
'^.+\\.(t|j)sx?$': ['@swc/jest', { configFile: '.swcrc' }],
Oddly, it also works if I keep the array syntax but change the regex (since I don't need to support .jsx or .ts files in my repo):
'^.+\\.(js)$': ['@swc/jest'],
But if I take away the brackets then it stops working:
'^.+\\.(js)$': '@swc/jest',
I'm running @swc/[email protected]
and [email protected]
Generators and async/await have been fully supported in Node for years, but the default SWC options are still set to transpile them to using regenerator-runtime. Since @swc/jest
is specifically for usage in Jest, if there isn't a jsc.target
specified in .swcrc
or the Jest config, can it default to whatever level is supported by the runtime Node version?
Reasoning: it's a little extra work for projects that don't yet have a SWC configuration to specify a jsc
target. https://swc.rs/docs/usage/jest indicates your Jest configuration only needs to include:
module.exports = {
transform: {
"^.+\\.(t|j)sx?$": ["@swc/jest"],
},
};
...but in actuality, if this is your first swc setup, you need something more like:
module.exports = {
transform: {
"^.+\\.(t|j)s$": [
"@swc/jest",
{
jsc: {
target: "es2021",
},
},
],
},
};
...which is a pain point for new SWC users and a bit of noisy configuration.
According to jest, jest.mock
shouldn't depend on anything defined top level, except mock*
variables (that seems to be hoisted in a specific way): https://jestjs.io/docs/es6-class-mocks#calling-jestmock-with-the-module-factory-parameter
When the same test in run in jest without swc and with, the behavior is slightly different:
Without | With |
---|---|
Repo to try it out: https://github.com/Ayc0/swc-jest-mock-bug
A recent pull request #66
This pull request set sourceMaps
to true
by default. This will cause the following error:
TypeError: Cannot set properties of undefined (setting 'sourceMaps')
at set (node_modules/@swc/jest/index.js:113:12)
at Object.process (node_modules/@swc/jest/index.js:69:17)
at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:620:31)
at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:766:40)
at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:823:19)
(Example repo: https://github.com/jkamzi/swc-jest-transform-opts-undefined)
The issue comes from:
Lines 48 to 50 in f05ee1e
swcTransformOpts
can be undefined, and the above if statement do not account for that, and when set
is called it will throw a TypeError
. Typescript playground link to demonstrate this
I put throw new Error('TEST ERROR')
in one of my test files.
.swcrc
Jest output shows the failure occurring at the wrong line:
FAIL src/__tests__/Skeleton.test.tsx
● disables the animation if and only if enableAnimation is false
TEST ERROR
68 | expect(skeleton).toHaveClass('react-loading-skeleton')
69 | expect(skeleton).toHaveClass('test-class')
> 70 | })
| ^
71 |
72 | it('applies the containerClassName and containerTestId', () => {
73 | render(<Skeleton containerClassName="test-class" containerTestId="myTestId" />)
at Object.<anonymous> (src/__tests__/Skeleton.test.tsx:70:11)
.swcrc
Jest output shows the failure occurring at the correct line:
FAIL src/__tests__/Skeleton.test.tsx
● disables the animation if and only if enableAnimation is false
TEST ERROR
58 | expect(skeleton.style.animation).toBe('none')
59 |
> 60 | throw new Error('TEST ERROR')
| ^
61 | })
62 |
63 | it('uses a custom className', () => {
at Object.<anonymous> (src/__tests__/Skeleton.test.tsx:60:11)
.swcrc
.@swc/jest
code.This occurred in a React .tsx
file.
.swcrc
:
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"dynamicImport": true
},
"target": "es2021"
},
"module": {
"type": "commonjs"
}
}
Hey team,
I have noticed a warning message stemming from your dependency in our codebase.
Before adding @swc/jest
to our dependencies
yarn install v1.22.17
[1/5] 🔍 Validating package.json...
[2/5] 🔍 Resolving packages...
success Already up-to-date.
After including it
yarn install v1.22.17
[1/5] 🔍 Validating package.json...
[2/5] 🔍 Resolving packages...
[3/5] 🚚 Fetching packages...
[4/5] 🔗 Linking dependencies...
warning Workspaces can only be enabled in private projects.
[5/5] 🔨 Building fresh packages...
success Saved lockfile.
I can link similar issues in other places: reduxjs/react-redux#1815 and webpack/webpack-cli#479
Trying to migrate a big suite from babel-jest
to @swc/jest
and hitting an issue with how it transpiles functions.
I created a reproduction repo here https://github.com/egilsster/swc-jest-issue
Essentially, I expect it to not transpile an arrow function to a regular function. I have target
set to es2015
but it acts the same with all future targets.
Arrow function should be printed as () => {}
@swc/jest
prints it as: function() {}
babel-jest
prints it as: () => {}
Hi there, I've been able to setup @swc/jest
in my project. It works on the command line via npx jest
but not in vscode
Inside vscode I get this error:
● Test suite failed to run
Can not load bindings
Installed packages: [core-darwin-arm64]
at loadBinding (node_modules/@node-rs/helper/lib/loader.js:50:11)
at Object.<anonymous> (node_modules/@swc/core/index.js:37:43)
at Object.<anonymous> (node_modules/@swc/jest/index.js:35:14)
After some debugging (console.log in lib/loader), I found out that the VSCode terminal runs on x64 architecture while my computer is a M1 (arm64).
I've tried to force VSCode to use arm64 inside the terminal without luck, I did not find any github issue about that also.
What I've done instead is:
npm i -D @swc/core-darwin-x64 --force
And now it works. Not sure what we could do to better support this. Thanks!
Hello!
I'm getting this error when trying to import less files and not sure why:
Cannot find module './styles.module' from '....../index.tsx'
This is the line used inside the file
import "./styles.module.less";
Not sure why this happens considering that I'm mapping less
files on moduleNameMapper
:
moduleNameMapper: {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
"<rootDir>/__test-utils__/mocks/file-mock.js",
"\\.(css|less)$": "identity-obj-proxy",
},
Any ideas?
Hi,
I tried to use swc-jest instead of ts-jest in clean Nest.js project. I used @swc-node/register to run app and it works like a charm. Then I tried to run jest and it produces error:
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
--> /home/brutkowski/WebstormProjects/nest-swc/src/app.module.ts:5:1
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.process (../node_modules/@swc/jest/index.js:21:27)
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)
I have created repository with complete reproduction at https://github.com/ruciu/nest-swc
To run test execute yarn run test:e2e.
Could you please tell me what should I do?
Thank you
Is there a fix for this issue, running on Github actions?
When using @swc/jest
as described in the readme for transforms in Jest tests, I can't seem to use any mocking.
With a test like this:
import got from 'got';
jest.mock('got');
describe('My Test', () => {
// ...
});
I will get:
TypeError: _got.default.mockImplementationOnce is not a function
Moving the jest.mock()
call to the top of the test file also doesn't work.
Any advice appreciated.
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)])
})
Hi Team
When React is not imported (v17 you don't have to) I get
● App › renders learn react link
ReferenceError: React is not defined
In jest.config.js, parsing .swcrc
with an exclude
option or passing the exclude
key in the transform options causes the transform options to be ignored and falls back to reading the .swcrc
.
node@16
@swc/[email protected]
@swc/[email protected]
@swc/[email protected]
[email protected]
{
"env": {
"targets": {
"node": "16"
}
},
"exclude": ["test.ts$"],
"jsc": {
"parser": {
"syntax": "typescript"
},
"baseUrl": ".",
"paths": {
"@entities/*": ["entities/*"],
"@src/*": ["src/*"]
},
"target": "es2017"
},
"module": {
"type": "commonjs"
},
"sourceMaps": true
}
const fs = require("fs")
const path = require("path")
const util = require("util")
const config = JSON.parse(
fs.readFileSync(path.join(process.cwd(), ".swcrc"), "utf-8")
)
// delete config.exclude
module.exports = {
testEnvironment: "node",
testMatch: ["<rootDir>/src/**/?(*.)test.ts"],
testPathIgnorePatterns: ["/node_modules/"],
transform: {
"^.+\\.ts$": [
"@swc/jest",
{
...config,
},
],
},
}
If exclude
exists in either the .swcrc
or is passed as a transform option, the transform options are skipped and the transform uses the fallback (which then defaults to .swcrc
). delete config.exclude
does allow it pick up the custom configuration and not try to read .swcrc
directly, as does passing a config object directly without exclude
.
I set up my .swcrc
for the build process which exclude
s my test files and expected to be able to pass an empty array to exclude
in the jest config to not have jest exclude those files.
Hi
When I use swc/ject I get a wrong branch coverage and wrong highlighting, but not when I use ts-jest
I have created repository with complete reproduction at https://github.com/sscode02/nest-swc
To run test execute npm run test:e2e:swc
Could you please tell me what should I do?
Thank you
I've set up a few paths under jsc.paths
in my .swcrc
file
They are being transformed by swc nicely but when they are mocked by jest.mock
the transformation is not done.
Ideally this would be performed by @swc/jest
Thanks for this great project and this great plugin!
I'm using ndb:
jest.config.js:
module.exports = {
testEnvironment: 'node',
testRunner: 'jest-circus/runner',
transform: {
'^.+\\.(t|j)sx?$': ['@swc/jest'],
},
....
}
I also have .swcrc
file in the root folder of the project but im not sure if it's being used:
{
"jsc": {
"parser": {
"syntax": "typescript",
"dynamicImport": true
},
"target": "es2019"
},
"module": {
"type": "commonjs",
"strict": true,
"noInterop": false
}
}
macos catalina 10.15.1 (19B2093)
node v15.3.0
ndb v1.1.5
@swc/[email protected]
@swc/[email protected]
took me a while to figure it out, but it's actually caused by swc.
npm install
npm test
If you replace swc in the reproducer with ts-jest, you won't get a BSOD.
Note that, after reproducing it, your node_modules dir might be corrupted, so you'll have to remove it and install again.
Windows 11 version: 22000.493
WSL version: 2 (Kernel version 5.10.60.1)
Ubuntu version: 2004.2022.1.0 (from windows store
Node version: 16.13.0
NPM version: 8.8.1
We are currently upgrading to NextJS 12, which is using SWC rather than babel.
I wanted to give @swc/jest
a try because of ESM module issues with babel-jest:
SyntaxError: Cannot use import statement outside a module
After switching from
'^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/node_modules/babel-jest'
to
'^.+\\.(t|j)sx?$': '@swc/jest'
I am getting the following errors:
FAIL stories/stories.test.js
● Test suite failed to run
error: Expression expected
|
36 | <RouterContext.Provider value={mockRouter}>
| ^
error: Expected ',', got 'value'
|
36 | <RouterContext.Provider value={mockRouter}>
| ^^^^^
Caused by:
0: failed to process js file
1: Syntax Error
Is @swc/jest
not supposed to work with jsx
/tsx
files? The regrex implies that it does work with it. Any suggestions?
Dear @swc/jest maintainers,
Thank you for your contribution to the open-source community.
This issue was automatically created to inform you a new version (0.2.18) of @swc/jest was published without a matching tag in this repo.
As part of our efforts to fight software supply chain attacks, we would like to verify this release is known and intended, and not a result of an unauthorized activity.
If you find this behavior legitimate, kindly close and ignore this issue. Read more
I am using jest plugin in intellij.
If I use ts-jest and set a breakpoint, while running test in debug mode using Intellij jest plugin test stops break point, but with swc it doesn't.
I suspect it has something to do with source maps.
I assume this also happens in webstorm but didn't try it.
Hi!
Thanks for this awesome package!
The following code throws an error.
describe('foo', () => {
it('bar', async () => {
const obj = { hi: 'there' }
for (const qux in obj) {
console.log(qux)
}
expect(await Promise.resolve(1)).toStrictEqual(1)
})
})
ReferenceError: qux is not defined
at _callee$ (test/index.test.ts:47:25)
at tryCatch (../../node_modules/regenerator-runtime/runtime.js:63:40)
at Generator.invoke [as _invoke] (../../node_modules/regenerator-runtime/runtime.js:294:22)
at Generator.next (../../node_modules/regenerator-runtime/runtime.js:119:21)
at asyncGeneratorStep (test/index.test.ts:5:28)
at _next (test/index.test.ts:23:17)
at test/index.test.ts:28:13
at Object.<anonymous> (test/index.test.ts:20:16)
This happens when 1) for-in
is used, AND 2) called in async callback of "it"(=="test")
.
I tested the same code with ts-jest, but it worked.
I tested a "similar"(for-in
in async function, but not with jest) code with swc
, and it worked as well.
Thus I think this is a bug of either @swc/jest
or regenerator-runtime
, how do you think?
I personally guess it can probably be caused by regenerator-runtime
's fault, but decided to report this behavior here first.
Thanks!
Info:
jest 27.3.1
using expect(...).toMatchInlineSnapshot()
Jest: Couldn't locate all inline snapshots.
at traverseAst (node_modules/jest-snapshot/build/InlineSnapshots.js:377:11)
I don't know if this is an issue specifically with @swc/jest
, but I tried the suggestions in this StackOverflow question and they made no difference. Here is my jest.config.js
:
module.exports = {
'roots': ['<rootDir>/../src'],
'moduleDirectories': ['node_modules', 'src'],
'setupFilesAfterEnv': ['<rootDir>/setup-tests.js'],
'coverageDirectory': '<rootDir>/../coverage',
'verbose': true,
'collectCoverage': true,
'transform': {
'^.+\\.(t|j)sx?$': [
'@swc/jest',
{
'jsc': {
target: 'es2021',
},
'sourceMaps': true,
},
],
},
'collectCoverageFrom': [
'<rootDir>/../src/**.{ts,js,tsx,jsx}',
'!**/node_modules/**',
],
}
My file structure looks like:
.
├── coverage
├── jest
│ ├── jest.config.js
│ ├── setup-tests.js
├── src/
├── tsconfig.json
The output looks like this:
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 11 passed, 11 total
Tests: 25 passed, 25 total
Snapshots: 0 total
Time: 1.307 s
Ran all test suites.
All my tests run, except those that deal with files which have wildcard imports or exports. (ex: import * from "./myfile"
)
Like babel, swc/jest transforms wildcard import to _interopRequireWildcard(require("./myfile"))
. (see swc tests). Strangely, jest throws the following error:
_ReferenceError: interopRequireWildcard is not defined
Here is my jest config:
const path = require("path");
const resolve = (_path) => path.resolve(__dirname, _path);
module.exports = {
testURL: "http://localhost",
testEnvironment: "jsdom",
snapshotSerializers: ["jest-serializer-html"],
testPathIgnorePatterns: ["e2e/", ".*donottest.*"],
transform: {
"^.+\\.(t|j)sx?$": ["@swc/jest"],
},
setupFiles: ["jest-canvas-mock"],
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
moduleFileExtensions: ["js", "jsx", "json", "ts", "tsx", "svg"],
globals: {
"ts-jest": {
tsconfig: resolve("./tsconfig.test.json"),
diagnostics: false,
},
},
};
How to fix this? All these tests run fine with babel-jest
& ts-jest
.
With React's new JSX runtime, we no longer need to import React
. This causes issues when transforming with @swc/jest
since it throws a React is undefined error.
https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html
It doesn't appear that there's any way to customize swc
's jsc
or module
configuration with @swc/jest
.
The options passed to transformSync
are built up like this:
Lines 9 to 23 in 6281cfb
.swcrc
seems to be ignored, and the overrides to the jsc
and module
properties mean that even if you pass transformer options in jest.config.js
, configuration for other properties under jsc
/module
will be discarded.
Ideally, I think the behavior would be for the options passed to transformSync
to use your .swcrc
options by default, then override just the specific subproperties required for Jest compat (commonjs + hidden.jest), then override with any explicit transformOptions.
It would also be nice to:
.swcrc
file, similar to how @swc/cli
supports a --config-file option.Context: hit this while attempting to apply noInterop: true
as a workaround for swc-project/swc#1778
It looks like @swc/jest
has trouble transforming the puppeteer package
Initialize project
yarn init --yes
yarn add -D puppeteer jest @types/jest @swc/jest @swc/core regenerator-runtime
Add jest.config.js
// jest.config.js
module.exports = {
transform: {
"^.+\\.(t|j)sx?$": "@swc/jest",
},
transformIgnorePatterns: [],
};
Add following test
// index.spec.ts
import puppeteer from "puppeteer";
test("hello", async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto("https://www.google.com");
} finally {
await browser.close();
}
});
Run
npx jest
Observe
FAIL ./index.spec.ts
✕ hello (2025 ms)
● hello
ReferenceError: navigate is not defined
at FrameManager._callee$ (node_modules/puppeteer/src/common/FrameManager.ts:493:44)
at tryCatch (node_modules/regenerator-runtime/runtime.js:49:25)
at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:175:30)
at Generator.next (node_modules/regenerator-runtime/runtime.js:77:29)
at asyncGeneratorStep (node_modules/puppeteer/src/common/FrameManager.ts:20:1)
at _next (node_modules/puppeteer/src/common/FrameManager.ts:57:3)
at node_modules/puppeteer/lib/cjs/puppeteer/common/FrameManager.js:45:13
at node_modules/puppeteer/src/common/FrameManager.ts:54:3
at FrameManager.navigateFrame (node_modules/puppeteer/lib/cjs/puppeteer/common/FrameManager.js:398:31)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 2.258 s, estimated 6 s
Ran all test suites.
Now change in jest.config.js
:
transformIgnorePatterns: ['/node_modules/puppeteer/.+\\.js$'],
And run again
npx jest
Observe
PASS ./index.spec.ts
✓ hello (2763 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.009 s
Ran all test suites.
@swc/[email protected]
@swc/[email protected]
[email protected]
[email protected]
node: v16.13.0
Package versions:
{
"@swc/core": "^1.2.108",
"@swc/jest": "^0.2.5"
}
using following transform:
const transform = {
'^.+\\.(t|j)sx?$': [
'@swc/jest',
{
module: {
type: 'es6',
},
jsc: {
baseUrl: '.',
paths: {
'@this/*': ['./*'],
},
parser: {
dynamicImport: true,
syntax: 'typescript',
decorators: false,
tsx: false,
},
transform: {
legacyDecorator: false,
decoratorMetadata: false,
},
target: 'es2021',
},
sourceMaps: true,
},
],
}
The following works in ts-jest
/ts-node
, but not with @swc/jest
:
import * as moduleArray from '@this/src/modules/array'
console.log(moduleArray)
Cannot find module './src/modules/array' from 'src/jest/__tests__/base.spec.ts'
ts-jest
uses the same baseUrl and paths.
Hello,
I was trying to use swc, performance seems great and everything was quite smooth.
However I hit two issues, the main one being about import order.
With a scenario like this:
my.test.ts
-> import file.ts
In classic jest, my.test.ts
is executed and then file.ts
With @swc/jest
it's the opposite (first file.ts
then my.test.ts
)
It's mostly fine, but it can break mocking and changing global var.
In my case, my.test.ts
was modifying process.env
first so that the rest of code act accordingly and it no longer works with swc. There are alternatives and could be expected, but I think it's worth pointing in case it was not intended behavior.
Best Regards
I'm attempting to use SWC to test a NestJS + TypeORM project. It's failing to compile the following class (irrelevant parts committed for brevity)
@Entity()
export class UniqueVendorAssociation {
constructor(props: Partial<UniqueVendorAssociation> = {}) {
Object.assign(this, props)
}
// This declaration is the problem
@ManyToOne(() => UniqueVendor, (vendor) => vendor.uniqueVendorAssociations)
@JoinColumn({ name: 'uniqueVendorId' })
uniqueVendor: Promise<UniqueVendor>
@Column()
uniqueVendorId: number
// More fields below...
}
.swcrc config
{
"jsc": {
"parser": {
"syntax": "typescript",
"decorators": true,
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
},
"keepClassNames": true,
"target": "es2020"
}
}
Error:
ColumnTypeUndefinedError: Column type for UniqueVendorAssociation#uniqueVendorId is not defined and cannot be guessed. Make sure you have turned on an "emitDecoratorMetadata": true option in tsconfig.json. Also make sure you have imported "reflect-metadata" on top of the main entry file in your application (before any entity imported).If you are using JavaScript instead of TypeScript you must explicitly provide a column type.
It looks like @JoinColumn({ name: 'uniqueVendorId' })
may be the issue. A reproduction of this case in a SWC playground seems to work just fine. Is there an issue with the jest integration that prevents support for compiling decorators like this?
It seems @swc/jest
doesn't read the .swcrc
configuration file, because Jest always passes it at least an empty options object (swcOptions = {}
), and so this conditional never applies:
Lines 58 to 61 in 82a6a95
Something like this might help:
--- if (!swcOptions) {
+++ if (!swcOptions || Object.keys(swcOptions).length === 0) {
const swcrc = path.join(process.cwd(), '.swcrc')
swcOptions = fs.existsSync(swcrc) ? JSON.parse(fs.readFileSync(swcrc, 'utf-8')) as Options : {}
}
I was able to test this by cloning this repo, and moving the config in examples/react/package.json
into examples/react/.swcrc
instead.
.mjs
extension does not pass the regex check in process()
. Hence, transforming .mjs
extension turns into a noop
https://github.com/swc-project/jest/blob/master/index.ts#L43
or keep swc core up to date
I just tried switching to this package instead of ts-jest since it was so slow at handling errors. I get this error on any test I run... I'm assuming I didn't configure this properly. Any ideas? Do I need to set up a .swcrc file? if so, what goes in there?
Thanks for your work on this.
Hello,
I'm trying to use this on my mono repo project and for some tests I have the following error :
TypeError: Cannot set property myVariable of [object Object] which has only a getter
myVariable is declared like that in a file external to the test files :
export const registerSettingsIntegrationDatalayer = () => myfunction()
I also tried to make my function return a string just for a dummy try but I got the same error.
I'm using @swc/core : ^1.2.137 and @swc/jest : ^0.2.17 and here is my swc configuration :
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"dynamicImport": true,
"privateMethod": false,
"functionBind": false,
"exportDefaultFrom": true,
"exportNamespaceFrom": false,
"decorators": false,
"decoratorsBeforeExport": false,
"topLevelAwait": false,
"importMeta": false
},
"transform": {"react": {"runtime": "automatic"}},
"target": "es5",
"loose": false,
"externalHelpers": false,
"keepClassNames": false,
},
"sourceMaps": true
}
Is there something in my configuration that I could modify to fix my issue ?
Thanks in advance
When switching to swc/jest, the following error occurs when executing the test. It seems to be related to jsdom. I tried to figure out what the problem was, but I couldn't find a solution. Can I get help solving this problem?
TypeError: 'removeEventListener' called on an object that is not a valid instance of EventTarget.
at JSDOMEnvironment.removeEventListener (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:15)
at tryCatch (node_modules/regenerator-runtime/runtime.js:49:25)
at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:175:30)
at Generator.next (node_modules/regenerator-runtime/runtime.js:77:29)
The jest setting is as follows.
module.exports = {
projects: ['<rootDir>/'],
// swc/jest
transform: {
'^.+\\.(t|j)sx?$': ['@swc/jest', ],
},
//testEnvironment: "jsdom",
testRegex: '\\.test\\.(ts|js)x?$',
moduleNameMapper: {
'@/(.*)$': '<rootDir>/src/$1',
'@mocks/(.*)$': '<rootDir>/mocks/$1',
'@pages/(.*)$': '<rootDir>/pages/$1'
},
setupFilesAfterEnv: [
'<rootDir>/src/__test__/setup-tests.tsx',
],
transformIgnorePatterns: [
'node_modules/?!core-js',
],
// https://jestjs.io/docs/jest-object#jestrestoreallmocks
restoreMocks: true,
clearMocks: true,
};
I'm using next.js and I'm doing the test below using react-testing-lib.
/**
* @jest-environment jsdom
*/
import * as Factory from 'factory.ts';
import { render, screen } from '@/__test__/test-utils';
import {
SummaryDetails,
SummaryDetailType,
} from '@src/components/summary-details';
const summeryDetailFactory = Factory.Sync.makeFactory<SummaryDetailType>({
title: Factory.each(i => i.toString()),
value: Factory.each(i => `${i},000,000w`),
});
describe('<SummeryDetails/>', () => {
it('render', () => {
// Given
const MOCK_SUMMARY_DETAILS = summeryDetailFactory.buildList(2);
// When
render(<SummaryDetails summaryDetails={MOCK_SUMMARY_DETAILS} />);
// Then
MOCK_SUMMARY_DETAILS.forEach(({ title, value }) => {
expect(screen.getByText(title)).toBeInTheDocument();
expect(screen.getByText(`${value}원`)).toBeInTheDocument();
});
});
});
Top-level await does not seem to work out of the box. I have tried to enable it in jsc.parser.topLevelAwait = true
but that did not change anything. @kdy1 Do you know if this is a bug or a configuration issue?
I also tried setting the target to es2018
and the module type to es6
with the other settings, but that did not help. We are using this in a TypeScript setup.
When a module export a constant:
export const FOO = 3;
export function getFoo() {
return FOO;
}
In Jest you can mock using:
jest.mock('./foo', () => {
const { getFoo } = jest.requireActual('./foo');
return {
FOO: 5,
getFoo
}
})
This will not work correctl because SWC is not using the export constant but an internal constant in the module
test('should be mock', () => {
expect(getFoo()).toBe(5); // Fail
})
The transpile code looks like:
const FOO = 3
exports.FOO = FOO;
exports.getFoo = function() {
return FOO; // It should be exports.FOO in order to work.
};
After switching to swc and next12, jest throws the following error
console.error
Warning: Received `true` for a non-boolean attribute `jsx`.
If you want to write it to the DOM, pass a string instead: jsx="true" or jsx={value.toString()}.
at style
at /Users/github/project/redacted/Component.tsx:30:16
at printWarning (../../node_modules/react-dom/cjs/react-dom.development.js:67:30)
at error (../../node_modules/react-dom/cjs/react-dom.development.js:43:5)
at validateProperty$1 (../../node_modules/react-dom/cjs/react-dom.development.js:3521:9)
at warnUnknownProperties (../../node_modules/react-dom/cjs/react-dom.development.js:3559:21)
at validateProperties$2 (../../node_modules/react-dom/cjs/react-dom.development.js:3583:3)
at validatePropertiesInDevelopment (../../node_modules/react-dom/cjs/react-dom.development.js:8765:5)
at setInitialProperties (../../node_modules/react-dom/cjs/react-dom.development.js:9041:5)
I'm not really sure what the jsx behavior should be here to be quite honest:
<style>
instead of <style jsx>
it doesn't affect tests any longer; however I'm not sure how that will affect the rendering in tests.jest.config.ts
:module.exports = {
transform: {
"^.+\\.(t|j)sx?$": "@swc/jest",
},
rootDir: "./",
setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
silent: true,
};
jest.setup.ts
:require("reflect-metadata");
/* eslint-disable @typescript-eslint/no-var-requires */
const Enzyme = require("enzyme");
const Adapter = require("@wojtekmaj/enzyme-adapter-react-17");
HTMLCanvasElement.prototype.getContext = () => {
// return whatever getContext has to return
};
Enzyme.configure({ adapter: new Adapter() });
Perhaps I am posting the bug in the wrong forum though. The ideal goal here would probably be to not have the error message.
Not sure how to fix this... Any help appreciated! 🙏
"@swc/core": "1.2.112",
"@swc/jest": "0.2.8",
{
"module": {
"type": "commonjs"
},
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"dynamicImport": true,
"decorators": false
},
"transform": {
"react": {
"pragma": "React.createElement",
"pragmaFrag": "React.Fragment",
"throwIfNamespace": true,
"development": false,
"useBuiltins": false
}
},
"target": "es2015",
"loose": false,
"externalHelpers": false,
"keepClassNames": false,
"sourceMaps": true
}
}
● Test suite failed to run
failed to process js file
Caused by:
0: failed to read swcrc file (/Users/joyu/Development/lending/frontend/borrower/test/jestSetup.js)
1: failed to deserialize .swcrc (json) file: unmatched data: 25:16
2: unknown field `sourceMaps`, expected one of `parser`, `transform`, `externalHelpers`, `target`, `loose`, `keepClassNames`, `baseUrl`, `paths`, `minify`, `experimental` at line 25 column 16
at Compiler.transformSync (node_modules/@swc/core/index.js:135:25)
at Object.transformSync (node_modules/@swc/core/index.js:215:21)
at Object.process (node_modules/@swc/jest/index.js:68:27)
Hey,
i've tried esbuild-jest which works better out of the box, but has issues with jest-mock() inside of test files.
Now i wanted to try swc-jest, which needs a lot more configuration and fiddling, but i don't get it to work.
In my jest.config.js we explicitly tell jest to look for these files:
testRegex: [".spec.(ts|tsx)$"],
but this seems to be ignored with swc-jest, cause its going through files which are not used in the test.
my .swcrc looks like this:
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": true,
"dynamicImport": true
},
"transform": {
"react": {
"development": false,
"useBuiltins": false,
"runtime": "automatic"
},
"optimizer": {
"globals": {
"vars": {
"__DEBUG__": "true"
}
}
},
"legacyDecorator": true,
"decoratorMetadata": true
},
"target": "es5",
"loose": false,
"externalHelpers": true,
"keepClassNames": false
}
}
Seems to me it tries to compile the whole project
I have come to @swc/jest
because of the recent ts-jest
issues kulshekhar/ts-jest#1967 (Granted it could be Jest
it could be v8
. Ultimately - I just wanted to move to SWC to get faster, more stable, and ultimately the most performant tests I can run).
I am trying to use this package with a React Native app - and am running into issues after I resolve the one listed here. I have tried a couple of different .swcrc
configurations:
And just a basic one from the example in the repo here:
jest/examples/react/package.json
Lines 33 to 51 in 4660359
The above works without a physical .swcrc
file - which is what I'll opt for since our App wont be built using SWC yet (or maybe ever 🤷 Depends on the RN support in the future.)
The issue I'm running into now - is very similar:
FAIL MyApp/x/y/z.spec.tsx
● Test suite failed to run
error: Expected ',', got ':'
|
51 | applyWithGuard<TArgs: $ReadOnlyArray<mixed>, TOut>(
| ^
Caused by:
0: failed to process js file
1: Syntax Error
at Compiler.transformSync (node_modules/@swc/core/index.js:137:25)
at transformSync (node_modules/@swc/core/index.js:217:21)
at Object.process (node_modules/@swc/jest/index.js:55:45)
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)
I haven't had any luck getting past this point and would LOVE some help troubleshooting how to move forward.
My current jest.config.js
module.exports = {
preset: "react-native",
transformIgnorePatterns: [
"node_modules/(?!((jest-)?(@react-native|react-native)|react-clone-referenced-element|expo(nent)?|@expo(nent)?/.*|@react-navigation/.*|@sentry|@react-native-community/.*))"
],
setupFilesAfterEnv: ["<rootDir>/someScriptThatWeRunThatMocksStuff.tsx"],
cacheDirectory: ".jest/cache",
clearMocks: true,
testPathIgnorePatterns: [
".ts-temp",
"<rootDir>/node_modules/",
"<rootDir>/e2e/",
"__fixtures__",
"\\.{snap, png, svg}$"
],
coveragePathIgnorePatterns: [
// patterns that we ignore coverage on
],
modulePathIgnorePatterns: [".ts-temp"],
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
// SWC
testEnvironment: "node",
transform: {
"^.+\\.(t|j)sx?$": [
"@swc/jest",
{
sourceMaps: true,
jsc: {
parser: {
syntax: "typescript",
tsx: true
},
transform: {
react: {
runtime: "automatic"
}
}
}
}
]
}
};
tsconfig.json
{
"compileOnSave": true,
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"isolatedModules": true,
"jsx": "react-jsx",
"lib": ["es6"],
"moduleResolution": "node",
"noEmit": true,
"strict": true,
"target": "esnext",
"noImplicitAny": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"baseUrl": "./",
"paths": {
"/* comment */": "a bunch of paths for app aliasing"
},
"exclude": [
"**/__mocks__/**",
"node_modules",
"**/node_modules/**",
"babel.config.js",
"metro.config.js",
"jest.config.js",
"e2e",
"ios",
"android",
"assets",
"coverage",
"dist",
]
}
babel.config.js
module.exports = api => ({
presets: [
[
"module:metro-react-native-babel-preset",
{ useTransformReactJSXExperimental: true }
]
],
plugins: configurePlugins(api) // custom setup - base plugins listed below
});
// base plugins
const basePlugins = [
[
"@babel/plugin-transform-react-jsx",
{
runtime: "automatic"
}
],
"babel-plugin-transform-inline-environment-variables",
[
"module-resolver",
{
root: ["./"],
extensions: [".ios.js", ".android.js", ".js", ".ts", ".tsx", ".json"],
alias: { // aliases we use in the app - they match `paths` from the `tsconfig` },
}
],
[
"formatjs",
{
// format js config
}
],
"react-native-reanimated/plugin",
}
Reproduction steps:
yarn
code .
src/Board.ts
in an editor (for comparison later)jest -- tests/Board.test.ts
Result: When it pauses on a particular debugger
line, VS Code will open a new, different Board.ts which seems to be the compiled result (and is definitely not typescript). The debugger will step through that file instead of the original.
I have these sourcemap settings enabled:
jest.config.js:
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: "ts-jest",
transform: {
"^.+\\.(t|j)sx?$": ["@swc/jest", { sourceMaps: true }],
// "^.+\\.jsx?$": "babel-jest",
// "^.+\\.tsx?$": "ts-jest",
},
testEnvironment: "node",
testMatch: ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).?(m)[jt]s?(x)"],
moduleFileExtensions: ["js", "jsx", "ts", "tsx", "mjs"],
setupFiles: ["./tests/setupTests.ts"],
};
.swcrc:
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true
},
"target": "es2021"
},
"sourceMaps": true
}
The problem occurs the same way if I remove .swcrc
. Same if I remove the sourceMaps option from jest.config.js. Same if I remove the preset
rule in jest.config.js, which seems to do nothing if I include the transform rule (I accidentally left it in from before). If I remove the transform
rule entirely as well as the preset, Jest just breaks (doesn't transpile files enough to run them).
This project is set up using Next.js, which may have some other configuration stuff affecting SWC, as Next.js uses SWC. Before adding @swc/jest myself, it wasn't using SWC on Jest (at least, judging by the 2x speedup I got from switching).
Note that debugging with sourceMaps DOES show the original source correctly when running the Next.js application through eg yarn run next
in the VS Code debugger and with the browser.
Confusingly, the compiled output I get is different (seemingly targeting an older ES version) when I re-clone my repo and reproduce this, but the problem is still essentially the same. No idea what would cause that difference.
I'm using swc/node in ts-node to strip typings from my nodejs codebase using their ts-node/esm
loader.
To keep tsc
happy while also following the esm spec to keep the extension of all my imports, all my imports end as .js despite the source files being ts.
While this works for both tsc
and ts-node
with swc
, all Jest tests fail due to imports of .ts
files with .js
that can't be resolved. I took the necessary steps to make Jest work with ESM, which used to work until I introduced TS there. Likewise, the tests work if I specify the ts extension for each of these imports, which would however break tsc.
I'm currently failing to fit the pieces together and have a hard time finding documentation or maybe a simple example that utilizes Node with ESM, SWC and imports ts files in a test suite.
I would also be happy to follow the Deno approach and explicitely keep the actual .ts extension on imports - However, I don’t know how I would typecheck my code then without tsc.
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.