如何使用import.meta访问ES模块元数据
import.meta 是一个在ES模块内部可用的对象,它包含关于模块运行环境的有用信息。
import.meta 对象是可扩展的,宿主可以把任何有用的信息写进它。
让我们来看看使用import.meta ,你可以获得哪些关于模块的有用信息。
1.模块的URL(浏览器)
浏览器和Node.js都给import.meta ,一个有用的属性是url 。
在浏览器中,import.meta.url 包含当前ES模块的绝对URL。
例如,让我们定义一个名为main.mjs 的模块,记录import.meta.url 的值。
javascript
// main.mjs
console.log(import.meta.url);
如果你在一个位于http://mysite.com 的网页中使用脚本标签(添加type="module" 属性)加载main.mjs 模块。
html
<script src="main.mjs" type="module"></script>
那么import.meta.url 将包含该脚本的绝对URL,例如:'http://mysite.com/main.mjs' 。
2.模块的路径 (Node.js)
但是如果你把main.mjs 作为一个Node.js脚本运行。
bash
node main.mjs
那么import.meta.url 将包含模块的绝对路径,例如:'file:///absolute-path/main.mjs' 。
import.meta.url 里面的绝对路径总是以file:// 为前缀。
挑战:在你的电脑上创建文件main.mjs ,然后运行node main.mjs 。你的控制台会记录下什么?
3.相对路径解析器(Node.js)
Node.js还在import.meta 下提供了一个异步函数。
javascript
const absolutePath = await import.meta.resolve(specifier[, parent]);
它可以将一个相对的specifier 与一个parent 的绝对路径进行解析。
parent 参数是可选的,默认为当前模块的绝对路径(即 )。import.meta.url
该函数仍然是实验性的,并且可以使用--experimental-import-meta-resolve 标志。
假设你有一个模块main.mjs ,绝对路径是/home/user/web-app/main.mjs 。你也有一个模块helper.mjs ,它与main.mjs 位于同一个文件夹中。你想得到helper.mjs 的绝对路径。
以下是你如何做的:
javascript
// main.mjs
const resolvedPath = await import.meta.resolve('./helper.mjs');
console.log(resolvedPath); // '/home/user/web-app/helper.mjs'
执行await import.meta.resolve('./helper.mjs') 将会把'./helper.mjs' 解析为'/home/user/web-app/helper.mjs' 的绝对路径。
如果解决的模块不存在,那么该函数将抛出一个未找到模块的错误。
4.4. 结论
import.meta 是一个在ES模块范围内可用的对象。这个对象包含关于模块的有用的元数据信息。
一个有用的模块元属性是import.meta.url - 它表示浏览器中模块的绝对URL或Node.js中的绝对路径(前缀为file:// )。
挑战:如果不使用import.meta.url ,你如何确定脚本标签的URL?