Skip to content

Commit

Permalink
feat: native plugin init (#1691)
Browse files Browse the repository at this point in the history
* feat: init rust plugin

* chore: delete print

* Rename cargo.toml to Cargo.toml

* chore: update

* fix: type

* fix: plugin options string

* fix: cfg test
  • Loading branch information
Jinbao1001 authored Dec 19, 2024
1 parent 817c03e commit bb4ebb2
Show file tree
Hide file tree
Showing 19 changed files with 392 additions and 68 deletions.
245 changes: 219 additions & 26 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ resolver = "2"
anyhow = "1.0.71"
cached = "0.46.1"
clap = "4.3.11"
mimalloc-rust = { version = "=0.2.1" }
oneshot = "0.1.8"
regex = "1.9.3"
serde = "1.0.211"
serde_json = "1.0.132"
swc_core = { version = "0.101.4", default-features = false }
swc_malloc = "1.0.0"
tikv-jemallocator = { version = "=0.5.4", features = ["disable_initial_exec_tls"] }

[profile.release]
Expand Down
7 changes: 1 addition & 6 deletions crates/binding/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,7 @@ napi-derive = "2.16.12"
oneshot = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }

[target.'cfg(not(target_os = "linux"))'.dependencies]
mimalloc-rust = { workspace = true }

[target.'cfg(all(target_os = "linux", target_env = "gnu", any(target_arch = "x86_64", target_arch = "aarch64")))'.dependencies]
tikv-jemallocator = { workspace = true }
swc_malloc = { workspace = true }

[build-dependencies]
napi-build = "2.0.1"
15 changes: 3 additions & 12 deletions crates/binding/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#![deny(clippy::all)]

extern crate swc_malloc;

use std::sync::{Arc, Once};

use js_hook::{JsHooks, TsFnHooks};
Expand All @@ -18,18 +20,6 @@ mod js_hook;
mod js_plugin;
mod threadsafe_function;

#[cfg(not(target_os = "linux"))]
#[global_allocator]
static GLOBAL: mimalloc_rust::GlobalMiMalloc = mimalloc_rust::GlobalMiMalloc;

#[cfg(all(
target_os = "linux",
target_env = "gnu",
any(target_arch = "x86_64", target_arch = "aarch64")
))]
#[global_allocator]
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;

static LOG_INIT: Once = Once::new();

