如何让SWC编译含React JSX的.js文件以适配Mocha测试?
问题:如何让SWC编译含React JSX的
.js文件用于Mocha测试? 简而言之
我正在把Mocha的编译工具从Babel换成SWC,但遇到了个头疼的问题:SWC只会处理.jsx文件里的JSX语法,对.js文件里的JSX完全视而不见。我已经做了最小化复现的仓库,去SWC的GitHub仓库求助没得到有用的反馈,问题还被关闭了,所以来这里问问有没有解决办法。
当前使用的配置文件
.swcrc
{ "$schema": "https://json.schemastore.org/swcrc", "jsc": { "parser": { "syntax": "ecmascript", "jsx": true, "dynamicImport": false, "privateMethod": true, "functionBind": false, "exportDefaultFrom": true, "exportNamespaceFrom": false, "decorators": true, "decoratorsBeforeExport": true, "topLevelAwait": false, "importMeta": false }, "transform": { "legacyDecorator": true, "react": { "pragma": "React.createElement", "pragmaFrag": "React.Fragment", "throwIfNamespace": true, "development": false, "useBuiltins": false }, "optimizer": { "globals": { "vars": { "__DEBUG__": "true" } } } }, "target": "es5", "loose": false, "externalHelpers": false, "keepClassNames": false }, "module": { "type": "commonjs" }, "minify": false }
package.json
{ "name": "swc-js-extension-fails-with-jsx-content", "version": "1.0.0", "description": "SWC not parsing jsx in js files", "author": { "name": "Yair Even-Or", "email": "vsync.design@gmail.com" }, "private": false, "type": "module", "dependencies": { "@babel/runtime": "7.17.8", "@swc-node/register": "1.5.5", "@swc/cli": "0.1.59", "@swc/core": "1.3.27", "@wojtekmaj/enzyme-adapter-react-17": "0.8.0", "jsdom": "^21.0.0", "react": "17.0.2", "react-dom": "17.0.2" }, "devDependencies": { "@babel/cli": "7.19.3", "@babel/core": "7.20.2", "@babel/eslint-parser": "7.19.1", "@babel/plugin-proposal-class-properties": "7.12.1", "@babel/plugin-proposal-decorators": "7.12.12", "@babel/plugin-proposal-export-default-from": "7.12.1", "@babel/plugin-proposal-function-bind": "7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator": "7.12.1", "@babel/plugin-proposal-optional-chaining": "7.12.7", "@babel/plugin-transform-runtime": "7.19.6", "@babel/preset-env": "7.20.2", "@babel/preset-react": "7.18.6", "@babel/register": "7.18.9", "chai": "4.3.7", "enzyme": "3.11.0", "mocha": "9.2.2" }, "browserslist": { "modern": [ "last 1 chrome version", "last 1 firefox version" ], "ssr": [ "node 14" ] }, "scripts": { "test": "mocha \"src/**/*.test.js\"" } }
jsconfig.json
{ "compilerOptions": { "baseUrl": ".", "target": "esnext", "moduleResolution": "Node", "experimentalDecorators": true, "jsx": "react-jsx" } }
两种工具的运行对比
使用Babel时一切正常
.mocharc.json配置:
"require": ["@babel/register", "setup.js"]

使用SWC时直接报错
.mocharc.json配置:
"require": ["@swc-node/register", "setup.js"]

解决办法
问题根源在于@swc-node/register默认只会对.jsx/.tsx文件启用JSX解析逻辑,对.js文件不会触发。这里有两种靠谱的解决方式:
方式1:修改@swc-node/register的处理规则
你可以在项目根目录创建.swc-node-registerrc.js文件,明确指定要处理的文件扩展名:
module.exports = { exts: ['.js', '.jsx', '.ts', '.tsx'], swcOpts: { jsc: { parser: { syntax: 'ecmascript', jsx: true } } } }
或者直接在package.json的测试脚本里传参数:
"scripts": { "test": "mocha --require '@swc-node/register?exts[]=.js&exts[]=.jsx' \"src/**/*.test.js\"" }
方式2:修改.swcrc配置(更推荐)
在.swcrc的module部分添加扩展名别名配置,强制让SWC把.js文件当作.jsx来处理:
{ // 保留原有配置... "module": { "type": "commonjs", "resolve": { "extensionAlias": { ".js": [".jsx", ".js"] } } } }
这个配置会让SWC解析.js文件时,优先使用.jsx的语法规则,自然就能正确处理里面的JSX了。
验证
修改完配置后重新运行npm test,应该就能正常编译.js文件里的JSX并通过Mocha测试了。
内容的提问来源于stack exchange,提问作者vsync
相关产品推荐
相关产品推荐

