@agoric/transform-module

中文文档
0.4.1发布于 2020/08/21Apache-2.0ESM + CJS零依赖近 30 天下载 7147

作为 Javascript 程序评价 ES 模块的变换

中文使用文档

变形模块

变形模块是一种从JS模块源到相应的转换 JS程序,在评估后产生一个可以执行模块的功能 协调其进出口. 静态模块记录包括对模块的静态分析:它是什么 进口和出口,以及它如何提到进口模块.

执行一个模块的工作流程,由一个模拟系统进行, 是分析模块源,与基于静态的其他模块的链接 记录的元数据,评价放克,用链接调用放克.

import { makeModuleAnalyzer } from './src/main.js';
import * as babel from '@agoric/babel-standalone';
const analyze = makeModuleAnalyzer(babel.default);
const moduleStaticRecord = analyze(moduleSource);
const moduleFunctor = evaluateModuleFunctor(moduleStaticRecord.functorSource, /* ... */);
moduleFunctor({
  imports(importedVariableUpdaters, exportAlls) { /* ... */ },
  liveVar: exportedVariableUpdaters,
  onceVar: exportedConstantEmitters,
});

因此,例如,以下模块非常彻底地使用进出口.

import foo from 'import-default-export-from-me.js';
import * as bar from 'import-all-from-me.js';
import { fizz, buzz } from 'import-named-exports-from-me.js';
import { color as colour } from 'import-named-export-and-rename.js';

export let quuux = null;

export { qux } from 'import-and-reexport-name-from-me.js';
export * from 'import-and-export-all.js';
export default 42;
export const quux = 'Hello, World!';

// Late binding of an exported variable.
quuux = 'Hello, World!';

从此分析器生成一个静态模块记录,显示哪些模块 模块需要与它们的进出口相联系,并如何将其联系起来.

{
  "exportAlls": [ "import-and-export-all.js" ],
  "imports": {
    "import-default-export-from-me.js": [ "default" ],
    "import-all-from-me.js": [ "*" ],
    "import-named-exports-from-me.js": [ "fizz", "buzz" ],
    "import-named-export-and-rename.js": [ "color" ],
    "import-and-reexport-name-from-me.js": [ "qux" ],
    "import-and-export-all.js": []
  },
  "liveExportMap": {
    "qux": [ "qux", false ],
    "quuux": [ "quuux", true ],
  },
  "fixedExportMap": {
    "default": [ "default" ],
    "quux": [ "quux" ],
  }
}

分光器源,模块转换成程序,有以下 形状. 名称被Unicode 0-width-joiners所进一步模糊,以避免 与智能构建的模块相相撞,转换保留 线条编号.

(({
  imports: $h_imports,
  liveVar: $h_live,
  onceVar: $h_once,
}) => {
  let foo, bar, fizz, buzz, colour;
  $h_imports(
    new Map([
      ["import-default-export-from-me.js", new Map([
        ["default", [$h_a => (foo = $h_a)]],
      ])],
      ["import-all-from-me.js", new Map([
        ["*", [$h_a => (bar = $h_a)]]
      ])],
      ["import-named-exports-from-me.js", new Map([
        ["fizz", [$h_a => (fizz = $h_a)]],
        ["buzz", [$h_a => (buzz = $h_a)]],
      ])],
      ["import-named-export-and-rename.js", new Map([
        ["color", [$h_a => (colour = $h_a)]],
      ])],
      ["import-and-reexport-name-from-me.js", new Map([
        ["qux", [$h_live["qux"]]]
      ])],
      ["import-and-export-all.js", new Map([])]
    ]),
    ["import-and-export-all.js"]
  );

  let $c_quuux = null;
  $h_live.quuux($c_quuux);

  const { default: $c_default } = { default: 42 };

  $h_once.default($c_default);

  const quux = 'Hello, World!';
  $h_once.quux(quux);

  quuux = 'Sorry for binding late!';
})

