Skip to content

Commit

Permalink
refactor: move web-bundler to a stand-alone crate called `metassr-bun…
Browse files Browse the repository at this point in the history
…dler`
  • Loading branch information
hulxv committed Sep 6, 2024
1 parent 0086a1f commit d6357a1
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 116 deletions.
17 changes: 15 additions & 2 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ serde = "1.0.207"
tower-layer = "0.3.3"
tower-service = "0.3.3"
metassr-create = { version = "0.1.0", path = "crates/metassr-create" }
metassr-bundler = { version = "0.1.0", path = "crates/metassr-bundler" }

[workspace]
members = [
Expand All @@ -40,7 +41,7 @@ members = [
"crates/metassr-utils",
"crates/html-generator",
"metassr-cli",
"crates/metassr-create",
"crates/metassr-create", "crates/metassr-bundler",
]

[[bin]]
Expand Down
1 change: 1 addition & 0 deletions crates/metassr-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ metassr-utils = { version = "0.1.0", path = "../metassr-utils" }
html-generator = { path = "../html-generator" }
lazy_static = "1.5.0"
serde = { version = "1.0.207", features = ["derive"] }
metassr-bundler = { version = "0.1.0", path = "../metassr-bundler" }
101 changes: 0 additions & 101 deletions crates/metassr-build/src/bundler.rs
Original file line number Diff line number Diff line change
@@ -1,101 +0,0 @@
use anyhow::{anyhow, Result};
use lazy_static::lazy_static;
use metacall::{loaders, metacall, MetacallNull};
use std::{collections::HashMap, ffi::OsStr, marker::Sized, path::Path, sync::Mutex};

use crate::traits::Exec;
lazy_static! {
static ref IS_BUNDLING_SCRIPT_LOADED: Mutex<BundleSciptLoadingState> =
Mutex::new(BundleSciptLoadingState::new());
}
static BUILD_SCRIPT: &str = include_str!("./scripts/bundle.js");
const BUNDLING_FUNC: &str = "web_bundling";

/// A detector for if the bundling script `./scripts/bundle.js` is loaded or not.
#[derive(Debug)]
pub struct BundleSciptLoadingState(bool);

impl BundleSciptLoadingState {
pub fn new() -> Self {
Self(false)
}
pub fn loaded(&mut self) {
self.0 = true
}
pub fn is_loaded(&self) -> bool {
self.0
}
}

impl Default for BundleSciptLoadingState {
fn default() -> Self {
Self::new()
}
}

#[derive(Debug)]

pub struct WebBundler<'a> {
pub targets: HashMap<String, &'a Path>,
pub dist_path: &'a Path,
}

impl<'a> WebBundler<'a> {
pub fn new<S>(targets: &'a HashMap<String, String>, dist_path: &'a S) -> Self
where
S: AsRef<OsStr> + ?Sized,
{
let targets: HashMap<String, &Path> = targets
.iter()
.map(|(k, v)| (k.into(), Path::new(v)))
.collect();

Self {
targets,
dist_path: Path::new(dist_path),
}
}
}

impl<'a> Exec for WebBundler<'a> {
type Output = ();
fn exec(&self) -> Result<Self::Output> {
if !IS_BUNDLING_SCRIPT_LOADED.lock().unwrap().is_loaded() {
if let Err(e) = loaders::from_memory("node", BUILD_SCRIPT) {
return Err(anyhow!("Cannot load bundling script: {e:?}"));
}
IS_BUNDLING_SCRIPT_LOADED.lock().unwrap().loaded();
}

if let Err(e) = metacall::<MetacallNull>(
BUNDLING_FUNC,
[
serde_json::to_string(&self.targets)?,
self.dist_path.to_str().unwrap().to_owned(),
],
) {
return Err(anyhow!("Cannot running {BUNDLING_FUNC}(): {e:?}"));
}

Ok(())
}
}

#[cfg(test)]
mod tests {
use super::*;
use metacall::switch;
#[test]
fn it_works() {
let _metacall = switch::initialize().unwrap();
WebBundler::new(
&HashMap::from([(
"pages/homes.tsx".to_owned(),
"../../tests/web-app/src/pages/home.tsx".to_owned(),
)]),
"../../tests/web-app/dist",
)
.exec()
.unwrap()
}
}
12 changes: 7 additions & 5 deletions crates/metassr-build/src/client/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use crate::bundler::WebBundler;
use crate::traits::{Build, Exec, Generate};
use crate::traits::{Build, Generate};
use crate::utils::setup_page_path;
use anyhow::{anyhow, Result};
use hydrator::Hydrator;
use metassr_utils::src_analyzer::special_entries;
use metassr_utils::{cache_dir::CacheDir, src_analyzer::SourceDir, traits::AnalyzeDir};

use metassr_bundler::WebBundler;
use metassr_utils::{
cache_dir::CacheDir, src_analyzer::special_entries, src_analyzer::SourceDir, traits::AnalyzeDir,
};
use std::{
collections::HashMap,
ffi::OsStr,
Expand Down Expand Up @@ -66,7 +68,7 @@ impl Build for ClientBuilder {
(entry_name.to_owned(), format!("{}", fullpath.display()))
})
.collect::<HashMap<String, String>>();

