最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Migrating from Babel to SWC with React - Stack Overflow

programmeradmin4浏览0评论

TL;DR

How to translate a node script like this:

"test": "NODE_ENV=test riteway -r @babel/register 'src/**/*.test.js' | tap-nirvana",

to use SWC instead of Babel?


Context

We recently upgraded our Next.js version. Next.js now supports SWC instead of Babel.

The unit tests for React in our project are written with RITEway. The test mand is:

"test": "NODE_ENV=test riteway -r @babel/register 'src/**/*.test.js' | tap-nirvana",

It transforms the files with Babel first because otherwise import statements and JSX would cause errors.

During our attempts to migrating to SWC, we had no luck with the CLI. However, we found the @swc-node/register package. It allowed us to transform our mand like this:

"test": "riteway -r @swc-node/register src/**/*.test.js | tap-nirvana"

which fixes new syntax like the import statement and a test like this would run:

import { describe } from 'riteway';

describe('my test', async assert => {
  assert({
    given: 'true',
    should: 'be true',
    actual: true,
    expected: true,
  });
});

However, tests for React ponents like this

import { describe } from 'riteway';
import render from 'riteway/render-ponent';

import Authentication from './user-authentication-ponent';

describe('user authentication ponent', async assert => {
  const $ = render(<Authentication />);

  assert({
    given: 'just rendering',
    should: "render 'Authentication'",
    actual: $('*:contains("Authentication")').text(),
    expected: 'Authentication',
  });
});

still throw the following error:

$ yarn test
yarn run v1.22.17
$ riteway -r @swc-node/register src/**/*.test.js | tap-nirvana
/Users/user/dev/learning-flow/node_modules/@swc/core/index.js:135
        return bindings.transformSync(isModule ? JSON.stringify(src) : src, isModule, toBuffer(newOptions));
                        ^

Error: error: Expression expected
 
  |
7 |   const $ = render(<Authentication />);
  |                                    ^

error: Expression expected
 
  |
7 |   const $ = render(<Authentication />);
  |                                     ^

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
 
  |
7 |   const $ = render(<Authentication />);
  |                                      ^



Caused by:
    0: failed to process js file
    1: Syntax Error
    at Compiler.transformSync

How can we create that mand so that it runs with SWC?

TL;DR

How to translate a node script like this:

"test": "NODE_ENV=test riteway -r @babel/register 'src/**/*.test.js' | tap-nirvana",

to use SWC instead of Babel?


Context

We recently upgraded our Next.js version. Next.js now supports SWC instead of Babel.

The unit tests for React in our project are written with RITEway. The test mand is:

"test": "NODE_ENV=test riteway -r @babel/register 'src/**/*.test.js' | tap-nirvana",

It transforms the files with Babel first because otherwise import statements and JSX would cause errors.

During our attempts to migrating to SWC, we had no luck with the CLI. However, we found the @swc-node/register package. It allowed us to transform our mand like this:

"test": "riteway -r @swc-node/register src/**/*.test.js | tap-nirvana"

which fixes new syntax like the import statement and a test like this would run:

import { describe } from 'riteway';

describe('my test', async assert => {
  assert({
    given: 'true',
    should: 'be true',
    actual: true,
    expected: true,
  });
});

However, tests for React ponents like this

import { describe } from 'riteway';
import render from 'riteway/render-ponent';

import Authentication from './user-authentication-ponent';

describe('user authentication ponent', async assert => {
  const $ = render(<Authentication />);

  assert({
    given: 'just rendering',
    should: "render 'Authentication'",
    actual: $('*:contains("Authentication")').text(),
    expected: 'Authentication',
  });
});

still throw the following error:

$ yarn test
yarn run v1.22.17
$ riteway -r @swc-node/register src/**/*.test.js | tap-nirvana
/Users/user/dev/learning-flow/node_modules/@swc/core/index.js:135
        return bindings.transformSync(isModule ? JSON.stringify(src) : src, isModule, toBuffer(newOptions));
                        ^

Error: error: Expression expected
 
  |
7 |   const $ = render(<Authentication />);
  |                                    ^

error: Expression expected
 
  |
7 |   const $ = render(<Authentication />);
  |                                     ^

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
 
  |
7 |   const $ = render(<Authentication />);
  |                                      ^



Caused by:
    0: failed to process js file
    1: Syntax Error
    at Compiler.transformSync

How can we create that mand so that it runs with SWC?

Share Improve this question edited Aug 21, 2023 at 19:22 Simon 154 bronze badges asked Nov 13, 2021 at 17:14 J. HestersJ. Hesters 14.8k34 gold badges155 silver badges267 bronze badges 3
  • I also have hundreds of tests file with .js extension, all with JSX (testing React code) and am looking for a way for SWC to treat them as jsx... – vsync Commented Jan 18, 2023 at 15:00
  • I've opened a ticket/question on Github regarding .js extension – vsync Commented Jan 18, 2023 at 15:21
  • Same issue with vite-plugin-react-swc – hungify Commented Mar 3, 2023 at 8:15
Add a ment  | 

2 Answers 2

Reset to default 8

After some experimentation I found out that it works if you import React from 'react'; in every file (both the ponent as well as the test) and change the file extensions to .jsx as described in the docs.

However, this is unsatisfying, as we'd like to use React 17's JSX transform feature to avoid having to import React in every file. Additionally, we'd like to keep all file endings .js.

We tried setting .swcrc without any luck so far.

I'm posting this answer here in case no way to configure .swcrc can be found.

I'll assume your question is only about jest and not about the webpack setup for swc.

I've never used swc myself in jest so this is just a shot in the dark, but I found a package for jest called @swc-node/jest which allows you to use a transformer like:

module.exports = {
  transform: {
    '^.+\\.(t|j)sx?$': ['@swc-node/jest'],
  },
}

Which should allow you to transpile all [jt]sx? imports.

There's also a different one called @swc/jest which seems to do the same thing.

I'd start with trying those.

Your issue is that jest isn't able to parse your code, for example if you were using typescript you'd need something like ts-jest in order to parse your TS for you, I think in this case you need a swc/jest transpiler which should first pile your code and output it to memory, then funnel it to jest to run it.

The alternative is that you could pile the tests before hand using swc, then run jest on the piled files as a separate step. At least with TS you can do that, first pile everything using tsc and then run jest on the .js output. I'm sure swc should work the same.

As to why the @swc-node/register package you're using isn't working, I have no idea.

发布评论

评论列表(0)

  1. 暂无评论