使用 React 从 Babel 迁移到 SWC
Migrating from Babel to SWC with React
TL;DR
如何翻译这样的节点脚本:
"test": "NODE_ENV=test riteway -r @babel/register 'src/**/*.test.js' | tap-nirvana",
要使用 SWC 而不是 Babel?
上下文
我们最近升级了 Next.js 版本。 Next.js 现在支持 SWC instead of Babel.
我们项目中React的单元测试是用RITEway写的。测试命令为:
"test": "NODE_ENV=test riteway -r @babel/register 'src/**/*.test.js' | tap-nirvana",
它首先使用 Babel 转换文件,否则 import
语句和 JSX 会导致错误。
在我们尝试迁移到 SWC 的过程中,我们在 CLI 方面运气不佳。但是,我们找到了@swc-node/register
package。它允许我们像这样转换我们的命令:
"test": "riteway -r @swc-node/register src/**/*.test.js | tap-nirvana"
修复了像 import
语句这样的新语法,这样的测试会 运行:
import { describe } from 'riteway';
describe('my test', async assert => {
assert({
given: 'true',
should: 'be true',
actual: true,
expected: true,
});
});
但是,像这样测试 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',
});
});
仍然抛出以下错误:
$ 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
我们如何创建该命令,使其 运行 与 SWC 一起使用?
我假设你的问题只是关于玩笑而不是关于 swc 的 webpack 设置。
我自己从未在玩笑中使用过 swc,所以这只是在黑暗中拍摄,但我找到了一个名为 @sec-node/jest
的玩笑包,它允许您使用像这样的转换器:
module.exports = {
transform: {
'^.+\.(t|j)sx?$': ['@swc-node/jest'],
},
}
这应该允许您转译所有 [jt]sx?
导入。
还有一个叫做 @swc/jest
的不同的似乎做同样的事情。
我会先尝试这些。
你的问题是 jest 无法解析你的代码,例如,如果你使用的是打字稿,你需要像 ts-jest
这样的东西来为你解析你的 TS,我认为在这个如果你需要一个 swc/jest
转译器,它应该首先编译你的代码并将其输出到内存,然后将它汇集到 运行 它。
另一种方法是,您可以先使用 swc 手动编译测试,然后 运行 作为单独的步骤对编译后的文件开玩笑。至少使用 TS 你可以做到这一点,首先使用 tsc
编译所有内容,然后 运行 在 .js
输出上开玩笑。我确定 swc 应该也能正常工作。
至于为什么您使用的 @swc-node/register
软件包不起作用,我不知道。
经过一些实验后,我发现如果您在每个文件(包括组件和测试)中 import React from 'react';
并将文件扩展名更改为 .jsx
,如 [=15] 所述,它会起作用=].
然而,这并不令人满意,因为我们想使用 React 17's JSX transform feature 来避免必须在每个文件中导入 React。此外,我们希望保留所有文件结尾 .js
.
我们尝试了 setting .swcrc
到目前为止没有任何运气。
我在这里发布这个答案以防无法找到配置 .swcrc
的方法。
TL;DR
如何翻译这样的节点脚本:
"test": "NODE_ENV=test riteway -r @babel/register 'src/**/*.test.js' | tap-nirvana",
要使用 SWC 而不是 Babel?
上下文
我们最近升级了 Next.js 版本。 Next.js 现在支持 SWC instead of Babel.
我们项目中React的单元测试是用RITEway写的。测试命令为:
"test": "NODE_ENV=test riteway -r @babel/register 'src/**/*.test.js' | tap-nirvana",
它首先使用 Babel 转换文件,否则 import
语句和 JSX 会导致错误。
在我们尝试迁移到 SWC 的过程中,我们在 CLI 方面运气不佳。但是,我们找到了@swc-node/register
package。它允许我们像这样转换我们的命令:
"test": "riteway -r @swc-node/register src/**/*.test.js | tap-nirvana"
修复了像 import
语句这样的新语法,这样的测试会 运行:
import { describe } from 'riteway';
describe('my test', async assert => {
assert({
given: 'true',
should: 'be true',
actual: true,
expected: true,
});
});
但是,像这样测试 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',
});
});
仍然抛出以下错误:
$ 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
我们如何创建该命令,使其 运行 与 SWC 一起使用?
我假设你的问题只是关于玩笑而不是关于 swc 的 webpack 设置。
我自己从未在玩笑中使用过 swc,所以这只是在黑暗中拍摄,但我找到了一个名为 @sec-node/jest
的玩笑包,它允许您使用像这样的转换器:
module.exports = {
transform: {
'^.+\.(t|j)sx?$': ['@swc-node/jest'],
},
}
这应该允许您转译所有 [jt]sx?
导入。
还有一个叫做 @swc/jest
的不同的似乎做同样的事情。
我会先尝试这些。
你的问题是 jest 无法解析你的代码,例如,如果你使用的是打字稿,你需要像 ts-jest
这样的东西来为你解析你的 TS,我认为在这个如果你需要一个 swc/jest
转译器,它应该首先编译你的代码并将其输出到内存,然后将它汇集到 运行 它。
另一种方法是,您可以先使用 swc 手动编译测试,然后 运行 作为单独的步骤对编译后的文件开玩笑。至少使用 TS 你可以做到这一点,首先使用 tsc
编译所有内容,然后 运行 在 .js
输出上开玩笑。我确定 swc 应该也能正常工作。
至于为什么您使用的 @swc-node/register
软件包不起作用,我不知道。
经过一些实验后,我发现如果您在每个文件(包括组件和测试)中 import React from 'react';
并将文件扩展名更改为 .jsx
,如 [=15] 所述,它会起作用=].
然而,这并不令人满意,因为我们想使用 React 17's JSX transform feature 来避免必须在每个文件中导入 React。此外,我们希望保留所有文件结尾 .js
.
我们尝试了 setting .swcrc
到目前为止没有任何运气。
我在这里发布这个答案以防无法找到配置 .swcrc
的方法。