对于最后的活性约束 quuux,我们依赖评估者 将一个 在瞄准镜链上代理拦截任务并进行更新 用于导入该值的所有模块.

// This is the signature of the analyze function, after composing it
// with Babel core.
type Analyzer = ({string: ModuleSource}) => StaticModuleRecord

type ModuleSource = string

type StaticModuleRecord = {
  exportAlls: ExportAlls,
  imports: Imports,
  liveExportMap: LiveExportMap,
  fixedExportMap: FixedExportMap,
  functorSource: string,
};

// ExportAlls are the relative module specifiers found in directives like:
//   export * from 'import-and-reexport-all-from-me.js';
// These are both on the static module record and passed to the import function
// injected into a module functor.
// TODO Consider removing the import argument.
// It does not appear to be used by module instances.
type ExportAlls = Array<RelativeModuleSpecifier>

// Imports includes a key for every relative module specifier in
// any static import declaration, including those implied by
// export/from clauses.
// The import names are the names from the dependency module
// that this module will import.
// If this module reexports names from the dependency module
// but doesn't capture them in its own scope, the imports map
// has an entry for the module but the array of import names is empty.
type Imports = Object<RelativeModuleSpecifier, Array<ImportNames>)

// ImportName is the name of a property of a module namespace object.
type ImportName = string

// LiveExportMap indicates which variables in this module's scope
// need to emit updates when they change.
type LiveExportMap = Object<ExportName, [ExportName, SetProxyTrap]>

// FixedExportMap indicates which constants in this module's scope
// need to emit updates when they are initialized.
// FixedExportMap is an aesthetic subtype of LiveExportMap.
// The single box around ImportName is not meaningful.
type FixedExportMap = Object<ExportName, [ExportName]>

// ExportName is the name of a property of a module namespace object.
type ExportName = string

// SetProxyTrap indicates that the variable has a temporal
// dead-zone and the module namespace should throw a ReferenceError
// before its first update.
type SetProxyTrap = bool

type ModuleFunctor = (UpdaterArgument):void
type UpdaterArgument = {
  imports(Updaters, ExportAlls) => void,
  liveVar(Exporters) => void,
  onceVar(Exporters) => void,
};

// Update functions communicate values both out of one module's scope and into
// another module's scope.
type UpdateFunction = (value:any) => void

// Modules use updaters to receive their imports
// as the exporting modules update them.
type Updaters = Map<RelativeModuleSpecifier, ModuleUpdaters>>
type ModuleUpdaters = Map<ImportName, Array<UpdateFunction>>
type ImportName = string
type RelativeModuleSpecifier = string

// Modules use update functions to ship values out.
type Exporters = Object<ExportName, UpdateFunction>

版本与发布记录

@agoric/transform-module 共发布 28 个版本,首次发布于 2019/07/31;过去 12 个月发布了 0 个版本。

版本发布日期距今
0.4.1latest2020/08/216 年前
0.4.02020/08/216 年前
0.3.02019/11/276 年前
0.2.22019/11/256 年前
0.2.12019/11/256 年前
0.2.02019/11/236 年前

关于 @agoric/transform-module 的常见问题

@agoric/transform-module 是什么?

作为 Javascript 程序评价 ES 模块的变换

如何安装 @agoric/transform-module?

在项目目录运行 npm install @agoric/transform-module,或使用 pnpm add / yarn add / bun add。

@agoric/transform-module 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/agoric__transform-module 是否存在。

@agoric/transform-module 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@agoric/transform-module 可以商用吗?

@agoric/transform-module 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@agoric/transform-module 的下载量有多少?

根据 npm 官方下载统计,@agoric/transform-module 在 2026/10/05 – 2026/11/03 这 30 天内被下载 7,147 次,日均约 238 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@agoric/transform-module 还在维护吗?

最新版本 0.4.1 发布于 2020/08/21(6 年前);至今共发布 28 个版本,其中过去 12 个月发布了 0 个;首次发布于 2019/07/31。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。