ES6 从根目录导入



我目前正在玩React Native。我正在尝试构建我的应用程序,但是导入开始变得混乱。

--app/
-- /components
-- Loading.js
-- index.ios.js

现在,在我的index.ios.js内,我可以简单地做:

import Loading from './components/Loading';

但是,当我开始创建更多具有更深目录结构的组件时,它开始变得混乱:

import Loading from '.../../../../components/Loading';

我知道首选的解决方案是为事物制作私有 npm 模块,但这对于一个小项目来说是矫枉过正的。

您可以在浏览器上执行global.requireRoot类型的解决方案,但是如何使用导入来实现这一点?

在 React 上遇到了同样的问题。 所以我为 babel 写了一些插件,可以从根角度导入模块 - 路径不短 - 但很明显你导入了什么。

所以代替:

import 'foo' from '../../../components/foo.js';

您可以使用:

import 'foo' from '~/components/foo.js';

这是插件(经过测试并带有清晰的自述文件)

react 文档解释了如何做到这一点: https://create-react-app.dev/docs/importing-a-component/#absolute-imports

只需在项目根目录中添加一个 jsconfig.json:

{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}

如果您使用的是 Webpack,则可以通过resolve属性对其进行配置以解析导入路径。

网络包 1

resolve: {
root: [
path.resolve(__dirname  + '/src')
]
}......

网络包 2

resolve: {
modules: [
path.resolve(__dirname + '/src'),
path.resolve(__dirname + '/node_modules')
]
}.....

之后您可以使用

import configureStore from "store/configureStore";

而不是:

import configureStore from "../../store/configureStore";

Webpack 将从传递的解析参数配置导入路径。

您可以使用 System.js 加载器执行相同的操作,但使用它自己的配置参数(它可以是映射路径。在系统.js文档中检查它)(如果您想使用它。它主要用于 Angular 2 案例。但我建议:不要使用标准系统.js即使您正在使用ng2。 网络包要好得多)。

我刚刚检查了一个 React 项目,该项目已有 6 个多月的历史,由于某些原因,我的导入不再有效。我尝试了第一个答案:

import 'foo' from '~/components/foo.js';

不幸的是,这没有奏效。

我在项目的根目录中添加了一个与package.json相同的.env文件。我将以下行添加到该文件中,这修复了我在项目中的导入。

NODE_PATH=src/

如果您使用的是Create-React-App,则只需更改环境变量NODE_PATH即可包含项目的根目录。

在您的 config.json 中,在运行 react-scripts 命令之前,执行以下更改以设置此变量:

"scripts": {
"start": "cross-env NODE_PATH=. react-scripts start",
"build": "cross-env NODE_PATH=. react-scripts build",
"test": "cross-env NODE_PATH=. react-scripts test",
"eject": "react-scripts eject"
},

我们使用 npm 库 cross-env,因为它适用于 unix 和 windows。语法是cross-env var=value command.

现在我们可以做import module from 'src/my/module'而不是import module from '../../my/module'

有关实施的其他详细信息

需要注意的是,cross-env 的作用域仅限于它执行的命令,因此cross-env var=val command1 && command2command1 期间只会设置 var。如果需要,请通过执行cross-env var=val command1 && cross-env var=val command2来解决此问题

create-react-app 将 node_modules/中的文件夹优先于 NODE_PATH 中的文件夹,这就是为什么我们将NODE_PATH设置为"."而不是"./src"。使用 "." 要求所有绝对导入都以 "src/" 开头,这意味着永远不会有名称冲突,除非您使用的是某些名为 src 的node_module。

(注意:上述解决方案取代了变量NODE_PATH。理想情况下,如果它已经存在,我们会附加到它。NODE_PATH 是一个 ":" 或 ";" 分隔的路径列表,具体取决于其 unix 还是窗口。如果有人找到跨平台解决方案来做到这一点,我可以编辑我的答案。

使用 webpack,您还可以创建以~解析为根的路径,因此您可以使用import Loading from '~/components/Loading';

resolve: {
extensions: ['.js'],
modules: [
'node_modules', 
path.resolve(__dirname + '/app')
],
alias: {
['~']: path.resolve(__dirname + '/app')
}
}

诀窍是使用 javascript 括号语法来分配属性。

Webpack 3中,配置略有不同:

import webpack from 'webpack';
import {resolve} from 'path';

module: {
loaders: [
{
test: /.js$/,
use: ["babel-loader"]
},
{
test: /.scss$|.css$/,
use: ["style-loader", "css-loader", "sass-loader"]
}
]
},
resolve: {
extensions: [".js"],
alias: {
["~"]: resolve(__dirname, "src")
}
},

如果您使用的是创建 React 应用程序,则可以在config/webpack.config.dev.jsconfig/webpack.config.prod.js中添加paths.appSrcresolve.modules

从:

resolve: {
modules: ['node_modules', paths.appNodeModules].concat(...

自:

resolve: {
modules: [paths.appSrc, 'node_modules', paths.appNodeModules].concat(...

然后,您的代码将起作用:

import Loading from 'components/Loading';

最新更新