Node.js ECMAScript 加载器钩子解析

🌙
手机阅读
本文目录结构

Node.js ECMAScript

加载器钩子

要自定义默认模块分辨率,可以选择通过Node.js的 --loader ./loader-name.mjs参数提供加载程序挂钩。

使用挂钩时,它们仅适用于ES模块加载,而不适用于加载的任何CommonJS模块。

解析钩子

resolve钩子返回给定模块说明符和父文件URL的已解析文件URL和模块格式

const baseURL = new URL('file://');
baseURL.pathname = `${process.cwd()}/`;

export async function resolve(specifier, parentModuleURL = baseURL,  defaultResolver) {
  return {
    url: new URL(specifier, parentModuleURL).href,
    format: 'esm'
  };
}

在执行主Node.js加载时,parentModuleURL以未定义的形式提供。

默认的Node.js ES模块解析功能作为解析器的第三个参数提供,以便于兼容性工作流程。

除了返回已解析的文件URL值之外,resolve hook还返回format属性,该属性指定已解析模块的模块格式。这可以是以下之一:

格式 描述
‘esm’ 加载标准JavaScript模块
‘cjs’ 加载节点式CommonJS模块
‘builtin’ 加载内置CommonJS模块的节点
‘json’ 加载JSON文件
‘addon’ 加载C ++插件
‘dynamic’ 使用动态实例化挂钩

例如,可以编写一个虚拟加载器,用于加载限制为浏览器解析规则的JavaScript,只有JS文件扩展名和Node.js内置模块支持

import path from 'path';
import process from 'process';
import Module from 'module';

const builtins = Module.builtinModules;
const JS_EXTENSIONS = new Set(['.js', '.mjs']);

const baseURL = new URL('file://');
baseURL.pathname = `${process.cwd()}/`;

export function resolve(specifier, parentModuleURL = baseURL, defaultResolve) {
  if (builtins.includes(specifier)) {
    return {
      url: specifier,
      format: 'builtin'
    };
  }
  if (/^\.{0,2}[/]/.test(specifier) !== true && !specifier.startsWith('file:')) {
    // For node_modules support:
    // return defaultResolve(specifier, parentModuleURL);
    throw new Error(
      `imports must begin with '/', './', or '../'; '${specifier}' does not`);
  }
  const resolved = new URL(specifier, parentModuleURL);
  const ext = path.extname(resolved.pathname);
  if (!JS_EXTENSIONS.has(ext)) {
    throw new Error(
      `Cannot load file with non-JavaScript file extension ${ext}.`);
  }
  return {
    url: resolved.href,
    format: 'esm'
  };
}

有了这个装载机,就可以运行

NODE_OPTIONS='--experimental-modules --loader ./custom-loader.mjs' node x.js

将模块x.js加载为具有相对分辨率支持的ES模块(在此示例中跳过了node_modules加载)


更多选项请参考:ECMAScript 模块,或者通过 点击对应菜单 进行查看;



AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

目前重心已经放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>