我有一个普通的旧 NodeJS 项目(带有 Typescript),我真的很难找到如何为本地文件进行 ES6 导入,而不必一直执行“../../../foo/bar” .
有很多类似的问题,但似乎都围绕着我没有使用的 babel/Webpack。
如果我执行以下操作:
import foo from `/bar`
它在我的电脑的根文件夹(例如 c:/bar)中查找它并失败。
我尝试使用 .env 文件,并将 NODE_PATH 设置为各种参数(“/”、“.”等),但没有成功。我还尝试在 package.json 中设置“type: 'module'”,并且我的 tsconfig.json 文件具有 {"baseUrl": "."}
所以我想我已经尝试了我能找到的所有答案。我只是以错误的组合进行操作还是解决方案有所不同?
这是我为此使用的两个技巧,即 Node.js 和原生 ES 模块。
file:
依赖关系如果您想从下两级的子包访问
<project root>/bar
,请将其添加到package.json
依赖项中:
"@local/bar": "file:../../bar",
..使
bar
可用于所述子包作为 @local/bar
.
虽然相对路径仍然存在,但它们现在都在
package.json
文件中,并且源永远不需要知道..
import()
选择常量的根文件夹路径并执行以下操作:
const foo = await import(`${rootPath}/bar`);
截至 2023 年 3 月,消除 NodeJS 相对路径的一个好方法是使用
imports
中的 package.json
属性。更多信息请参考这篇文章:
在下面的代码中,#root 是项目根目录。
(如果这个答案和这篇文章对您有帮助,请点赞。谢谢!)
// package.json
{
"imports": {
"#root/*.js": "./*.js"
}
}
// main.js:
const Source = require('#root/path/to/Source.js');
// Source.js:
module.exports = class Source {
// ...
}
// package.json:
{
"type" : "module",
"imports": {
"#root/*.js": "./*.js"
}
}
// main.js
import { Source } from '#root/path/to/Source.js';
// Source.js:
export class Source {
// ...
}
不需要“导入”或“要求”任何额外的包(没有 Babel.js、没有 Webpack、没有 RequireJS)。安装 NodeJS 后,此方法开箱即用。
IDE 链接按预期工作(按住 Ctrl 键单击类名可直接跳转到源文件。此外,移动源文件(通过拖放)将自动更新文件路径引用。已在
WebStorm 2022.3.2
和 VS Code 1.76.2
上测试
。)
适用于
.mjs
(ECMAScript 模块系统)和 .cjs
(CommonJS)文件类型。请参阅这篇关于 .cjs 和 .mjs 的参考帖子。
无需修改保留的
node_modules
目录
无需在操作系统级别设置任何linux文件链接
这对我来说实现起来非常简单,在 VSCode 中使用 Typescript。
在
tsconfig.json
中,我在"baseUrl": "./",
下添加了
compilerOptions
重启 VSCode 后,VSCode 将自动使用伪绝对路径导入。
路径不会以
/
开头,它仍然指向您的驱动器根目录。
如果位于当前文件下方,它仍然会使用
./relative/path
,但不再使用 ../../tree/traversing
然后我将packages.json中的dev设置为
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "cross-env NODE_PATH=./ nodemon ./app.ts"
},
我用
cross-env
。您可以使用 set
命令和 nodemon
自动重新加载更改文件。
将
NODE_PATH
设置为 ./
告诉 NodeJS 执行 Visual Studio 和 TypeScript 正在执行的操作。
我的
package.json
目录中有 src
。您可能不会,并且可能需要更改一些路径来进行调整。
我不确定“本地文件无需执行
"../../../foo/bar"
”是什么意思
让我解释一下 Javascript 如何处理导入。这是基本的文件夹结构。
C:Users/NAME/Project/randomfolder/bar.js
- Project
- Random Folder
- foo.js
- bar.js
选项 1 对于您将要做的 95% 的事情来说可能是更好的选择
假设您正在尝试将 foo.js 导入到 bar.js 中,我们首先使用
.
获取 bar.js 的当前位置,所以它会是
import foo from "./Random Folder/foo.js"
如果您采用另一种方式,
.
仍然用于表示获取文件夹结构中的当前位置,但您传递第二个.
,因此..
,然后使用/
进入文件夹。因此,要将 bar.js 导入到 foo.js 中,它看起来像这样:
import bar from "../bar.js"
我们正在进入一个文件夹,然后寻找我们想要的文件。
选项2
但是,如果您知道文件夹结构将非常大,并且总是会向上或向下导入一些文件夹,为什么不创建一个变量,然后使用字符串文字。
let folder = `../../../`
import test from `${folder}foo`
您有几种选择来处理您想做的事情。
选项 3 对于 NodeJS 和模块
如果您使用 NodeJS 并且想要获取非相对路径,请使用 app-root-path 模块。它可以让您始终获得项目根目录,然后相应地深入到文件中。这可以通过字符串文字来完成。
var appRoot = require('app-root-path');
import foo from appRoot + "/foo/bar/folders/bla/bla"
or
import foo from `${appRoot}/foo/bar/folders/bla/bla` <-- string literals