[英]SWC with JavaScript: How to handle CSS imports and how to absolute imports?
我们正在从 Babel 迁移到SWC 。 (我刚才问了一个问题。我正在改进那个问题的答案。)
我们从以下位置迁移了命令:
"test": "NODE_ENV=test riteway -r @babel/register 'src/**/*.test.js' | tap-nirvana",
到
"test": "SWC_NODE_PROJECT=./jsconfig.json riteway -r @swc-node/register src/**/*.test.js | tap-nirvana",
其中jsconfig.json
看起来像这样:
{
"compilerOptions": {
"allowJs": true,
"baseUrl": "./src",
"jsx": "react-jsx"
}
}
如果我们尝试为独立组件(没有绝对导入,没有 CSS)编译测试,它会起作用:
import { describe } from 'riteway';
import render from 'riteway/render-component';
function HomePageComponent({ user: { email } }) {
return <p>{email}</p>;
}
describe('home page component', async assert => {
const user = { email: 'foo' };
const $ = render(<HomePageComponent user={user} />);
assert({
given: 'a user',
should: 'render its email',
actual: $('p').text(),
expected: user.email,
});
});
测试编译正常。
使用 Babel,我们有一个像这样的.babelrc
:
{
"env": {
"test": {
"plugins": [
[
"module-resolver",
{
"root": [
"."
],
"alias": {
"components": "./src/components",
"config": "./src/config",
"features": "./src/features",
"hocs": "./src/hocs",
"hooks": "./src/hooks",
"pages": "./src/pages",
"redux": "./src/redux",
"styles": "./src/styles",
"tests": "./src/tests",
"utils": "./src/utils"
}
}
]
]
}
},
"presets": [
[
"next/babel",
{
"ramda": {}
}
]
],
"plugins": [
["styled-components", { "ssr": true }]
]
}
其中 styles 由 styled-components 处理,而绝对导入是通过module-resolver
插件定义的。 (我们从 styled-components 切换到 CSS 模块,这就是我们从.module.css
CSS 文件导入的原因。无论如何......)
如果我们编写测试,我们希望如何使用他们的实际导入来编写它,如下所示:
import { describe } from 'riteway';
import render from 'riteway/render-component';
import { createPopulatedUserProfile } from 'user-profile/user-profile-factories';
import HomePageComponent from './home-page-component';
describe('home page component', async assert => {
const user = createPopulatedUserProfile();
const $ = render(<HomePageComponent user={user} />);
assert({
given: 'a user',
should: 'render its email',
actual: $('p').text(),
expected: user.email,
});
});
它失败了:
$ SWC_NODE_PROJECT=./jsconfig.json riteway -r @swc-node/register src/features/home/home-page-component.test.js | tap-nirvana
/Users/janhesters/dev/my-project/src/features/home/home.module.css:1
(function (exports, require, module, __filename, __dirname) { .container {
^
SyntaxError: Unexpected token '.'
当我们离开home-page-component.js
中的 CSS 导入时,或者:
$ SWC_NODE_PROJECT=./jsconfig.json riteway -r @swc-node/register src/features/home/home-page-component.test.js | tap-nirvana
node:internal/modules/cjs/loader:936
throw err;
^
Error: Cannot find module 'user-profile/user-profile-factories'
Require stack:
- /Users/janhesters/dev/my-project/src/features/home/home-page-component.test.js
- /Users/janhesters/dev/my-project/node_modules/riteway/bin/riteway
分别,当我们摆脱 CSS 进口。
我们如何帮助 SWC 理解 CSS(或模拟 CSS 模块)以及我们如何帮助它理解绝对导入?
我们已经在jsconfig.json
baseUrl
styled-components
会处理这个问题。 您需要对 SWC 执行相同的操作。 我找不到执行此操作的现有 SWC 插件,但您可以推出自己的. 显然这是一种痛苦,但这就是使用新工具的成本。baseUrl
和paths
的.swrc
选项应该做你想做的事,但这似乎也有一些问题。 直接在@swc-node
GitHub 存储库中创建问题可能会更好,但鉴于那里的评论,感觉你可能会成为 SOL 一段时间。 使用Next 开箱即用支持的库之一可能会更快/更容易地重写您的测试。
关于绝对路径
您已经在jsconfig.json
文件中添加了baseUrl
但没有添加路径,您应该像我一样修改您的配置文件:
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@screens": ["./screens"],
"@shared": ["./shared"],
"@shared/*": ["./shared/*"]
},
路径是module-resolver
的alias
,我猜你的root
不应该是"."
,它应该与您的jsconfig.json
文件完全相同,我的意思是baseUrl
值。
"plugins": [
[
"module-resolver",
{
"root": ["./src"],
"extensions": [".ts", ".tsx", ".js", ".jsx", ".json"],
"alias": {
"@screens": "./src/screens",
"@shared": "./src/shared"
}
}
]
],
如果你有 Webpack,你应该在你的resolve
键中有alias
配置关闭 Webpack 配置 object,就像我的:
const resolve = {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
alias: {
'@screens': path.join(__dirname, 'src/screens/'),
'@shared': path.join(__dirname, 'src/shared/'),
},
modules: ['src', 'node_modules'],
descriptionFiles: ['package.json'],
};
关于CSS
实际上,您使用 CSS 文件作为 CSS-Modules 不像推荐的 NexJS doc ,在文档中开发人员应该像import './styles.css'
一样导入 CSS ,然后在 JSX 中将其用作string
,如<div className="main"
但
您正在像模块(CSS-Module)一样导入它:
// you did it
import styles from './styles.css';
<div className={styles.main}
如您所知,它是这个文档的内置支持,NextJS 支持它,但 SWC 无法理解它。 我花了几个小时来寻找一种方法,但似乎 SWC 还不支持 CSS-Module。 您应该为 SWC 创建自己的插件以支持 CSS-Module。
我能够在不编写任何插件的情况下解决所有问题。 我从问题中将解决方案推到了我的示例回购中。
首先,使用官方的 SWC 项目的 register 。 这意味着,您必须像这样编译测试:
"test": "riteway -r @swc/register 'src/**/*.test.js' | tap-nirvana",
您可以通过运行以下命令来安装它:
yarn add --dev @swc/core @swc/register
我们需要这个版本的寄存器,因为它考虑了一个.swcrc
文件,而另一个没有。
其次,您需要"path"
和"baseUrl"
来修复绝对导入,因为出于某种原因,SWC 不会仅提供"baseUrl"
来推断所有路径。 你需要调整你的.swcrc
来处理 React。
{
"jsc": {
"baseUrl": "./src",
"paths": {
"*.css": ["utils/identity-object-proxy.js"],
"utils/*": ["utils/*"]
},
"parser": {
"jsx": true,
"syntax": "ecmascript"
},
"transform": {
"react": {
"runtime": "automatic"
}
}
},
"module": {
"type": "commonjs"
}
}
第三,要解决.css
,您需要将所有对.css
文件的导入重新映射到身份 object 代理,您可以在上面的.swcrc
示例中看到。 身份 object 代理是一个 object,当您引用任何属性时,它会返回您尝试引用的字符串化键。 你可以像这样自己创建一个:
const identityObjectProxy = new Proxy(
{},
{
get: function getter(target, key) {
if (key === '__esModule') {
return false;
}
return key;
},
},
);
export default identityObjectProxy;
要使.css
重新映射到 go 生效,您需要将所有导入到.css
文件的文件绝对导入。 ( import styles from './styles.module.css
不会工作!)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.