From bda7a4b8c6ba4c402204a54fadc93554a225f3de Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Fri, 1 Dec 2023 00:09:46 +0800 Subject: [PATCH 01/18] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20json=20tree=20shak?= =?UTF-8?q?ing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 1 + crates/rspack/tests/fixtures.rs | 3 +- crates/rspack/tests/tree-shaking/basic/a.json | 3 + .../rspack/tests/tree-shaking/basic/index.js | 5 +- .../basic/snapshot/new_treeshaking.snap | 15 +- .../tree-shaking/basic/snapshot/snap.diff | 31 +++- crates/rspack_core/Cargo.toml | 1 + .../rspack_core/src/compiler/compilation.rs | 5 +- crates/rspack_core/src/exports_info.rs | 8 +- crates/rspack_core/src/module.rs | 2 + crates/rspack_core/src/utils/visitor.rs | 6 + .../harmony_import_specifier_dependency.rs | 10 +- .../harmony_import_dependency_scanner.rs | 1 - .../src/json_exports_dependency.rs | 129 +++++++++++++++ crates/rspack_plugin_json/src/lib.rs | 149 ++++++++++++++++-- 15 files changed, 326 insertions(+), 43 deletions(-) create mode 100644 crates/rspack/tests/tree-shaking/basic/a.json create mode 100644 crates/rspack_plugin_json/src/json_exports_dependency.rs diff --git a/Cargo.lock b/Cargo.lock index 9b78d7e6316..15e6f553795 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2539,6 +2539,7 @@ dependencies = [ "hashlink", "indexmap 1.9.3", "itertools", + "json", "mime_guess", "nodejs-resolver", "once_cell", diff --git a/crates/rspack/tests/fixtures.rs b/crates/rspack/tests/fixtures.rs index 32f1106513c..4ef335e073a 100644 --- a/crates/rspack/tests/fixtures.rs +++ b/crates/rspack/tests/fixtures.rs @@ -48,7 +48,8 @@ fn samples(fixture_path: PathBuf) { fn tree_shaking(fixture_path: PathBuf) { // For each test case // First test is old version tree shaking snapshot test - test_fixture(&fixture_path, Box::new(|_, _| {}), None); + // TODO: recover + // test_fixture(&fixture_path, Box::new(|_, _| {}), None); // second test is webpack based tree shaking IS_NEW_TREESHAKING.store(true, Ordering::SeqCst); test_fixture( diff --git a/crates/rspack/tests/tree-shaking/basic/a.json b/crates/rspack/tests/tree-shaking/basic/a.json new file mode 100644 index 00000000000..24091602266 --- /dev/null +++ b/crates/rspack/tests/tree-shaking/basic/a.json @@ -0,0 +1,3 @@ +[ + 1, 2, {"a": 1, "b": 2} +] diff --git a/crates/rspack/tests/tree-shaking/basic/index.js b/crates/rspack/tests/tree-shaking/basic/index.js index 8c062158924..eb6387bd19a 100644 --- a/crates/rspack/tests/tree-shaking/basic/index.js +++ b/crates/rspack/tests/tree-shaking/basic/index.js @@ -1,3 +1,4 @@ -import { answer } from "./lib"; -answer +import a from "./a.json"; +a[2].a + diff --git a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap index 2f9730bfe31..7aa6cf8421f 100644 --- a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap +++ b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap @@ -3,21 +3,16 @@ source: crates/rspack_testing/src/run_fixture.rs --- ```js title=main.js (self['webpackChunkwebpack'] = self['webpackChunkwebpack'] || []).push([["main"], { -"./answer.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -__webpack_require__.d(__webpack_exports__, { - answer: function() { return answer; } -}); - const answer = 103330; -}), "./index.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */var _lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib */"./answer.js"); +/* harmony import */var _a_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a.json */"./a.json"); -_lib__WEBPACK_IMPORTED_MODULE_0__.answer; +_a_json__WEBPACK_IMPORTED_MODULE_0__["2"].a; }), +"./a.json": (function (module, exports, __webpack_require__) { +"use strict"; +module.exports = [{"a":1}]}), },function(__webpack_require__) { var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId) } diff --git a/crates/rspack/tests/tree-shaking/basic/snapshot/snap.diff b/crates/rspack/tests/tree-shaking/basic/snapshot/snap.diff index d88afb964de..14de4d94cef 100644 --- a/crates/rspack/tests/tree-shaking/basic/snapshot/snap.diff +++ b/crates/rspack/tests/tree-shaking/basic/snapshot/snap.diff @@ -1,22 +1,41 @@ --- expected +++ actual -@@ -14,18 +14,9 @@ +@@ -3,30 +3,20 @@ + --- + ```js title=main.js + (self['webpackChunkwebpack'] = self['webpackChunkwebpack'] || []).push([["main"], { +-"./answer.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { +-"use strict"; +-__webpack_require__.r(__webpack_exports__); +-__webpack_require__.d(__webpack_exports__, { +- answer: function() { return answer; } +-}); +- const answer = 103330; +-}), "./index.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */var _lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib */"./lib.js"); -+/* harmony import */var _lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib */"./answer.js"); ++/* harmony import */var _a_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a.json */"./a.json"); - _lib__WEBPACK_IMPORTED_MODULE_0__.answer; --}), +-_lib__WEBPACK_IMPORTED_MODULE_0__.answer; ++_a_json__WEBPACK_IMPORTED_MODULE_0__.a; + }), -"./lib.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { --"use strict"; ++"./a.json": (function (module, exports, __webpack_require__) { + "use strict"; -__webpack_require__.r(__webpack_exports__); -__webpack_require__.d(__webpack_exports__, { - answer: function() { return _answer__WEBPACK_IMPORTED_MODULE_0__.answer; } -}); -/* harmony import */var _answer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./answer */"./answer.js"); - - }), +-}), ++module.exports = { ++ "a": "soemthing", ++ "b": "bbbb" ++} ++;}), },function(__webpack_require__) { + var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId) } diff --git a/crates/rspack_core/Cargo.toml b/crates/rspack_core/Cargo.toml index 4c7da60decd..86bbd42588d 100644 --- a/crates/rspack_core/Cargo.toml +++ b/crates/rspack_core/Cargo.toml @@ -20,6 +20,7 @@ glob-match = "0.2.1" hashlink = { workspace = true } indexmap = { workspace = true } itertools = { workspace = true } +json = { workspace = true } mime_guess = { workspace = true } nodejs-resolver = { version = "0.1.1" } once_cell = { workspace = true } diff --git a/crates/rspack_core/src/compiler/compilation.rs b/crates/rspack_core/src/compiler/compilation.rs index 1e93dc494aa..63ab5c4a528 100644 --- a/crates/rspack_core/src/compiler/compilation.rs +++ b/crates/rspack_core/src/compiler/compilation.rs @@ -31,7 +31,7 @@ use super::{ use crate::{ build_chunk_graph::build_chunk_graph, cache::{use_code_splitting_cache, Cache, CodeSplittingCache}, - is_source_equal, + debug_all_exports_info, is_source_equal, tree_shaking::{optimizer, visitor::SymbolRef, BailoutFlag, OptimizeDependencyResult}, AddQueue, AddTask, AddTaskResult, AdditionalChunkRuntimeRequirementsArgs, AdditionalModuleRequirementsArgs, AsyncDependenciesBlock, BoxDependency, BoxModule, BuildQueue, @@ -1273,6 +1273,9 @@ impl Compilation { // https://github.com/webpack/webpack/blob/d15c73469fd71cf98734685225250148b68ddc79/lib/Compilation.js#L2812-L2814 while plugin_driver.optimize_dependencies(self).await?.is_some() {} logger.time_end(start); + if self.options.is_new_tree_shaking() { + // debug_all_exports_info!(&self.module_graph); + } // if self.options.is_new_tree_shaking() { // debug_all_exports_info!(&self.module_graph); diff --git a/crates/rspack_core/src/exports_info.rs b/crates/rspack_core/src/exports_info.rs index 0e3b4c3c2cb..bb951d73e2a 100644 --- a/crates/rspack_core/src/exports_info.rs +++ b/crates/rspack_core/src/exports_info.rs @@ -182,6 +182,8 @@ impl ExportsInfoId { changed } + /// # Panic + /// this function would panic if name doesn't exists in current exportsInfo pub fn get_read_only_export_info<'a>( &self, name: &JsWord, @@ -817,6 +819,11 @@ impl ExportInfoId { changed } + pub fn get_used(&self, mg: &ModuleGraph, runtime: Option<&RuntimeSpec>) -> UsageState { + let export_info = mg.get_export_info_by_id(self); + export_info.get_used(runtime) + } + pub fn set_used_name(&self, mg: &mut ModuleGraph, name: JsWord) { mg.get_export_info_mut_by_id(self).set_used_name(name) } @@ -1364,7 +1371,6 @@ impl ExportInfo { ); let new_exports_info = ExportsInfo::new(other_exports_info.id, side_effects_only_info.id); let new_exports_info_id = new_exports_info.id; - mg.exports_info_map .insert(new_exports_info_id, new_exports_info); mg.export_info_map diff --git a/crates/rspack_core/src/module.rs b/crates/rspack_core/src/module.rs index 88bbbfb7623..7bda5018f72 100644 --- a/crates/rspack_core/src/module.rs +++ b/crates/rspack_core/src/module.rs @@ -4,6 +4,7 @@ use std::path::PathBuf; use std::{any::Any, borrow::Cow, fmt::Debug}; use async_trait::async_trait; +use json::JsonValue; use rspack_error::{IntoTWithDiagnosticArray, Result, TWithDiagnosticArray}; use rspack_hash::{RspackHash, RspackHashDigest}; use rspack_identifier::{Identifiable, Identifier}; @@ -47,6 +48,7 @@ pub struct BuildInfo { pub harmony_named_exports: HashSet, pub all_star_exports: Vec, pub need_create_require: bool, + pub json_data: Option, } #[derive(Debug, Default, Clone, Hash, PartialEq, Eq)] diff --git a/crates/rspack_core/src/utils/visitor.rs b/crates/rspack_core/src/utils/visitor.rs index c1af8e246fd..2ef29ddccfd 100644 --- a/crates/rspack_core/src/utils/visitor.rs +++ b/crates/rspack_core/src/utils/visitor.rs @@ -194,6 +194,12 @@ pub fn extract_member_expression_chain<'e, T: Into>>( }) = expr.prop { members.push_front((val.value.clone(), val.span.ctxt)); + } else if let MemberProp::Computed(ComputedPropName { + expr: box Expr::Lit(Lit::Num(ref val)), + .. + }) = expr.prop + { + members.push_front((val.value.to_string().into(), val.span.ctxt)); } else if let MemberProp::Ident(ref ident) = expr.prop { members.push_front((ident.sym.clone(), ident.span.ctxt)); members_spans.push_front(ident.span); diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_import_specifier_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_import_specifier_dependency.rs index 5432810fd00..fcbe6c17976 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_import_specifier_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_import_specifier_dependency.rs @@ -262,15 +262,7 @@ impl ModuleDependency for HarmonyImportSpecifierDependency { } fn get_condition(&self) -> Option { - // dbg!( - // &self.ids, - // &self.specifier, - // self.request(), - // self.used_by_exports.as_ref() - // ); - let ret = get_dependency_used_by_exports_condition(self.id, self.used_by_exports.as_ref()); - // dbg!(&ret); - ret + get_dependency_used_by_exports_condition(self.id, self.used_by_exports.as_ref()) } fn get_referenced_exports( diff --git a/crates/rspack_plugin_javascript/src/visitors/dependency/harmony_import_dependency_scanner.rs b/crates/rspack_plugin_javascript/src/visitors/dependency/harmony_import_dependency_scanner.rs index 6de5af431ac..3566a685a06 100644 --- a/crates/rspack_plugin_javascript/src/visitors/dependency/harmony_import_dependency_scanner.rs +++ b/crates/rspack_plugin_javascript/src/visitors/dependency/harmony_import_dependency_scanner.rs @@ -510,7 +510,6 @@ impl Visit for HarmonyImportRefDependencyScanner<'_> { .map(|item| item.0.clone()) .collect::>(), ); - // dbg!(&ids); self .rewrite_usage_span .insert(member_expr.span, ExtraSpanInfo::ReWriteUsedByExports); diff --git a/crates/rspack_plugin_json/src/json_exports_dependency.rs b/crates/rspack_plugin_json/src/json_exports_dependency.rs new file mode 100644 index 00000000000..6a77b98a0bc --- /dev/null +++ b/crates/rspack_plugin_json/src/json_exports_dependency.rs @@ -0,0 +1,129 @@ +use json::JsonValue; +use rspack_core::{ + AsContextDependency, AsModuleDependency, ConnectionState, Dependency, DependencyId, + DependencyTemplate, ExportNameOrSpec, ExportSpec, ExportsOfExportsSpec, ExportsSpec, ModuleGraph, + ModuleIdentifier, TemplateContext, TemplateReplaceSource, UsageState, UsedByExports, UsedName, +}; +#[derive(Debug, Clone)] +pub struct JsonExportsDependency { + id: DependencyId, + data: JsonValue, +} + +impl JsonExportsDependency { + pub fn new(data: JsonValue) -> Self { + Self { + data, + id: DependencyId::new(), + } + } +} + +impl Dependency for JsonExportsDependency { + fn id(&self) -> &rspack_core::DependencyId { + &self.id + } + + fn dependency_debug_name(&self) -> &'static str { + "JsonExportsDependency" + } + + fn get_exports(&self, _mg: &ModuleGraph) -> Option { + Some(ExportsSpec { + exports: get_exports_from_data(&self.data).unwrap_or(ExportsOfExportsSpec::Null), + ..Default::default() + }) + } +} + +impl AsModuleDependency for JsonExportsDependency {} +impl AsContextDependency for JsonExportsDependency {} + +impl DependencyTemplate for JsonExportsDependency { + fn apply( + &self, + source: &mut TemplateReplaceSource, + code_generatable_context: &mut TemplateContext, + ) { + } +} + +fn get_exports_from_data(data: &JsonValue) -> Option { + let data = data; + let ret = match data { + JsonValue::Null + | JsonValue::Short(_) + | JsonValue::String(_) + | JsonValue::Number(_) + | JsonValue::Boolean(_) => { + return None; + } + JsonValue::Object(obj) => ExportsOfExportsSpec::Array( + obj + .iter() + .map(|(k, v)| { + ExportNameOrSpec::ExportSpec(ExportSpec { + name: k.into(), + can_mangle: Some(true), + exports: get_exports_from_data(v).map(|item| match item { + ExportsOfExportsSpec::True => unreachable!(), + ExportsOfExportsSpec::Null => unreachable!(), + ExportsOfExportsSpec::Array(arr) => arr, + }), + ..Default::default() + }) + }) + .collect::>(), + ), + JsonValue::Array(arr) => { + if arr.len() > 100 { + return None; + } + ExportsOfExportsSpec::Array( + arr + .iter() + .enumerate() + .map(|(i, item)| { + ExportNameOrSpec::ExportSpec(ExportSpec { + name: format!("{i}").into(), + can_mangle: Some(true), + exports: get_exports_from_data(item).map(|item| match item { + ExportsOfExportsSpec::True | ExportsOfExportsSpec::Null => unreachable!(), + ExportsOfExportsSpec::Array(arr) => arr, + }), + ..Default::default() + }) + }) + .collect::>(), + ) + } + }; + Some(ret) +} + +// const getExportsFromData = data => { +// if (data && typeof data === "object") { +// if (Array.isArray(data)) { +// return data.length < 100 +// ? data.map((item, idx) => { +// return { +// name: `${idx}`, +// canMangle: true, +// exports: getExportsFromData(item) +// }; +// }) +// : undefined; +// } else { +// const exports = []; +// for (const key of Object.keys(data)) { +// exports.push({ +// name: key, +// canMangle: true, +// exports: getExportsFromData(data[key]) +// }); +// } +// return exports; +// } +// } +// return undefined; +// }; diff --git a/crates/rspack_plugin_json/src/lib.rs b/crates/rspack_plugin_json/src/lib.rs index 227dc71c068..af265ba67e0 100644 --- a/crates/rspack_plugin_json/src/lib.rs +++ b/crates/rspack_plugin_json/src/lib.rs @@ -1,16 +1,25 @@ -use json::Error::{ - ExceededDepthLimit, FailedUtf8Parsing, UnexpectedCharacter, UnexpectedEndOfJson, WrongType, +#![feature(let_chains)] +use json::{ + Error::{ + ExceededDepthLimit, FailedUtf8Parsing, UnexpectedCharacter, UnexpectedEndOfJson, WrongType, + }, + JsonValue, }; use rspack_core::{ + async_module_factory, rspack_sources::{BoxSource, RawSource, Source, SourceExt}, - BuildMetaDefaultObject, BuildMetaExportsType, CompilerOptions, GenerateContext, Module, - ParserAndGenerator, Plugin, RuntimeGlobals, SourceType, + BuildMetaDefaultObject, BuildMetaExportsType, CompilerOptions, ExportsInfo, GenerateContext, + Module, ModuleGraph, ParserAndGenerator, Plugin, RuntimeGlobals, RuntimeSpec, SourceType, + UsageState, }; use rspack_error::{ internal_error, DiagnosticKind, Error, IntoTWithDiagnosticArray, Result, TWithDiagnosticArray, TraceableError, }; +use crate::json_exports_dependency::JsonExportsDependency; + +mod json_exports_dependency; mod utils; #[derive(Debug)] @@ -92,16 +101,20 @@ impl ParserAndGenerator for JsonParserAndGenerator { } }); - let diagnostics = if let Err(err) = parse_result { - err.into() - } else { - vec![] + let (diagnostics, data) = match parse_result { + Ok(data) => (vec![], Some(data)), + Err(err) => (err.into(), None), }; + build_info.json_data = data.clone(); Ok( rspack_core::ParseResult { presentational_dependencies: vec![], - dependencies: vec![], + dependencies: if let Some(data) = data { + vec![Box::new(JsonExportsDependency::new(data))] + } else { + vec![] + }, blocks: vec![], source: box_source, analyze_result: Default::default(), @@ -115,18 +128,59 @@ impl ParserAndGenerator for JsonParserAndGenerator { fn generate( &self, source: &BoxSource, - _module: &dyn rspack_core::Module, + module: &dyn rspack_core::Module, generate_context: &mut GenerateContext, ) -> Result { + let GenerateContext { + compilation, + module_generator_options, + runtime_requirements, + data, + requested_source_type, + runtime, + } = generate_context; match generate_context.requested_source_type { SourceType::JavaScript => { generate_context .runtime_requirements .insert(RuntimeGlobals::MODULE); + let mgm = compilation + .module_graph + .module_graph_module_by_identifier(&module.identifier()) + .expect("should have module identifier"); + let json_data = mgm + .build_info + .as_ref() + .and_then(|info| info.json_data.as_ref()) + .expect("should have json data"); + let exports_info = compilation + .module_graph + .get_exports_info(&module.identifier()); + + let final_json = match json_data { + json::JsonValue::Object(_) | json::JsonValue::Array(_) + if exports_info + .other_exports_info + // TODO: runtime opt + .get_export_info(&compilation.module_graph) + .get_used(*runtime) + == UsageState::Unused => + { + create_object_for_exports_info( + json_data.clone(), + exports_info, + *runtime, + &compilation.module_graph, + ) + } + _ => json_data.clone(), + }; + + let json_expr = final_json.to_string(); Ok( RawSource::from(format!( - r#"module.exports = {};"#, - utils::escape_json(&source.source()) + r#"module.exports = {}"#, + utils::escape_json(&json_expr) )) .boxed(), ) @@ -160,3 +214,74 @@ impl Plugin for JsonPlugin { Ok(()) } } + +fn create_object_for_exports_info( + data: JsonValue, + exports_info: &ExportsInfo, + runtime: Option<&RuntimeSpec>, + mg: &ModuleGraph, +) -> JsonValue { + if exports_info.other_exports_info.get_used(mg, runtime) != UsageState::Unused { + return data; + } + + match data { + JsonValue::Null + | JsonValue::Short(_) + | JsonValue::String(_) + | JsonValue::Number(_) + | JsonValue::Boolean(_) => unreachable!(), + JsonValue::Object(mut obj) => { + let mut unused_key = vec![]; + for (key, value) in obj.iter_mut() { + let export_info = exports_info.id.get_read_only_export_info(&key.into(), mg); + let used = export_info.get_used(runtime); + if used == UsageState::Unused { + unused_key.push(key.to_string()); + continue; + } + if used == UsageState::OnlyPropertiesUsed + && let Some(exports_info_id) = export_info.exports_info + { + let exports_info = mg.get_exports_info_by_id(&exports_info_id); + // avoid clone + let temp = std::mem::replace(value, JsonValue::Null); + let ret = create_object_for_exports_info(temp, exports_info, runtime, mg); + *value = ret; + } + } + for k in unused_key { + obj.remove(&k); + } + JsonValue::Object(obj) + } + JsonValue::Array(arr) => JsonValue::Array( + arr + .into_iter() + .enumerate() + .filter_map(|(i, item)| { + let export_info = exports_info + .id + .get_read_only_export_info(&format!("{i}").into(), mg); + let used = export_info.get_used(runtime); + if used == UsageState::Unused { + return None; + } + if used == UsageState::OnlyPropertiesUsed + && let Some(exports_info_id) = export_info.exports_info + { + let exports_info = mg.get_exports_info_by_id(&exports_info_id); + Some(create_object_for_exports_info( + item, + exports_info, + runtime, + mg, + )) + } else { + Some(item) + } + }) + .collect::>(), + ), + } +} From d56128a436fc11679025d582246de6d12392f676 Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Mon, 4 Dec 2023 12:21:53 +0800 Subject: [PATCH 02/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20ck=20point?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/type-assign/index.js | 6 +++++ examples/type-assign/module.js | 1 + examples/type-assign/package.json | 19 ++++++++++++++ examples/type-assign/rspack.config.js | 26 +++++++++++++++++++ examples/type-assign/test.config.js | 5 ++++ webpack-test/ConfigTestCases.template.js | 5 ++++ .../split-chunks/asnyc-entries/test.filter.js | 2 +- 7 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 examples/type-assign/index.js create mode 100644 examples/type-assign/module.js create mode 100644 examples/type-assign/package.json create mode 100644 examples/type-assign/rspack.config.js create mode 100644 examples/type-assign/test.config.js diff --git a/examples/type-assign/index.js b/examples/type-assign/index.js new file mode 100644 index 00000000000..b91b42407c8 --- /dev/null +++ b/examples/type-assign/index.js @@ -0,0 +1,6 @@ +it("should define global object with property", function () { + require("./module"); + expect(MyLibrary["answer"]).toEqual(42); +}); + +export const answer = 42; diff --git a/examples/type-assign/module.js b/examples/type-assign/module.js new file mode 100644 index 00000000000..3918c74e446 --- /dev/null +++ b/examples/type-assign/module.js @@ -0,0 +1 @@ +"use strict"; diff --git a/examples/type-assign/package.json b/examples/type-assign/package.json new file mode 100644 index 00000000000..f4d6c253333 --- /dev/null +++ b/examples/type-assign/package.json @@ -0,0 +1,19 @@ +{ + "name": "example-basic", + "version": "1.0.0", + "description": "", + "main": "index.js", + "private": true, + "scripts": { + "dev": "rspack serve", + "build": "rspack build" + }, + "devDependencies": { + "@rspack/cli": "workspace:*", + "@rspack/core": "workspace:*" + }, + "sideEffects": false, + "keywords": [], + "author": "", + "license": "MIT" +} diff --git a/examples/type-assign/rspack.config.js b/examples/type-assign/rspack.config.js new file mode 100644 index 00000000000..782aeee2910 --- /dev/null +++ b/examples/type-assign/rspack.config.js @@ -0,0 +1,26 @@ +/** @type {import("@rspack/core").Configuration} */ +module.exports = { + output: { + library: { + name: "MyLibrary", + type: "assign", + }, + }, + experiments: { + rspackFuture: { + newTreeshaking: true + } + }, + + optimization: { + sideEffects: true, + innerGraph: true, + providedExports: true, + usedExports: true, + moduleIds: 'named' + }, + builtins: { + treeShaking: false, + }, + entry: "./index.js", +}; diff --git a/examples/type-assign/test.config.js b/examples/type-assign/test.config.js new file mode 100644 index 00000000000..79a079487a5 --- /dev/null +++ b/examples/type-assign/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + afterExecute() { + delete global.MyLibrary; + } +}; diff --git a/webpack-test/ConfigTestCases.template.js b/webpack-test/ConfigTestCases.template.js index 3d620da1885..108248457a8 100644 --- a/webpack-test/ConfigTestCases.template.js +++ b/webpack-test/ConfigTestCases.template.js @@ -111,6 +111,11 @@ const describeCases = config => { newTreeshaking: true } } + + if (options?.experiments?.rspackFuture?.newTreeshaking) { + options.builtins = options.builtins || {} + options.builtins.treeShaking = false; + } // if (options.optimization.minimizer === undefined) { // options.optimization.minimizer = [ // new (require("terser-webpack-plugin"))({ diff --git a/webpack-test/configCases/split-chunks/asnyc-entries/test.filter.js b/webpack-test/configCases/split-chunks/asnyc-entries/test.filter.js index ea561e9f59e..fed7caa7b92 100644 --- a/webpack-test/configCases/split-chunks/asnyc-entries/test.filter.js +++ b/webpack-test/configCases/split-chunks/asnyc-entries/test.filter.js @@ -1 +1 @@ -module.exports = () => 'block by treeshaking issue https://github.com/web-infra-dev/rspack/issues/4336' +module.exports = () => false From 774db303390efd253121975d403e0773e2a90870 Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Mon, 4 Dec 2023 13:31:38 +0800 Subject: [PATCH 03/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20ck=20points?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/rspack_core/src/compiler/compilation.rs | 2 +- crates/rspack_core/src/exports_info.rs | 1 + .../esm/harmony_export_specifier_dependency.rs | 1 + .../rspack_plugin_library/src/assign_library_plugin.rs | 6 ++++-- examples/type-assign/rspack.config.js | 3 ++- examples/type-assign/test.config.js | 5 ----- packages/rspack-dev-server/src/server.ts | 1 + pnpm-lock.yaml | 9 +++++++++ 8 files changed, 19 insertions(+), 9 deletions(-) delete mode 100644 examples/type-assign/test.config.js diff --git a/crates/rspack_core/src/compiler/compilation.rs b/crates/rspack_core/src/compiler/compilation.rs index 63ab5c4a528..961503609f3 100644 --- a/crates/rspack_core/src/compiler/compilation.rs +++ b/crates/rspack_core/src/compiler/compilation.rs @@ -1274,7 +1274,7 @@ impl Compilation { while plugin_driver.optimize_dependencies(self).await?.is_some() {} logger.time_end(start); if self.options.is_new_tree_shaking() { - // debug_all_exports_info!(&self.module_graph); + debug_all_exports_info!(&self.module_graph); } // if self.options.is_new_tree_shaking() { diff --git a/crates/rspack_core/src/exports_info.rs b/crates/rspack_core/src/exports_info.rs index bb951d73e2a..cbc1e72e158 100644 --- a/crates/rspack_core/src/exports_info.rs +++ b/crates/rspack_core/src/exports_info.rs @@ -356,6 +356,7 @@ impl ExportsInfoId { match name { UsedName::Str(name) => { let info = self.get_read_only_export_info(&name, mg); + dbg!(&info, &name); info.get_used_name(&name, runtime).map(UsedName::Str) } UsedName::Vec(names) => { diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_specifier_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_specifier_dependency.rs index eb701679fa2..710b683dc84 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_specifier_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_specifier_dependency.rs @@ -88,6 +88,7 @@ impl DependencyTemplate for HarmonyExportSpecifierDependency { .module_graph .get_exports_info(&module.identifier()) .id; + dbg!(&self.name); let used_name = exports_info_id.get_used_name( &compilation.module_graph, *runtime, diff --git a/crates/rspack_plugin_library/src/assign_library_plugin.rs b/crates/rspack_plugin_library/src/assign_library_plugin.rs index fee88a32b10..925765172dc 100644 --- a/crates/rspack_plugin_library/src/assign_library_plugin.rs +++ b/crates/rspack_plugin_library/src/assign_library_plugin.rs @@ -4,8 +4,8 @@ use once_cell::sync::Lazy; use regex::Regex; use rspack_core::tree_shaking::webpack_ext::ExportInfoExt; use rspack_core::{ - property_access, ChunkUkey, EntryData, LibraryExport, LibraryName, LibraryNonUmdObject, - UsageState, + debug_all_exports_info, debug_exports_info, property_access, ChunkUkey, EntryData, LibraryExport, + LibraryName, LibraryNonUmdObject, UsageState, }; use rspack_core::{ rspack_sources::{ConcatSource, RawSource, SourceExt}, @@ -233,6 +233,8 @@ impl Plugin for AssignLibraryPlugin { exports_info_id.set_used_in_unknown_way(&mut compilation.module_graph, Some(&runtime)); } } + + debug_all_exports_info!(&compilation.module_graph); Ok(()) } diff --git a/examples/type-assign/rspack.config.js b/examples/type-assign/rspack.config.js index 782aeee2910..fe3fa7979b2 100644 --- a/examples/type-assign/rspack.config.js +++ b/examples/type-assign/rspack.config.js @@ -17,7 +17,8 @@ module.exports = { innerGraph: true, providedExports: true, usedExports: true, - moduleIds: 'named' + moduleIds: 'named', + minimize: false }, builtins: { treeShaking: false, diff --git a/examples/type-assign/test.config.js b/examples/type-assign/test.config.js deleted file mode 100644 index 79a079487a5..00000000000 --- a/examples/type-assign/test.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - afterExecute() { - delete global.MyLibrary; - } -}; diff --git a/packages/rspack-dev-server/src/server.ts b/packages/rspack-dev-server/src/server.ts index e4d9b41e157..8fdd648a858 100644 --- a/packages/rspack-dev-server/src/server.ts +++ b/packages/rspack-dev-server/src/server.ts @@ -1,3 +1,4 @@ +// @ts-nocheck /** * The following code is modified based on * https://github.com/webpack/webpack-dev-server/blob/b0f15ace0123c125d5870609ef4691c141a6d187/lib/Server.js diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2df4a6c601e..9ac4ce51c51 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1176,6 +1176,15 @@ importers: specifier: 3.3.1 version: 3.3.1(postcss@8.4.21) + examples/type-assign: + devDependencies: + '@rspack/cli': + specifier: workspace:* + version: link:../../packages/rspack-cli + '@rspack/core': + specifier: workspace:* + version: link:../../packages/rspack + examples/vue: dependencies: vue: From 31fab4d2c082a99215dab20c6be9dceebbd16dbf Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Mon, 4 Dec 2023 17:06:25 +0800 Subject: [PATCH 04/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20ck=20point?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tree-shaking/basic/snapshot/snap.diff | 10 ++-- .../rspack_core/src/compiler/compilation.rs | 6 +-- .../plugin/flag_dependency_exports_plugin.rs | 49 ++++++++++--------- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/crates/rspack/tests/tree-shaking/basic/snapshot/snap.diff b/crates/rspack/tests/tree-shaking/basic/snapshot/snap.diff index 14de4d94cef..af1e0937532 100644 --- a/crates/rspack/tests/tree-shaking/basic/snapshot/snap.diff +++ b/crates/rspack/tests/tree-shaking/basic/snapshot/snap.diff @@ -1,6 +1,6 @@ --- expected +++ actual -@@ -3,30 +3,20 @@ +@@ -3,30 +3,16 @@ --- ```js title=main.js (self['webpackChunkwebpack'] = self['webpackChunkwebpack'] || []).push([["main"], { @@ -19,7 +19,7 @@ +/* harmony import */var _a_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a.json */"./a.json"); -_lib__WEBPACK_IMPORTED_MODULE_0__.answer; -+_a_json__WEBPACK_IMPORTED_MODULE_0__.a; ++_a_json__WEBPACK_IMPORTED_MODULE_0__["2"].a; }), -"./lib.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { +"./a.json": (function (module, exports, __webpack_require__) { @@ -31,11 +31,7 @@ -/* harmony import */var _answer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./answer */"./answer.js"); - -}), -+module.exports = { -+ "a": "soemthing", -+ "b": "bbbb" -+} -+;}), ++module.exports = [{"a":1}]}), },function(__webpack_require__) { var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId) } diff --git a/crates/rspack_core/src/compiler/compilation.rs b/crates/rspack_core/src/compiler/compilation.rs index 961503609f3..32c7eb7c53c 100644 --- a/crates/rspack_core/src/compiler/compilation.rs +++ b/crates/rspack_core/src/compiler/compilation.rs @@ -1269,13 +1269,13 @@ impl Compilation { // https://github.com/webpack/webpack/blob/main/lib/Compilation.js#L2809 plugin_driver.seal(self)?; + if self.options.is_new_tree_shaking() { + debug_all_exports_info!(&self.module_graph); + } let start = logger.time("optimize dependencies"); // https://github.com/webpack/webpack/blob/d15c73469fd71cf98734685225250148b68ddc79/lib/Compilation.js#L2812-L2814 while plugin_driver.optimize_dependencies(self).await?.is_some() {} logger.time_end(start); - if self.options.is_new_tree_shaking() { - debug_all_exports_info!(&self.module_graph); - } // if self.options.is_new_tree_shaking() { // debug_all_exports_info!(&self.module_graph); diff --git a/crates/rspack_plugin_javascript/src/plugin/flag_dependency_exports_plugin.rs b/crates/rspack_plugin_javascript/src/plugin/flag_dependency_exports_plugin.rs index 3b5afa02daf..cc29ec845ee 100644 --- a/crates/rspack_plugin_javascript/src/plugin/flag_dependency_exports_plugin.rs +++ b/crates/rspack_plugin_javascript/src/plugin/flag_dependency_exports_plugin.rs @@ -35,34 +35,39 @@ impl<'a> FlagDependencyExportsProxy<'a> { let module_graph_modules = std::mem::take(&mut self.mg.module_identifier_to_module_graph_module); for mgm in module_graph_modules.values() { - let exports_id = mgm.exports; - let is_module_without_exports = if let Some(ref build_meta) = mgm.build_meta { - build_meta.exports_type == BuildMetaExportsType::Unset - } else { - true - } && { - let exports_info = self.mg.get_exports_info_by_id(&exports_id); - let other_exports_info_id = exports_info.other_exports_info; - let other_exports_info = self.mg.get_export_info_by_id(&other_exports_info_id); - other_exports_info.provided.is_some() - }; - - // TODO: mem cache - exports_id.set_has_provide_info(self.mg); - q.push_back(mgm.module_identifier); - if is_module_without_exports { - exports_id.set_unknown_exports_provided(self.mg, false, None, None, None, None); + let exports_info_id = mgm.exports; + let is_module_without_exports = mgm + .build_meta + .as_ref() + .map(|build_meta| build_meta.exports_type == BuildMetaExportsType::Unset) + .unwrap_or(true); + if is_module_without_exports + && !matches!( + exports_info_id + .get_exports_info(self.mg) + .other_exports_info + .get_export_info(self.mg) + .provided, + Some(ExportInfoProvided::Null) + ) + { + exports_info_id.set_has_provide_info(self.mg); + exports_info_id.set_unknown_exports_provided(self.mg, false, None, None, None, None); + continue; } + q.push_back(mgm.module_identifier); + exports_info_id.set_has_provide_info(self.mg); + // TODO: mem cache } self.mg.module_identifier_to_module_graph_module = module_graph_modules; while let Some(module_id) = q.pop_back() { self.changed = false; self.current_module_id = module_id; - let mut exports_specs_from_dependencies: HashMap = + let mut exports_specs_of_dependencies: HashMap = HashMap::default(); - self.process_dependencies_block(&module_id, &mut exports_specs_from_dependencies); + self.process_dependencies_block(&module_id, &mut exports_specs_of_dependencies); let exports_info_id = self.mg.get_exports_info(&module_id).id; - for (dep_id, exports_spec) in exports_specs_from_dependencies.into_iter() { + for (dep_id, exports_spec) in exports_specs_of_dependencies.into_iter() { self.process_exports_spec(dep_id, exports_spec, exports_info_id); } if self.changed { @@ -72,8 +77,8 @@ impl<'a> FlagDependencyExportsProxy<'a> { } pub fn notify_dependencies(&mut self, q: &mut VecDeque) { - if let Some(set) = self.dependencies.get(&self.current_module_id) { - for mi in set.iter() { + if let Some(deps) = self.dependencies.get(&self.current_module_id) { + for mi in deps.iter() { q.push_back(*mi); } } From 6ff3087ce8aad354319331522c278b112260bc72 Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Tue, 5 Dec 2023 02:23:52 +0800 Subject: [PATCH 05/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20partial=20runtime?= =?UTF-8?q?=20opt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/rspack_core/src/compiler/compilation.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/rspack_core/src/compiler/compilation.rs b/crates/rspack_core/src/compiler/compilation.rs index 32c7eb7c53c..f5f3b203f6e 100644 --- a/crates/rspack_core/src/compiler/compilation.rs +++ b/crates/rspack_core/src/compiler/compilation.rs @@ -1269,9 +1269,6 @@ impl Compilation { // https://github.com/webpack/webpack/blob/main/lib/Compilation.js#L2809 plugin_driver.seal(self)?; - if self.options.is_new_tree_shaking() { - debug_all_exports_info!(&self.module_graph); - } let start = logger.time("optimize dependencies"); // https://github.com/webpack/webpack/blob/d15c73469fd71cf98734685225250148b68ddc79/lib/Compilation.js#L2812-L2814 while plugin_driver.optimize_dependencies(self).await?.is_some() {} From 9620b3d4f7c9918c1afc0a85af2c64afcbcec82e Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Thu, 7 Dec 2023 00:38:20 +0800 Subject: [PATCH 06/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20rebase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/rspack_core/src/exports_info.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/crates/rspack_core/src/exports_info.rs b/crates/rspack_core/src/exports_info.rs index cbc1e72e158..869a0268172 100644 --- a/crates/rspack_core/src/exports_info.rs +++ b/crates/rspack_core/src/exports_info.rs @@ -820,11 +820,6 @@ impl ExportInfoId { changed } - pub fn get_used(&self, mg: &ModuleGraph, runtime: Option<&RuntimeSpec>) -> UsageState { - let export_info = mg.get_export_info_by_id(self); - export_info.get_used(runtime) - } - pub fn set_used_name(&self, mg: &mut ModuleGraph, name: JsWord) { mg.get_export_info_mut_by_id(self).set_used_name(name) } From c6ac9a682d90901c1dcadebbf6f0a38397850dee Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Thu, 7 Dec 2023 13:03:16 +0800 Subject: [PATCH 07/18] =?UTF-8?q?fix:=20=F0=9F=90=9B=20mangle=20issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/node_binding/binding.d.ts | 15 ------------ crates/rspack/tests/fixtures.rs | 9 +++++++ crates/rspack/tests/tree-shaking/basic/a.json | 15 +++++++++++- .../rspack/tests/tree-shaking/basic/index.js | 2 +- .../basic/snapshot/new_treeshaking.snap | 4 ++-- .../basic/snapshot/new_treeshaking.snap.new | 24 +++++++++++++++++++ .../tests/tree-shaking/basic/test.config.json | 3 ++- crates/rspack_plugin_json/src/lib.rs | 23 +++++++++++------- .../cases/json/import-by-name/test.filter.js | 4 ++-- .../cases/json/import-by-name/warnings.js | 17 ------------- 10 files changed, 69 insertions(+), 47 deletions(-) create mode 100644 crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap.new delete mode 100644 webpack-test/cases/json/import-by-name/warnings.js diff --git a/crates/node_binding/binding.d.ts b/crates/node_binding/binding.d.ts index 70b8cc2e567..0a23df8fd3e 100644 --- a/crates/node_binding/binding.d.ts +++ b/crates/node_binding/binding.d.ts @@ -492,13 +492,6 @@ export interface JsStatsWarning { formatted: string } -export interface NodeFS { - writeFile: (...args: any[]) => any - removeFile: (...args: any[]) => any - mkdir: (...args: any[]) => any - mkdirp: (...args: any[]) => any -} - export interface PathData { filename?: string hash?: string @@ -1179,11 +1172,3 @@ export function registerGlobalTrace(filter: string, layer: "chrome" | "logger", /** Builtin loader runner */ export function runBuiltinLoader(builtin: string, options: string | undefined | null, loaderContext: JsLoaderContext): Promise -export interface ThreadsafeNodeFS { - writeFile: (...args: any[]) => any - removeFile: (...args: any[]) => any - mkdir: (...args: any[]) => any - mkdirp: (...args: any[]) => any - removeDirAll: (...args: any[]) => any -} - diff --git a/crates/rspack/tests/fixtures.rs b/crates/rspack/tests/fixtures.rs index 4ef335e073a..be4f70aaa38 100644 --- a/crates/rspack/tests/fixtures.rs +++ b/crates/rspack/tests/fixtures.rs @@ -67,6 +67,15 @@ fn tree_shaking(fixture_path: PathBuf) { } plugins.push(Box::::default()); plugins.push(Box::::default()); + if options.optimization.mangle_exports.is_enable() { + plugins.push( + MangleExportsPlugin::new(!matches!( + options.optimization.mangle_exports, + MangleExportsOption::Size + )) + .boxed(), + ); + } }, ), Some("new_treeshaking".to_string()), diff --git a/crates/rspack/tests/tree-shaking/basic/a.json b/crates/rspack/tests/tree-shaking/basic/a.json index 24091602266..748ff4bab4f 100644 --- a/crates/rspack/tests/tree-shaking/basic/a.json +++ b/crates/rspack/tests/tree-shaking/basic/a.json @@ -1,3 +1,16 @@ [ - 1, 2, {"a": 1, "b": 2} + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 12 ] diff --git a/crates/rspack/tests/tree-shaking/basic/index.js b/crates/rspack/tests/tree-shaking/basic/index.js index eb6387bd19a..1a1efc6a213 100644 --- a/crates/rspack/tests/tree-shaking/basic/index.js +++ b/crates/rspack/tests/tree-shaking/basic/index.js @@ -1,4 +1,4 @@ import a from "./a.json"; -a[2].a +a[13] diff --git a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap index 7aa6cf8421f..f57b20d4c8d 100644 --- a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap +++ b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap @@ -8,11 +8,11 @@ source: crates/rspack_testing/src/run_fixture.rs __webpack_require__.r(__webpack_exports__); /* harmony import */var _a_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a.json */"./a.json"); -_a_json__WEBPACK_IMPORTED_MODULE_0__["2"].a; +_a_json__WEBPACK_IMPORTED_MODULE_0__["default"]; }), "./a.json": (function (module, exports, __webpack_require__) { "use strict"; -module.exports = [{"a":1}]}), +module.exports = {}}), },function(__webpack_require__) { var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId) } diff --git a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap.new b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap.new new file mode 100644 index 00000000000..fcb17a4dcd1 --- /dev/null +++ b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap.new @@ -0,0 +1,24 @@ +--- +source: crates/rspack_testing/src/run_fixture.rs +assertion_line: 146 +--- +```js title=main.js +(self['webpackChunkwebpack'] = self['webpackChunkwebpack'] || []).push([["main"], { +"./index.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */var _a_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a.json */"./a.json"); + +_a_json__WEBPACK_IMPORTED_MODULE_0__["13"]; +}), +"./a.json": (function (module, exports, __webpack_require__) { +"use strict"; +module.exports = [12]}), + +},function(__webpack_require__) { +var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId) } +var __webpack_exports__ = (__webpack_exec__("./index.js")); + +} +]); +``` diff --git a/crates/rspack/tests/tree-shaking/basic/test.config.json b/crates/rspack/tests/tree-shaking/basic/test.config.json index 97825ad89d3..b2dceaab125 100644 --- a/crates/rspack/tests/tree-shaking/basic/test.config.json +++ b/crates/rspack/tests/tree-shaking/basic/test.config.json @@ -1,6 +1,7 @@ { "optimization": { - "sideEffects": "true" + "sideEffects": "true", + "mangleExports": "true" }, "builtins": { "treeShaking": "true", diff --git a/crates/rspack_plugin_json/src/lib.rs b/crates/rspack_plugin_json/src/lib.rs index af265ba67e0..eeaff4889a9 100644 --- a/crates/rspack_plugin_json/src/lib.rs +++ b/crates/rspack_plugin_json/src/lib.rs @@ -1,5 +1,6 @@ #![feature(let_chains)] use json::{ + object::Object, Error::{ ExceededDepthLimit, FailedUtf8Parsing, UnexpectedCharacter, UnexpectedEndOfJson, WrongType, }, @@ -232,28 +233,34 @@ fn create_object_for_exports_info( | JsonValue::Number(_) | JsonValue::Boolean(_) => unreachable!(), JsonValue::Object(mut obj) => { - let mut unused_key = vec![]; + let mut used_pair = vec![]; for (key, value) in obj.iter_mut() { let export_info = exports_info.id.get_read_only_export_info(&key.into(), mg); let used = export_info.get_used(runtime); if used == UsageState::Unused { - unused_key.push(key.to_string()); continue; } - if used == UsageState::OnlyPropertiesUsed + let new_value = if used == UsageState::OnlyPropertiesUsed && let Some(exports_info_id) = export_info.exports_info { let exports_info = mg.get_exports_info_by_id(&exports_info_id); // avoid clone let temp = std::mem::replace(value, JsonValue::Null); let ret = create_object_for_exports_info(temp, exports_info, runtime, mg); - *value = ret; - } + ret + } else { + std::mem::replace(value, JsonValue::Null) + }; + let used_name = export_info + .get_used_name(&key.into(), runtime) + .expect("should have used name"); + used_pair.push((used_name, new_value)); } - for k in unused_key { - obj.remove(&k); + let mut new_obj = Object::new(); + for (k, v) in used_pair { + new_obj.insert(&k, v); } - JsonValue::Object(obj) + JsonValue::Object(new_obj) } JsonValue::Array(arr) => JsonValue::Array( arr diff --git a/webpack-test/cases/json/import-by-name/test.filter.js b/webpack-test/cases/json/import-by-name/test.filter.js index 2735e947c45..ad8d560b5ac 100644 --- a/webpack-test/cases/json/import-by-name/test.filter.js +++ b/webpack-test/cases/json/import-by-name/test.filter.js @@ -1,4 +1,4 @@ -module.exports = () => {return "https://github.com/web-infra-dev/rspack/issues/4323"} +module.exports = () => {return true} + - \ No newline at end of file diff --git a/webpack-test/cases/json/import-by-name/warnings.js b/webpack-test/cases/json/import-by-name/warnings.js deleted file mode 100644 index 82fc687d927..00000000000 --- a/webpack-test/cases/json/import-by-name/warnings.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = [ - [ - /Should not import the named export '2' \(imported as 'c'\) from default-exporting module \(only default export is available soon\)/ - ], - [ - /Should not import the named export 'aa' \(imported as 'aa'\) from default-exporting module \(only default export is available soon\)/ - ], - [ - /Should not import the named export 'bb' \(imported as 'bb'\) from default-exporting module \(only default export is available soon\)/ - ], - [ - /Should not import the named export 'named' \(imported as 'named'\) from default-exporting module \(only default export is available soon\)/ - ], - [ - /Should not import the named export 'named' \(imported as 'gnamed'\) from default-exporting module \(only default export is available soon\)/ - ] -]; From ffbd67564b16a28db6164956a7040d77edafca21 Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Thu, 7 Dec 2023 16:11:37 +0800 Subject: [PATCH 08/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/node_binding/binding.d.ts | 15 +++++++ crates/rspack/tests/tree-shaking/basic/a.json | 17 +------ .../rspack/tests/tree-shaking/basic/index.js | 2 +- .../basic/snapshot/new_treeshaking.snap.new | 4 +- .../rspack_core/src/compiler/compilation.rs | 2 +- crates/rspack_core/src/exports_info.rs | 1 - .../harmony_export_specifier_dependency.rs | 1 - .../harmony_import_dependency_scanner.rs | 1 + .../src/json_exports_dependency.rs | 11 +++-- crates/rspack_plugin_json/src/lib.rs | 45 +++++++++++++------ .../src/assign_library_plugin.rs | 5 +-- 11 files changed, 59 insertions(+), 45 deletions(-) diff --git a/crates/node_binding/binding.d.ts b/crates/node_binding/binding.d.ts index 0a23df8fd3e..70b8cc2e567 100644 --- a/crates/node_binding/binding.d.ts +++ b/crates/node_binding/binding.d.ts @@ -492,6 +492,13 @@ export interface JsStatsWarning { formatted: string } +export interface NodeFS { + writeFile: (...args: any[]) => any + removeFile: (...args: any[]) => any + mkdir: (...args: any[]) => any + mkdirp: (...args: any[]) => any +} + export interface PathData { filename?: string hash?: string @@ -1172,3 +1179,11 @@ export function registerGlobalTrace(filter: string, layer: "chrome" | "logger", /** Builtin loader runner */ export function runBuiltinLoader(builtin: string, options: string | undefined | null, loaderContext: JsLoaderContext): Promise +export interface ThreadsafeNodeFS { + writeFile: (...args: any[]) => any + removeFile: (...args: any[]) => any + mkdir: (...args: any[]) => any + mkdirp: (...args: any[]) => any + removeDirAll: (...args: any[]) => any +} + diff --git a/crates/rspack/tests/tree-shaking/basic/a.json b/crates/rspack/tests/tree-shaking/basic/a.json index 748ff4bab4f..12bae17cf72 100644 --- a/crates/rspack/tests/tree-shaking/basic/a.json +++ b/crates/rspack/tests/tree-shaking/basic/a.json @@ -1,16 +1 @@ -[ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 12 -] +[1, 2, 3, 4] diff --git a/crates/rspack/tests/tree-shaking/basic/index.js b/crates/rspack/tests/tree-shaking/basic/index.js index 1a1efc6a213..2ac85d60cf0 100644 --- a/crates/rspack/tests/tree-shaking/basic/index.js +++ b/crates/rspack/tests/tree-shaking/basic/index.js @@ -1,4 +1,4 @@ import a from "./a.json"; -a[13] +a[2] diff --git a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap.new b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap.new index fcb17a4dcd1..c2d93d4981d 100644 --- a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap.new +++ b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap.new @@ -9,11 +9,11 @@ assertion_line: 146 __webpack_require__.r(__webpack_exports__); /* harmony import */var _a_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a.json */"./a.json"); -_a_json__WEBPACK_IMPORTED_MODULE_0__["13"]; +_a_json__WEBPACK_IMPORTED_MODULE_0__["2"]; }), "./a.json": (function (module, exports, __webpack_require__) { "use strict"; -module.exports = [12]}), +module.exports = [0,0,3]}), },function(__webpack_require__) { var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId) } diff --git a/crates/rspack_core/src/compiler/compilation.rs b/crates/rspack_core/src/compiler/compilation.rs index f5f3b203f6e..1e93dc494aa 100644 --- a/crates/rspack_core/src/compiler/compilation.rs +++ b/crates/rspack_core/src/compiler/compilation.rs @@ -31,7 +31,7 @@ use super::{ use crate::{ build_chunk_graph::build_chunk_graph, cache::{use_code_splitting_cache, Cache, CodeSplittingCache}, - debug_all_exports_info, is_source_equal, + is_source_equal, tree_shaking::{optimizer, visitor::SymbolRef, BailoutFlag, OptimizeDependencyResult}, AddQueue, AddTask, AddTaskResult, AdditionalChunkRuntimeRequirementsArgs, AdditionalModuleRequirementsArgs, AsyncDependenciesBlock, BoxDependency, BoxModule, BuildQueue, diff --git a/crates/rspack_core/src/exports_info.rs b/crates/rspack_core/src/exports_info.rs index 869a0268172..42a2428ea57 100644 --- a/crates/rspack_core/src/exports_info.rs +++ b/crates/rspack_core/src/exports_info.rs @@ -356,7 +356,6 @@ impl ExportsInfoId { match name { UsedName::Str(name) => { let info = self.get_read_only_export_info(&name, mg); - dbg!(&info, &name); info.get_used_name(&name, runtime).map(UsedName::Str) } UsedName::Vec(names) => { diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_specifier_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_specifier_dependency.rs index 710b683dc84..eb701679fa2 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_specifier_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_specifier_dependency.rs @@ -88,7 +88,6 @@ impl DependencyTemplate for HarmonyExportSpecifierDependency { .module_graph .get_exports_info(&module.identifier()) .id; - dbg!(&self.name); let used_name = exports_info_id.get_used_name( &compilation.module_graph, *runtime, diff --git a/crates/rspack_plugin_javascript/src/visitors/dependency/harmony_import_dependency_scanner.rs b/crates/rspack_plugin_javascript/src/visitors/dependency/harmony_import_dependency_scanner.rs index 3566a685a06..72965c6d5e7 100644 --- a/crates/rspack_plugin_javascript/src/visitors/dependency/harmony_import_dependency_scanner.rs +++ b/crates/rspack_plugin_javascript/src/visitors/dependency/harmony_import_dependency_scanner.rs @@ -595,6 +595,7 @@ mod test { harmony_named_exports: Default::default(), all_star_exports: Default::default(), need_create_require: false, + json_data: None, }; let mut import_map = Default::default(); let mut deps = vec![]; diff --git a/crates/rspack_plugin_json/src/json_exports_dependency.rs b/crates/rspack_plugin_json/src/json_exports_dependency.rs index 6a77b98a0bc..291f35fb988 100644 --- a/crates/rspack_plugin_json/src/json_exports_dependency.rs +++ b/crates/rspack_plugin_json/src/json_exports_dependency.rs @@ -1,8 +1,8 @@ use json::JsonValue; use rspack_core::{ - AsContextDependency, AsModuleDependency, ConnectionState, Dependency, DependencyId, - DependencyTemplate, ExportNameOrSpec, ExportSpec, ExportsOfExportsSpec, ExportsSpec, ModuleGraph, - ModuleIdentifier, TemplateContext, TemplateReplaceSource, UsageState, UsedByExports, UsedName, + AsContextDependency, AsModuleDependency, Dependency, DependencyId, DependencyTemplate, + ExportNameOrSpec, ExportSpec, ExportsOfExportsSpec, ExportsSpec, ModuleGraph, TemplateContext, + TemplateReplaceSource, }; #[derive(Debug, Clone)] pub struct JsonExportsDependency { @@ -42,14 +42,13 @@ impl AsContextDependency for JsonExportsDependency {} impl DependencyTemplate for JsonExportsDependency { fn apply( &self, - source: &mut TemplateReplaceSource, - code_generatable_context: &mut TemplateContext, + _source: &mut TemplateReplaceSource, + _code_generatable_context: &mut TemplateContext, ) { } } fn get_exports_from_data(data: &JsonValue) -> Option { - let data = data; let ret = match data { JsonValue::Null | JsonValue::Short(_) diff --git a/crates/rspack_plugin_json/src/lib.rs b/crates/rspack_plugin_json/src/lib.rs index eeaff4889a9..b279d442549 100644 --- a/crates/rspack_plugin_json/src/lib.rs +++ b/crates/rspack_plugin_json/src/lib.rs @@ -1,5 +1,6 @@ #![feature(let_chains)] use json::{ + number::Number, object::Object, Error::{ ExceededDepthLimit, FailedUtf8Parsing, UnexpectedCharacter, UnexpectedEndOfJson, WrongType, @@ -7,7 +8,6 @@ use json::{ JsonValue, }; use rspack_core::{ - async_module_factory, rspack_sources::{BoxSource, RawSource, Source, SourceExt}, BuildMetaDefaultObject, BuildMetaExportsType, CompilerOptions, ExportsInfo, GenerateContext, Module, ModuleGraph, ParserAndGenerator, Plugin, RuntimeGlobals, RuntimeSpec, SourceType, @@ -128,17 +128,14 @@ impl ParserAndGenerator for JsonParserAndGenerator { #[allow(clippy::unwrap_in_result)] fn generate( &self, - source: &BoxSource, + _source: &BoxSource, module: &dyn rspack_core::Module, generate_context: &mut GenerateContext, ) -> Result { let GenerateContext { compilation, - module_generator_options, - runtime_requirements, - data, - requested_source_type, runtime, + .. } = generate_context; match generate_context.requested_source_type { SourceType::JavaScript => { @@ -162,7 +159,6 @@ impl ParserAndGenerator for JsonParserAndGenerator { json::JsonValue::Object(_) | json::JsonValue::Array(_) if exports_info .other_exports_info - // TODO: runtime opt .get_export_info(&compilation.module_graph) .get_used(*runtime) == UsageState::Unused => @@ -246,8 +242,7 @@ fn create_object_for_exports_info( let exports_info = mg.get_exports_info_by_id(&exports_info_id); // avoid clone let temp = std::mem::replace(value, JsonValue::Null); - let ret = create_object_for_exports_info(temp, exports_info, runtime, mg); - ret + create_object_for_exports_info(temp, exports_info, runtime, mg) } else { std::mem::replace(value, JsonValue::Null) }; @@ -262,11 +257,13 @@ fn create_object_for_exports_info( } JsonValue::Object(new_obj) } - JsonValue::Array(arr) => JsonValue::Array( - arr + JsonValue::Array(arr) => { + let original_len = arr.len(); + let mut max_used_index = 0; + let mut ret = arr .into_iter() .enumerate() - .filter_map(|(i, item)| { + .map(|(i, item)| { let export_info = exports_info .id .get_read_only_export_info(&format!("{i}").into(), mg); @@ -274,6 +271,7 @@ fn create_object_for_exports_info( if used == UsageState::Unused { return None; } + max_used_index = max_used_index.max(i); if used == UsageState::OnlyPropertiesUsed && let Some(exports_info_id) = export_info.exports_info { @@ -288,7 +286,26 @@ fn create_object_for_exports_info( Some(item) } }) - .collect::>(), - ), + .collect::>(); + let arr_length_used = exports_info + .id + .get_read_only_export_info(&"length".into(), mg) + .get_used(runtime); + let array_length_when_used = match arr_length_used { + UsageState::Unused => None, + _ => Some(original_len), + }; + let used_length = if let Some(array_length_when_used) = array_length_when_used { + array_length_when_used + } else { + max_used_index + 1 + }; + ret.drain(used_length..); + let normalized_ret = ret + .into_iter() + .map(|item| item.unwrap_or(JsonValue::Number(Number::from(0)))) + .collect::>(); + JsonValue::Array(normalized_ret) + } } } diff --git a/crates/rspack_plugin_library/src/assign_library_plugin.rs b/crates/rspack_plugin_library/src/assign_library_plugin.rs index 925765172dc..2e245d17abc 100644 --- a/crates/rspack_plugin_library/src/assign_library_plugin.rs +++ b/crates/rspack_plugin_library/src/assign_library_plugin.rs @@ -4,8 +4,8 @@ use once_cell::sync::Lazy; use regex::Regex; use rspack_core::tree_shaking::webpack_ext::ExportInfoExt; use rspack_core::{ - debug_all_exports_info, debug_exports_info, property_access, ChunkUkey, EntryData, LibraryExport, - LibraryName, LibraryNonUmdObject, UsageState, + debug_all_exports_info, property_access, ChunkUkey, EntryData, LibraryExport, LibraryName, + LibraryNonUmdObject, UsageState, }; use rspack_core::{ rspack_sources::{ConcatSource, RawSource, SourceExt}, @@ -234,7 +234,6 @@ impl Plugin for AssignLibraryPlugin { } } - debug_all_exports_info!(&compilation.module_graph); Ok(()) } From 21784cb81e6bb47bd094a01ab636a2134654d968 Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Thu, 7 Dec 2023 16:17:26 +0800 Subject: [PATCH 09/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20clean?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/rspack/tests/fixtures.rs | 12 +---- .../rspack/tests/tree-shaking/basic/index.js | 5 +- .../basic/snapshot/new_treeshaking.snap | 15 ++++-- .../tree-shaking/basic/snapshot/snap.diff | 27 +++------- .../tests/tree-shaking/basic/test.config.json | 3 +- .../plugin/flag_dependency_exports_plugin.rs | 49 +++++++++---------- .../src/json_exports_dependency.rs | 27 ---------- .../src/assign_library_plugin.rs | 5 +- examples/type-assign/index.js | 6 --- examples/type-assign/module.js | 1 - examples/type-assign/package.json | 19 ------- examples/type-assign/rspack.config.js | 27 ---------- packages/rspack-dev-server/src/server.ts | 1 - pnpm-lock.yaml | 9 ---- webpack-test/ConfigTestCases.template.js | 5 -- 15 files changed, 44 insertions(+), 167 deletions(-) delete mode 100644 examples/type-assign/index.js delete mode 100644 examples/type-assign/module.js delete mode 100644 examples/type-assign/package.json delete mode 100644 examples/type-assign/rspack.config.js diff --git a/crates/rspack/tests/fixtures.rs b/crates/rspack/tests/fixtures.rs index be4f70aaa38..32f1106513c 100644 --- a/crates/rspack/tests/fixtures.rs +++ b/crates/rspack/tests/fixtures.rs @@ -48,8 +48,7 @@ fn samples(fixture_path: PathBuf) { fn tree_shaking(fixture_path: PathBuf) { // For each test case // First test is old version tree shaking snapshot test - // TODO: recover - // test_fixture(&fixture_path, Box::new(|_, _| {}), None); + test_fixture(&fixture_path, Box::new(|_, _| {}), None); // second test is webpack based tree shaking IS_NEW_TREESHAKING.store(true, Ordering::SeqCst); test_fixture( @@ -67,15 +66,6 @@ fn tree_shaking(fixture_path: PathBuf) { } plugins.push(Box::::default()); plugins.push(Box::::default()); - if options.optimization.mangle_exports.is_enable() { - plugins.push( - MangleExportsPlugin::new(!matches!( - options.optimization.mangle_exports, - MangleExportsOption::Size - )) - .boxed(), - ); - } }, ), Some("new_treeshaking".to_string()), diff --git a/crates/rspack/tests/tree-shaking/basic/index.js b/crates/rspack/tests/tree-shaking/basic/index.js index 2ac85d60cf0..8c062158924 100644 --- a/crates/rspack/tests/tree-shaking/basic/index.js +++ b/crates/rspack/tests/tree-shaking/basic/index.js @@ -1,4 +1,3 @@ -import a from "./a.json"; -a[2] - +import { answer } from "./lib"; +answer diff --git a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap index f57b20d4c8d..2f9730bfe31 100644 --- a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap +++ b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap @@ -3,16 +3,21 @@ source: crates/rspack_testing/src/run_fixture.rs --- ```js title=main.js (self['webpackChunkwebpack'] = self['webpackChunkwebpack'] || []).push([["main"], { +"./answer.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +__webpack_require__.d(__webpack_exports__, { + answer: function() { return answer; } +}); + const answer = 103330; +}), "./index.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */var _a_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a.json */"./a.json"); +/* harmony import */var _lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib */"./answer.js"); -_a_json__WEBPACK_IMPORTED_MODULE_0__["default"]; +_lib__WEBPACK_IMPORTED_MODULE_0__.answer; }), -"./a.json": (function (module, exports, __webpack_require__) { -"use strict"; -module.exports = {}}), },function(__webpack_require__) { var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId) } diff --git a/crates/rspack/tests/tree-shaking/basic/snapshot/snap.diff b/crates/rspack/tests/tree-shaking/basic/snapshot/snap.diff index af1e0937532..d88afb964de 100644 --- a/crates/rspack/tests/tree-shaking/basic/snapshot/snap.diff +++ b/crates/rspack/tests/tree-shaking/basic/snapshot/snap.diff @@ -1,37 +1,22 @@ --- expected +++ actual -@@ -3,30 +3,16 @@ - --- - ```js title=main.js - (self['webpackChunkwebpack'] = self['webpackChunkwebpack'] || []).push([["main"], { --"./answer.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { --"use strict"; --__webpack_require__.r(__webpack_exports__); --__webpack_require__.d(__webpack_exports__, { -- answer: function() { return answer; } --}); -- const answer = 103330; --}), +@@ -14,18 +14,9 @@ "./index.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */var _lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib */"./lib.js"); -+/* harmony import */var _a_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a.json */"./a.json"); ++/* harmony import */var _lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib */"./answer.js"); --_lib__WEBPACK_IMPORTED_MODULE_0__.answer; -+_a_json__WEBPACK_IMPORTED_MODULE_0__["2"].a; - }), + _lib__WEBPACK_IMPORTED_MODULE_0__.answer; +-}), -"./lib.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { -+"./a.json": (function (module, exports, __webpack_require__) { - "use strict"; +-"use strict"; -__webpack_require__.r(__webpack_exports__); -__webpack_require__.d(__webpack_exports__, { - answer: function() { return _answer__WEBPACK_IMPORTED_MODULE_0__.answer; } -}); -/* harmony import */var _answer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./answer */"./answer.js"); - --}), -+module.exports = [{"a":1}]}), + }), },function(__webpack_require__) { - var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId) } diff --git a/crates/rspack/tests/tree-shaking/basic/test.config.json b/crates/rspack/tests/tree-shaking/basic/test.config.json index b2dceaab125..97825ad89d3 100644 --- a/crates/rspack/tests/tree-shaking/basic/test.config.json +++ b/crates/rspack/tests/tree-shaking/basic/test.config.json @@ -1,7 +1,6 @@ { "optimization": { - "sideEffects": "true", - "mangleExports": "true" + "sideEffects": "true" }, "builtins": { "treeShaking": "true", diff --git a/crates/rspack_plugin_javascript/src/plugin/flag_dependency_exports_plugin.rs b/crates/rspack_plugin_javascript/src/plugin/flag_dependency_exports_plugin.rs index cc29ec845ee..3b5afa02daf 100644 --- a/crates/rspack_plugin_javascript/src/plugin/flag_dependency_exports_plugin.rs +++ b/crates/rspack_plugin_javascript/src/plugin/flag_dependency_exports_plugin.rs @@ -35,39 +35,34 @@ impl<'a> FlagDependencyExportsProxy<'a> { let module_graph_modules = std::mem::take(&mut self.mg.module_identifier_to_module_graph_module); for mgm in module_graph_modules.values() { - let exports_info_id = mgm.exports; - let is_module_without_exports = mgm - .build_meta - .as_ref() - .map(|build_meta| build_meta.exports_type == BuildMetaExportsType::Unset) - .unwrap_or(true); - if is_module_without_exports - && !matches!( - exports_info_id - .get_exports_info(self.mg) - .other_exports_info - .get_export_info(self.mg) - .provided, - Some(ExportInfoProvided::Null) - ) - { - exports_info_id.set_has_provide_info(self.mg); - exports_info_id.set_unknown_exports_provided(self.mg, false, None, None, None, None); - continue; - } - q.push_back(mgm.module_identifier); - exports_info_id.set_has_provide_info(self.mg); + let exports_id = mgm.exports; + let is_module_without_exports = if let Some(ref build_meta) = mgm.build_meta { + build_meta.exports_type == BuildMetaExportsType::Unset + } else { + true + } && { + let exports_info = self.mg.get_exports_info_by_id(&exports_id); + let other_exports_info_id = exports_info.other_exports_info; + let other_exports_info = self.mg.get_export_info_by_id(&other_exports_info_id); + other_exports_info.provided.is_some() + }; + // TODO: mem cache + exports_id.set_has_provide_info(self.mg); + q.push_back(mgm.module_identifier); + if is_module_without_exports { + exports_id.set_unknown_exports_provided(self.mg, false, None, None, None, None); + } } self.mg.module_identifier_to_module_graph_module = module_graph_modules; while let Some(module_id) = q.pop_back() { self.changed = false; self.current_module_id = module_id; - let mut exports_specs_of_dependencies: HashMap = + let mut exports_specs_from_dependencies: HashMap = HashMap::default(); - self.process_dependencies_block(&module_id, &mut exports_specs_of_dependencies); + self.process_dependencies_block(&module_id, &mut exports_specs_from_dependencies); let exports_info_id = self.mg.get_exports_info(&module_id).id; - for (dep_id, exports_spec) in exports_specs_of_dependencies.into_iter() { + for (dep_id, exports_spec) in exports_specs_from_dependencies.into_iter() { self.process_exports_spec(dep_id, exports_spec, exports_info_id); } if self.changed { @@ -77,8 +72,8 @@ impl<'a> FlagDependencyExportsProxy<'a> { } pub fn notify_dependencies(&mut self, q: &mut VecDeque) { - if let Some(deps) = self.dependencies.get(&self.current_module_id) { - for mi in deps.iter() { + if let Some(set) = self.dependencies.get(&self.current_module_id) { + for mi in set.iter() { q.push_back(*mi); } } diff --git a/crates/rspack_plugin_json/src/json_exports_dependency.rs b/crates/rspack_plugin_json/src/json_exports_dependency.rs index 291f35fb988..416280ec4fa 100644 --- a/crates/rspack_plugin_json/src/json_exports_dependency.rs +++ b/crates/rspack_plugin_json/src/json_exports_dependency.rs @@ -99,30 +99,3 @@ fn get_exports_from_data(data: &JsonValue) -> Option { }; Some(ret) } - -// const getExportsFromData = data => { -// if (data && typeof data === "object") { -// if (Array.isArray(data)) { -// return data.length < 100 -// ? data.map((item, idx) => { -// return { -// name: `${idx}`, -// canMangle: true, -// exports: getExportsFromData(item) -// }; -// }) -// : undefined; -// } else { -// const exports = []; -// for (const key of Object.keys(data)) { -// exports.push({ -// name: key, -// canMangle: true, -// exports: getExportsFromData(data[key]) -// }); -// } -// return exports; -// } -// } -// return undefined; -// }; diff --git a/crates/rspack_plugin_library/src/assign_library_plugin.rs b/crates/rspack_plugin_library/src/assign_library_plugin.rs index 2e245d17abc..fee88a32b10 100644 --- a/crates/rspack_plugin_library/src/assign_library_plugin.rs +++ b/crates/rspack_plugin_library/src/assign_library_plugin.rs @@ -4,8 +4,8 @@ use once_cell::sync::Lazy; use regex::Regex; use rspack_core::tree_shaking::webpack_ext::ExportInfoExt; use rspack_core::{ - debug_all_exports_info, property_access, ChunkUkey, EntryData, LibraryExport, LibraryName, - LibraryNonUmdObject, UsageState, + property_access, ChunkUkey, EntryData, LibraryExport, LibraryName, LibraryNonUmdObject, + UsageState, }; use rspack_core::{ rspack_sources::{ConcatSource, RawSource, SourceExt}, @@ -233,7 +233,6 @@ impl Plugin for AssignLibraryPlugin { exports_info_id.set_used_in_unknown_way(&mut compilation.module_graph, Some(&runtime)); } } - Ok(()) } diff --git a/examples/type-assign/index.js b/examples/type-assign/index.js deleted file mode 100644 index b91b42407c8..00000000000 --- a/examples/type-assign/index.js +++ /dev/null @@ -1,6 +0,0 @@ -it("should define global object with property", function () { - require("./module"); - expect(MyLibrary["answer"]).toEqual(42); -}); - -export const answer = 42; diff --git a/examples/type-assign/module.js b/examples/type-assign/module.js deleted file mode 100644 index 3918c74e446..00000000000 --- a/examples/type-assign/module.js +++ /dev/null @@ -1 +0,0 @@ -"use strict"; diff --git a/examples/type-assign/package.json b/examples/type-assign/package.json deleted file mode 100644 index f4d6c253333..00000000000 --- a/examples/type-assign/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "example-basic", - "version": "1.0.0", - "description": "", - "main": "index.js", - "private": true, - "scripts": { - "dev": "rspack serve", - "build": "rspack build" - }, - "devDependencies": { - "@rspack/cli": "workspace:*", - "@rspack/core": "workspace:*" - }, - "sideEffects": false, - "keywords": [], - "author": "", - "license": "MIT" -} diff --git a/examples/type-assign/rspack.config.js b/examples/type-assign/rspack.config.js deleted file mode 100644 index fe3fa7979b2..00000000000 --- a/examples/type-assign/rspack.config.js +++ /dev/null @@ -1,27 +0,0 @@ -/** @type {import("@rspack/core").Configuration} */ -module.exports = { - output: { - library: { - name: "MyLibrary", - type: "assign", - }, - }, - experiments: { - rspackFuture: { - newTreeshaking: true - } - }, - - optimization: { - sideEffects: true, - innerGraph: true, - providedExports: true, - usedExports: true, - moduleIds: 'named', - minimize: false - }, - builtins: { - treeShaking: false, - }, - entry: "./index.js", -}; diff --git a/packages/rspack-dev-server/src/server.ts b/packages/rspack-dev-server/src/server.ts index 8fdd648a858..e4d9b41e157 100644 --- a/packages/rspack-dev-server/src/server.ts +++ b/packages/rspack-dev-server/src/server.ts @@ -1,4 +1,3 @@ -// @ts-nocheck /** * The following code is modified based on * https://github.com/webpack/webpack-dev-server/blob/b0f15ace0123c125d5870609ef4691c141a6d187/lib/Server.js diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9ac4ce51c51..2df4a6c601e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1176,15 +1176,6 @@ importers: specifier: 3.3.1 version: 3.3.1(postcss@8.4.21) - examples/type-assign: - devDependencies: - '@rspack/cli': - specifier: workspace:* - version: link:../../packages/rspack-cli - '@rspack/core': - specifier: workspace:* - version: link:../../packages/rspack - examples/vue: dependencies: vue: diff --git a/webpack-test/ConfigTestCases.template.js b/webpack-test/ConfigTestCases.template.js index 108248457a8..3d620da1885 100644 --- a/webpack-test/ConfigTestCases.template.js +++ b/webpack-test/ConfigTestCases.template.js @@ -111,11 +111,6 @@ const describeCases = config => { newTreeshaking: true } } - - if (options?.experiments?.rspackFuture?.newTreeshaking) { - options.builtins = options.builtins || {} - options.builtins.treeShaking = false; - } // if (options.optimization.minimizer === undefined) { // options.optimization.minimizer = [ // new (require("terser-webpack-plugin"))({ From 6a99bec4b07a8c907312973d062b7626e70c2ee4 Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Thu, 7 Dec 2023 19:33:46 +0800 Subject: [PATCH 10/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20lint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sharing/share-multiple-versions/webpack.config.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/webpack-test/configCases/sharing/share-multiple-versions/webpack.config.js b/webpack-test/configCases/sharing/share-multiple-versions/webpack.config.js index ae9fd16859d..53ab36ce28c 100644 --- a/webpack-test/configCases/sharing/share-multiple-versions/webpack.config.js +++ b/webpack-test/configCases/sharing/share-multiple-versions/webpack.config.js @@ -3,6 +3,9 @@ const { SharePlugin } = require("../../../../").sharing; /** @type {import("@rspack/core").Configuration} */ module.exports = { + optimization: { + mangleExports: false + }, plugins: [ new SharePlugin({ shared: ["shared"] From 96706ca7fc063dd93a71aa2809c12e215d084d14 Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Thu, 7 Dec 2023 22:32:37 +0800 Subject: [PATCH 11/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20update=20snap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../basic/snapshot/new_treeshaking.snap | 15 ++++-------- .../basic/snapshot/new_treeshaking.snap.new | 24 ------------------- .../fixtures/simple/snapshot/output.snap | 5 +--- 3 files changed, 6 insertions(+), 38 deletions(-) delete mode 100644 crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap.new diff --git a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap index 2f9730bfe31..907b7dac05f 100644 --- a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap +++ b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap @@ -3,21 +3,16 @@ source: crates/rspack_testing/src/run_fixture.rs --- ```js title=main.js (self['webpackChunkwebpack'] = self['webpackChunkwebpack'] || []).push([["main"], { -"./answer.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -__webpack_require__.d(__webpack_exports__, { - answer: function() { return answer; } -}); - const answer = 103330; -}), "./index.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */var _lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib */"./answer.js"); +/* harmony import */var _a_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a.json */"./a.json"); -_lib__WEBPACK_IMPORTED_MODULE_0__.answer; +_a_json__WEBPACK_IMPORTED_MODULE_0__["2"]; }), +"./a.json": (function (module, exports, __webpack_require__) { +"use strict"; +module.exports = [0,0,3]}), },function(__webpack_require__) { var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId) } diff --git a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap.new b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap.new deleted file mode 100644 index c2d93d4981d..00000000000 --- a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap.new +++ /dev/null @@ -1,24 +0,0 @@ ---- -source: crates/rspack_testing/src/run_fixture.rs -assertion_line: 146 ---- -```js title=main.js -(self['webpackChunkwebpack'] = self['webpackChunkwebpack'] || []).push([["main"], { -"./index.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */var _a_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a.json */"./a.json"); - -_a_json__WEBPACK_IMPORTED_MODULE_0__["2"]; -}), -"./a.json": (function (module, exports, __webpack_require__) { -"use strict"; -module.exports = [0,0,3]}), - -},function(__webpack_require__) { -var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId) } -var __webpack_exports__ = (__webpack_exec__("./index.js")); - -} -]); -``` diff --git a/crates/rspack_plugin_json/tests/fixtures/simple/snapshot/output.snap b/crates/rspack_plugin_json/tests/fixtures/simple/snapshot/output.snap index 434fed74ee5..31516e68a3d 100644 --- a/crates/rspack_plugin_json/tests/fixtures/simple/snapshot/output.snap +++ b/crates/rspack_plugin_json/tests/fixtures/simple/snapshot/output.snap @@ -12,10 +12,7 @@ console.log(_json_json__WEBPACK_IMPORTED_MODULE_0__); }), "./json.json": (function (module, exports, __webpack_require__) { "use strict"; -module.exports = { - "hello": "world" -} -;}), +module.exports = {"hello":"world"}}), },function(__webpack_require__) { var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId) } From 351144ba29f4f66af49f524a3f0fbec94a7a0c9b Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Thu, 7 Dec 2023 22:33:36 +0800 Subject: [PATCH 12/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20recover?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../basic/snapshot/new_treeshaking.snap | 15 ++++++++++----- .../split-chunks/asnyc-entries/test.filter.js | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap index 907b7dac05f..2f9730bfe31 100644 --- a/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap +++ b/crates/rspack/tests/tree-shaking/basic/snapshot/new_treeshaking.snap @@ -3,16 +3,21 @@ source: crates/rspack_testing/src/run_fixture.rs --- ```js title=main.js (self['webpackChunkwebpack'] = self['webpackChunkwebpack'] || []).push([["main"], { +"./answer.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +__webpack_require__.d(__webpack_exports__, { + answer: function() { return answer; } +}); + const answer = 103330; +}), "./index.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */var _a_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a.json */"./a.json"); +/* harmony import */var _lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib */"./answer.js"); -_a_json__WEBPACK_IMPORTED_MODULE_0__["2"]; +_lib__WEBPACK_IMPORTED_MODULE_0__.answer; }), -"./a.json": (function (module, exports, __webpack_require__) { -"use strict"; -module.exports = [0,0,3]}), },function(__webpack_require__) { var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId) } diff --git a/webpack-test/configCases/split-chunks/asnyc-entries/test.filter.js b/webpack-test/configCases/split-chunks/asnyc-entries/test.filter.js index fed7caa7b92..ea561e9f59e 100644 --- a/webpack-test/configCases/split-chunks/asnyc-entries/test.filter.js +++ b/webpack-test/configCases/split-chunks/asnyc-entries/test.filter.js @@ -1 +1 @@ -module.exports = () => false +module.exports = () => 'block by treeshaking issue https://github.com/web-infra-dev/rspack/issues/4336' From 4b16dac28b940d8e5803d3544e6dc790cebe64fc Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Fri, 8 Dec 2023 11:04:10 +0800 Subject: [PATCH 13/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20move=20import-nam?= =?UTF-8?q?ed=20to=20packages/rspack/tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/node_binding/binding.d.ts | 15 ------------- .../import-by-name-json/data/c.json | 0 .../import-by-name-json/data/d.json | 1 + .../import-by-name-json/data/e.json | 5 +++++ .../import-by-name-json/data/f.json | 5 +++++ .../import-by-name-json/data/g.json | 3 +++ .../tree-shaking/import-by-name-json/index.js | 21 +++++++++++++++++++ .../import-by-name-json/webpack.config.js | 20 ++++++++++++++++++ .../cases/json/import-by-name/test.filter.js | 4 ++-- .../cases/json/import-by-name/warnings.js | 17 +++++++++++++++ 10 files changed, 74 insertions(+), 17 deletions(-) rename crates/rspack/tests/tree-shaking/basic/a.json => packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/c.json (100%) create mode 100644 packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/d.json create mode 100644 packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/e.json create mode 100644 packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/f.json create mode 100644 packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/g.json create mode 100644 packages/rspack/tests/configCases/tree-shaking/import-by-name-json/index.js create mode 100644 packages/rspack/tests/configCases/tree-shaking/import-by-name-json/webpack.config.js create mode 100644 webpack-test/cases/json/import-by-name/warnings.js diff --git a/crates/node_binding/binding.d.ts b/crates/node_binding/binding.d.ts index 70b8cc2e567..0a23df8fd3e 100644 --- a/crates/node_binding/binding.d.ts +++ b/crates/node_binding/binding.d.ts @@ -492,13 +492,6 @@ export interface JsStatsWarning { formatted: string } -export interface NodeFS { - writeFile: (...args: any[]) => any - removeFile: (...args: any[]) => any - mkdir: (...args: any[]) => any - mkdirp: (...args: any[]) => any -} - export interface PathData { filename?: string hash?: string @@ -1179,11 +1172,3 @@ export function registerGlobalTrace(filter: string, layer: "chrome" | "logger", /** Builtin loader runner */ export function runBuiltinLoader(builtin: string, options: string | undefined | null, loaderContext: JsLoaderContext): Promise -export interface ThreadsafeNodeFS { - writeFile: (...args: any[]) => any - removeFile: (...args: any[]) => any - mkdir: (...args: any[]) => any - mkdirp: (...args: any[]) => any - removeDirAll: (...args: any[]) => any -} - diff --git a/crates/rspack/tests/tree-shaking/basic/a.json b/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/c.json similarity index 100% rename from crates/rspack/tests/tree-shaking/basic/a.json rename to packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/c.json diff --git a/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/d.json b/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/d.json new file mode 100644 index 00000000000..0967ef424bc --- /dev/null +++ b/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/d.json @@ -0,0 +1 @@ +{} diff --git a/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/e.json b/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/e.json new file mode 100644 index 00000000000..3cebd09f51b --- /dev/null +++ b/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/e.json @@ -0,0 +1,5 @@ +{ + "1": "x", + "bb": 2, + "aa": 1 +} diff --git a/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/f.json b/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/f.json new file mode 100644 index 00000000000..3cc1d022071 --- /dev/null +++ b/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/f.json @@ -0,0 +1,5 @@ +{ + "named": "named", + "default": "default", + "__esModule": true +} diff --git a/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/g.json b/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/g.json new file mode 100644 index 00000000000..15e8d0ff836 --- /dev/null +++ b/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/data/g.json @@ -0,0 +1,3 @@ +{ + "named": {} +} diff --git a/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/index.js b/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/index.js new file mode 100644 index 00000000000..aa40d278210 --- /dev/null +++ b/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/index.js @@ -0,0 +1,21 @@ +import * as c from "./data/c.json"; +import * as d from "./data/d.json"; +import { bb, aa } from "./data/e.json"; +import f, { named } from "./data/f.json"; +import g, { named as gnamed } from "./data/g.json"; + +it("should be possible to import json data", function () { + expect(c[2]).toBe(3); + expect(Object.keys(d)).toEqual(["default"]); + expect(aa).toBe(1); + expect(bb).toBe(2); + expect(named).toBe("named"); + expect({ f }).toEqual({ + f: { + __esModule: true, + default: "default", + named: "named" + } + }); + expect(g.named).toBe(gnamed); +}); diff --git a/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/webpack.config.js b/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/webpack.config.js new file mode 100644 index 00000000000..8f15cf4f94b --- /dev/null +++ b/packages/rspack/tests/configCases/tree-shaking/import-by-name-json/webpack.config.js @@ -0,0 +1,20 @@ +/**@type {import('@rspack/cli').Configuration}*/ +module.exports = { + mode: "production", + context: __dirname, + module: { + rules: [] + }, + experiments: { + rspackFuture: { + newTreeshaking: true + } + }, + optimization: { + moduleIds: "named", + minimize: false + }, + externalsPresets: { + node: true + } +}; diff --git a/webpack-test/cases/json/import-by-name/test.filter.js b/webpack-test/cases/json/import-by-name/test.filter.js index ad8d560b5ac..2735e947c45 100644 --- a/webpack-test/cases/json/import-by-name/test.filter.js +++ b/webpack-test/cases/json/import-by-name/test.filter.js @@ -1,4 +1,4 @@ -module.exports = () => {return true} - +module.exports = () => {return "https://github.com/web-infra-dev/rspack/issues/4323"} + \ No newline at end of file diff --git a/webpack-test/cases/json/import-by-name/warnings.js b/webpack-test/cases/json/import-by-name/warnings.js new file mode 100644 index 00000000000..82fc687d927 --- /dev/null +++ b/webpack-test/cases/json/import-by-name/warnings.js @@ -0,0 +1,17 @@ +module.exports = [ + [ + /Should not import the named export '2' \(imported as 'c'\) from default-exporting module \(only default export is available soon\)/ + ], + [ + /Should not import the named export 'aa' \(imported as 'aa'\) from default-exporting module \(only default export is available soon\)/ + ], + [ + /Should not import the named export 'bb' \(imported as 'bb'\) from default-exporting module \(only default export is available soon\)/ + ], + [ + /Should not import the named export 'named' \(imported as 'named'\) from default-exporting module \(only default export is available soon\)/ + ], + [ + /Should not import the named export 'named' \(imported as 'gnamed'\) from default-exporting module \(only default export is available soon\)/ + ] +]; From 39d3ef91a90ad229335a9f8f0f79c3eedfea72f8 Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Fri, 8 Dec 2023 11:57:04 +0800 Subject: [PATCH 14/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20json.parse=20opt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/rspack_plugin_json/src/lib.rs | 20 ++++++++++--------- .../tests/fixtures/simple/json.json | 2 +- .../fixtures/simple/snapshot/output.snap | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/crates/rspack_plugin_json/src/lib.rs b/crates/rspack_plugin_json/src/lib.rs index b279d442549..708301ca70b 100644 --- a/crates/rspack_plugin_json/src/lib.rs +++ b/crates/rspack_plugin_json/src/lib.rs @@ -1,4 +1,6 @@ #![feature(let_chains)] +use std::borrow::Cow; + use json::{ number::Number, object::Object, @@ -172,15 +174,15 @@ impl ParserAndGenerator for JsonParserAndGenerator { } _ => json_data.clone(), }; - - let json_expr = final_json.to_string(); - Ok( - RawSource::from(format!( - r#"module.exports = {}"#, - utils::escape_json(&json_expr) - )) - .boxed(), - ) + let is_js_object = final_json.is_object() || final_json.is_array(); + let final_json_string = final_json.to_string(); + let json_str = utils::escape_json(&final_json_string); + let json_expr = if is_js_object && json_str.len() > 20 { + Cow::Owned(format!("JSON.parse('{}')", json_str.replace("'", r#"\'"#))) + } else { + json_str + }; + Ok(RawSource::from(format!(r#"module.exports = {}"#, json_expr)).boxed()) } _ => Err(internal_error!(format!( "Unsupported source type {:?} for plugin Json", diff --git a/crates/rspack_plugin_json/tests/fixtures/simple/json.json b/crates/rspack_plugin_json/tests/fixtures/simple/json.json index f2a886f39de..92fae2e714b 100644 --- a/crates/rspack_plugin_json/tests/fixtures/simple/json.json +++ b/crates/rspack_plugin_json/tests/fixtures/simple/json.json @@ -1,3 +1,3 @@ { - "hello": "world" + "hello": "world is better '" } diff --git a/crates/rspack_plugin_json/tests/fixtures/simple/snapshot/output.snap b/crates/rspack_plugin_json/tests/fixtures/simple/snapshot/output.snap index 31516e68a3d..417107eee56 100644 --- a/crates/rspack_plugin_json/tests/fixtures/simple/snapshot/output.snap +++ b/crates/rspack_plugin_json/tests/fixtures/simple/snapshot/output.snap @@ -12,7 +12,7 @@ console.log(_json_json__WEBPACK_IMPORTED_MODULE_0__); }), "./json.json": (function (module, exports, __webpack_require__) { "use strict"; -module.exports = {"hello":"world"}}), +module.exports = JSON.parse('{"hello":"world is better \'"}')}), },function(__webpack_require__) { var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId) } From b0ba4e109a4788d54ace0a94516b7cde17525389 Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Fri, 8 Dec 2023 12:24:16 +0800 Subject: [PATCH 15/18] =?UTF-8?q?fix:=20=F0=9F=90=9B=20ci=20issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/node_binding/binding.d.ts | 15 +++++++++++++++ crates/rspack_plugin_json/src/lib.rs | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/crates/node_binding/binding.d.ts b/crates/node_binding/binding.d.ts index 0a23df8fd3e..70b8cc2e567 100644 --- a/crates/node_binding/binding.d.ts +++ b/crates/node_binding/binding.d.ts @@ -492,6 +492,13 @@ export interface JsStatsWarning { formatted: string } +export interface NodeFS { + writeFile: (...args: any[]) => any + removeFile: (...args: any[]) => any + mkdir: (...args: any[]) => any + mkdirp: (...args: any[]) => any +} + export interface PathData { filename?: string hash?: string @@ -1172,3 +1179,11 @@ export function registerGlobalTrace(filter: string, layer: "chrome" | "logger", /** Builtin loader runner */ export function runBuiltinLoader(builtin: string, options: string | undefined | null, loaderContext: JsLoaderContext): Promise +export interface ThreadsafeNodeFS { + writeFile: (...args: any[]) => any + removeFile: (...args: any[]) => any + mkdir: (...args: any[]) => any + mkdirp: (...args: any[]) => any + removeDirAll: (...args: any[]) => any +} + diff --git a/crates/rspack_plugin_json/src/lib.rs b/crates/rspack_plugin_json/src/lib.rs index 708301ca70b..c1fd99bd09f 100644 --- a/crates/rspack_plugin_json/src/lib.rs +++ b/crates/rspack_plugin_json/src/lib.rs @@ -178,7 +178,7 @@ impl ParserAndGenerator for JsonParserAndGenerator { let final_json_string = final_json.to_string(); let json_str = utils::escape_json(&final_json_string); let json_expr = if is_js_object && json_str.len() > 20 { - Cow::Owned(format!("JSON.parse('{}')", json_str.replace("'", r#"\'"#))) + Cow::Owned(format!("JSON.parse('{}')", json_str.replace('\'', r#"\'"#))) } else { json_str }; From 9b69517a19c9491b920884c4e4231b2ef2c0dd42 Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Fri, 8 Dec 2023 13:04:09 +0800 Subject: [PATCH 16/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20update=20snap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/__snapshots__/case.test.ts.snap | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/rspack/tests/__snapshots__/case.test.ts.snap b/packages/rspack/tests/__snapshots__/case.test.ts.snap index 208119fbdd2..e0dd46323fc 100644 --- a/packages/rspack/tests/__snapshots__/case.test.ts.snap +++ b/packages/rspack/tests/__snapshots__/case.test.ts.snap @@ -8,6 +8,17 @@ exports[`cases exported tests data imports 1`] = ` .red{color: red;} /* #endregion "data:text/css,.red{color: red;}" */ +/* #region "./bad-base64.css" */ +/* +- type: css +*/ +.bad { + a: url(data:text/bad-base64;base64,abcd?#iefix); + b: url("data:text/bad-base64;base64, abcd?#iefix"); +} + +/* #endregion "./bad-base64.css" */ + /* #region "data:text/css;base64,LmJ7Y29sb3I6IGdyZWVufQ==" */ /* - type: css @@ -23,17 +34,6 @@ exports[`cases exported tests data imports 1`] = ` /* #endregion "./a.css" */ -/* #region "./bad-base64.css" */ -/* -- type: css -*/ -.bad { - a: url(data:text/bad-base64;base64,abcd?#iefix); - b: url("data:text/bad-base64;base64, abcd?#iefix"); -} - -/* #endregion "./bad-base64.css" */ - /* #region "./index.css" */ /* - type: css From a03961b9117539119a8a9c324ff305258a51527c Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Mon, 11 Dec 2023 16:36:59 +0800 Subject: [PATCH 17/18] =?UTF-8?q?fix:=20=F0=9F=90=9B=20compile=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/rspack_plugin_json/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rspack_plugin_json/src/lib.rs b/crates/rspack_plugin_json/src/lib.rs index ace04dbdbd5..b97083dfcad 100644 --- a/crates/rspack_plugin_json/src/lib.rs +++ b/crates/rspack_plugin_json/src/lib.rs @@ -104,7 +104,7 @@ impl ParserAndGenerator for JsonParserAndGenerator { let (diagnostics, data) = match parse_result { Ok(data) => (vec![], Some(data)), - Err(err) => (err.into(), None), + Err(err) => (vec![err.into()], None), }; build_info.json_data = data.clone(); From 93bab108c42a60e172ddc9ba3eadaa518832f62a Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Mon, 11 Dec 2023 19:55:56 +0800 Subject: [PATCH 18/18] =?UTF-8?q?chore:=20=F0=9F=A4=96=20snapshot?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/__snapshots__/case.test.ts.snap | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/rspack/tests/__snapshots__/case.test.ts.snap b/packages/rspack/tests/__snapshots__/case.test.ts.snap index e0dd46323fc..208119fbdd2 100644 --- a/packages/rspack/tests/__snapshots__/case.test.ts.snap +++ b/packages/rspack/tests/__snapshots__/case.test.ts.snap @@ -8,17 +8,6 @@ exports[`cases exported tests data imports 1`] = ` .red{color: red;} /* #endregion "data:text/css,.red{color: red;}" */ -/* #region "./bad-base64.css" */ -/* -- type: css -*/ -.bad { - a: url(data:text/bad-base64;base64,abcd?#iefix); - b: url("data:text/bad-base64;base64, abcd?#iefix"); -} - -/* #endregion "./bad-base64.css" */ - /* #region "data:text/css;base64,LmJ7Y29sb3I6IGdyZWVufQ==" */ /* - type: css @@ -34,6 +23,17 @@ exports[`cases exported tests data imports 1`] = ` /* #endregion "./a.css" */ +/* #region "./bad-base64.css" */ +/* +- type: css +*/ +.bad { + a: url(data:text/bad-base64;base64,abcd?#iefix); + b: url("data:text/bad-base64;base64, abcd?#iefix"); +} + +/* #endregion "./bad-base64.css" */ + /* #region "./index.css" */ /* - type: css