import.meta
– module metadataThe proposal “import.meta
” by Domenic Denicola is currently at stage 3. This blog post explains how it works.
When it comes to working with a module, you are normally interested in what’s inside it. But occasionally, you need information about the module – its metadata. One example of module metadata for Node.js modules is the global variable __dirname
which contains the path of the directory in which the current module is stored.
The proposal introduces the pseudo-property import.meta
which holds an object with metadata for the current module. Let’s look at uses cases for module metadata.
In Node.js, you can store data supporting a CommonJS module next to that module and get to it as follows:
const fs = require('fs');
const path = require('path');
const TEMPLATE_PATH = path.resolve(__dirname, 'template.txt'); // (A)
const TEMPLATE_TEXT = fs.readFileSync(
TEMPLATE_PATH, { encoding: 'utf8' });
The key piece is the module metadata __dirname
in line A.
This is how you can achieve something similar in a cross-platform way (on Node.js, you need a polyfill for the fetch()
API).
async function main() {
const TEMPLATE_URL = new URL('../template.txt', import.meta.url); // (A)
const response = await fetch(TEMPLATE_URL);
const TEMPLATE_TEXT = await response.text();
···
}
main();
Note the metaproperty import.meta.url
(line A), which contains the URL of the current module.
On Node.js, a CommonJS module can play two roles:
You can handle the two roles as follows.
// Library stuff goes here
if (require.main === module) {
// Executable stuff goes here
// (uses library stuff)
}
At the moment, no concrete metaproperty has been proposed, but import.meta.entryUrl
would work:
// Library stuff goes here
if (import.meta.entryUrl === import.meta.url) {
// Executable stuff goes here
// (uses library stuff)
}
Browsers will have the metaproperty import.meta.scriptElement
that gives modules access to the script element that loaded them.
// my-module.mjs
console.log(import.meta.scriptElement.dataset.foo); // "abc"
HTML:
<script type="module" src="my-module.mjs" data-foo="abc"></script>
Non-module scripts get this information via document.currentScript
.
import.meta
As of now:
import.meta
will be extensible (you are able to add properties).The rationale for keeping everything mutable is to enable polyfilling of upcoming features. Note that, by default, module metadata can only be accessed by the module. That is, unless the module passes the metadata object elsewhere, it is local.
import.meta
? import()
– dynamically importing ES modules”