Skip to content

Commit

Permalink
fix: output.clean can not remove *.hot-update.js (#3689)
Browse files Browse the repository at this point in the history
fix: output.clean can not remove hot-update.js
  • Loading branch information
jerrykingxyz authored Jul 3, 2023
1 parent 14795c3 commit a5f739f
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 17 deletions.
1 change: 1 addition & 0 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ export interface JsStatsWarning {

export interface NodeFS {
writeFile: (...args: any[]) => any
removeFile: (...args: any[]) => any
mkdir: (...args: any[]) => any
mkdirp: (...args: any[]) => any
}
Expand Down
31 changes: 16 additions & 15 deletions crates/rspack_core/src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ mod resolver;
use std::{path::Path, sync::Arc};

pub use compilation::*;
use dashmap::DashMap;
pub use make::MakeParam;
pub use queue::*;
pub use resolver::*;
use rspack_error::Result;
use rspack_fs::AsyncWritableFileSystem;
use rspack_futures::FuturesResults;
use rspack_identifier::IdentifierSet;
use rustc_hash::FxHashMap as HashMap;
use tracing::instrument;

use crate::{
Expand All @@ -34,8 +34,8 @@ where
pub resolver_factory: Arc<ResolverFactory>,
pub cache: Arc<Cache>,
/// emitted asset versions
/// the key of DashMap is filename, the value of DashMap is version
pub emitted_asset_versions: DashMap<String, String>,
/// the key of HashMap is filename, the value of HashMap is version
pub emitted_asset_versions: HashMap<String, String>,
}

impl<T> Compiler<T>
Expand Down Expand Up @@ -210,11 +210,10 @@ where
let _ = self
.emitted_asset_versions
.iter()
.filter_map(|item| {
let filename = item.key();
.filter_map(|(filename, _version)| {
if !assets.contains_key(filename) {
self.emitted_asset_versions.remove(filename);
Some(self.output_filesystem.remove_file(filename))
let file_path = Path::new(&self.options.output.path).join(filename);
Some(self.output_filesystem.remove_file(file_path))
} else {
None
}
Expand All @@ -225,19 +224,28 @@ where

self.plugin_driver.emit(&mut self.compilation).await?;

let mut new_emitted_asset_versions = HashMap::default();
let results = self
.compilation
.assets()
.iter()
.filter_map(|(filename, asset)| {
// collect version info to new_emitted_asset_versions
if self.options.is_incremental_rebuild_emit_asset_enabled() {
new_emitted_asset_versions.insert(filename.to_string(), asset.info.version.clone());
}

if let Some(old_version) = self.emitted_asset_versions.get(filename) {
if old_version.as_str() == asset.info.version {
if old_version.as_str() == asset.info.version && !old_version.is_empty() {
return None;
}
}

Some(self.emit_asset(&self.options.output.path, filename, asset))
})
.collect::<FuturesResults<_>>();

self.emitted_asset_versions = new_emitted_asset_versions;
// return first error
for item in results.into_inner() {
item?;
Expand Down Expand Up @@ -271,13 +279,6 @@ where
.write(&file_path, source.buffer())
.await?;

if !asset.info.version.is_empty() && self.options.is_incremental_rebuild_emit_asset_enabled()
{
self
.emitted_asset_versions
.insert(filename.to_string(), asset.info.version.clone());
}

self.compilation.emitted_assets.insert(filename.to_string());

let asset_emitted_args = AssetEmittedArgs {
Expand Down
3 changes: 3 additions & 0 deletions crates/rspack_fs/src/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ pub trait AsyncWritableFileSystem {
/// This function will create a file if it does not exist, and will entirely replace its contents if it does.
fn write<P: AsRef<Path>, D: AsRef<[u8]>>(&self, file: P, data: D) -> BoxFuture<'_, Result<()>>;

/// Removes a file from the filesystem.
fn remove_file<P: AsRef<Path>>(&self, file: P) -> BoxFuture<'_, Result<()>>;

/// Removes a directory at this path, after removing all its contents. Use carefully.
fn remove_dir_all<P: AsRef<Path>>(&self, dir: P) -> BoxFuture<'_, Result<()>>;
}

Expand Down
10 changes: 10 additions & 0 deletions crates/rspack_fs_node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ mod node_test {
pub async fn mkdirp(&self, file: String) {
self.writable_fs.create_dir_all(file).await.unwrap();
}

#[napi]
pub async fn remove_file(&self, file: String) {
self.writable_fs.remove_file(file).await.unwrap();
}

#[napi]
pub async fn remove_dir_all(&self, file: String) {
self.writable_fs.remove_dir_all(file).await.unwrap();
}
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/rspack_fs_node/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ impl Drop for JsFunctionRef {
#[napi(object, js_name = "NodeFS")]
pub struct NodeFS {
pub write_file: JsFunction,
pub remove_file: JsFunction,
pub mkdir: JsFunction,
pub mkdirp: JsFunction,
}
Expand Down
44 changes: 43 additions & 1 deletion packages/playground/cases/hooks/asset-emitted/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,47 @@ test("asset emitted hook should only emit modified assets", async ({
return text === "__OTHER_TEXT____VALUE__";
});
// main.js contains runtime module, so it should also emit
expect(assets).toEqual(["src_foo_js.js", "main.js"]);
expect(assets.sort()).toEqual(["main.js", "src_foo_js.js"]);

// check dist dir
// the outputFileSystem can contain only one main hot-update.js
const files = rspack.compiler.outputFileSystem.readdirSync(
"dist",
{}
) as string[];
expect(
files.filter(item => /^main(.+)\.hot-update\.js$/.test(item)).length
).toBe(1);
});

test("asset emitted should not emit removed assets", async ({
page,
rspack,
fileAction
}) => {
let assets: string[] = [];
rspack.compiler.hooks.assetEmitted.tap("test", function (name) {
if (name.includes(".hot-update.")) {
return;
}
assets.push(name);
});

expect(await page.textContent("#root")).toBe("__ROOT_TEXT____FOO_VALUE__");
// update js file
fileAction.updateFile("src/index.js", () => {
return 'document.getElementById("root").innerText = "__ROOT_TEXT__"';
});
await rspack.waitingForHmr(async () => {
const text = await page.textContent("#root");
return text === "__ROOT_TEXT__";
});
expect(assets).toEqual(["main.js"]);

// check dist dir
const files = rspack.compiler.outputFileSystem.readdirSync(
"dist",
{}
) as string[];
expect(files.every(item => item !== "src_foo_js.js")).toBeTruthy();
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = {
}
]
},
output: { clean: true },
experiments: {
incrementalRebuild: {
emitAsset: true
Expand Down
2 changes: 1 addition & 1 deletion packages/playground/fixtures/rspack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class Rspack {
if (tries === maxTries - 1) {
throw new Error("outof max retry time");
}
await sleep(100);
await sleep(200);
}
}
}
Expand Down

0 comments on commit a5f739f

Please sign in to comment.