使用带有ES模块的Node.js中的相对路径导入

时间:2018-07-21 04:14:22

标签: node.js es-module mjs

过去,我想在Node.js应用程序中使用相对路径时使用app-module-path。如果我通过.mjs格式使用ES模块,那么当某个目录路径成为相对目录时,我如何具有相同的功能?

以另一种方式,我将能够为目录分配别名,以便所有相对路径都相对于该别名,就像./是相对于当前目录的路径的别名一样。

2 个答案:

答案 0 :(得分:2)

可以通过内置的require猴子修补程序为module加载的CommonJS模块的某些路径赋予别名。

ES模块提供了一种通过指定custom ES module loader来更改模块加载行为的方式,如this related answer中所述。

这样,根源路径(将相对于加载器位置指定)可以映射到某些别名(对于前端项目,为@ is conventional):

custom-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)如何处理此代码。

答案 1 :(得分:0)

适用于ES模块的更多2019版本。

到目前为止,我发现的最简单的方法是使用实​​验性功能--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

注意:如果在最接近的.mjs中指定"type": "module",则无需使用package.json扩展名。你可以保持无休止的。
注意2:您可以将src字符串替换为通常放置代码的位置,甚至可以使用基于process.env.NODE_ENV的分辨率。
注意3:如果给@提供目录,它将期望找到一个index.js文件。
注意4:您可以使用想要的别名,只需替换正则表达式