提问人:ghybs 提问时间:11/9/2023 最后编辑:ghybs 更新时间:11/16/2023 访问量:158
在 Meteor 中使用 Babel 配置 MUI 组件选择器 API 在项目启动时出现“TypeError: Cannot read property 'id' of null”
Configuring MUI Components selector API with Babel in Meteor "TypeError: Cannot read property 'id' of null" on project start
问:
我有一个 Meteor React 项目,我为此添加了 Material UI v5(安装说明),它带有 CSS-in-JS 样式的 Emotion:
$ meteor create --react meteor-react-mui
Created a new Meteor app in 'meteor-react-mui'.
$ cd meteor-react-mui
$ meteor npm install @mui/material @emotion/react @emotion/styled
+ @emotion/[email protected]
+ @emotion/[email protected]
+ @mui/[email protected]
added 79 packages from 99 contributors and audited 193 packages in 51.3s
我想使用组件选择器 API,因此我根据需要进行了安装:@emotion/babel-plugin
$ meteor npm install @emotion/babel-plugin
+ @emotion/babel-plug[email protected]
updated 1 package and audited 194 packages in 1.643s
...然后我将配置(如上述文档所述)添加到我的文件中:.babelrc
{
"plugins": [
[
"@emotion",
{
"importMap": {
"@mui/system": {
"styled": {
"canonicalImport": ["@emotion/styled", "default"],
"styledBaseImport": ["@mui/system", "styled"]
}
},
"@mui/material/styles": {
"styled": {
"canonicalImport": ["@emotion/styled", "default"],
"styledBaseImport": ["@mui/material/styles", "styled"]
}
}
}
}
]
]
}
但是,现在当我启动项目时,我遇到了以下错误:
$ meteor
[[[[[ ~/.../meteor-react-mui ]]]]]
=> Started proxy.
=> Started HMR server.
/.../.meteor/packages/meteor-tool/.../dev_bundle/lib/node_modules/meteor-promise/promise_server.js:218
throw error;
^
TypeError: Cannot read property 'id' of null
at InputFile.resolve (/tools/isobuild/compiler-plugin.js:403:61)
at packages/babel-compiler.js:574:23
at Array.some (<anonymous>)
at requireWithPrefixes (packages/babel-compiler.js:569:26)
at requireWithPath (packages/babel-compiler.js:487:14)
at resolveHelper (packages/babel-compiler.js:459:24)
at resolveHelper (packages/babel-compiler.js:450:21)
at packages/babel-compiler.js:432:19
at Array.forEach (<anonymous>)
at walkHelper (packages/babel-compiler.js:431:10)
at walkBabelRC (packages/babel-compiler.js:417:24)
at BabelCompiler.BCp._inferHelper (packages/babel-compiler.js:514:17)
at BabelCompiler.BCp._inferFromBabelRc (packages/babel-compiler.js:359:14)
at BabelCompiler.BCp.inferExtraBabelOptions (packages/babel-compiler.js:333:10)
at BabelCompiler.BCp.processOneFileForTarget (packages/babel-compiler.js:209:10)
at packages/babel-compiler.js:123:25
以下是我的依赖项:package.json
{
"dependencies": {
"@babel/runtime": "^7.20.7",
"@emotion/babel-plugin": "^11.11.0",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/material": "^5.14.17",
"meteor-node-stubs": "^1.2.5",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
Meteor 发布版本:.meteor/release
[email protected]
和 Meteor 打包版本:.meteor/packages
[email protected] # Packages every Meteor app needs to have
[email protected] # Packages for a great mobile UX
[email protected] # The database Meteor supports right now
[email protected] # Reactive variable for tracker
[email protected] # CSS minifier run for production mode
[email protected] # JS minifier run for production mode
[email protected] # ECMAScript 5 compatibility for older browsers
[email protected] # Enable ECMAScript2015+ syntax in app code
[email protected] # Enable TypeScript syntax in .ts and .tsx modules
[email protected] # Server-side component of the `meteor shell` command
[email protected] # Update client in development without reloading the page
[email protected] # Define static page content in .html files
react-meteor-data # React higher-order component for reactively tracking Meteor data
注意:如果我使用模板(而不是上面所示的模板),我会遇到同样的问题,但错误消息略有不同:--typescript
--react
TypeError: Cannot read property 'id' of null
at InputFile.resolve (/tools/isobuild/compiler-plugin.js:403:61)
at packages/babel-compiler.js:574:23
at Array.some (<anonymous>)
at requireWithPrefixes (packages/babel-compiler.js:569:26)
at requireWithPath (packages/babel-compiler.js:487:14)
at resolveHelper (packages/babel-compiler.js:459:24)
at resolveHelper (packages/babel-compiler.js:450:21)
at packages/babel-compiler.js:432:19
at Array.forEach (<anonymous>)
at walkHelper (packages/babel-compiler.js:431:10)
at walkBabelRC (packages/babel-compiler.js:417:24)
at TypeScriptCompiler.BCp._inferHelper (packages/babel-compiler.js:514:17)
at TypeScriptCompiler.BCp._inferFromBabelRc (packages/babel-compiler.js:359:14)
at TypeScriptCompiler.BCp.inferExtraBabelOptions (packages/babel-compiler.js:333:10)
at TypeScriptCompiler.BCp.processOneFileForTarget (packages/babel-compiler.js:209:10)
at packages/babel-compiler.js:123:25
答:
看起来只需在 Babel 配置文件中使用包的全名就可以解决 Meteor 构建的问题:@emotion/babel-plugin
.babelrc
{
"plugins": [
[
"@emotion/babel-plugin", // Use full name, instead of just "@emotion"
{
// Etc.
}
]
]
}
在普通的 React 和 Babel 堆栈中,Babel 配置中的短名称实际上会自动规范化为该全名,因此 Material UI 文档仅提供短名称:@emotion
Babel 有一个名称规范化阶段,[它] 会在加载 [plugin] 项时自动添加这些前缀。
[...]
babel-plugin
/babel-preset
如果仅给出 -scope 名称,则将作为包名称注入。@
输入: / 规范化:
"@scope"
"@scope/babel-plugin"
不幸的是,看起来 Meteor 包装包重新实现了这个逻辑,但只有最简单的部分:babel-compiler
prefixes.push("@babel/plugin-", "babel-plugin-");
// ...
prefixes.push("");
// ...
inputFile.resolve(prefix + id, controlFilePath))
因此,指定 Babel 插件的实际全名比依赖名称规范化更安全。
注意:顺便说一句,虽然构建现在可以工作,但我在浏览器中显示网页时仍然遇到问题,在浏览器控制台中显示以下消息:
未捕获的错误:组件选择器只能与 @emotion/babel-plugin、swc Emotion 插件或其他 Emotion 感知编译器转换结合使用。
我像这样使用组件选择器 API:
import { styled } from "@mui/material"; // Import from MUI instead of from @emotion, e.g. to benefit from theme prop
const StyledDiv = styled("div")({
// Some style...
});
const StyledParent = styled("div")({
[StyledDiv]: { // Use the actual component as a selector
// Some other style...
}
});
由于从父包导入函数,而不是 Babel 配置中提到的更具体的函数,因此后者无法捕获要转换的导入。因此,我只需要将缺少的导入路径添加到配置中:styled
@mui/material
@mui/material/styles
{
"plugins": [
[
"@emotion/babel-plugin",
{
"importMap": {
"@mui/system": {
"styled": {
"canonicalImport": ["@emotion/styled", "default"],
"styledBaseImport": ["@mui/system", "styled"]
}
},
"@mui/material/styles": {
"styled": {
"canonicalImport": ["@emotion/styled", "default"],
"styledBaseImport": ["@mui/material/styles", "styled"]
}
},
"@mui/material": { // Add the missing import path
"styled": {
"canonicalImport": ["@emotion/styled", "default"],
"styledBaseImport": ["@mui/material", "styled"]
}
}
}
}
]
]
}
...现在一切正常!
评论