簡體   English   中英

ES 模塊命名導入是否可以使用本機節點絕對(即根相對)路徑?

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

通常在節點一中可以使用NODE_PATH=./src"來代替:

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

你可以這樣做:

import { foo } from 'src/bar'

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是現代替代品嗎?

我已經嘗試了以下所有方法,但它們似乎都不起作用(盡管我可能沒有正確使用它們,並且歡迎任何澄清):

  • 本地文件(即 `"dependencies": { "src": "file:./src",) - 甚至無法正常工作
  • 符號鏈接(即從node_modules/src添加符號鏈接到project-root/src ) - 將文件導入為 CommonJS package,而不是 ES,這意味着命名導入不起作用
  • 工作區(即"workspaces": ["src"],package.json中) - 同樣的問題:沒有命名導入
  • 導入(即"imports": {"#src": "./src"} ) - 忽略--experimental-specifier-resolution=node標志(所以它只有在我想通過 go 並手動添加.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 年的某個時候;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM