From bd78e52d00edc5ad11b8beb72fce6bbdb6ef081c Mon Sep 17 00:00:00 2001 From: neverland Date: Fri, 15 Nov 2024 17:06:27 +0800 Subject: [PATCH 01/10] test: replace strip-ansi with Node.js builtin util (#8439) --- packages/rspack-cli/package.json | 1 - packages/rspack-cli/tests/utils/test-utils.ts | 2 +- packages/rspack-test-tools/package.json | 1 - .../rspack-test-tools/src/helper/legacy/captureStdio.js | 2 +- packages/rspack-test-tools/src/processor/defaults.ts | 2 +- pnpm-lock.yaml | 9 --------- tests/webpack-cli-test/api/do-install.test.js | 2 +- tests/webpack-cli-test/utils/test-utils.js | 2 +- tests/webpack-test/Defaults.unittest.js | 2 +- tests/webpack-test/helpers/captureStdio.js | 2 +- tests/webpack-test/helpers/diffStats.js | 2 +- tests/webpack-test/package.json | 1 - 12 files changed, 8 insertions(+), 20 deletions(-) diff --git a/packages/rspack-cli/package.json b/packages/rspack-cli/package.json index 59c7c559f1bc..9bdd71284560 100644 --- a/packages/rspack-cli/package.json +++ b/packages/rspack-cli/package.json @@ -55,7 +55,6 @@ "cross-env": "^7.0.3", "execa": "^5.0.0", "internal-ip": "6.2.0", - "strip-ansi": "6.0.1", "ts-node": "^10.9.2", "typescript": "^5.6.3" }, diff --git a/packages/rspack-cli/tests/utils/test-utils.ts b/packages/rspack-cli/tests/utils/test-utils.ts index f6f65fcd303f..015b14212b9d 100644 --- a/packages/rspack-cli/tests/utils/test-utils.ts +++ b/packages/rspack-cli/tests/utils/test-utils.ts @@ -3,7 +3,7 @@ "use strict"; const os = require("os"); -const stripAnsi = require("strip-ansi"); +const { stripVTControlCharacters: stripAnsi } = require("node:util"); const path = require("path"); const fs = require("fs"); const execa = require("execa"); diff --git a/packages/rspack-test-tools/package.json b/packages/rspack-test-tools/package.json index a6ca6c778caa..4cf833fc8b92 100644 --- a/packages/rspack-test-tools/package.json +++ b/packages/rspack-test-tools/package.json @@ -64,7 +64,6 @@ "path-serializer": "0.1.2", "pretty-format": "29.7.0", "rimraf": "3.0.2", - "strip-ansi": "6.0.1", "webpack": "^5.94.0", "webpack-merge": "5.9.0", "webpack-sources": "3.2.3" diff --git a/packages/rspack-test-tools/src/helper/legacy/captureStdio.js b/packages/rspack-test-tools/src/helper/legacy/captureStdio.js index 17043afc8303..66fc51a4ed82 100644 --- a/packages/rspack-test-tools/src/helper/legacy/captureStdio.js +++ b/packages/rspack-test-tools/src/helper/legacy/captureStdio.js @@ -1,5 +1,5 @@ // @ts-nocheck -const stripAnsi = require("strip-ansi"); +const { stripVTControlCharacters: stripAnsi } = require("node:util"); module.exports = (stdio, tty) => { let logs = []; diff --git a/packages/rspack-test-tools/src/processor/defaults.ts b/packages/rspack-test-tools/src/processor/defaults.ts index 9950dfc8e6ba..62eae56994dd 100644 --- a/packages/rspack-test-tools/src/processor/defaults.ts +++ b/packages/rspack-test-tools/src/processor/defaults.ts @@ -1,5 +1,5 @@ +import { stripVTControlCharacters as stripAnsi } from "node:util"; import { diff as jestDiff } from "jest-diff"; -import stripAnsi from "strip-ansi"; import type { ECompilerType, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7f3629d8cb7..51b0295cd09a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -503,9 +503,6 @@ importers: internal-ip: specifier: 6.2.0 version: 6.2.0 - strip-ansi: - specifier: 6.0.1 - version: 6.0.1 ts-node: specifier: ^10.9.2 version: 10.9.2(@swc/core@1.7.40(@swc/helpers@0.5.13))(@types/node@20.12.7)(typescript@5.6.3) @@ -575,9 +572,6 @@ importers: rimraf: specifier: 3.0.2 version: 3.0.2 - strip-ansi: - specifier: 6.0.1 - version: 6.0.1 webpack: specifier: ^5.94.0 version: 5.94.0(@swc/core@1.7.40(@swc/helpers@0.5.13))(webpack-cli@5.1.4(webpack@5.94.0)) @@ -1030,9 +1024,6 @@ importers: source-map: specifier: ^0.7.4 version: 0.7.4 - strip-ansi: - specifier: ^6.0.0 - version: 6.0.1 terser: specifier: 5.27.2 version: 5.27.2 diff --git a/tests/webpack-cli-test/api/do-install.test.js b/tests/webpack-cli-test/api/do-install.test.js index e6d99b53ef05..2e90dc7ef62d 100644 --- a/tests/webpack-cli-test/api/do-install.test.js +++ b/tests/webpack-cli-test/api/do-install.test.js @@ -4,7 +4,7 @@ const CLI = require("../../packages/webpack-cli/lib/webpack-cli"); // eslint-disable-next-line node/no-unpublished-require -const stripAnsi = require("strip-ansi"); +const { stripVTControlCharacters: stripAnsi } = require("node:util"); const readlineQuestionMock = jest.fn(); diff --git a/tests/webpack-cli-test/utils/test-utils.js b/tests/webpack-cli-test/utils/test-utils.js index 1952425076b1..7ad2391187f5 100644 --- a/tests/webpack-cli-test/utils/test-utils.js +++ b/tests/webpack-cli-test/utils/test-utils.js @@ -3,7 +3,7 @@ "use strict"; const os = require("os"); -const stripAnsi = require("strip-ansi"); +const { stripVTControlCharacters: stripAnsi } = require("node:util"); const path = require("path"); const fs = require("fs"); const execa = require("execa"); diff --git a/tests/webpack-test/Defaults.unittest.js b/tests/webpack-test/Defaults.unittest.js index 9ec44e0b3a28..d179f1c59223 100644 --- a/tests/webpack-test/Defaults.unittest.js +++ b/tests/webpack-test/Defaults.unittest.js @@ -3,7 +3,7 @@ require("./helpers/warmup-webpack"); const path = require("path"); const jestDiff = require("jest-diff").diff; -const stripAnsi = require("strip-ansi"); +const { stripVTControlCharacters: stripAnsi } = require("node:util"); /** * Escapes regular expression metacharacters diff --git a/tests/webpack-test/helpers/captureStdio.js b/tests/webpack-test/helpers/captureStdio.js index e3678e110871..5e915ace23b2 100644 --- a/tests/webpack-test/helpers/captureStdio.js +++ b/tests/webpack-test/helpers/captureStdio.js @@ -1,4 +1,4 @@ -const stripAnsi = require("strip-ansi"); +const { stripVTControlCharacters: stripAnsi } = require("node:util"); module.exports = (stdio, tty) => { let logs = []; diff --git a/tests/webpack-test/helpers/diffStats.js b/tests/webpack-test/helpers/diffStats.js index 57fbef3f14be..3a7b513e1e01 100644 --- a/tests/webpack-test/helpers/diffStats.js +++ b/tests/webpack-test/helpers/diffStats.js @@ -1,5 +1,5 @@ const diff = require("jest-diff").diff; -const stripAnsi = require("strip-ansi"); +const { stripVTControlCharacters: stripAnsi } = require("node:util"); const processStats = str => { return str.trim().split('\n').map(i => i.trim()).join('\n').replace(/\d+(\.\d+)?/g, 'XX').replace(/"/g, ""); diff --git a/tests/webpack-test/package.json b/tests/webpack-test/package.json index 36fecc0ecb51..8d8578673c5d 100644 --- a/tests/webpack-test/package.json +++ b/tests/webpack-test/package.json @@ -51,7 +51,6 @@ "sass-embedded": "^1.77.8", "sass-loader": "^16.0.0", "source-map": "^0.7.4", - "strip-ansi": "^6.0.0", "terser": "5.27.2", "terser-webpack-plugin": "^5.3.10", "ts-node": "^10.9.2", From 49a99741c2cfa141b1f2323d05fbf8b06f4b8d01 Mon Sep 17 00:00:00 2001 From: Wei Date: Fri, 15 Nov 2024 17:16:03 +0800 Subject: [PATCH 02/10] feat: support attributes for ESM external module (#8422) --- crates/rspack_core/src/external_module.rs | 46 +++++-- crates/rspack_plugin_externals/src/plugin.rs | 1 + .../src/modern_module/import_dependency.rs | 14 ++- .../src/modern_module_library_plugin.rs | 2 +- .../src/module_library_plugin.rs | 11 +- .../index.js | 1 + .../main.js | 3 +- .../rspack.config.js | 1 + .../webpack-test/ConfigTestCases.template.js | 118 +++++++++--------- .../import-attributes/test.filter.js | 8 +- .../import-attributes/webpack.config.js | 2 +- tests/webpack-test/helpers/pkg.json | 3 + 12 files changed, 129 insertions(+), 81 deletions(-) create mode 100644 tests/webpack-test/helpers/pkg.json diff --git a/crates/rspack_core/src/external_module.rs b/crates/rspack_core/src/external_module.rs index 1b6283a4168c..cc072a59edf0 100644 --- a/crates/rspack_core/src/external_module.rs +++ b/crates/rspack_core/src/external_module.rs @@ -13,8 +13,8 @@ use crate::{ to_identifier, AsyncDependenciesBlockIdentifier, BuildContext, BuildInfo, BuildMeta, BuildMetaExportsType, BuildResult, ChunkInitFragments, ChunkUkey, CodeGenerationDataUrl, CodeGenerationResult, Compilation, ConcatenationScope, Context, DependenciesBlock, DependencyId, - ExternalType, FactoryMeta, InitFragmentExt, InitFragmentKey, InitFragmentStage, LibIdentOptions, - Module, ModuleType, NormalInitFragment, RuntimeGlobals, RuntimeSpec, SourceType, + ExternalType, FactoryMeta, ImportAttributes, InitFragmentExt, InitFragmentKey, InitFragmentStage, + LibIdentOptions, Module, ModuleType, NormalInitFragment, RuntimeGlobals, RuntimeSpec, SourceType, StaticExportsDependency, StaticExportsSpec, NAMESPACE_OBJECT_EXPORT, }; use crate::{ChunkGraph, ModuleGraph}; @@ -112,12 +112,24 @@ fn get_source_for_commonjs(module_and_specifiers: &ExternalRequestValue) -> Stri fn get_source_for_import( module_and_specifiers: &ExternalRequestValue, compilation: &Compilation, + attributes: &Option, ) -> String { - format!( - "{}({})", - compilation.options.output.import_function_name, - serde_json::to_string(module_and_specifiers.primary()).expect("invalid json to_string") - ) + format!("{}({})", compilation.options.output.import_function_name, { + let attributes_str = if let Some(attributes) = attributes { + format!( + ", {{ with: {} }}", + serde_json::to_string(attributes).expect("invalid json to_string") + ) + } else { + String::new() + }; + + format!( + "{}{}", + serde_json::to_string(module_and_specifiers.primary()).expect("invalid json to_string"), + attributes_str + ) + }) } /** @@ -178,6 +190,7 @@ pub type MetaExternalType = Option; #[derive(Debug)] pub struct DependencyMeta { pub external_type: MetaExternalType, + pub attributes: Option, } impl ExternalModule { @@ -300,7 +313,7 @@ impl ExternalModule { "import" if let Some(request) = request => format!( "{} = {};", get_namespace_object_export(concatenation_scope, supports_const), - get_source_for_import(request, compilation) + get_source_for_import(request, compilation, &self.dependency_meta.attributes) ), "var" | "promise" | "const" | "let" | "assign" if let Some(request) = request => format!( "{} = {};", @@ -313,9 +326,20 @@ impl ExternalModule { chunk_init_fragments.push( NormalInitFragment::new( format!( - "import * as __WEBPACK_EXTERNAL_MODULE_{}__ from {};\n", + "import * as __WEBPACK_EXTERNAL_MODULE_{}__ from {}{};\n", id.clone(), - json_stringify(request.primary()) + json_stringify(request.primary()), + { + let meta = &self.dependency_meta.attributes; + if let Some(meta) = meta { + format!( + " with {}", + serde_json::to_string(meta).expect("json stringify failed"), + ) + } else { + String::new() + } + }, ), InitFragmentStage::StageESMImports, 0, @@ -344,7 +368,7 @@ impl ExternalModule { format!( "{} = {};", get_namespace_object_export(concatenation_scope, supports_const), - get_source_for_import(request, compilation) + get_source_for_import(request, compilation, &self.dependency_meta.attributes) ) } } diff --git a/crates/rspack_plugin_externals/src/plugin.rs b/crates/rspack_plugin_externals/src/plugin.rs index 6539624810ec..c10dddffa922 100644 --- a/crates/rspack_plugin_externals/src/plugin.rs +++ b/crates/rspack_plugin_externals/src/plugin.rs @@ -103,6 +103,7 @@ impl ExternalsPlugin { } let dependency_meta: DependencyMeta = DependencyMeta { + attributes: dependency.get_attributes().cloned(), external_type: { if dependency .as_any() diff --git a/crates/rspack_plugin_library/src/modern_module/import_dependency.rs b/crates/rspack_plugin_library/src/modern_module/import_dependency.rs index b6cc783cbcb8..6dbb1afc8a03 100644 --- a/crates/rspack_plugin_library/src/modern_module/import_dependency.rs +++ b/crates/rspack_plugin_library/src/modern_module/import_dependency.rs @@ -97,13 +97,23 @@ impl DependencyTemplate for ModernModuleImportDependency { }; if let Some(request_and_external_type) = request_and_external_type.0 { + let attributes_str = if let Some(attributes) = &self.attributes { + format!( + ", {{ with: {} }}", + serde_json::to_string(attributes).expect("invalid json to_string") + ) + } else { + String::new() + }; + source.replace( self.range.start, self.range.end, format!( - "import({})", + "import({}{})", serde_json::to_string(request_and_external_type.primary()) - .expect("invalid json to_string") + .expect("invalid json to_string"), + attributes_str ) .as_str(), None, diff --git a/crates/rspack_plugin_library/src/modern_module_library_plugin.rs b/crates/rspack_plugin_library/src/modern_module_library_plugin.rs index 541f050e1c88..877e7c6cdd5e 100644 --- a/crates/rspack_plugin_library/src/modern_module_library_plugin.rs +++ b/crates/rspack_plugin_library/src/modern_module_library_plugin.rs @@ -249,7 +249,7 @@ async fn finish_modules(&self, compilation: &mut Compilation) -> Result<()> { external_module.request.clone(), external_module.external_type.clone(), import_dependency.range.clone(), - None, + import_dependency.get_attributes().cloned(), ); deps_to_replace.push(( diff --git a/crates/rspack_plugin_library/src/module_library_plugin.rs b/crates/rspack_plugin_library/src/module_library_plugin.rs index e57f08094705..b6e917ed801d 100644 --- a/crates/rspack_plugin_library/src/module_library_plugin.rs +++ b/crates/rspack_plugin_library/src/module_library_plugin.rs @@ -3,8 +3,8 @@ use std::hash::Hash; use rspack_core::rspack_sources::{ConcatSource, RawSource, SourceExt}; use rspack_core::{ property_access, to_identifier, ApplyContext, ChunkUkey, Compilation, CompilationParams, - CompilerCompilation, CompilerOptions, LibraryOptions, ModuleGraph, ModuleIdentifier, Plugin, - PluginContext, + CompilerCompilation, CompilerOptions, ExportInfoProvided, LibraryOptions, ModuleGraph, + ModuleIdentifier, Plugin, PluginContext, }; use rspack_error::{error_bail, Result}; use rspack_hash::RspackHash; @@ -76,6 +76,13 @@ fn render_startup( } let exports_info = module_graph.get_exports_info(module); for export_info in exports_info.ordered_exports(&module_graph) { + if !(matches!( + export_info.provided(&module_graph), + Some(ExportInfoProvided::True) + )) { + continue; + }; + let chunk = compilation.chunk_by_ukey.expect_get(chunk_ukey); let info_name = export_info.name(&module_graph).expect("should have name"); let used_name = export_info diff --git a/packages/rspack-test-tools/tests/configCases/library/modern-module-dynamic-import-runtime/index.js b/packages/rspack-test-tools/tests/configCases/library/modern-module-dynamic-import-runtime/index.js index 50773c569b91..fdbcf1aa7726 100644 --- a/packages/rspack-test-tools/tests/configCases/library/modern-module-dynamic-import-runtime/index.js +++ b/packages/rspack-test-tools/tests/configCases/library/modern-module-dynamic-import-runtime/index.js @@ -11,6 +11,7 @@ it("modern-module-dynamic-import-runtime", () => { expect(initialChunk).toContain('import * as __WEBPACK_EXTERNAL_MODULE_angular_alias__ from "angular-alias"'); expect(initialChunk).toContain('const reactNs = await import("react-alias")'); expect(initialChunk).toContain('const vueNs = await import("vue-alias")'); + expect(initialChunk).toContain('const jqueryNs = await import("jquery-alias", { with: {"type":"url"} })'); expect(asyncChunk).toContain('const litNs = await import("lit-alias")'); expect(asyncChunk).toContain('const solidNs = await import("solid-alias")'); diff --git a/packages/rspack-test-tools/tests/configCases/library/modern-module-dynamic-import-runtime/main.js b/packages/rspack-test-tools/tests/configCases/library/modern-module-dynamic-import-runtime/main.js index 56d3b40b09a2..0fb39228c959 100644 --- a/packages/rspack-test-tools/tests/configCases/library/modern-module-dynamic-import-runtime/main.js +++ b/packages/rspack-test-tools/tests/configCases/library/modern-module-dynamic-import-runtime/main.js @@ -5,5 +5,6 @@ export const main = async () => { const dyn = await import('./dyn.js') // lazy dynamic import const reactNs = await import('react') // 'module' + 'import' externalized const vueNs = await import('vue') // 'import' externalized - console.log(angular, react, reactNs, vueNs, dyn) + const jqueryNs = await import('jquery', { with: { type: 'url' } }) // import attributes should be preserved + console.log(angular, react, reactNs, vueNs, dyn, jqueryNs) } diff --git a/packages/rspack-test-tools/tests/configCases/library/modern-module-dynamic-import-runtime/rspack.config.js b/packages/rspack-test-tools/tests/configCases/library/modern-module-dynamic-import-runtime/rspack.config.js index fb939a310c4b..c512dd8afe74 100644 --- a/packages/rspack-test-tools/tests/configCases/library/modern-module-dynamic-import-runtime/rspack.config.js +++ b/packages/rspack-test-tools/tests/configCases/library/modern-module-dynamic-import-runtime/rspack.config.js @@ -21,6 +21,7 @@ module.exports = [{ svelte: 'svelte-alias', lit: 'lit-alias', solid: 'solid-alias', + jquery: 'jquery-alias', }, externalsType: 'module-import', experiments: { diff --git a/tests/webpack-test/ConfigTestCases.template.js b/tests/webpack-test/ConfigTestCases.template.js index 47f6471880c8..143696f8f8b5 100644 --- a/tests/webpack-test/ConfigTestCases.template.js +++ b/tests/webpack-test/ConfigTestCases.template.js @@ -567,6 +567,7 @@ const describeCases = config => { } if (esmMode === "unlinked") return esm; return (async () => { + if (esmMode === "unlinked") return esm; await esm.link( async (specifier, referencingModule) => { return await asModule( @@ -597,64 +598,69 @@ const describeCases = config => { ? ns.default : ns; })(); - } else { - if (p in requireCache) { - return requireCache[p].exports; - } - const m = { - exports: {} - }; - requireCache[p] = m; - const moduleScope = { - ...baseModuleScope, - require: _require.bind( - null, - path.dirname(p), - options - ), - importScripts: url => { - expect(url).toMatch( - /^https:\/\/test\.cases\/path\// - ); - _require( - outputDirectory, - options, - `.${url.slice( - "https://test.cases/path".length - )}` - ); - }, - module: m, - exports: m.exports, - __dirname: path.dirname(p), - __filename: p, - _globalAssign: { expect } - }; - if (testConfig.moduleScope) { - testConfig.moduleScope(moduleScope); - } - if (!runInNewContext) - content = `Object.assign(global, _globalAssign); ${content}`; - const args = Object.keys(moduleScope); - const argValues = args.map(arg => moduleScope[arg]); - const code = `(function(${args.join( - ", " - )}) {${content}\n})`; + } + const isJSON = p.endsWith(".json"); + if (isJSON) { + return JSON.parse(content); + } - let oldCurrentScript = document.currentScript; - document.currentScript = new CurrentScript(subPath); - const fn = runInNewContext - ? vm.runInNewContext(code, globalContext, p) - : vm.runInThisContext(code, p); - fn.call( - testConfig.nonEsmThis - ? testConfig.nonEsmThis(module) - : m.exports, - ...argValues - ); - document.currentScript = oldCurrentScript; - return m.exports; + if (p in requireCache) { + return requireCache[p].exports; } + const m = { + exports: {} + }; + requireCache[p] = m; + + const moduleScope = { + ...baseModuleScope, + require: _require.bind( + null, + path.dirname(p), + options + ), + importScripts: url => { + expect(url).toMatch( + /^https:\/\/test\.cases\/path\// + ); + _require( + outputDirectory, + options, + `.${url.slice( + "https://test.cases/path".length + )}` + ); + }, + module: m, + exports: m.exports, + __dirname: path.dirname(p), + __filename: p, + _globalAssign: { expect } + }; + if (testConfig.moduleScope) { + testConfig.moduleScope(moduleScope); + } + if (!runInNewContext) + content = `Object.assign(global, _globalAssign); ${content}`; + const args = Object.keys(moduleScope); + const argValues = args.map(arg => moduleScope[arg]); + const code = `(function(${args.join( + ", " + )}) {${content}\n})`; + + let oldCurrentScript = document.currentScript; + document.currentScript = new CurrentScript(subPath); + const fn = runInNewContext + ? vm.runInNewContext(code, globalContext, p) + : vm.runInThisContext(code, p); + fn.call( + testConfig.nonEsmThis + ? testConfig.nonEsmThis(module) + : m.exports, + ...argValues + ); + document.currentScript = oldCurrentScript; + return m.exports; } else if ( testConfig.modules && module in testConfig.modules diff --git a/tests/webpack-test/configCases/externals/import-attributes/test.filter.js b/tests/webpack-test/configCases/externals/import-attributes/test.filter.js index 28d3a82d21b9..2ce4d1c330ea 100644 --- a/tests/webpack-test/configCases/externals/import-attributes/test.filter.js +++ b/tests/webpack-test/configCases/externals/import-attributes/test.filter.js @@ -1,7 +1 @@ - -// TODO: Should create a issue for this test -// TODO: _painic -module.exports = () => { - // return /^v(2[2-9])/.test(process.version); - return false; -}; +module.exports = () => /^v(2[2-9])/.test(process.version); diff --git a/tests/webpack-test/configCases/externals/import-attributes/webpack.config.js b/tests/webpack-test/configCases/externals/import-attributes/webpack.config.js index 77d69ca387b3..5c3911098a58 100644 --- a/tests/webpack-test/configCases/externals/import-attributes/webpack.config.js +++ b/tests/webpack-test/configCases/externals/import-attributes/webpack.config.js @@ -58,7 +58,7 @@ module.exports = { "./eager.json": "import ./eager.json", "./weak.json": "import ./weak.json", "./pkg.json": "import ./pkg.json", - "./pkg": "import ./pkg", + "./pkg": "import ./pkg.json", "./re-export.json": "module ./re-export.json", "./re-export-directly.json": "module ./re-export-directly.json" } diff --git a/tests/webpack-test/helpers/pkg.json b/tests/webpack-test/helpers/pkg.json new file mode 100644 index 000000000000..c8c4105eb57c --- /dev/null +++ b/tests/webpack-test/helpers/pkg.json @@ -0,0 +1,3 @@ +{ + "foo": "bar" +} From d84e9318d840901a6013b87d8a2621369d5d89ff Mon Sep 17 00:00:00 2001 From: neverland Date: Fri, 15 Nov 2024 18:04:26 +0800 Subject: [PATCH 03/10] docs: polish module methods documentation (#8448) --- website/docs/en/api/cli.mdx | 2 +- .../en/api/runtime-api/module-methods.mdx | 24 ++++++++------ .../en/api/runtime-api/module-variables.mdx | 2 ++ .../en/guide/optimization/code-splitting.mdx | 8 ++--- website/docs/en/guide/tech/react.mdx | 6 ++-- website/docs/zh/api/cli.mdx | 2 +- .../zh/api/runtime-api/module-methods.mdx | 32 +++++++++++-------- .../zh/guide/optimization/code-splitting.mdx | 8 ++--- website/docs/zh/guide/tech/react.mdx | 8 ++--- 9 files changed, 51 insertions(+), 41 deletions(-) diff --git a/website/docs/en/api/cli.mdx b/website/docs/en/api/cli.mdx index e04cdc0c36ad..d6c291da5568 100644 --- a/website/docs/en/api/cli.mdx +++ b/website/docs/en/api/cli.mdx @@ -1,6 +1,6 @@ # Command Line Interface (CLI) -@rspack/cli provides two common subcommands, serve and build, to simplify daily work. If you do not have @rspack/cli installed, please read the [Quick Start](/guide/start/quick-start) section first. +[@rspack/cli](https://npmjs.com/package/@rspack/cli) provides two common subcommands, serve and build, to simplify daily work. If you do not have @rspack/cli installed, please read the [Quick Start](/guide/start/quick-start) section first. :::warning Compatible with webpack-cli @rspack/cli is not going to be compatible with webpack-cli, so there will be many differences between the two. diff --git a/website/docs/en/api/runtime-api/module-methods.mdx b/website/docs/en/api/runtime-api/module-methods.mdx index 6e2f85418f17..c33a1abe14de 100644 --- a/website/docs/en/api/runtime-api/module-methods.mdx +++ b/website/docs/en/api/runtime-api/module-methods.mdx @@ -5,11 +5,11 @@ import { ApiMeta } from '@components/ApiMeta'; # Module Methods -This section covers all methods available in code compiled with Rspack. When using Rspack to bundle your application, you can pick from a variety of module syntax styles including ES6, CommonJS. +This section covers all methods available in code compiled with Rspack. When using Rspack to bundle your application, you can pick from a variety of module syntax styles including [ES modules](https://nodejs.org/api/esm.html#modules-ecmascript-modules) and [CommonJS](https://nodejs.org/api/modules.html). -While Rspack supports multiple module syntaxes, we recommend following a single syntax for consistency and to avoid odd behaviors/bugs. +While Rspack supports multiple module syntaxes, we recommend following a single syntax for consistency and to avoid odd behaviors or bugs. -Actually Rspack would enforce the recommendation for `.mjs` files, `.cjs` files or `.js` files when their nearest parent `package.json` file contains a `"type"` field with a value of either `"module"` or `"commonjs"`. Please pay attention to these enforcements before you read on: +Actually Rspack would enforce the recommendation for `.mjs` files, `.cjs` files or `.js` files when their nearest parent `package.json` file contains a ["type"](https://nodejs.org/api/packages.html#type) field with a value of either `"module"` or `"commonjs"`. Please pay attention to these enforcements before you read on: - `.mjs` or `.js` with `"type": "module"` in package.json - No CommonJS allowed, for example, you can't use `require`, `module.exports` or `exports` @@ -17,9 +17,9 @@ Actually Rspack would enforce the recommendation for `.mjs` files, `.cjs` files - `.cjs` or `.js` with "type": "commonjs" in package.json - Neither import nor export is available -## ES6 (Recommended) +## ES modules (Recommended) -Rspack support ES6 module syntax natively, you can use static `import`, `export` and `import()` syntax. +Rspack support ES modules syntax natively, you can use static `import`, `export` and `import()` syntax. :::warning Keep in mind that you will still probably need SWC or Babel for other ES6+ features. @@ -67,7 +67,9 @@ export default { function import(path: string): Promise; ``` -Dynamically load modules. Calls to `import()` are treated as split points, meaning the requested module and its children are split out into a separate chunk. +Dynamically load modules, see [Dynamic import](/guide/optimization/code-splitting#dynamic-import) for more details. + +Calls to `import()` are treated as split points, meaning the requested module and its children are split out into a separate chunk. ```js if (module.hot) { @@ -78,14 +80,15 @@ if (module.hot) { ``` :::warning -This feature relies on `Promise` internally. If you use import() with older browsers, remember to shim `Promise` using a polyfill such as [es6-promise](https://github.com/stefanpenner/es6-promise) or [promise-polyfill](https://github.com/taylorhakes/promise-polyfill). +This feature relies on `Promise` internally. If you use `import()` with legacy browsers, remember to shim `Promise` using a polyfill such as [core-js](https://github.com/zloirock/core-js), [es6-promise](https://github.com/stefanpenner/es6-promise) or [promise-polyfill](https://github.com/taylorhakes/promise-polyfill). ::: #### Dynamic expressions in import() It is not possible to use a fully dynamic import statement, such as `import(foo)`. Because `foo` could potentially be any path to any file in your system or project. -The `import()` must contain at least some information about where the module is located. Bundling can be limited to a specific directory or set of files so that when you are using a dynamic expression - every module that could potentially be requested on an `import()` call is included. +The `import()` must contain at least some information about where the module is located. Bundling can be limited to a specific directory or set of files so that when you are using a dynamic expression, every module that could potentially be requested on an `import()` call is included. + For example, `import(`./locale/$\{language}.json`)` will cause every `.json` file in the `./locale` directory to be bundled into the new chunk. At run time, when the variable `language` has been computed, any file like `english.json` or `german.json` will be available for consumption. ```js @@ -100,7 +103,7 @@ import(`./locale/${language}.json`).then(module => { -Inline comments to make features work. By adding comments to the import, we can do things such as name our chunk or select different modes. For a full list of these magic comments see the code below followed by an explanation of what these comments do. +Inline comments to make features work. By adding comments to the import, we can do things such as specify chunk name or select different loading modes. For a full list of these magic comments see the code below followed by an explanation of what these comments do. ```js // Single target @@ -128,7 +131,7 @@ import( - **Type:** `boolean` -Disables dynamic import parsing when set to true.{' '} +Disables dynamic import parsing when set to true. :::warning Note that setting webpackIgnore to true opts out of code splitting. @@ -137,6 +140,7 @@ Note that setting webpackIgnore to true opts out of code splitting. ##### webpackMode - **Type:** `"eager" | "lazy" | "weak" | "lazy-once"` +- **Default:** `'lazy'` Different modes for resolving dynamic imports can be specified. The following options are supported: diff --git a/website/docs/en/api/runtime-api/module-variables.mdx b/website/docs/en/api/runtime-api/module-variables.mdx index 2883cdb4e5a2..636881901fbe 100644 --- a/website/docs/en/api/runtime-api/module-variables.mdx +++ b/website/docs/en/api/runtime-api/module-variables.mdx @@ -6,6 +6,8 @@ import { ApiMeta } from '@components/ApiMeta'; # Module Variables +This section covers all variables available in code compiled with Rspack. Modules will be able to access specific data from the compilation process through `module` and other variables. + ## CommonJs ### module.loaded diff --git a/website/docs/en/guide/optimization/code-splitting.mdx b/website/docs/en/guide/optimization/code-splitting.mdx index 9480b2744887..a06bdc580855 100644 --- a/website/docs/en/guide/optimization/code-splitting.mdx +++ b/website/docs/en/guide/optimization/code-splitting.mdx @@ -12,10 +12,6 @@ Here we introduce a concept called Chunk, representing a resource that a browser Rspack use the [import()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) syntax that conforms to the ECMAScript proposal for dynamic imports. -:::tip Inconsistent behaviors with webpack -Rspack doesn't support `require.ensure`. -::: - In `index.js`, we dynamically import two modules through `import()`, thereby separating into a new chunk. ```js title=index.js @@ -35,6 +31,10 @@ console.log('bar.js'); Now we build this project, we get 3 chunks, `src_bar_js.js`, `src_foo_js.js` and `main.js`, if you see them, you will find `shared.js` exist in both `src_bar_js.js` and `src_foo_js.js`, we will remove duplicated modules in later chapters. +:::tip +Refer to [Module Methods - Dynamic import()](/api/runtime-api/module-methods#dynamic-import) for the detailed dynamic import API, as well as how to use dynamic expressions and magic comments in dynamic import. +::: + :::info Though `shared.js` exist in 2 chunks, but it is executed only once, you don't have to worry about issue of multiple instance. ::: diff --git a/website/docs/en/guide/tech/react.mdx b/website/docs/en/guide/tech/react.mdx index 13e857820568..761a5f22e7cb 100644 --- a/website/docs/en/guide/tech/react.mdx +++ b/website/docs/en/guide/tech/react.mdx @@ -12,9 +12,9 @@ Rspack provides two solutions to support React: ## Configure JSX/TSX -Rspack leverages SWC transformer for JSX/TSX. +Rspack leverages SWC transformer for supporting JSX and TSX. -Add `builtin:swc-loader` loader to support `jsx` and `tsx`: +You can add [builtin:swc-loader](/guide/features/builtin-swc-loader) loader to support `.jsx` and `.tsx` files: ```js title=rspack.config.js module.exports = { @@ -55,7 +55,7 @@ module.exports = { }; ``` -Refer to [Builtin swc-loader](guide/features/builtin-swc-loader) for detailed configurations. +Refer to [builtin:swc-loader](/guide/features/builtin-swc-loader) for detailed configurations. ## Fast Refresh diff --git a/website/docs/zh/api/cli.mdx b/website/docs/zh/api/cli.mdx index e269bb458d74..d748394a6158 100644 --- a/website/docs/zh/api/cli.mdx +++ b/website/docs/zh/api/cli.mdx @@ -1,6 +1,6 @@ # 命令行接口 (CLI) -@rspack/cli 提供了 `serve` 和 `build` 两个常用的子命令来简化日常工作。如果你没有安装过 `@rspack/cli`,请先阅读[快速开始](/guide/start/quick-start)章节。 +[@rspack/cli](https://npmjs.com/package/@rspack/cli) 提供了 `serve` 和 `build` 两个常用的子命令来简化日常工作。如果你没有安装过 `@rspack/cli`,请先阅读[快速开始](/guide/start/quick-start)章节。 :::warning 和 webpack-cli 的兼容性 `@rspack/cli` 不计划和 `webpack-cli` 进行兼容,因此 `@rspack/cli` 和 `webpack-cli` 会有很多使用方式的差异。 diff --git a/website/docs/zh/api/runtime-api/module-methods.mdx b/website/docs/zh/api/runtime-api/module-methods.mdx index a4233157ede6..732e657617b6 100644 --- a/website/docs/zh/api/runtime-api/module-methods.mdx +++ b/website/docs/zh/api/runtime-api/module-methods.mdx @@ -5,24 +5,24 @@ import { ApiMeta } from '@components/ApiMeta'; # 模块方法 -当使用 Rspack 打包应用程序时,你可以选择多种模块语法风格,包括 ES6、CommonJS。 +当使用 Rspack 打包应用程序时,你可以选择多种模块语法风格,包括 [ES modules](https://nodejs.org/api/esm.html#modules-ecmascript-modules) 和 [CommonJS](https://nodejs.org/api/modules.html)。 尽管 Rspack 支持多种模块语法,但我们还是建议尽量使用一致的语法,以此避免一些奇怪的行为和 bug。 -事实上,当距离最近的 `package.json` 文件中 `"type"` 字段值为 `"module"` 或 `"commonjs"` 时,Rspack 会对 `.mjs` 文件、`.cjs` 文件或`.js` 文件进行对应的处理: +事实上,当距离最近的 `package.json` 文件中 ["type"](https://nodejs.org/api/packages.html#type) 字段值为 `"module"` 或 `"commonjs"` 时,Rspack 会对 `.mjs` 文件、`.cjs` 文件或`.js` 文件进行对应的处理: -- 后缀为 `.mjs` 或者 `package.json` 中 `"type": "module"` 且后缀为 `.js` 时: +- 文件后缀为 `.mjs`,或者 `package.json` 中 `"type": "module"` 且后缀为 `.js` 时: - 不允许使用 CommonJS,如 `require`,`module.exports` 或 `exports` - 引入文件时需指定扩展名,例如,应使用 `import './src/App.mjs'`,而非 `import './src/App'` -- 后缀为 `.cjs` 或者 `package.json` 中 `"type": "commonjs"` 且后缀为 `.js` 时: +- 文件后缀为 `.cjs`,或者 `package.json` 中 `"type": "commonjs"` 且后缀为 `.js` 时: - 不允许使用 ESM,如 `import` 和 `export` -## ES6 (推荐) +## ES modules (推荐) -Rspack 原生支持 ES6 模块语法,可以使用静态的 `import`、`export` 和 `import()` 语法。 +Rspack 原生支持 ES modules 语法,可以使用静态的 `import`、`export` 和 `import()` 语法。 :::warning -如果使用其他的 ES6+ 特性,仍然需要引入 SWC / Babel 进行转换。 +如果使用其他的 ES6+ 特性,你仍然需要引入 SWC 或 Babel 进行转换。 ::: ### import @@ -61,13 +61,15 @@ export default { }; ``` -### 动态 import() +### Dynamic import() ```ts function import(path: string): Promise; ``` -动态加载模块。对 `import()` 的调用被视为分割点,这意味着请求的模块及其子模块被拆分成单独的 chunk。 +动态加载模块,参考 [Dynamic import](guide/optimization/code-splitting#动态导入dynamic-import) 了解更多。 + +对 `import()` 的调用被视为分割点,这意味着请求的模块及其子模块被拆分成单独的 chunk。 ```js if (module.hot) { @@ -77,15 +79,16 @@ if (module.hot) { } ``` -:::warning 警告 -此功能内部依赖于 `Promise`。如果你在旧版浏览器中使用 `import()`,请记得使用类似于 [`es6-promise`](https://github.com/stefanpenner/es6-promise) 或 [`promise-polyfill`](https://github.com/taylorhakes/promise-polyfill) 的 polyfill 来模拟 `Promise`。 +:::warning +此功能内部依赖于 `Promise`。如果你在旧版浏览器中使用 `import()`,请记得使用类似于 [core-js](https://github.com/zloirock/core-js), [es6-promise](https://github.com/stefanpenner/es6-promise) 或 [promise-polyfill](https://github.com/taylorhakes/promise-polyfill) 的 polyfill 来模拟 `Promise`。 ::: #### import() 中的动态表达式 -无法使用完全动态的导入语句,例如 `import(foo)`。因为 `foo` 可能是系统或项目中任何文件的任何路径。 +`import()` 无法使用完全动态的导入语句,例如 `import(foo)`。因为 `foo` 可能是系统或项目中任何文件的任何路径。 + +`import()` 必须至少包含一些关于模块所在位置的信息。可以将打包限制在特定目录或一组文件中,这样当你使用动态表达式时,在 `import()` 调用中可能被请求的每个模块都会被包括进来。 -`import()` 必须至少包含一些关于模块所在位置的信息。可以将打包限制在特定目录或一组文件中,这样当你使用动态表达式时 - 在 `import()` 调用中可能被请求的每个模块都会被包括进来。 例如,`import(./locale/${language}.json)` 会将 `./locale` 目录中的每个 `.json` 文件都被打包进新的代码块。在运行时,一旦变量 `language` 被计算出来,任何像 `english.json` 或 `german.json` 这样的文件都将可供使用。 ```js @@ -100,7 +103,7 @@ import(`./locale/${language}.json`).then(module => { -通过向 import 语句添加注释,我们可以执行诸如命名 chunk 或选择不同模式等操作。有关这些魔法注释的完整列表,请参见下面的代码,以及对这些注释功能的解释。 +通过向 import 语句添加注释,我们可以实现「指定 chunk 名称」或「设置加载模式」等操作。有关这些魔法注释的完整列表,请参见下面的代码,以及对这些注释功能的解释。 ```js // 单个模块 @@ -136,6 +139,7 @@ import( ##### webpackMode - **类型:** `"eager" | "lazy" | "weak" | "lazy-once"` +- **默认值:** `'lazy'` 可以指定以不同的模式解析动态导入。支持以下选项: diff --git a/website/docs/zh/guide/optimization/code-splitting.mdx b/website/docs/zh/guide/optimization/code-splitting.mdx index 54e20e78f06e..3d27794b0459 100644 --- a/website/docs/zh/guide/optimization/code-splitting.mdx +++ b/website/docs/zh/guide/optimization/code-splitting.mdx @@ -12,10 +12,6 @@ Rspack 支持代码分割特性,允许让你对代码进行分割,控制生 当涉及到动态代码拆分时, Rspack 使用符合 ECMAScript 提案的 [import()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) 语法来实现动态导入。 -:::tip 与 webpack 的差异点 -Rspack 不支持 `require.ensure` 功能。 -::: - 我们在 `index.js` 通过 `import()` 来动态导入 2 个模块,从而分离出一个新的 Chunk。 ```js title=index.js @@ -35,6 +31,10 @@ console.log('bar.js'); 此时我们执行构建,会得到 3 个 Chunk ,`src_bar_js.js`,`src_foo_js.js` 以及 `main.js`,如果我们查看他们,会发现 `src_bar_js.js` 和 `src_foo_js.js` 中有重复的部分:`shared.js`,我们后面会介绍为何存在重复模块,以及如何去除重复模块。 +:::tip +参考 [模块方法 - Dynamic import()](/api/runtime-api/module-methods#dynamic-import) 了解详细的 dynamic import API,以及如何在 dynamic import 中使用动态表达式和 magic comments。 +::: + :::info 虽然 `shared.js` 在 2 个 Chunk 中重复出现,但它只会被执行一次,不用担心重复模块会重复执行的问题。 ::: diff --git a/website/docs/zh/guide/tech/react.mdx b/website/docs/zh/guide/tech/react.mdx index 139b7ccd60fd..7ae556cbc358 100644 --- a/website/docs/zh/guide/tech/react.mdx +++ b/website/docs/zh/guide/tech/react.mdx @@ -12,9 +12,9 @@ Rspack 提供两种方案来支持 React: ## 配置 JSX/TSX -Rspack 使用 SWC 转译器支持 JSX/TSX。 +Rspack 使用 SWC 转译器支持 JSX 和 TSX。 -添加 `builtin:swc-loader` 以支持 `jsx` 和 `tsx`: +你可以添加 [builtin:swc-loader](/guide/features/builtin-swc-loader) 以支持 `.jsx` 和 `.tsx` 文件: ```js title=rspack.config.js module.exports = { @@ -55,7 +55,7 @@ module.exports = { }; ``` -关于配置项的更多信息请参考 [内置 swc-loader](guide/features/builtin-swc-loader)。 +关于配置项的更多信息请参考 [builtin:swc-loader](/guide/features/builtin-swc-loader)。 ## Fast Refresh @@ -65,7 +65,7 @@ module.exports = { [React Fast Refresh](https://reactnative.dev/docs/fast-refresh) 功能的开启主要分为两部分:代码注入和代码转换 -- 代码注入会注入 `react-refresh` 包中的一些代码,以及一些自定义的运行时代码,都已集成在 [@rspack/plugin-react-refresh](https://github.com/rspack-contrib/rspack-plugin-react-refresh) 插件中,可通过该插件注入 +- 代码注入会注入 `react-refresh` 包中的一些代码,以及一些自定义的运行时代码,都已集成在 [@rspack/plugin-react-refresh](https://github.com/rspack-contrib/rspack-plugin-react-refresh) 插件中,可通过该插件注入。 - 代码转换可通过 loader 来完成,比如 `swc-loader` 的 [jsc.transform.react.refresh](https://swc.rs/docs/configuration/compilation#jsctransformreactrefresh) 或 `babel-loader` 的 [react-refresh/babel 插件](https://github.com/facebook/react/tree/main/packages/react-refresh)。 ```js title=rspack.config.js From 425deee909426763c08fa124ff24257ceed4885a Mon Sep 17 00:00:00 2001 From: jinrui Date: Fri, 15 Nov 2024 21:17:28 +0800 Subject: [PATCH 04/10] fix: align bytes ptr address for `cacheable::from_byte` (#8450) * fix: cacheable::from_byte align bytes ptr address * ci: miri test add env MIRIFLAGS --- .github/workflows/ci.yml | 2 ++ crates/rspack_cacheable/src/deserialize.rs | 8 +++++++- crates/rspack_cacheable_test/tests/macro/cacheable_dyn.rs | 2 ++ .../tests/macro/manual_cacheable_dyn.rs | 1 + .../tests/macro/manual_cacheable_dyn_with_generics.rs | 1 + crates/rspack_macros_test/tests/compiletest.rs | 1 + 6 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0f658df1ec91..36e0bb5c6ea2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -346,6 +346,8 @@ jobs: echo 'debug = false' >> Cargo.toml - name: Run test + env: + MIRIFLAGS: -Zmiri-tree-borrows -Zmiri-disable-isolation # reason for excluding https://github.com/napi-rs/napi-rs/issues/2200 run: cargo miri test --workspace --exclude rspack_binding_options --exclude rspack_node -- --nocapture diff --git a/crates/rspack_cacheable/src/deserialize.rs b/crates/rspack_cacheable/src/deserialize.rs index a5981cea4f44..2e57b6970ef9 100644 --- a/crates/rspack_cacheable/src/deserialize.rs +++ b/crates/rspack_cacheable/src/deserialize.rs @@ -6,6 +6,7 @@ use rkyv::{ bytecheck::CheckBytes, de::Pool, rancor::{BoxedError, Source, Strategy, Trace}, + util::AlignedVec, Archive, Deserialize, }; @@ -79,8 +80,13 @@ where let guard = ContextGuard::new(context); let mut deserializer = Pool::default(); guard.add_to_pooling(&mut deserializer)?; + // The `bytes` ptr address in miri will throw UnalignedPointer error in rkyv. + // AlignedVec will force aligned the ptr address. + // Refer code: https://github.com/rkyv/rkyv/blob/dabbc1fcf5052f141403b84493bddb74c44f9ba9/rkyv/src/validation/archive/validator.rs#L135 + let mut aligned_vec = AlignedVec::<16>::new(); + aligned_vec.extend_from_slice(bytes); deserialize_using( - access::(bytes)?, + access::(&aligned_vec)?, &mut deserializer, ) } diff --git a/crates/rspack_cacheable_test/tests/macro/cacheable_dyn.rs b/crates/rspack_cacheable_test/tests/macro/cacheable_dyn.rs index 421db0f7823e..d02c88cf8877 100644 --- a/crates/rspack_cacheable_test/tests/macro/cacheable_dyn.rs +++ b/crates/rspack_cacheable_test/tests/macro/cacheable_dyn.rs @@ -1,6 +1,7 @@ use rspack_cacheable::{cacheable, cacheable_dyn, from_bytes, to_bytes}; #[test] +#[cfg_attr(miri, ignore)] fn test_cacheable_dyn_macro() { struct Context; @@ -71,6 +72,7 @@ fn test_cacheable_dyn_macro() { } #[test] +#[cfg_attr(miri, ignore)] fn test_cacheable_dyn_macro_with_generics() { struct Context; diff --git a/crates/rspack_cacheable_test/tests/macro/manual_cacheable_dyn.rs b/crates/rspack_cacheable_test/tests/macro/manual_cacheable_dyn.rs index 6ae4fe67684a..cac51e1ac587 100644 --- a/crates/rspack_cacheable_test/tests/macro/manual_cacheable_dyn.rs +++ b/crates/rspack_cacheable_test/tests/macro/manual_cacheable_dyn.rs @@ -1,6 +1,7 @@ use rspack_cacheable::{cacheable, from_bytes, to_bytes}; #[test] +#[cfg_attr(miri, ignore)] fn test_manual_cacheable_dyn_macro() { struct Context; diff --git a/crates/rspack_cacheable_test/tests/macro/manual_cacheable_dyn_with_generics.rs b/crates/rspack_cacheable_test/tests/macro/manual_cacheable_dyn_with_generics.rs index 55d070eee5ea..26ae3577a471 100644 --- a/crates/rspack_cacheable_test/tests/macro/manual_cacheable_dyn_with_generics.rs +++ b/crates/rspack_cacheable_test/tests/macro/manual_cacheable_dyn_with_generics.rs @@ -1,6 +1,7 @@ use rspack_cacheable::{cacheable, from_bytes, to_bytes}; #[test] +#[cfg_attr(miri, ignore)] fn test_manual_cacheable_dyn_macro_with_generics() { struct Context; diff --git a/crates/rspack_macros_test/tests/compiletest.rs b/crates/rspack_macros_test/tests/compiletest.rs index c67968303c3c..d1760ea1a8b6 100644 --- a/crates/rspack_macros_test/tests/compiletest.rs +++ b/crates/rspack_macros_test/tests/compiletest.rs @@ -1,4 +1,5 @@ #[test] +#[cfg_attr(miri, ignore)] fn ui() { let t = trybuild::TestCases::new(); t.compile_fail("tests/ui/hook/*.rs"); From 3c74282fbfb6e522d719571c77d0d6f2de915105 Mon Sep 17 00:00:00 2001 From: xiaohai Date: Fri, 15 Nov 2024 21:58:12 +0800 Subject: [PATCH 05/10] docs: update prefetching link (#8449) doc: update Prefetching link --- website/docs/zh/api/runtime-api/module-methods.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/zh/api/runtime-api/module-methods.mdx b/website/docs/zh/api/runtime-api/module-methods.mdx index 732e657617b6..414858b6f169 100644 --- a/website/docs/zh/api/runtime-api/module-methods.mdx +++ b/website/docs/zh/api/runtime-api/module-methods.mdx @@ -154,7 +154,7 @@ import( - `number`: 预取优先级 - `boolean`: `false` 表示不预取, `true` 表示预取并且优先级是 `0` -告诉浏览器将来可能需要该资源来进行某些导航跳转,详情请查看[预取/预载模块](/guide/optimization/code-splitting#预取预载模块)。 +告诉浏览器将来可能需要该资源来进行某些导航跳转,详情请查看[预取/预载模块](/guide/optimization/code-splitting#prefetchingpreloading-模块)。 ##### webpackPreload @@ -162,7 +162,7 @@ import( - `number`: 预载优先级 - `boolean`: `false` 表示不预载, `true` 表示预载并且优先级是 `0` -告诉浏览器在当前导航期间可能需要该资源,详情请查看[预取/预载模块](/guide/optimization/code-splitting#预取预载模块)。 +告诉浏览器在当前导航期间可能需要该资源,详情请查看[预取/预载模块](/guide/optimization/code-splitting#prefetchingpreloading-模块)。 ##### webpackChunkName From 1ca6b68892e06b7228bb16d3c85b6f8e1acee278 Mon Sep 17 00:00:00 2001 From: inottn Date: Sat, 16 Nov 2024 16:18:45 +0800 Subject: [PATCH 06/10] fix: correct favicon path when output.publicPath is set to `auto` (#8415) --- crates/rspack_plugin_html/src/asset.rs | 24 ++++++++---------- .../favicon.ico | Bin 0 -> 766 bytes .../index.js | 11 ++++++++ .../rspack.config.js | 14 ++++++++++ .../favicon.ico | Bin 0 -> 766 bytes .../index.js | 11 ++++++++ .../rspack.config.js | 14 ++++++++++ 7 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-publicpath-auto/favicon.ico create mode 100644 packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-publicpath-auto/index.js create mode 100644 packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-publicpath-auto/rspack.config.js create mode 100644 packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-publicpath-auto/favicon.ico create mode 100644 packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-publicpath-auto/index.js create mode 100644 packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-publicpath-auto/rspack.config.js diff --git a/crates/rspack_plugin_html/src/asset.rs b/crates/rspack_plugin_html/src/asset.rs index 8777f07b657a..80462f3d053a 100644 --- a/crates/rspack_plugin_html/src/asset.rs +++ b/crates/rspack_plugin_html/src/asset.rs @@ -111,21 +111,17 @@ impl HtmlPluginAssets { favicon_relative_path.to_string_lossy().to_string().as_str(), )); - let fake_html_file_name = compilation - .get_path( - html_file_name, - PathData::default().filename(output_path.as_str()), - ) - .always_ok(); - if favicon_path.to_str().unwrap_or_default().is_empty() { - favicon_path = compilation - .options - .output - .path - .as_std_path() - .join(favicon_relative_path) - .relative(PathBuf::from(fake_html_file_name).join("..")); + let fake_html_file_name = compilation + .get_path( + html_file_name, + PathData::default().filename(output_path.as_str()), + ) + .always_ok(); + let output_path = compilation.options.output.path.as_std_path(); + favicon_path = output_path + .relative(output_path.join(fake_html_file_name).join("..")) + .join(favicon_relative_path); } else { favicon_path.push(favicon_relative_path); } diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-publicpath-auto/favicon.ico b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-publicpath-auto/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..be74abd69ad6a32de7375df13cab9354798e328f GIT binary patch literal 766 zcmc(dze~eV5XUd2fg&jH87YDYDQKxq1{4b-_ydP-wqS9vgGh17QXQQAwOE{VaBvi* zmu^z9t({y-&1ey8Y_x;?x+`BviV9;aRjMgZ8M*!jgkRrFqSI9;F zHyfX@Az|AvVmn~YWWZP`0&JWEY~BFm?*Vq}VD7&_%x%MP$p`D`4JMC!K|B7pt?Mmp zUJAB7rxMXS6=!P+AtLU9V)J#61WPxwipRXCHO{BJ`l{m53#=t97a!znv~vfmr|AaP zRGIT7#0FyJy3Z*hL{GQp-0TRhX8UzZ)+>%?mK0^goaX4Q;x { + const faviconPath = path.join(__dirname, "./favicon.ico"); + expect(fs.existsSync(faviconPath)).toBe(true); + + const htmlPath = path.join(__dirname, "./index.html"); + const htmlContent = fs.readFileSync(htmlPath, "utf-8"); + expect(htmlContent).toContain(''); +}); diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-publicpath-auto/rspack.config.js b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-publicpath-auto/rspack.config.js new file mode 100644 index 000000000000..846fc992b940 --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-publicpath-auto/rspack.config.js @@ -0,0 +1,14 @@ +const path = require("path"); +const { rspack } = require("@rspack/core"); + +/** @type {import("@rspack/core").Configuration} */ +module.exports = { + output: { + publicPath: "auto", + }, + plugins: [ + new rspack.HtmlRspackPlugin({ + favicon: path.resolve(__dirname, "favicon.ico") + }) + ] +}; diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-publicpath-auto/favicon.ico b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-publicpath-auto/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..be74abd69ad6a32de7375df13cab9354798e328f GIT binary patch literal 766 zcmc(dze~eV5XUd2fg&jH87YDYDQKxq1{4b-_ydP-wqS9vgGh17QXQQAwOE{VaBvi* zmu^z9t({y-&1ey8Y_x;?x+`BviV9;aRjMgZ8M*!jgkRrFqSI9;F zHyfX@Az|AvVmn~YWWZP`0&JWEY~BFm?*Vq}VD7&_%x%MP$p`D`4JMC!K|B7pt?Mmp zUJAB7rxMXS6=!P+AtLU9V)J#61WPxwipRXCHO{BJ`l{m53#=t97a!znv~vfmr|AaP zRGIT7#0FyJy3Z*hL{GQp-0TRhX8UzZ)+>%?mK0^goaX4Q;x { + const faviconPath = path.join(__dirname, "./favicon.ico"); + expect(fs.existsSync(faviconPath)).toBe(true); + + const htmlPath = path.join(__dirname, "./index.html"); + const htmlContent = fs.readFileSync(htmlPath, "utf-8"); + expect(htmlContent).toContain(''); +}); diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-publicpath-auto/rspack.config.js b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-publicpath-auto/rspack.config.js new file mode 100644 index 000000000000..e0469fe6bc5f --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-publicpath-auto/rspack.config.js @@ -0,0 +1,14 @@ +const path = require("path"); +const { rspack } = require("@rspack/core"); + +/** @type {import("@rspack/core").Configuration} */ +module.exports = { + output: { + publicPath: "auto", + }, + plugins: [ + new rspack.HtmlRspackPlugin({ + favicon: "favicon.ico" + }) + ] +}; From 9112e35f97eeac430691e15c0305763fec56e890 Mon Sep 17 00:00:00 2001 From: yifancong Date: Sun, 17 Nov 2024 17:52:10 +0800 Subject: [PATCH 07/10] test: fix some unstable test cases for layer stats (#8453) fix(test): fix some tests error for layer stats --- .../tests/__snapshots__/StatsAPI.test.js.snap | 4 ++++ packages/rspack-test-tools/tests/statsAPICases/layer-stats.js | 2 ++ 2 files changed, 6 insertions(+) diff --git a/packages/rspack-test-tools/tests/__snapshots__/StatsAPI.test.js.snap b/packages/rspack-test-tools/tests/__snapshots__/StatsAPI.test.js.snap index 300626545436..96b5db08b7f6 100644 --- a/packages/rspack-test-tools/tests/__snapshots__/StatsAPI.test.js.snap +++ b/packages/rspack-test-tools/tests/__snapshots__/StatsAPI.test.js.snap @@ -1659,6 +1659,8 @@ Object { modules: Array [ Object { children: Array [], + issuer: , + issuerName: , layer: test, size: 304, sizes: Object { @@ -1668,6 +1670,8 @@ Object { }, Object { children: Array [], + issuer: , + issuerName: , layer: legacy, size: 304, sizes: Object { diff --git a/packages/rspack-test-tools/tests/statsAPICases/layer-stats.js b/packages/rspack-test-tools/tests/statsAPICases/layer-stats.js index 0c097a6f4639..cb64f3c858b1 100644 --- a/packages/rspack-test-tools/tests/statsAPICases/layer-stats.js +++ b/packages/rspack-test-tools/tests/statsAPICases/layer-stats.js @@ -27,6 +27,8 @@ module.exports = { }; const statsData = stats?.toJson(options); statsData.modules.forEach(mod => { + mod.issuer = ''; + mod.issuerName = ''; mod.children = []; }); From 8b52f4d58c522f82b394b8d5a3f48a74b4aec874 Mon Sep 17 00:00:00 2001 From: qixuan <58852732+GiveMe-A-Name@users.noreply.github.com> Date: Mon, 18 Nov 2024 12:06:59 +0800 Subject: [PATCH 08/10] fix(lightning css): align type with lightningcss (#8456) fix(lightning css): align type with lightning css Co-authored-by: zackarychapple --- crates/node_binding/binding.d.ts | 1 + .../raw_builtins/raw_lightning_css_minimizer.rs | 13 ++++++++++--- crates/rspack_loader_lightningcss/src/config.rs | 5 ++++- packages/rspack/etc/core.api.md | 2 ++ .../rspack/src/builtin-loader/lightningcss/index.ts | 5 +++++ .../LightningCssMinimizerRspackPlugin.ts | 10 +++++++++- .../guide/features/builtin-lightningcss-loader.mdx | 5 +++++ .../lightning-css-minimizer-rspack-plugin.mdx | 5 +++++ .../guide/features/builtin-lightningcss-loader.mdx | 5 +++++ .../lightning-css-minimizer-rspack-plugin.mdx | 5 +++++ 10 files changed, 51 insertions(+), 5 deletions(-) diff --git a/crates/node_binding/binding.d.ts b/crates/node_binding/binding.d.ts index 79455c23db67..c7586ddb8949 100644 --- a/crates/node_binding/binding.d.ts +++ b/crates/node_binding/binding.d.ts @@ -1551,6 +1551,7 @@ export interface RawLightningCssMinimizerOptions { include?: number exclude?: number draft?: RawDraft + drafts?: RawDraft nonStandard?: RawNonStandard pseudoClasses?: RawLightningCssPseudoClasses unusedSymbols: Array diff --git a/crates/rspack_binding_options/src/options/raw_builtins/raw_lightning_css_minimizer.rs b/crates/rspack_binding_options/src/options/raw_builtins/raw_lightning_css_minimizer.rs index 3fa4058b3d41..3f1a367f5eea 100644 --- a/crates/rspack_binding_options/src/options/raw_builtins/raw_lightning_css_minimizer.rs +++ b/crates/rspack_binding_options/src/options/raw_builtins/raw_lightning_css_minimizer.rs @@ -25,7 +25,9 @@ pub struct RawLightningCssMinimizerOptions { pub targets: Option>, pub include: Option, pub exclude: Option, + // TODO: deprecate `draft` in favor of `drafts` pub draft: Option, + pub drafts: Option, pub non_standard: Option, pub pseudo_classes: Option, pub unused_symbols: Vec, @@ -90,9 +92,14 @@ impl TryFrom for PluginOptions { .flatten(), include: value.minimizer_options.include, exclude: value.minimizer_options.exclude, - draft: value.minimizer_options.draft.map(|d| Draft { - custom_media: d.custom_media, - }), + // We should use `drafts` if it is present, otherwise use `draft` + draft: value + .minimizer_options + .drafts + .or(value.minimizer_options.draft) + .map(|d| Draft { + custom_media: d.custom_media, + }), non_standard: value.minimizer_options.non_standard.map(|n| NonStandard { deep_selector_combinator: n.deep_selector_combinator, }), diff --git a/crates/rspack_loader_lightningcss/src/config.rs b/crates/rspack_loader_lightningcss/src/config.rs index 95792c9f8124..428af730b6c9 100644 --- a/crates/rspack_loader_lightningcss/src/config.rs +++ b/crates/rspack_loader_lightningcss/src/config.rs @@ -44,7 +44,9 @@ pub struct RawConfig { pub targets: Option>, pub include: Option, pub exclude: Option, + // TODO: deprecate `draft` in favor of `drafts` pub draft: Option, + pub drafts: Option, pub non_standard: Option, pub pseudo_classes: Option, pub unused_symbols: Option>, @@ -64,7 +66,8 @@ impl TryFrom for Config { .flatten(), include: value.include, exclude: value.exclude, - draft: value.draft, + // We should use `drafts` if it is present, otherwise use `draft` + draft: value.drafts.or(value.draft), non_standard: value.non_standard, pseudo_classes: value.pseudo_classes, unused_symbols: value.unused_symbols, diff --git a/packages/rspack/etc/core.api.md b/packages/rspack/etc/core.api.md index 2405fdee82fa..9fe475258895 100644 --- a/packages/rspack/etc/core.api.md +++ b/packages/rspack/etc/core.api.md @@ -3112,6 +3112,7 @@ export type LightningcssLoaderOptions = { include?: LightningcssFeatureOptions; exclude?: LightningcssFeatureOptions; draft?: Drafts; + drafts?: Drafts; nonStandard?: NonStandard; pseudoClasses?: PseudoClasses; unusedSymbols?: string[]; @@ -3140,6 +3141,7 @@ export type LightningCssMinimizerRspackPluginOptions = { include?: LightningcssFeatureOptions; exclude?: LightningcssFeatureOptions; draft?: Drafts; + drafts?: Drafts; nonStandard?: NonStandard; pseudoClasses?: PseudoClasses; unusedSymbols?: string[]; diff --git a/packages/rspack/src/builtin-loader/lightningcss/index.ts b/packages/rspack/src/builtin-loader/lightningcss/index.ts index 24fe410fc502..6b52099f6d6c 100644 --- a/packages/rspack/src/builtin-loader/lightningcss/index.ts +++ b/packages/rspack/src/builtin-loader/lightningcss/index.ts @@ -254,7 +254,12 @@ export type LoaderOptions = { targets?: Targets | string[] | string; include?: FeatureOptions; exclude?: FeatureOptions; + /** + * @deprecated Use `drafts` instead. + * This will be removed in the next major version. + */ draft?: Drafts; + drafts?: Drafts; nonStandard?: NonStandard; pseudoClasses?: PseudoClasses; unusedSymbols?: string[]; diff --git a/packages/rspack/src/builtin-plugin/LightningCssMinimizerRspackPlugin.ts b/packages/rspack/src/builtin-plugin/LightningCssMinimizerRspackPlugin.ts index 5305ea02efb3..42d802675da2 100644 --- a/packages/rspack/src/builtin-plugin/LightningCssMinimizerRspackPlugin.ts +++ b/packages/rspack/src/builtin-plugin/LightningCssMinimizerRspackPlugin.ts @@ -23,7 +23,12 @@ export type LightningCssMinimizerRspackPluginOptions = { targets?: string[] | string; include?: FeatureOptions; exclude?: FeatureOptions; + /** + * @deprecated Use `drafts` instead. + * This will be removed in the next major version. + */ draft?: Drafts; + drafts?: Drafts; nonStandard?: NonStandard; pseudoClasses?: PseudoClasses; unusedSymbols?: string[]; @@ -35,7 +40,7 @@ export const LightningCssMinimizerRspackPlugin = create( ( options?: LightningCssMinimizerRspackPluginOptions ): RawLightningCssMinimizerRspackPluginOptions => { - const { include, exclude, draft, nonStandard, pseudoClasses } = + const { include, exclude, draft, nonStandard, pseudoClasses, drafts } = options?.minimizerOptions ?? {}; const targets = options?.minimizerOptions?.targets ?? "fully supports es6"; // last not support es module chrome version return { @@ -50,6 +55,9 @@ export const LightningCssMinimizerRspackPlugin = create( exclude: exclude ? toFeatures(exclude) : undefined, targets: typeof targets === "string" ? [targets] : targets, draft: draft ? { customMedia: draft.customMedia ?? false } : undefined, + drafts: drafts + ? { customMedia: drafts.customMedia ?? false } + : undefined, nonStandard: nonStandard ? { deepSelectorCombinator: diff --git a/website/docs/en/guide/features/builtin-lightningcss-loader.mdx b/website/docs/en/guide/features/builtin-lightningcss-loader.mdx index f3cf6d42d667..e400fca5a787 100644 --- a/website/docs/en/guide/features/builtin-lightningcss-loader.mdx +++ b/website/docs/en/guide/features/builtin-lightningcss-loader.mdx @@ -98,7 +98,12 @@ type LightningcssLoaderOptions = { targets?: string[] | string; include?: LightningcssFeatureOptions; exclude?: LightningcssFeatureOptions; + /** + * @deprecated Use `drafts` instead. + * This will be removed in the next major version. + */ draft?: Drafts; + drafts?: Drafts; nonStandard?: NonStandard; pseudoClasses?: PseudoClasses; unusedSymbols?: Set; diff --git a/website/docs/en/plugins/rspack/lightning-css-minimizer-rspack-plugin.mdx b/website/docs/en/plugins/rspack/lightning-css-minimizer-rspack-plugin.mdx index 022bde676427..888d9fd7e1d6 100644 --- a/website/docs/en/plugins/rspack/lightning-css-minimizer-rspack-plugin.mdx +++ b/website/docs/en/plugins/rspack/lightning-css-minimizer-rspack-plugin.mdx @@ -89,7 +89,12 @@ type LightningCssMinimizerOptions = { targets?: string[] | string; include?: LightningcssFeatureOptions; exclude?: LightningcssFeatureOptions; + /** + * @deprecated Use `drafts` instead. + * This will be removed in the next major version. + */ draft?: Drafts; + drafts?: Drafts; nonStandard?: NonStandard; pseudoClasses?: PseudoClasses; unusedSymbols?: Set; diff --git a/website/docs/zh/guide/features/builtin-lightningcss-loader.mdx b/website/docs/zh/guide/features/builtin-lightningcss-loader.mdx index 17b459474654..c70be0ee5ac8 100644 --- a/website/docs/zh/guide/features/builtin-lightningcss-loader.mdx +++ b/website/docs/zh/guide/features/builtin-lightningcss-loader.mdx @@ -98,7 +98,12 @@ type LightningcssLoaderOptions = { targets?: string[] | string; include?: LightningcssFeatureOptions; exclude?: LightningcssFeatureOptions; + /** + * @deprecated Use `drafts` instead. + * This will be removed in the next major version. + */ draft?: Drafts; + drafts?: Drafts; nonStandard?: NonStandard; pseudoClasses?: PseudoClasses; unusedSymbols?: Set; diff --git a/website/docs/zh/plugins/rspack/lightning-css-minimizer-rspack-plugin.mdx b/website/docs/zh/plugins/rspack/lightning-css-minimizer-rspack-plugin.mdx index af8c23c87107..a1239214be85 100644 --- a/website/docs/zh/plugins/rspack/lightning-css-minimizer-rspack-plugin.mdx +++ b/website/docs/zh/plugins/rspack/lightning-css-minimizer-rspack-plugin.mdx @@ -89,7 +89,12 @@ type LightningCssMinimizerOptions = { targets?: string[] | string; include?: LightningcssFeatureOptions; exclude?: LightningcssFeatureOptions; + /** + * @deprecated Use `drafts` instead. + * This will be removed in the next major version. + */ draft?: Drafts; + drafts?: Drafts; nonStandard?: NonStandard; pseudoClasses?: PseudoClasses; unusedSymbols?: string[]; From 343f27965b142ab37d1f8ef2061421addee9f17f Mon Sep 17 00:00:00 2001 From: inottn Date: Mon, 18 Nov 2024 14:20:19 +0800 Subject: [PATCH 09/10] fix: the attribute values of HTML tags should not be converted to lowercase (#8443) --- crates/rspack_binding_values/src/html.rs | 2 +- .../builtins/html-issue-8410/index.js | 8 ++++++ .../builtins/html-issue-8410/rspack.config.js | 27 +++++++++++++++++++ .../builtins/html-issue-8410/test.config.js | 6 +++++ 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 packages/rspack-test-tools/tests/configCases/builtins/html-issue-8410/index.js create mode 100644 packages/rspack-test-tools/tests/configCases/builtins/html-issue-8410/rspack.config.js create mode 100644 packages/rspack-test-tools/tests/configCases/builtins/html-issue-8410/test.config.js diff --git a/crates/rspack_binding_values/src/html.rs b/crates/rspack_binding_values/src/html.rs index 0743a0d69a19..11c315439f64 100644 --- a/crates/rspack_binding_values/src/html.rs +++ b/crates/rspack_binding_values/src/html.rs @@ -56,7 +56,7 @@ impl From for HtmlPluginTag { value.as_ref().and_then(|v| match v { Either::A(x) => Some(HtmlPluginAttribute { attr_name: key.cow_to_ascii_lowercase().into_owned(), - attr_value: Some(x.cow_to_ascii_lowercase().into_owned()), + attr_value: Some(x.to_owned()), }), Either::B(x) => { if *x { diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-issue-8410/index.js b/packages/rspack-test-tools/tests/configCases/builtins/html-issue-8410/index.js new file mode 100644 index 000000000000..7cf58e4e23d7 --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/builtins/html-issue-8410/index.js @@ -0,0 +1,8 @@ +const fs = require("fs"); +const path = require("path"); + +it("html plugin should respect output.publicPath", () => { + const htmlPath = path.join(__dirname, "./index.html"); + const htmlContent = fs.readFileSync(htmlPath, "utf-8"); + expect(htmlContent.includes('