如何检测 ECMAScript 模块是否是主模块?这对于 CommonJS 模块来说很容易(请参阅检测是否通过 require 调用或直接通过命令行调用)。
没有
require
或require.main
没有
process.mainModule
import.meta
没有任何线索,只有url
es-main
。
来自包自述文件:
import esMain from 'es-main';
if (esMain(import.meta)) {
// Module run directly.
}
注意:该模块只能在 Node.JS 环境中工作,因为模块代码使用原生 Node.JS 模块。
在浏览器中我不知道,但在带有
.mjs
模块的节点中,以下似乎可以工作:
const isMainModule = import.meta.url.endsWith(process.argv[1])
说明:
import.meta.url
以协议开头 file://
例如:
file:///path/to/my/module.mjs
但是在node中,process.argv[1]更短,例如:
/path/to/my/module.mjs
所以
endsWith
在这里很有用。
在网络浏览器中,目前严格来说这不可能通过 JS 实现,但在 HTML 的帮助下,这是可以做到的。
例如,如果您有一个页面
foo.html
导入脚本,
<!-- foo.html -->
<body>
<script type="module" src="./foo.js"></script>
</body>
你可以在模块中这样写:
// foo.js
function main() {
// code specifically for foo.html, for example a demo of some APIs
if (exampleA) doSomething()
if (exampleB) doSomethingElse()
}
// Run the demo code only on the foo.html page.
if (location.pathname.endsWith('foo.html')) main()
// Export some APIs that some other page (or users of a library) might use:
export function doSomething() { ... }
export function doSomethingElse() { ... }
现在,在其他一些文件中,例如
bar.html
可能会实现一些不同的演示,它可以从 doSomething()
导入 foo.js
而无需 foo.js
运行其演示代码:
<!-- bar.html -->
<script type="module" src="./bar.js"></script>
// bar.js
import {doSomething} from './foo.js'
if (location.pathname.endsWith('bar.html')) {
// ... run bar.js demo only on bar.js ...
}
// bar.js may export other APIs for other demos or end users:
export function doAnotherThing() { ... }
这是 CodePen 上的一个实例,用于将内容从一支笔共享到另一支笔:
以下笔有一个演示,并导出一些可重用的功能:
https://codepen.io/trusktr/pen/YzGbeKG
注意它是如何
exports
一些事情的。然后下面的笔从前面的笔导入JS文件来创建一个稍微高级的例子:
https://codepen.io/trusktr/pen/oNzRKJN
另一个例子在这里:
注意它是从
001_create.js
和 002_traverse_edges.js
导入的。
它导入的那些JS文件也有演示,例如:
和
这些演示都可以在这里找到:
https://github.com/trusktr/bmesh/tree/ef32c00f72370013c796833ccecc0e4826d9edf5/prototypes/ops/
如果您粘贴索引文件,
进入 raw.githack.com,你会得到一个可查看的 URL:
在那里可以查看的所有演示都使用相同的概念,仅根据 HTML 文件运行顶级模块代码。
提示:我将在主分支上更新这些演示,
https://github.com/trusktr/bmesh/tree/main/prototypes/ops/
并且带有分支名称而不是提交哈希(dev而不是prod)的raw.githack.com URL可用于查看最新的,f.e.
https://raw.githack.com/trusktr/bmesh/main/prototypes/ops/index.html
但我建议始终与提交哈希值共享 URL,以便 StackOverflow 上的此类答案始终是可重复的(尽管主分支可能会继续发展,但某些演示可能会被删除/移动或工作方式与以前不同)。