简体   繁体   English

ES 模块命名导入是否可以使用本机节点绝对(即根相对)路径?

[英]Are Native Node Absolute (ie. Root-Relative) Paths Possible With ES Module Named Imports?

Normally in Node one can use NODE_PATH=./src" to make it so that instead of:通常在节点一中可以使用NODE_PATH=./src"来代替:

import { foo } from '../../../bar'

You can just do:你可以这样做:

import { foo } from 'src/bar'

However, that only works if you use the esm package (ie. node -r esm ): NODE_PATH doesn't work with native ES Modules (ie. adding "type": "module" to package.json )... so what is the modern replacement? However, that only works if you use the esm package (ie. node -r esm esm ): NODE_PATH doesn't work with native ES Modules (ie. adding "type": "module" to package.json )... so what是现代替代品吗?

I've tried all of the following, and none of them seem to work (though I may not be using them correctly, and would welcome any clarification):我已经尝试了以下所有方法,但它们似乎都不起作用(尽管我可能没有正确使用它们,并且欢迎任何澄清):

  • local files (ie. `"dependencies": { "src": "file:./src",) - couldn't get this to even work本地文件(即 `"dependencies": { "src": "file:./src",) - 甚至无法正常工作
  • symlinks (ie. adding a symlink from node_modules/src to project-root/src ) - that imports the file as a CommonJS package, not an ES one, which means that named imports don't work符号链接(即从node_modules/src添加符号链接到project-root/src ) - 将文件导入为 CommonJS package,而不是 ES,这意味着命名导入不起作用
  • workspaces (ie. "workspaces": ["src"], in package.json ) - same issue: no named imports工作区(即"workspaces": ["src"],package.json中) - 同样的问题:没有命名导入
  • imports (ie. "imports": {"#src": "./src"} ) - ignores the --experimental-specifier-resolution=node flag (so it only works IF I want to go through and manually add .js to every import in my project)导入(即"imports": {"#src": "./src"} ) - 忽略--experimental-specifier-resolution=node标志(所以它只有在我想通过 go 并手动添加.js时才有效到我项目中的每个导入)
  • custom loaders (ie. making a loader.js file and using node --loader loader.js ) - I couldn't figure out how to make this work, as there is almost no documentation on custom loaders自定义加载器(即制作loader.js文件并使用node --loader loader.js ) - 我无法弄清楚如何使这项工作,因为几乎没有关于自定义加载器的文档

Ideally, I'd prefer not to have to implement all of Babel/Webpack/Typescript/etc.理想情况下,我宁愿不必实现所有 Babel/Webpack/Typescript/etc。 on my project, just to replace NODE_PATH=./src , but it seems like adding some such tool is the only way now?在我的项目中,只是为了替换NODE_PATH=./src ,但现在似乎添加一些这样的工具是唯一的方法?

It looks like the only viable option... if you want root-relative imports AND you don't want to specify the .js extension... is to use a custom loader.看起来唯一可行的选择...如果您想要相对于根的导入并且不想指定.js扩展名...是使用自定义加载程序。

For reference, the one I made to achieve this was:作为参考,我为实现这一目标所做的一个是:

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);
}

Then you can use that loader with the --loader option, eg.然后您可以将该加载程序与--loader选项一起使用,例如。

node --loader loader.js index.js

However, it's worth noting that the loader stuff is still under development, and could change (making the above loader invalid) in the future.但是,值得注意的是,加载器的东西仍在开发中,将来可能会发生变化(使上述加载器无效)。 Probably sometime in 2030, given how slow the Node org is with their development;)考虑到 Node 组织的发展速度有多慢,可能在 2030 年的某个时候;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM