import.meta是ES模块(ESM)中由引擎注入的只读元数据对象,仅在.mjs文件或<script type="module">中可用;非模块脚本访问会报ReferenceError,因它非全局变量且依赖模块上下文。
import.meta 是 ES 模块(ESM)环境下的只读对象,由 JavaScript 引擎自动注入,仅在 .mjs 文件或 <script type="module"> 中可用。它不是全局变量,也不属于 window 或 globalThis —— 在非模块脚本(如 <script>)中访问 import.meta 会直接报 ReferenceError: import.meta is not defined。
常见误操作:把 type="module" 忘了写,或者用 node --loader 运行但没加 --experimental-modules(旧 Node 版本),都会导致该对象不可用。
<script type="module" src="app.js"></script> 才能启用.mjs,或 package.json 中声明 "type": "module"
target: 'es5' 可能移除该特性import.meta.url 返回一个 file://(Node)或 https://(浏览器)开头的完整 URL 字符串,是定位模块资源最可靠的方式。相比 document.currentScript.src 或 __dirname,它不依赖执行上下文,且在动态导入、Worker、嵌套模块中依然准确。
典型场景:加载同目录下的 JSON 配置、图片或 Web Worker:
立即学习“前端免费学习笔记(深入)”;
const configUrl = new URL('./config.json', import.meta.url);fetch(configUrl).then(r => r.json());
注意:import.meta.url 是只读字符串,不能直接当 path.dirname() 用;需配合 URL 构造函数解析路径,否则在浏览器中用 file:// 协议时容易出错。
new URL('./data/', import.meta.url) 能正确解析相对路径import.meta.url 是 file:///abs/path/to/file.mjs,可转为 file:// → file: 前缀需保留import.meta.url 做字符串截取(如 .replace('file://', '')),协议和编码规则因环境而异import.meta.env 不是原生 JS 特性,而是 Vite、Webpack、Rollup 等构建工具注入的伪对象。它在源码中存在,但实际值由构建时替换(define)或运行时注入,**不会出现在未构建的纯 ESM HTML 页面中**。
例如 Vite 中写 import.meta.env.PROD,构建后变成 true 或 false 字面量;而 import.meta.env.BASE_URL 会被替换成部署路径前缀。
import.meta.env 是一个空对象,除非你显式配置了 define
Cannot read property 'ENV' of undefined
import.meta.env 注入到前端,避免泄露IE 完全不支持 import.meta,Chrome 64+/Firefox 60+/Safari 12.1+ 开始支持。即使现代浏览器,也需确保模块加载链完整:比如从 <script type="module"> 加载的模块里能用,但从 eval() 或 new Function() 动态生成的代码里不能用 —— 因为没有模块上下文。
import.meta.url 和浏览器不一致,路径逻辑需区分环境import.meta.resolve()(实验性)需开启 --experimental-import-meta-resolve(Node 20.6+),且尚未被所有浏览器支持import.meta,但若配置了 experiments.topLevelAwait: false,可能影响相关行为真正容易被忽略的是:它只反映「声明位置」,而非「调用位置」—— 一个工具函数无论被多少层模块引用,import.meta.url 始终指向它自己所在的文件,不是调用者的文件。