typescript 在NodeJS中导入带有绝对路径的ES6模块,而不使用Babel/Webpack

vzgqcmou  于 2023-03-24  发布在  TypeScript
关注(0)|答案(4)|浏览(146)

我有一个普通的旧NodeJS项目(使用Typescript),我真的很难找到如何为本地文件进行ES6导入,而不必一直执行“../../../foo/bar”。
有很多类似的问题,但似乎都围绕着我没有使用的babel/Webpack。
如果我执行以下操作:

import foo from `/bar`

它在我的PC的根文件夹(eidogg. c:/bar)中查找它,但失败了。
我试过使用一个.env文件,并将NODE_PATH设置为不同的hings(“/",“.”等),但没有成功。我也试过设置“type:我的package.json和tsconfig.json文件中有{“baseUrl”:“."}
所以我想我已经试过了我能找到的每一个答案。我只是把它们组合错了,还是解决方案有什么不同?

zyfwsgd6

zyfwsgd61#

这里有两个我使用的技巧,使用Node.js和原生ES模块。

  1. file:依赖项
    如果你想从两个级别的子包访问<project root>/bar,将其添加到package.json依赖项中:
"@local/bar": "file:../../bar",

..使得bar作为@local/bar可用于所述子包。
虽然相对路径仍然存在,但它们现在都在package.json文件中,并且源永远不需要知道。
1.使用动态import()
选择一个常量的根文件夹路径,然后执行以下操作:

const foo = await import(`${rootPath}/bar`);
v8wbuo2f

v8wbuo2f2#

使用Imports属性

截至2023年3月,消除NodeJS相对路径的一个好方法是在package.json中使用imports属性。有关更多信息,请参阅此帖子:

在下面的代码中,#root是项目根。
(请投票支持这个答案,如果他们帮助你,请this post。谢谢!)

对于CommonJS风格的JavaScript:

// package.json
{
  "imports": {
    "#root/*.js": "./*.js"
  }
}

// main.js:
const Source = require('#root/path/to/Source.js');

// Source.js:
module.exports = class Source {
  // ...
}

ECMAScript风格的JavaScript:

// 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.2VS Code 1.76.2上进行了测试。)
  • 同时支持.mjs(ECMAScript模块系统)和.cjs(CommonJS)文件类型。请参阅reference Post on .cjs and .mjs.
  • 不需要使用保留的node_modules目录进行修改
  • 无需在操作系统级别设置任何linux文件链接
643ylb08

643ylb083#

这对我来说很容易实现,在VSCode中使用Typescript。
tsconfig.json中,我在compilerOptions下添加了"baseUrl": "./",
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正在做的事情。
我的src目录中确实有package.json。你可能没有,可能需要改变一些路径来调整。

uemypmqf

uemypmqf4#

我不知道你说的“本地文件而不必做"../../../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

相关问题