Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions contrib/import-meta-env/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.wasm
target/
6 changes: 6 additions & 0 deletions contrib/import-meta-env/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
__tests__/
tests/
src/
Cargo.toml
Cargo.lock
*.rs
7 changes: 7 additions & 0 deletions contrib/import-meta-env/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# @swc-contrib/plugin-import-meta-env

## 1.15.41

### Minor Changes

- Add `@swc-contrib/plugin-import-meta-env`, based on `swc-plugin-import-meta-env`.
24 changes: 24 additions & 0 deletions contrib/import-meta-env/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
authors = ["Alex Miller <codex.nz@gmail.com>"]
description = "SWC plugin for handling the transformation of import.meta.env"
edition = "2021"
license = "Apache-2.0"
name = "swc_plugin_import_meta_env"
publish = false
readme = "README.md"
rust-version = "1.70"
version = "1.15.41"

[lib]
crate-type = ["cdylib"]

[dependencies]
swc_core = { workspace = true, features = [
"common",
"ecma_ast",
"ecma_parser",
"ecma_plugin_transform",
"ecma_visit",
"testing",
"testing_transform",
] }
35 changes: 35 additions & 0 deletions contrib/import-meta-env/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# `@swc-contrib/plugin-import-meta-env`

Simple SWC plugin to transform `import.meta.env` to `process.env`.

This package is based on [`swc-plugin-import-meta-env`](https://github.com/Codex-/swc-plugin-import-meta-env) and is maintained under the SWC contrib plugin workspace.

## Installation

```bash
npm i -D @swc-contrib/plugin-import-meta-env
```

## Usage

Add the plugin to the `jsc.experimental.plugins` field of your `.swcrc`.

```json
{
"jsc": {
"experimental": {
"plugins": [["@swc-contrib/plugin-import-meta-env", {}]]
}
}
}
```

The plugin only rewrites the `import.meta.env` expression shape. It does not load or expand environment files, so populate `process.env` through your test setup, runtime, or another tool such as `dotenv`.

# @swc-contrib/plugin-import-meta-env

## 1.15.41

### Minor Changes

- Add `@swc-contrib/plugin-import-meta-env`, based on `swc-plugin-import-meta-env`.
38 changes: 38 additions & 0 deletions contrib/import-meta-env/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@swc-contrib/plugin-import-meta-env",
"version": "1.15.41",
"publishConfig": {
"access": "public",
"provenance": true
},
"description": "SWC plugin for handling the transformation of import.meta.env",
"author": "Alex Miller <codex.nz@gmail.com>",
"license": "Apache-2.0",
"keywords": [
"swc-plugin",
"import.meta.env"
],
"main": "swc_plugin_import_meta_env.wasm",
"scripts": {
"prepack": "pnpm run build",
"build": "RUSTFLAGS='--cfg swc_ast_unknown' cargo build --release -p swc_plugin_import_meta_env --target wasm32-wasip1 && cp ../../target/wasm32-wasip1/release/swc_plugin_import_meta_env.wasm .",
"build:debug": "RUSTFLAGS='--cfg swc_ast_unknown' cargo build -p swc_plugin_import_meta_env --target wasm32-wasip1 && cp ../../target/wasm32-wasip1/debug/swc_plugin_import_meta_env.wasm .",
"test": "cargo test -p swc_plugin_import_meta_env --color always"
},
"homepage": "https://github.com/swc-project/plugins/tree/main/contrib/import-meta-env",
"repository": {
"type": "git",
"url": "git+https://github.com/swc-project/plugins.git",
"directory": "contrib/import-meta-env"
},
"bugs": {
"url": "https://github.com/swc-project/plugins/issues"
},
"files": [
"swc_plugin_import_meta_env.wasm"
],
"preferUnplugged": true,
"peerDependencies": {
"@swc/core": ">=1.15.4"
}
}
95 changes: 95 additions & 0 deletions contrib/import-meta-env/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#![allow(clippy::not_unsafe_ptr_arg_deref)]

use swc_core::{
common::DUMMY_SP,
ecma::{
ast::{Expr, Ident, MemberExpr, MetaPropKind, Program},
visit::{noop_visit_mut_type, visit_mut_pass, VisitMut, VisitMutWith},
},
plugin::{plugin_transform, proxies::TransformPluginProgramMetadata},
};

pub struct TransformVisitor;

impl VisitMut for TransformVisitor {
noop_visit_mut_type!();

fn visit_mut_expr(&mut self, n: &mut Expr) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Rewrite import.meta.env when it is the assignment target

Because this visitor only rewrites Expr::Member, the exact left-hand target import.meta.env in an assignment is visited as a MemberExpr target rather than as an expression, so code such as import.meta.env = { MODE: "test" } is left unchanged. That still leaves import.meta in the emitted code for test/setup files that replace the env bag, defeating the plugin's stated transform for this expression shape; add a member-expression visitor or shared helper so assignment targets are rewritten too.

Useful? React with 👍 / 👎.

n.visit_mut_children_with(self);

if let Expr::Member(member) = n {
if is_import_meta_env(member) {
member.obj = Box::new(Ident::new_no_ctxt("process".into(), DUMMY_SP).into());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Mark inserted process as unresolved

This injects a fresh process identifier with no_ctxt while the plugin metadata's unresolved_mark is ignored. In files that declare a local process binding, or when this pass is composed with SWC resolver/hygiene, the emitted process.env can be treated as a normal user identifier instead of the intended global, so import.meta.env.MODE may read the local binding rather than the environment object. Thread metadata.unresolved_mark into the visitor and create the inserted global with that syntax context, as other plugins in this repo do for injected globals.

Useful? React with 👍 / 👎.

}
}
}
}

fn is_import_meta_env(n: &MemberExpr) -> bool {
let Some(obj) = n.obj.as_meta_prop() else {
return false;
};
let Some(prop) = n.prop.as_ident() else {
return false;
};

obj.kind == MetaPropKind::ImportMeta && prop.sym == "env"
}

#[plugin_transform]
pub fn process_transform(program: Program, _metadata: TransformPluginProgramMetadata) -> Program {
program.apply(&mut visit_mut_pass(TransformVisitor))
}

#[cfg(test)]
mod tests {
use swc_core::ecma::{
parser::{EsSyntax, Syntax},
transforms::testing::test,
visit::visit_mut_pass,
};

use super::*;

fn syntax() -> Syntax {
Syntax::Es(EsSyntax {
import_attributes: true,
..Default::default()
})
}

test!(
syntax(),
|_| visit_mut_pass(TransformVisitor),
transform_import_meta_env,
r#"import.meta.env"#
);

test!(
syntax(),
|_| visit_mut_pass(TransformVisitor),
transform_import_meta_env_prop,
r#"import.meta.env.MODE"#
);

test!(
syntax(),
|_| visit_mut_pass(TransformVisitor),
transform_import_meta_env_key,
r#"import.meta.env["PROP"]"#
);

test!(
syntax(),
|_| visit_mut_pass(TransformVisitor),
no_transform_import_meta,
r#"import.meta"#
);

test!(
syntax(),
|_| visit_mut_pass(TransformVisitor),
no_transform_import_meta_glob,
r#"import.meta.glob"#
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import.meta;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import.meta.glob;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
process.env;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
process.env["PROP"];
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
process.env.MODE;
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading