过去,每当我想在Node.js应用程序中拥有相对路径时,我都会使用app-module-path
。如果我通过.mjs
格式使用ES模块,那么在某个目录路径变为相对路径的情况下,我如何具有相同的功能?
在另一种方式中,我是否可以为目录分配一个别名,以便所有相对路径都相对于该别名,就像./
是相对于当前目录的路径的别名一样。
使用;进口;财产
截至2023年3月,消除NodeJS相对路径的一个好方法是在package.json
中使用imports
属性。欲了解更多信息,请参阅这篇文章:
- 如何使用项目根目录中的文件路径在NodeJS中导入JavaScript文件
在下面的代码中,#root是项目根。
(如果这个答案和这个帖子对你有帮助,请投赞成票。谢谢!(
对于CommonJS风格的JavaScripts:
// package.json
{
"imports": {
"#root/*.js": "./*.js"
}
}
// main.js:
const Source = require('#root/path/to/Source.js');
// Source.js:
module.exports = class Source {
// ...
}
对于ECMAScript样式的JavaScripts:
// 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文件链接
通过monkey修补内置的module
模块,可以为加载了require
的CommonJS模块的某些路径提供别名。
ES模块提供了一种通过指定自定义ES模块加载器来改变模块加载行为的方法,如本相关答案中所述。
通过这种方式,根源路径(将相对于加载器位置指定(可以映射到某个别名(@
是前端项目的常规路径(:
自定义加载器.mjs
import path from 'path';
const ROOT_PATH = new URL(path.dirname(import.meta.url) + '/src').pathname;
export function resolve(specifier, parentModuleURL, defaultResolver) {
specifier = specifier.replace(/^@/, ROOT_PATH);
return defaultResolver(specifier, parentModuleURL);
}
其用法类似:
node --experimental-modules --loader ./custom-loader.mjs ./app.mjs
请注意,这为ES模块提供了一种不自然的行为,这可能会影响IDE等其他工具如何处理此代码。
2019年版本,适用于ES模块。
到目前为止,我发现的最简单的方法是使用实验特性--loader
。
我使用类似的东西来要求import { SOME_CONSTANT } from '@config'
或import { createConnection } from '@server/connection'
。
加载程序代码:
import path from 'path'
import fs from 'fs'
export function resolve (specifier, parentModuleURL, defaultResolver) {
specifier = specifier.replace(/^@/, path.resolve('.') + '/src/')
specifier = fs.existsSync(specifier) && fs.lstatSync(specifier).isDirectory() ? `${specifier}/index` : specifier
specifier += '.js'
return defaultResolver(specifier, parentModuleURL)
}
然后node --experimental-modules --loader ./moduleResolver.js ./myScriptWithoutExtension
注意:如果在最近的package.json
中指定了"type": "module"
,则不需要使用.mjs
扩展名。你可以无限期地呆着
NOTE2:您可以将src
字符串替换为通常放置代码的位置,甚至可以使用基于process.env.NODE_ENV
的解析
注意3:如果给@
一个目录,它将期望找到一个index.js
文件
注意4:您可以使用任何您想要的别名,只需替换regex