如何确定 javascript 模块是否通过脚本 src 导入或加载?

And*_*III 5 javascript browser es6-modules

假设我有一个名为module.js

export default function greet() { console.info( 'hello' ); }
Run Code Online (Sandbox Code Playgroud)

module.js(在 function 内部或外部greet)内,如何确定模块是否已使用以下方式加载:

<script type=module src="./module.js">
Run Code Online (Sandbox Code Playgroud)

相对:

<script type=module>
import greet from './module.js';
</script>
Run Code Online (Sandbox Code Playgroud)

不管怎样,import.meta是相同的,document.currentScriptnull, 和 NodeJS 的require(因此require.main) 和module都是undefined

谢谢!

FZs*_*FZs 4

当您导入任何模块(使用import<script type="module">)时,即使您从多个位置导入该模块,该模块的主体也只会被评估一次。

所以,如下:

//module.js
console.log('I was imported')
Run Code Online (Sandbox Code Playgroud)
<script type="module">
  import './module.js'
</script>
<script type="module" src="./module.js"></script>
Run Code Online (Sandbox Code Playgroud)

...只会记录I was imported一次。

由此,我们可以清楚地看到,一个模块可能会同时被多种方式导入,因此不可能有任何方法来确定模块是如何导入的......

...只要您不使用导出。

使用 script 标签包含模块与import 'modulepath'语法相同,即,用 MDN 的话说导入模块只是为了其副作用

这意味着,不进行任何导出,仅对模块进行评估。

但是,如果使用了其中一个导出(例如,调用),则可以排除使用导出的模块实例是由脚本标记导入的可能性。

不过,以下情况仍然是可能的:

//module.js
export default function greet() { 
  console.info('hello'); //<-- This must have been called from an `import` import
}
Run Code Online (Sandbox Code Playgroud)
<script type="module">
  import greet from './module.js';
  greet()  //imported by `import`
</script>
<script type="module" src="./module.js"></script> <!-- imported by script tag -->
Run Code Online (Sandbox Code Playgroud)