let bundler = WebBundler::new(&targets, &self.dist_path);
if let Err(e) = bundler.exec() {
return Err(anyhow!("Bundling failed: {e}"));
Expand Down
7 changes: 3 additions & 4 deletions crates/metassr-build/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ mod render;
mod render_exec;
mod targets;

use crate::{
bundler::WebBundler,
traits::{Build, Exec},
};
use crate::traits::Build;
use manifest::ManifestGenerator;

use metassr_bundler::WebBundler;
use metassr_utils::{
cache_dir::CacheDir,
dist_analyzer::DistDir,
Expand Down
9 changes: 6 additions & 3 deletions crates/metassr-build/src/server/renderer/head.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{
collections::HashMap, ffi::OsStr, path::PathBuf, sync::Mutex, thread::sleep, time::Duration,
};

use crate::{bundler::WebBundler, traits::Exec};
use metassr_bundler::WebBundler;

lazy_static! {
static ref IS_HEAD_SCRIPT_LOADED: Mutex<HeadSciptLoadingState> =
Expand Down Expand Up @@ -52,7 +52,8 @@ impl HeadRenderer {
}

pub fn render(&mut self, bundler: bool) -> Result<String> {
if !IS_HEAD_SCRIPT_LOADED.lock().unwrap().is_loaded() {
let mut guard = IS_HEAD_SCRIPT_LOADED.lock().unwrap();
if !guard.is_loaded() {
if bundler {
self.bundle()?;
// TODO: remove this line
Expand All @@ -63,8 +64,10 @@ impl HeadRenderer {
"node",
format!("{}/head.js", self.cache_dir.dir_path().display()),
);
IS_HEAD_SCRIPT_LOADED.lock().unwrap().loaded()
guard.loaded()
}
drop(guard);

match metacall_no_arg::<String>("render_head") {
Err(e) => Err(anyhow!("Couldn't render head: {e:?}")),
Ok(out) => Ok(out),
Expand Down
13 changes: 13 additions & 0 deletions crates/metassr-bundler/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "metassr-bundler"
version = "0.0.1-alpha"
edition = "2021"
description = "A simple crate is used for web bundling built on Metacall and Rspack."
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = "1.0.86"
lazy_static = "1.5.0"
metacall = "0.4.1"
metassr-utils = { version = "0.1.0", path = "../metassr-utils" }
serde_json = "1.0.128"
File renamed without changes.
98 changes: 98 additions & 0 deletions crates/metassr-bundler/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use anyhow::{anyhow, Result};
use lazy_static::lazy_static;
use metacall::{loaders, metacall, MetacallNull};
use std::{collections::HashMap, ffi::OsStr, marker::Sized, path::Path, sync::Mutex};

lazy_static! {
static ref IS_BUNDLING_SCRIPT_LOADED: Mutex<BundleSciptLoadingState> =
Mutex::new(BundleSciptLoadingState::new());
}
static BUILD_SCRIPT: &str = include_str!("./bundle.js");
const BUNDLING_FUNC: &str = "web_bundling";

/// A detector for if the bundling script `./bundle.js` is loaded or not.
#[derive(Debug)]
pub struct BundleSciptLoadingState(bool);

impl BundleSciptLoadingState {
pub fn new() -> Self {
Self(false)
}
pub fn loaded(&mut self) {
self.0 = true
}
pub fn is_loaded(&self) -> bool {
self.0
}
}

impl Default for BundleSciptLoadingState {
fn default() -> Self {
Self::new()
}
}

#[derive(Debug)]

pub struct WebBundler<'a> {
pub targets: HashMap<String, &'a Path>,
pub dist_path: &'a Path,
}

impl<'a> WebBundler<'a> {
pub fn new<S>(targets: &'a HashMap<String, String>, dist_path: &'a S) -> Self
where
S: AsRef<OsStr> + ?Sized,
{
let targets: HashMap<String, &Path> = targets
.iter()
.map(|(k, v)| (k.into(), Path::new(v)))
.collect();

Self {
targets,
dist_path: Path::new(dist_path),
}
}
pub fn exec(&self) -> Result<()> {
let mut guard = IS_BUNDLING_SCRIPT_LOADED.lock().unwrap();
if !guard.is_loaded() {
if let Err(e) = loaders::from_memory("node", BUILD_SCRIPT) {
return Err(anyhow!("Cannot load bundling script: {e:?}"));
}
guard.loaded();
}
drop(guard);

if let Err(e) = metacall::<MetacallNull>(
BUNDLING_FUNC,
[
serde_json::to_string(&self.targets)?,
self.dist_path.to_str().unwrap().to_owned(),
],
) {
return Err(anyhow!("Cannot running {BUNDLING_FUNC}(): {e:?}"));
}

Ok(())
}
}

#[cfg(test)]
mod tests {
use super::*;
use metacall::switch;
#[test]
fn it_works() {
let _metacall = switch::initialize().unwrap();
WebBundler::new(
&HashMap::from([(
"pages/homes.tsx".to_owned(),
"../../tests/web-app/src/pages/home.tsx".to_owned(),
)]),
"../../tests/web-app/dist",
)
.exec()
.unwrap()
}
}

0 comments on commit d6357a1

Please sign in to comment.