#[napi(object)]
Expand Down Expand Up @@ -168,6 +158,7 @@ pub struct BuildParams {
};
experimental?: {
webpackSyntaxValidate?: string[];
rustPlugins?: Array<[string, any]>;
};
watch?: {
ignoredPaths?: string[];
Expand Down
15 changes: 8 additions & 7 deletions crates/mako/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ oxc_resolver = { version = "=1.7.0", features = ["package_json_raw_json_api"
percent-encoding = { version = "2.3.1" }
serde = { workspace = true }
serde_json = { workspace = true }
swc_malloc = { workspace = true }
url = { version = "2.5.0" }

swc_core = { workspace = true, features = [
Expand All @@ -47,6 +48,7 @@ swc_core = { workspace = true, features = [
"ecma_minifier",
"ecma_minifier_concurrent",
"ecma_parser",
"ecma_plugin_transform",
"ecma_preset_env",
"ecma_quote",
"ecma_transforms_compat",
Expand All @@ -57,10 +59,11 @@ swc_core = { workspace = true, features = [
"ecma_transforms_typescript",
"ecma_utils",
"ecma_visit_path",
"swc_common",
"swc_ecma_quote_macros",
] }

swc_emotion = "0.72.19"
swc_emotion = "=0.72.22"
swc_error_reporters = "0.21.0"
swc_node_comments = "0.24.0"

Expand All @@ -81,6 +84,7 @@ hyper-staticfile = "0.9.6"
hyper-tungstenite = "0.10.0"
indexmap = "2.0.0"
indicatif = "0.17.8"
libloading = "0.8"
md5 = "0.7.0"
mdxjs = "0.2.6"
mime_guess = "2.0.4"
Expand All @@ -90,15 +94,18 @@ parking_lot = { version = "0.12", features = ["nightly"] }
path-clean = "1.0.1"
pathdiff = "0.2.1"
petgraph = "0.6.3"
proc-macro2 = "1"
puffin = { version = "0.16.0", optional = true }
puffin_egui = { version = "0.22.0", optional = true }
quote = "1"
rayon = "1.7.0"
regex = { workspace = true }
sailfish = "0.8.3"
semver = "1.0.23"
serde-xml-rs = "0.6.0"
serde_yaml = "0.9.22"
svgr-rs = { path = "../svgr-rs" }
syn = { version = "2", features = ["full"] }
thiserror = "1.0.43"
tokio = { version = "1", features = ["rt-multi-thread", "sync"] }
tokio-tungstenite = "0.19.0"
Expand All @@ -108,12 +115,6 @@ tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
tungstenite = "0.19.0"
twox-hash = "1.6.3"

[target.'cfg(not(target_os = "linux"))'.dependencies]
mimalloc-rust = { workspace = true }

[target.'cfg(all(target_os = "linux", target_env = "gnu", any(target_arch = "x86_64", target_arch = "aarch64")))'.dependencies]
tikv-jemallocator = { workspace = true }

[dev-dependencies]
insta = { version = "1.30.0", features = ["yaml"] }
maplit = "1.0.2"
Expand Down
2 changes: 1 addition & 1 deletion crates/mako/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ pub(crate) mod js_ast;
pub(crate) mod sourcemap;
#[cfg(test)]
pub mod tests;
pub(crate) mod utils;
pub mod utils;

pub const DUMMY_CTXT: SyntaxContext = SyntaxContext::empty();
17 changes: 16 additions & 1 deletion crates/mako/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use std::time::Instant;

use anyhow::{anyhow, Error, Result};
use colored::Colorize;
use libloading::Library;
use regex::Regex;
use serde_json::Value;
use swc_core::common::sync::Lrc;
use swc_core::common::{Globals, SourceMap, DUMMY_SP};
use swc_core::ecma::ast::Ident;
Expand Down Expand Up @@ -238,6 +240,19 @@ impl Compiler {
if let Some(extra_plugins) = extra_plugins {
plugins.extend(extra_plugins);
}

let mut external_plugins: Vec<Arc<dyn Plugin>> = vec![];
unsafe {
for rust_plugin in config.experimental.rust_plugins.clone() {
let lib = Arc::new(Library::new(rust_plugin.path)?);
let plugin_create_fn: libloading::Symbol<
unsafe extern "C" fn(option: Value) -> Arc<dyn Plugin>,
> = lib.get(b"_plugin_create").unwrap();
let plugin = plugin_create_fn(rust_plugin.options);
external_plugins.push(plugin);
}
}

let builtin_plugins: Vec<Arc<dyn Plugin>> = vec![
// features
Arc::new(plugins::manifest::ManifestPlugin {}),
Expand All @@ -254,6 +269,7 @@ impl Compiler {
Arc::new(plugins::tree_shaking::FarmTreeShake {}),
Arc::new(plugins::detect_circular_dependence::LoopDetector {}),
];
plugins.extend(external_plugins);
plugins.extend(builtin_plugins);

let mut config = config;
Expand Down Expand Up @@ -488,7 +504,6 @@ impl Compiler {
let mg = self.context.module_graph.read().unwrap();
cg.full_hash(&mg)
}

fn clean_dist(&self) -> Result<()> {
// compiler 前清除 dist,如果后续 dev 环境不在 output_path 里,需要再补上 dev 的逻辑
let output_path = &self.context.config.output.path;
Expand Down
22 changes: 21 additions & 1 deletion crates/mako/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub use resolve::ResolveConfig;
pub use rsc_client::{deserialize_rsc_client, LogServerComponent, RscClientConfig};
pub use rsc_server::{deserialize_rsc_server, RscServerConfig};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use serde_json::{json, Value};
pub use stats::{deserialize_stats, StatsConfig};
use thiserror::Error;
pub use transform_import::{TransformImportConfig, TransformImportStyle};
Expand All @@ -75,6 +75,7 @@ pub use umd::{deserialize_umd, Umd};
pub use watch::WatchConfig;

use crate::build::load::JS_EXTENSIONS;
use crate::config::experimental::RustPlugin;
use crate::features::node::Node;

#[derive(Debug, Diagnostic)]
Expand Down Expand Up @@ -236,14 +237,25 @@ impl Config {
) -> Result<Self> {
let abs_config_file = root.join(CONFIG_FILE);
let abs_config_file = abs_config_file.to_str().unwrap();
let mut overrides_json: Option<Value> = None;
let c = config::Config::builder();
// default config
let c = c.add_source(config::File::from_str(
DEFAULT_CONFIG,
config::FileFormat::Json5,
));

// default config from args
let c = if let Some(default_config) = default_config {
let result: Result<Value, serde_json::Error> = serde_json::from_str(default_config);
if let Ok(config) = result {
if let Some(rust_plugins) = config
.get("experimental")
.and_then(|experimental| experimental.get("rustPlugins"))
{
overrides_json = Some(json!({ "rust_plugins": rust_plugins }));
}
};
c.add_source(config::File::from_str(
default_config,
config::FileFormat::Json5,
Expand All @@ -269,6 +281,14 @@ impl Config {
let mut ret = c.try_deserialize::<Config>();
// normalize & check
if let Ok(config) = &mut ret {
// overrides config

if let Some(overrides) = overrides_json {
let rust_plugins: Vec<RustPlugin> =
serde_json::from_value(overrides.get("rust_plugins").unwrap().clone())?;
config.experimental.rust_plugins = rust_plugins;
}

// normalize output
if config.output.path.is_relative() {
config.output.path = root.join(config.output.path.to_string_lossy().to_string());
Expand Down
8 changes: 8 additions & 0 deletions crates/mako/src/config/experimental.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::create_deserialize_fn;

#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct RustPlugin {
pub path: String,
pub options: Value,
}

#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ExperimentalConfig {
Expand All @@ -12,6 +19,7 @@ pub struct ExperimentalConfig {
pub magic_comment: bool,
#[serde(deserialize_with = "deserialize_detect_loop")]
pub detect_circular_dependence: Option<DetectCircularDependence>,
pub rust_plugins: Vec<RustPlugin>,
pub central_ensure: bool,
pub imports_checker: bool,
}
Expand Down
1 change: 1 addition & 0 deletions crates/mako/src/config/mako.config.default.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"rscClient": false,
"experimental": {
"webpackSyntaxValidate": [],
"rustPlugins": [],
"requireContext": true,
"ignoreNonLiteralRequire": false,
"magicComment": true,
Expand Down
4 changes: 3 additions & 1 deletion crates/mako/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub mod config;
pub mod dev;
mod features;
mod generate;
mod module;
pub mod module;
mod module_graph;
pub mod plugin;
mod plugins;
Expand All @@ -20,6 +20,8 @@ pub mod stats;
pub mod utils;
mod visitors;

pub use {swc_core, swc_malloc};

#[macro_export]
macro_rules! mako_profile_scope {
($id:expr) => {
Expand Down
14 changes: 2 additions & 12 deletions crates/mako/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#![feature(box_patterns)]
#![feature(let_chains)]

extern crate swc_malloc;

use std::sync::Arc;

use anyhow::{anyhow, Result};
Expand All @@ -15,18 +17,6 @@ use mako::utils::tokio_runtime;
use mako::{cli, config};
use tracing::debug;

#[cfg(not(target_os = "linux"))]
#[global_allocator]
static GLOBAL: mimalloc_rust::GlobalMiMalloc = mimalloc_rust::GlobalMiMalloc;

#[cfg(all(
target_os = "linux",
target_env = "gnu",
any(target_arch = "x86_64", target_arch = "aarch64")
))]
#[global_allocator]
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;

fn main() -> Result<()> {
let fut = async { run().await };

Expand Down
14 changes: 14 additions & 0 deletions crates/mako_plugin_macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "mako_plugin_macro"
version = "0.0.1"
edition = "2021"
license = "MIT"

[dependencies]
proc-macro2 = "1"
quote = "1"
serde_json = { workspace = true }
syn = { version = "2", features = ["full"] }

[lib]
proc-macro = true
Loading

0 comments on commit bb4ebb2

Please sign in to comment.