Skip to content

Commit

Permalink
feat: plugin for generate assets manifest (#5)
Browse files Browse the repository at this point in the history
* feat: plugin for generate assets manifest

* fix: camel case

---------

Co-authored-by: 鲲尘 <[email protected]>
  • Loading branch information
ClarkXia and 鲲尘 authored Nov 23, 2023
1 parent 4558398 commit c2c2672
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 21 deletions.
3 changes: 3 additions & 0 deletions crates/plugin_manifest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ edition = "2021"
[dependencies]
async-trait = { workspace = true }
tracing = { workspace = true }
regex = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
rspack_core = { path = "../.rspack_crates/rspack_core" }
rspack_error = { path = "../.rspack_crates/rspack_error" }

Expand Down
87 changes: 67 additions & 20 deletions crates/plugin_manifest/src/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
use std::collections::HashMap;
use serde::{Serialize, Deserialize};

use rspack_core::{
Plugin,PluginContext, PluginProcessAssetsOutput,ProcessAssetsArgs,
CompilationAsset,
CompilationAsset, PublicPath,
rspack_sources::{RawSource, SourceExt},
};
// use rspack_error::Result;

#[derive(Debug)]
pub struct ManifestPlugin;


#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssetsManifest {
pub pages: HashMap<String, Vec<String>>,
pub entries: HashMap<String, Vec<String>>,
pub public_path: String,
}

const AUTO_PUBLIC_PATH_PLACEHOLDER: &str = "__RSPACK_PLUGIN_CSS_AUTO_PUBLIC_PATH__";

impl ManifestPlugin {
pub fn new() -> Self {
Self {}
}
}

fn default_cotent() -> &'static str {
r#"{"assets": []}"#
}

#[async_trait::async_trait]
impl Plugin for ManifestPlugin {
fn name(&self) -> &'static str {
Expand All @@ -30,29 +40,66 @@ impl Plugin for ManifestPlugin {
args: ProcessAssetsArgs<'_>,
)-> PluginProcessAssetsOutput {
let compilation = args.compilation;
let public_path = match &compilation.options.output.public_path {
PublicPath::String(p) => p,
PublicPath::Auto => AUTO_PUBLIC_PATH_PLACEHOLDER,
};
let mut assets_mainfest = AssetsManifest {
pages: HashMap::new(),
entries: HashMap::new(),
public_path: public_path.to_string(),
};
let entry_points = &compilation.entrypoints;
println!("entry_points: {:?}", entry_points);
Ok(())
}

async fn process_assets_stage_optimize_inline(
&self,
_ctx: PluginContext,
args: ProcessAssetsArgs<'_>,
) -> PluginProcessAssetsOutput {
let compilation = args.compilation;

let assets = &compilation.assets();

entry_points.iter().for_each(|(name, _entry)| {
let mut files: Vec<String> = Vec::new();
compilation.entrypoint_by_name(name).chunks.iter().for_each(|chunk| {

if let Some(chunk) = compilation.chunk_by_ukey.get(chunk) {
chunk.files.iter().for_each(|file| {
if let Some(asset) = assets.get(file) {
if !asset.info.hot_module_replacement && !asset.info.development {
files.push(file.to_string());
}
} else {
files.push(file.to_string());
}
});
};
});
assets_mainfest.entries.insert(name.to_string(), files);
});
let page_chunk_name_regex = regex::Regex::new(r"^p_").unwrap();
compilation
.chunk_by_ukey
.values()
.for_each(|c| {
if let Some(name) = &c.id {
if !c.has_entry_module(&compilation.chunk_graph) && !c.can_be_initial(&compilation.chunk_group_by_ukey) {
assets_mainfest.pages.insert(
page_chunk_name_regex.replace(name, "").to_string(),
Vec::from_iter(
c.files
.iter()
// Only collect js and css files.
.filter(|f| f.ends_with(".js") || f.ends_with(".css"))
.cloned()
),
);
}
}
});
let json_string = serde_json::to_string(&assets_mainfest).unwrap();
let output_path = compilation
.options
.output
.path
.join("manifest.json".to_string()).to_string_lossy().to_string();
println!("output_path: {}", output_path);
.join("assets-manifest.json".to_string()).to_string_lossy().to_string();
compilation.emit_asset(
output_path,
CompilationAsset::from(RawSource::from(default_cotent().to_owned()).boxed()),
CompilationAsset::from(RawSource::from(json_string).boxed()),
);

Ok(())
}
}
2 changes: 1 addition & 1 deletion crates/plugin_manifest/tests/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use rspack_core::PluginExt;
use rspack_testing::{fixture,test_fixture_insta};
use plugin_manifest::ManifestPlugin;

#[fixture("tests/fixtures/*")]
#[fixture("tests/fixtures/with-assets")]
fn manifest(fixture_path: PathBuf) {
test_fixture_insta(
&fixture_path,
Expand Down
1 change: 1 addition & 0 deletions crates/plugin_manifest/tests/fixtures/with-assets/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('a.js');
1 change: 1 addition & 0 deletions crates/plugin_manifest/tests/fixtures/with-assets/b.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('b.js');
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions crates/plugin_manifest/tests/fixtures/with-assets/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import url from './img.png';

import('./a.js');
import('./b.js');
console.log('url', url);
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
source: crates/.rspack_crates/rspack_testing/src/run_fixture.rs
---

13 changes: 13 additions & 0 deletions crates/plugin_manifest/tests/fixtures/with-assets/test.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"module": {
"rules": [
{
"test": {
"type": "regexp",
"matcher": "\\.png$"
},
"type": "asset/resource"
}
]
}
}

0 comments on commit c2c2672

Please sign in to comment.