From 703c545a7d208908eac939e55eb2501daeb76a0d Mon Sep 17 00:00:00 2001 From: Jan Martin Date: Mon, 30 Sep 2024 16:04:25 -0700 Subject: [PATCH] esm: add import.meta.env --- doc/api/cli.md | 11 ++++++++++ doc/api/esm.md | 14 ++++++++++++ doc/node.1 | 3 +++ .../modules/esm/initialize_import_meta.js | 5 +++++ src/node_options.cc | 4 ++++ src/node_options.h | 1 + test/es-module/test-esm-import-meta-env.mjs | 22 +++++++++++++++++++ 7 files changed, 60 insertions(+) create mode 100644 test/es-module/test-esm-import-meta-env.mjs diff --git a/doc/api/cli.md b/doc/api/cli.md index 588c9cc8640ab7..e0acadf64a87f4 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -992,6 +992,17 @@ added: v22.3.0 Enable exposition of [EventSource Web API][] on the global scope. +### `--experimental-import-meta-env` + + + +> Stability: 1 - Experimental + +Enable experimental `import.meta.env` support. + ### `--experimental-import-meta-resolve` + +> Stability: 1 - Experimental + +This feature is only available with the `--experimental-import-meta-env` +command flag enabled. + +Provides access to environment variables, just like `process.env`. + ## Interoperability with CommonJS ### `import` statements diff --git a/doc/node.1 b/doc/node.1 index 3d92fcd7858b98..24a38004251ee5 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -168,6 +168,9 @@ Interpret as either ES modules or CommonJS modules input via --eval or STDIN, wh .js or extensionless files with no sibling or parent package.json; .js or extensionless files whose nearest parent package.json lacks a "type" field, unless under node_modules. . +.It Fl -experimental-import-meta-env +Enable experimental ES modules support for import.meta.env. +. .It Fl -experimental-import-meta-resolve Enable experimental ES modules support for import.meta.resolve(). . diff --git a/lib/internal/modules/esm/initialize_import_meta.js b/lib/internal/modules/esm/initialize_import_meta.js index 43064f14b057a4..b493c1a8df96a5 100644 --- a/lib/internal/modules/esm/initialize_import_meta.js +++ b/lib/internal/modules/esm/initialize_import_meta.js @@ -7,6 +7,7 @@ const { const { getOptionValue } = require('internal/options'); const { fileURLToPath } = require('internal/url'); const { dirname } = require('path'); +const experimentalImportMetaEnv = getOptionValue('--experimental-import-meta-env'); const experimentalImportMetaResolve = getOptionValue('--experimental-import-meta-resolve'); /** @@ -65,6 +66,10 @@ function initializeImportMeta(meta, context, loader) { meta.filename = filePath; } + if (experimentalImportMetaEnv && (!loader || loader.loaderType !== 'internal')) { + meta.env = process.env; + } + if (!loader || loader.allowImportMetaResolve) { meta.resolve = createImportMetaResolve(url, loader, experimentalImportMetaResolve); } diff --git a/src/node_options.cc b/src/node_options.cc index 3bfab2759b18f4..a18c582677493a 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -453,6 +453,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { "experimental ES Module support for webassembly modules", &EnvironmentOptions::experimental_wasm_modules, kAllowedInEnvvar); + AddOption("--experimental-import-meta-env", + "experimental ES Module import.meta.env support", + &EnvironmentOptions::experimental_import_meta_env, + kAllowedInEnvvar); AddOption("--experimental-import-meta-resolve", "experimental ES Module import.meta.resolve() parentURL support", &EnvironmentOptions::experimental_import_meta_resolve, diff --git a/src/node_options.h b/src/node_options.h index ed89f08f3b4140..4031ff1b2f95cd 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -129,6 +129,7 @@ class EnvironmentOptions : public Options { bool experimental_global_navigator = true; bool experimental_global_web_crypto = true; bool experimental_wasm_modules = false; + bool experimental_import_meta_env = false; bool experimental_import_meta_resolve = false; std::string input_type; // Value of --input-type std::string type; // Value of --experimental-default-type diff --git a/test/es-module/test-esm-import-meta-env.mjs b/test/es-module/test-esm-import-meta-env.mjs new file mode 100644 index 00000000000000..a3f0ce7401768f --- /dev/null +++ b/test/es-module/test-esm-import-meta-env.mjs @@ -0,0 +1,22 @@ +// Flags: --experimental-import-meta-env +import '../common/index.mjs'; +import assert from 'assert/strict'; +import { env } from 'process'; + +// Currently, the object is literally the same. +assert.equal(import.meta.env, env); +assert.equal(import.meta.env, process.env); + +// It reflects changes to environment variables. +assert.equal(import.meta.env['TEST_VAR_1'], undefined); +process.env['TEST_VAR_1'] = 'x'; +assert.equal(import.meta.env['TEST_VAR_1'], 'x'); + +// It allows modifying environment variables. +assert.equal(process.env['TEST_VAR_2'], undefined); +import.meta.env['TEST_VAR_1'] = 'x'; +assert.equal(process.env['TEST_VAR_2'], 'x'); + +// It's possible to overwrite `import.meta.env`. +import.meta.env = 42; +assert.equal(import.meta.env, 42);