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
26 changes: 26 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions packages/swc-inject-imports/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__tests__/
transform/
Cargo.toml
1 change: 1 addition & 0 deletions packages/swc-inject-imports/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# ChangeLog
25 changes: 25 additions & 0 deletions packages/swc-inject-imports/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]

description = "SWC Plugin for swc-experimental-inject-imports"


authors = { workspace = true }
edition = { workspace = true }
homepage = { workspace = true }
license = { workspace = true }
name = "swc_plugin_swc_inject_imports"
publish = false
repository = { workspace = true }
rust-version = { workspace = true }
version = "0.7.4"


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

[dependencies]
serde_json = { workspace = true }
swc_core = { workspace = true, features = ["ecma_plugin_transform"] }


swc_inject_imports = { path = "./transform" }
23 changes: 23 additions & 0 deletions packages/swc-inject-imports/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# @swc/plugin-swc-experimental-inject-imports

## Usage

.swcrc:

```json
{
"jsc": {
"experimental": {
"plugins": [
"@swc/plugin-swc-experimental-inject-imports",
{
"importsPaths": ["@swc/experimental-inject-imports"],
"onlyFilenames": ["page.tsx", "layout.tsx"]
}
]
}
}
}
```

# @swc/plugin-swc-experimental-inject-imports
23 changes: 23 additions & 0 deletions packages/swc-inject-imports/README.tmpl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# @swc/plugin-swc-experimental-inject-imports

## Usage

.swcrc:

```json
{
"jsc": {
"experimental": {
"plugins": [
"@swc/plugin-swc-experimental-inject-imports",
{
"importsPaths": ["@swc/example-import"],
"onlyFilenames": ["page.tsx", "layout.tsx"]
}
]
}
}
}
```

${CHANGELOG}
29 changes: 29 additions & 0 deletions packages/swc-inject-imports/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@swc/plugin-swc-experimental-inject-imports",
"version": "1.0.0",
"publishConfig": {
"access": "public",
"provenance": true
},
"description": "SWC plugin for swc-experimental-inject-imports",
"main": "swc_plugin_swc_inject_imports.wasm",
"scripts": {
"prepack": "cargo build --release -p swc_plugin_swc_inject_imports --target wasm32-wasip1 && cp ../../target/wasm32-wasip1/release/swc_plugin_swc_inject_imports.wasm ."
},
"homepage": "https://swc.rs",
"repository": {
"type": "git",
"url": "git+https://github.com/swc-project/plugins.git",
"directory": "packages/swc-experimental-inject-imports"
},
"bugs": {
"url": "https://github.com/swc-project/plugins/issues"
},
"author": "강동윤 <[email protected]>",
"keywords": [],
"license": "Apache-2.0",
"preferUnplugged": true,
"dependencies": {
"@swc/counter": "^0.1.3"
}
}
33 changes: 33 additions & 0 deletions packages/swc-inject-imports/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#![allow(clippy::not_unsafe_ptr_arg_deref)]
#![feature(box_patterns)]

use swc_core::{
ecma::ast::Program,
plugin::{
metadata::TransformPluginMetadataContextKind, plugin_transform,
proxies::TransformPluginProgramMetadata,
},
};

#[plugin_transform]
fn swc_inject_imports_plugin(
mut program: Program,
data: TransformPluginProgramMetadata,
) -> Program {
let config = serde_json::from_str::<swc_inject_imports::Config>(
&data
.get_transform_plugin_config()
.expect("failed to get plugin config for swc-experimental-inject-imports"),
)
.expect("invalid config for swc-experimental-inject-imports");

let filename = data
.get_context(&TransformPluginMetadataContextKind::Filename)
.unwrap()
.to_string()
.into();

program.mutate(swc_inject_imports::swc_inject_imports(filename, config));

program
}
29 changes: 29 additions & 0 deletions packages/swc-inject-imports/transform/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]

description = "AST transforms visitor for swc-experimental-inject-imports"


authors = { workspace = true }
edition = { workspace = true }
homepage = { workspace = true }
license = { workspace = true }
name = "swc_inject_imports"
repository = { workspace = true }
rust-version = { workspace = true }
version = "0.1.0"


[dependencies]
rustc-hash = { workspace = true }
serde = { workspace = true, features = ["derive"] }
swc_atoms = { workspace = true }
swc_common = { workspace = true }
swc_ecma_ast = { workspace = true }
swc_ecma_utils = { workspace = true }
swc_ecma_visit = { workspace = true }

[dev-dependencies]
swc_ecma_parser = { workspace = true }
swc_ecma_transforms_base = { workspace = true }
swc_ecma_transforms_testing = { workspace = true }
testing = { workspace = true }
61 changes: 61 additions & 0 deletions packages/swc-inject-imports/transform/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#![feature(box_patterns)]

use serde::Deserialize;
use swc_atoms::Atom;
use swc_common::util::take::Take;
use swc_ecma_ast::{ImportDecl, Module, ModuleDecl, ModuleItem, Pass, Program, Str};
use swc_ecma_utils::prepend_stmts;

#[derive(Debug, Default, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Config {
#[serde(default)]
pub imports_paths: Vec<Atom>,

#[serde(default)]
pub only_filenames: Vec<Atom>,
}

pub fn swc_inject_imports(filename: Atom, config: Config) -> impl Pass {
InjectImports { config, filename }
}

struct InjectImports {
config: Config,
filename: Atom,
}

impl Pass for InjectImports {
fn process(&mut self, program: &mut swc_ecma_ast::Program) {
if self.config.imports_paths.is_empty() {
return;
}

if !self.config.only_filenames.is_empty() {
let mut find = false;
for filename_filter in self.config.only_filenames.iter() {
if self.filename.ends_with(&**filename_filter) {
find = true;
break;
}
}
if !find {
return;
}
}

let Program::Module(Module { body, .. }) = program else {
return;
};

let new_imports = self.config.imports_paths.iter().map(|path| {
ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl {
src: Box::new(Str::from(path.clone())),
specifiers: vec![],
..Take::dummy()
}))
});

prepend_stmts(body, new_imports);
}
}
34 changes: 34 additions & 0 deletions packages/swc-inject-imports/transform/tests/fixture.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use std::path::PathBuf;

use swc_atoms::Atom;
use swc_common::Mark;
use swc_ecma_parser::Syntax;
use swc_ecma_transforms_base::resolver;
use swc_ecma_transforms_testing::test_fixture;
use swc_inject_imports::Config;

#[testing::fixture("tests/fixture/**/input.js")]
fn pure(input: PathBuf) {
let output = input.parent().unwrap().join("output.js");
test_fixture(
Syntax::default(),
&|_tr| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();

(
resolver(unresolved_mark, top_level_mark, false),
swc_inject_imports::swc_inject_imports(
"test.js".into(),
Config {
imports_paths: vec![Atom::new("@swc/experimental-inject-imports")],
only_filenames: vec![],
},
),
)
},
&input,
&output,
Default::default(),
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use client';

import { useEffect } from "react";

console.log(useEffect);
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
'use client';
import "@swc/experimental-inject-imports";
import { useEffect } from "react";
console.log(useEffect);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { markAsPure } from "not-swc-experimental-inject-imports";

markAsPure(console.log("test!"));
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import "@swc/experimental-inject-imports";
import { markAsPure } from "not-swc-experimental-inject-imports";
markAsPure(console.log("test!"));
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { markAsPure } from "@swc/experimental-inject-imports";

markAsPure(console.log("test!"));
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import "@swc/experimental-inject-imports";
import { markAsPure } from "@swc/experimental-inject-imports";
markAsPure(console.log("test!"));
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