使用 ES 模块在 Node.js 中使用相对路径导入
Importing using relative paths in Node.js with ES Modules
过去,每当我想在 Node.js 应用程序中使用相对路径时,我都会使用 app-module-path
。如果我通过 .mjs
格式使用 ES 模块,我如何在某个目录路径变为相对路径时拥有相同的功能?
以另一种方式,我是否可以为目录分配别名,以便所有相对路径都相对于该别名,就像 ./
是相对于当前路径的别名一样目录。
可以通过 monkey-patching 内置 module
模块为使用 require
加载的 CommonJS 模块的某些路径指定别名。
ES 模块提供了一种通过指定 custom ES module loader, as explained in .
来更改模块加载行为的方法
这样根源路径(将相对于加载器位置指定)可以映射到一些别名( 对于前端项目):
自定义-loader.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
扩展名。你可以保持无扩展。
注意 2:您可以将 src
字符串替换为您通常放置代码的位置,您甚至可以使用基于 process.env.NODE_ENV
的分辨率。
注 3:如果您将目录提供给 @
,它将期望找到一个 index.js
文件。
注意4:您可以使用任何您想要的别名,只需替换正则表达式
过去,每当我想在 Node.js 应用程序中使用相对路径时,我都会使用 app-module-path
。如果我通过 .mjs
格式使用 ES 模块,我如何在某个目录路径变为相对路径时拥有相同的功能?
以另一种方式,我是否可以为目录分配别名,以便所有相对路径都相对于该别名,就像 ./
是相对于当前路径的别名一样目录。
可以通过 monkey-patching 内置 module
模块为使用 require
加载的 CommonJS 模块的某些路径指定别名。
ES 模块提供了一种通过指定 custom ES module loader, as explained in
这样根源路径(将相对于加载器位置指定)可以映射到一些别名(
自定义-loader.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
扩展名。你可以保持无扩展。
注意 2:您可以将 src
字符串替换为您通常放置代码的位置,您甚至可以使用基于 process.env.NODE_ENV
的分辨率。
注 3:如果您将目录提供给 @
,它将期望找到一个 index.js
文件。
注意4:您可以使用任何您想要的别名,只需替换正则表达式