简体   繁体   English

使用 React 从 Babel 迁移到 SWC

[英]Migrating from Babel to SWC with React

TL;DR TL; 博士

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?使用SWC而不是 Babel?


Context语境

We recently upgraded our Next.js version.我们最近升级了 Next.js 版本。 Next.js now supports SWC instead of Babel. Next.js 现在支持SWC 而不是 Babel。

The unit tests for React in our project are written with RITEway .我们项目中 React 的单元测试是用RITEway编写的。 The test command 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.它首先使用 Babel 转换文件,否则import语句和 JSX 会导致错误。

During our attempts to migrating to SWC, we had no luck with the CLI.在我们尝试迁移到 SWC 的过程中,我们没有使用 CLI。 However, we found the @swc-node/register package .但是,我们找到了@swc-node/register It allowed us to transform our command 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语句这样的新语法,并且将运行这样的测试:

import { describe } from 'riteway';

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

However, tests for React components like this然而,像这样的 React 组件测试

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

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

describe('user authentication component', 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 command so that it runs with SWC?我们如何创建该命令以便它与 SWC 一起运行?

I'll assume your question is only about jest and not about the webpack setup for swc.我假设你的问题只是关于玩笑而不是关于 swc 的 webpack 设置。

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 @sec-node/jest which allows you to use a transformer like:我自己从来没有在玩笑中使用过 swc,所以这只是在黑暗中的一个镜头,但我发现了一个名为@sec-node/jest包,它允许您使用如下转换器:

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

Which should allow you to transpile all [jt]sx?哪个应该允许您转译所有[jt]sx? imports.进口。

There's also a different one called @swc/jest which seems to do the same thing.还有一个叫做@swc/jest的不同的似乎做同样的事情。

I'd start with trying those.我会从尝试这些开始。

Overall 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 compile your code and output it to memory, then funnel it to jest to run it.总的来说,您的问题是 jest 无法解析您的代码,例如,如果您使用的是打字稿,您需要像ts-jest这样的东西来为您解析您的 TS,我认为在这种情况下您需要一个swc/jest编译器应该首先编译您的代码并将其输出到内存中,然后将其汇集到 jest 以运行它。

The alternative is that you could compile the tests before hand using swc, then run jest on the compiled files as a separate step.另一种方法是您可以使用 swc 事先编译测试,然后在编译后的文件上运行 jest 作为单独的步骤。 At least with TS you can do that, first compile everything using tsc and then run jest on the .js output.至少使用 TS 可以做到这一点,首先使用tsc编译所有内容,然后在.js输出上运行 jest。 I'm sure swc should work the same.我确定 swc 应该也能正常工作。

As to why the @swc-node/register package you're using isn't working, I have no idea.至于为什么您使用的@swc-node/register包不起作用,我不知道。

After some experimentation I found out that it works if you import React from 'react';经过一些实验,我发现如果您import React from 'react'; ,它会起作用import React from 'react'; in every file (both the component as well as the test) and change the file extensions to .jsx as described in the docs .在每个文件(组件和测试)中,并将文件扩展名更改为.jsx ,如文档中所述

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.然而,这并不令人满意,因为我们希望使用React 17 的 JSX 转换功能来避免在每个文件中导入 React。 Additionally, we'd like to keep all file endings .js .此外,我们希望保留所有文件结尾.js

We tried setting .swcrc without any luck so far.到目前为止,我们尝试设置.swcrc没有任何运气。

I'm posting this answer here in case no way to configure .swcrc can be found.我在这里发布这个答案,以防找不到配置.swcrc方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM