我刚刚使用react native建立了一个小测试项目。这对我来说是全新的(包括ECMAScript 6)。 Eslint告诉我一些有关“循环依赖项”的信息,我不知道该如何解决这个问题。该代码仍然可以正常工作。
我的package.json:
...
"dependencies": {
"axios": "^0.19.0",
"node-sass": "^4.12.0",
"react": "16.8.3",
"react-native": "0.59.9",
"react-navigation": "^3.11.0"
},
"devDependencies": {
"@babel/core": "7.4.5",
"@babel/runtime": "7.4.5",
"babel-eslint": "^10.0.1",
"babel-jest": "24.8.0",
"babel-plugin-module-resolver": "^3.2.0",
"eslint": "^5.16.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-import-resolver-babel-module": "^5.1.0",
"eslint-plugin-import": "^2.17.3",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-react": "^7.13.0",
"jest": "24.8.0",
"metro-react-native-babel-preset": "0.54.1",
"react-dom": "^16.8.6",
"react-test-renderer": "16.8.3"
},
...
src/index.jsx
是主要的JSX文件:
import { Comp1 } from 'components';
...
我创建了一个src/components/index.jsx
以启用类似的导入
import { Comp1, Comp2, Comp3 } from 'components'
代替
import { Comp1 } from 'components/comp1';
import { Comp2 } from 'components/comp2';
import { Comp3 } from 'components/comp3';
文件src/components/index.jsx
如下:
export * from './button';
export * from './comp1';
...
src/components/button/index.jsx
:
import React from 'react';
import {
Text,
TouchableOpacity
} from 'react-native';
import style from './style';
const Button = ({ onPress, children }) => {
const {
buttonStyle,
textStyle
} = style;
return (
<TouchableOpacity onPress={onPress} style={buttonStyle}>
<Text style={textStyle}>
{children}
</Text>
</TouchableOpacity>
);
};
export default Button;
export { Button };
src/components/comp1/index.jsx
:
import React from 'react';
import {
Text,
View
} from 'react-native';
import { Button } from 'components';
import style from './style';
const Comp1 = (props) => {
const {
textStyle,
viewStyle
} = style;
return (
<View style={viewStyle}>
<Text style={textStyle}>some text</Text>
<Button>Test</Button>
</View>
);
};
export default Comp1;
export { Comp1 };
运行此设置会产生错误es import/no-cycle。代码本身有效。
如果我将import { Button } from 'components'
中的src/components/comp1/index.jsx
更改为import { Button } from 'components/button'
,则会弹出no eslint错误。
我想使用如上所述的这种简短的导入语法,而又不会降低在彼此内部使用模块的可能性。有办法吗?
答案 0 :(得分:2)
您的结构 在components/index.jsx
和comp1/index.jsx
(以及您拥有相同事物的其他对象)之间建立循环依赖关系。 comp1/index.jsx
从components/index.jsx
导入,而comp1/index.jsx
从exports
导入。
对于实际的ESM¹模块而言,这不是问题,但是如果将它们转译为CJS²或类似代码,则需要格外小心(因此有规则)。因此,该规则警告您。
这并不意味着您无法使用CJS做到这一点,仅意味着(再次)您需要格外小心。 CJS通过动态填充的comp1/index.jsx
对象工作。当两个模块之间存在循环依赖关系(为简单起见)时,这意味着两个模块中的一个将在另一个模块之前运行,这意味着尚未定义从另一个模块导入的任何内容。因此,两个模块之一中的顶级代码不能依赖现有的导入。
在您的示例中,我不希望这是一个问题,因为循环中模块中的顶级代码未使用循环中其他模块的导入,因此仅在称为之后(Button
使用Comp1
,但只有在被调用时才使用import
,并且在顶层代码中不会调用它。(该过程可能会更加复杂除此之外,但是...)
如果代码已经过测试并且可以正常工作,则可以使用configuration comments对组件文件禁用该规则(如果允许的话)。这样一来,您就可以在实际问题循环的情况下全局地保留规则,而不必为测试和知道的循环感到烦恼。
¹ESM = E CMA S cript M odles,真正的原生JavaScript模块,如果仅使用{{1 }}和export
声明(不是import()
动态导入)。
²CJS = C ommon JS ,一种使用require
和exports
对象的动态模块结构。