通常在 Node 中可以使用NODE_PATH=./src"
来代替:
import { foo } from '../../../bar'
你可以这样做:
import { foo } from 'src/bar'
但是,只有在使用 esm
包(即 node -r esm
)时才有效:NODE_PATH
doesn' t 使用原生 ES 模块(即添加 "type": "module"
到 package.json
)...那么现代的替代品是什么?
我已经尝试了以下所有方法,但似乎都不起作用(尽管我可能没有正确使用它们,并且欢迎任何澄清):
- 本地文件(即 `"dependency": { "src": "file:./src",) - 无法使其正常工作
- 符号链接(symbolic link)(即从
node_modules/src
添加符号链接(symbolic link)到project-root/src
) - 将文件导入为 CommonJS包,而不是 ES 包,这意味着命名导入不起作用 - 工作区(即
package.json
中的"workspaces": ["src"],
) - 同样的问题:没有命名导入 - 导入(即
"imports": {"#src": "./src"}
) - 忽略--experimental-specifier- resolution=node
标志(因此,只有当我想检查并手动将.js
添加到项目中的每个导入中时,它才有效) - 自定义加载程序(即制作
loader.js
文件并使用node --loader loader.js
) - 我不能弄清楚如何进行这项工作,因为几乎没有关于自定义加载程序的文档
理想情况下,我不想实现所有 Babel/Webpack/Typescript/etc。在我的项目中,只是替换 NODE_PATH=./src
,但似乎添加一些此类工具是现在唯一的方法?
最佳答案
这看起来是唯一可行的选择...如果您想要相对根导入并且不想指定 .js
扩展名...就是使用自定义加载程序。
作为引用,我为实现这一目标所做的是:
import path from 'path';
import fs from 'fs';
export function resolve(originalSpecifier, context, defaultResolver) {
let specifier = originalSpecifier;
try {
// All my root-relative imports start with "src/"; if you
// have other folders you'll need to account for them here
if (specifier.startsWith('src')) {
specifier = specifier.replace(/^src/, path.resolve('.') + '/src');
// If the import is for a directory, get its index.js file
const itExists = fs.existsSync(specifier);
let isDirectory = false;
try {
isDirectory = fs.lstatSync(specifier).isDirectory();
} catch (err) {}
specifier = itExists && isDirectory ? `${specifier}/index` : specifier;
// Add the ".js" extension if not specified
specifier += specifier.endsWith('.js') ? '' : '.js';
return {
format: 'module',
url: new URL(specifier, context.parentURL).href,
};
}
} catch (err) {
console.error(err);
}
// If we're not handling our special cases, just use the
// default handler
return defaultResolver(specifier, context);
}
然后您可以通过 --loader
选项使用该加载程序,例如。
node --loader loader.js index.js
但是,值得注意的是,加载程序仍在开发中,并且将来可能会发生变化(使上述加载程序无效)。考虑到 Node 组织的开发速度有多慢,可能是 2030 年的某个时候;)
关于javascript - ES 模块命名导入是否可以实现 native Node 绝对(即根相对)路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73140041/