diff --git a/crates/rspack_plugin_esm_library/src/link.rs b/crates/rspack_plugin_esm_library/src/link.rs index 8affdbedb3cd..a6be5c883e84 100644 --- a/crates/rspack_plugin_esm_library/src/link.rs +++ b/crates/rspack_plugin_esm_library/src/link.rs @@ -18,22 +18,23 @@ use rspack_core::{ reserved_names::RESERVED_NAMES, rspack_sources::ReplaceSource, split_readable_identifier, to_normal_comment, }; -use rspack_error::{Diagnostic, Result}; +use rspack_error::{Diagnostic, Error, Result}; use rspack_javascript_compiler::ast::Ast; use rspack_plugin_javascript::{ JsPlugin, RenderSource, dependency::ESMExportImportedSpecifierDependency, visitors::swc_visitor::resolver, }; use rspack_util::{ + SpanExt, atom::Atom, fx_hash::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, indexmap}, swc::join_atom, }; use swc_core::{ - common::{FileName, SyntaxContext}, + common::{FileName, Spanned, SyntaxContext}, ecma::{ ast::{EsVersion, Program}, - parser::{Syntax, parse_file_as_module}, + parser::{EsSyntax, Syntax, parse_file_as_module}, }, }; @@ -166,6 +167,15 @@ impl EsmLibraryPlugin { let mut hoisted_modules = IdentifierIndexSet::default(); for m in modules.iter() { + if compilation + .code_generation_results + .get_one(m) + .get(&SourceType::JavaScript) + .is_none() + { + continue; + } + let info = concate_modules_map .get(m) .unwrap_or_else(|| panic!("should have set module info for {m}")); @@ -761,6 +771,16 @@ var {} = {{}}; let m = module_graph .module_by_identifier(&id) .expect("should have module"); + let jsx = m + .as_ref() + .as_normal_module() + .and_then(|normal_module| normal_module.get_parser_options()) + .and_then(|options| { + options + .get_javascript() + .and_then(|js_options| js_options.jsx) + }) + .unwrap_or(false); let cm: Arc = Default::default(); let readable_identifier = m.readable_identifier(&compilation.options.context); let fm = cm.new_source_file( @@ -772,14 +792,28 @@ var {} = {{}}; .into_owned(), ); let mut errors = vec![]; - let module = parse_file_as_module( + let module = match parse_file_as_module( &fm, - Syntax::default(), + Syntax::Es(EsSyntax { + jsx, + ..Default::default() + }), EsVersion::EsNext, None, &mut errors, - ) - .expect("parse failed"); + ) { + Ok(module) => module, + Err(err) => { + // return empty error as we already push error to compilation.diagnostics + return Err(Error::from_string( + Some(fm.src.clone().into_string()), + err.span().real_lo() as usize, + err.span().real_hi() as usize, + "JavaScript parse error:\n".to_string(), + err.kind().msg().to_string(), + )); + } + }; let mut ast = Ast::new(Program::Module(module), cm, None); let mut global_ctxt = SyntaxContext::empty(); @@ -1330,6 +1364,13 @@ var {} = {{}}; .all_dependencies() .chain(compilation.global_entry.all_dependencies()) .filter_map(|dep_id| module_graph.module_identifier_by_dependency_id(dep_id)) + .filter(|module| { + compilation + .code_generation_results + .get_one(module) + .get(&SourceType::JavaScript) + .is_some() + }) .copied() { let entry_module_chunk = Self::get_module_chunk(entry_module, compilation); diff --git a/crates/rspack_plugin_esm_library/src/plugin.rs b/crates/rspack_plugin_esm_library/src/plugin.rs index f5b67db72a37..6f85c7d7ff55 100644 --- a/crates/rspack_plugin_esm_library/src/plugin.rs +++ b/crates/rspack_plugin_esm_library/src/plugin.rs @@ -421,6 +421,7 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> { self_path.pop(); let chunk_ids_to_ukey = self.chunk_ids_to_ukey.borrow(); + for captures in RSPACK_ESM_CHUNK_PLACEHOLDER_RE.find_iter(&content) { let chunk_id = captures .as_str() @@ -440,7 +441,13 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> { let js_files = chunk .files() .iter() - .filter(|f| f.ends_with("js")) + .filter(|f| { + // find ref asset info + let Some(asset) = compilation.assets().get(*f) else { + return false; + }; + asset.get_info().javascript_module.unwrap_or_default() + }) .collect::>(); if js_files.len() > 1 { return Err(rspack_error::error!( @@ -448,17 +455,13 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> { js_files )); } - let chunk_path = output_path.join( - js_files - .first() - .unwrap_or_else(|| { - panic!( - "at least one path for chunk: {:?}", - chunk.id().map(|id| { id.as_str() }) - ) - }) - .as_str(), - ); + if js_files.is_empty() { + return Err(rspack_error::error!( + "chunk {:?} should have at least one file", + chunk.id() + )); + } + let chunk_path = output_path.join(js_files.first().expect("should have at least one file")); let relative = chunk_path.relative(self_path.as_path()); let relative = relative .to_slash() diff --git a/crates/rspack_plugin_esm_library/src/render.rs b/crates/rspack_plugin_esm_library/src/render.rs index 79eaa5d93082..50bdb833a3c9 100644 --- a/crates/rspack_plugin_esm_library/src/render.rs +++ b/crates/rspack_plugin_esm_library/src/render.rs @@ -233,6 +233,7 @@ var {} = {{}}; } let mut already_required = IdentifierIndexSet::default(); + for m in &chunk_link.hoisted_modules { let info = concatenated_modules_map .get(m) @@ -729,7 +730,12 @@ var {} = {{}}; info: &ConcatenatedModuleInfo, chunk_link: &ChunkLinkContext, ) -> Result { - let mut source = info.source.clone().expect("should have source"); + let Some(mut source) = info.source.clone() else { + return Err(rspack_error::Error::error(format!( + "module: {} has no source", + info.module + ))); + }; for ((atom, ctxt), refs) in &info.binding_to_ref { if ctxt == &info.global_ctxt diff --git a/packages/rspack-test-tools/src/case/config.ts b/packages/rspack-test-tools/src/case/config.ts index 9b7945f0d94e..e2bfee386610 100644 --- a/packages/rspack-test-tools/src/case/config.ts +++ b/packages/rspack-test-tools/src/case/config.ts @@ -101,6 +101,14 @@ export function defaultOptions( }; } +export function enableEsmLibraryPlugin(options: RspackOptions): boolean { + return ( + options.output?.library === 'modern-module' || + (typeof options.output?.library === 'object' && + (options.output?.library as { type: string }).type === 'modern-module') + ); +} + export function overrideOptions( index: number, context: ITestContext, @@ -113,9 +121,17 @@ export function overrideOptions( options.amd = {}; } if (!options.output?.filename) { - const outputModule = options.experiments?.outputModule; + const runtimeChunkForModernModule = + options.optimization?.runtimeChunk === undefined && + enableEsmLibraryPlugin(options); + const outputModule = + options.experiments?.outputModule || enableEsmLibraryPlugin(options); options.output ??= {}; - options.output.filename = `bundle${index}${outputModule ? '.mjs' : '.js'}`; + options.output.filename = `${runtimeChunkForModernModule ? `[name]${outputModule ? '.mjs' : '.js'}` : `bundle${index}${outputModule ? '.mjs' : '.js'}`}`; + } + if (enableEsmLibraryPlugin(options)) { + options.optimization ??= {}; + options.optimization.runtimeChunk ??= { name: `runtime~${index}` }; } if (options.cache === undefined) options.cache = false; diff --git a/packages/rspack-test-tools/src/runner/node/index.ts b/packages/rspack-test-tools/src/runner/node/index.ts index 0b48f76089c3..dfce625c67ec 100644 --- a/packages/rspack-test-tools/src/runner/node/index.ts +++ b/packages/rspack-test-tools/src/runner/node/index.ts @@ -3,6 +3,7 @@ import path from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; import vm, { SourceTextModule } from 'node:vm'; import type { RspackOptions, StatsCompilation } from '@rspack/core'; +import { enableEsmLibraryPlugin } from '../../case/config'; import asModule from '../../helper/legacy/asModule'; import createFakeWorker from '../../helper/legacy/createFakeWorker'; import urlToRelativePath from '../../helper/legacy/urlToRelativePath'; @@ -306,15 +307,17 @@ export class NodeRunner implements ITestRunner { file, }); } + if ( - file.path.endsWith('.mjs') && - this._options.compilerOptions.experiments?.outputModule + file.path.endsWith('.mjs') || + enableEsmLibraryPlugin(this._options.compilerOptions) ) { return this.requirers.get('esm')!(currentDirectory, modulePath, { ...context, file, }); } + return this.requirers.get('cjs')!(currentDirectory, modulePath, { ...context, file, diff --git a/packages/rspack/etc/core.api.md b/packages/rspack/etc/core.api.md index 838022cd3b50..08c144bb6b52 100644 --- a/packages/rspack/etc/core.api.md +++ b/packages/rspack/etc/core.api.md @@ -4428,6 +4428,7 @@ export type LibraryOptions = { name?: LibraryName; type: LibraryType; umdNamedDefine?: UmdNamedDefine; + preserveModules?: string; }; // @public diff --git a/packages/rspack/src/builtin-plugin/EsmLibraryPlugin.ts b/packages/rspack/src/builtin-plugin/EsmLibraryPlugin.ts index 44274d91dc1d..d734b85cb3c8 100644 --- a/packages/rspack/src/builtin-plugin/EsmLibraryPlugin.ts +++ b/packages/rspack/src/builtin-plugin/EsmLibraryPlugin.ts @@ -2,10 +2,9 @@ import { BuiltinPluginName } from '@rspack/binding'; import type { Compiler } from '../Compiler'; import type { RspackOptionsNormalized } from '../config'; import WebpackError from '../lib/WebpackError'; -import type { Logger } from '../logging/Logger'; import { RemoveDuplicateModulesPlugin } from './RemoveDuplicateModulesPlugin'; -function applyLimits(options: RspackOptionsNormalized, logger: Logger) { +export function applyLimits(options: RspackOptionsNormalized) { // concatenateModules is not supported in ESM library mode, it has its own scope hoist algorithm options.optimization.concatenateModules = false; @@ -19,9 +18,6 @@ function applyLimits(options: RspackOptionsNormalized, logger: Logger) { options.output.module = true; if (options.output.chunkLoading && options.output.chunkLoading !== 'import') { - logger.warn( - `\`output.chunkLoading\` should be \`"import"\` or \`false\`, but got ${options.output.chunkLoading}, changed it to \`"import"\``, - ); options.output.chunkLoading = 'import'; } @@ -29,10 +25,6 @@ function applyLimits(options: RspackOptionsNormalized, logger: Logger) { options.output.chunkLoading = 'import'; } - if (options.output.library) { - options.output.library = undefined; - } - let { splitChunks } = options.optimization; if (splitChunks === undefined) { splitChunks = options.optimization.splitChunks = {}; @@ -58,10 +50,7 @@ export class EsmLibraryPlugin { } apply(compiler: Compiler) { - const logger = compiler.getInfrastructureLogger( - EsmLibraryPlugin.PLUGIN_NAME, - ); - applyLimits(compiler.options, logger); + applyLimits(compiler.options); new RemoveDuplicateModulesPlugin().apply(compiler); let err; @@ -86,6 +75,7 @@ function checkConfig(config: RspackOptionsNormalized): string | undefined { } if (config.output.chunkFormat !== false) { + console.log(config.output.chunkFormat); return 'You should disable default chunkFormat by `config.output.chunkFormat = false`'; } } diff --git a/packages/rspack/src/config/defaults.ts b/packages/rspack/src/config/defaults.ts index 4ea11b354737..9c9fb3af2f13 100644 --- a/packages/rspack/src/config/defaults.ts +++ b/packages/rspack/src/config/defaults.ts @@ -10,6 +10,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { + applyLimits, LightningCssMinimizerRspackPlugin, SwcJsMinimizerRspackPlugin, } from '../builtin-plugin'; @@ -22,7 +23,6 @@ import type { EntryDescriptionNormalized, EntryNormalized, ExperimentsNormalized, - OutputNormalized, RspackOptionsNormalized, } from './normalization'; import { @@ -110,7 +110,7 @@ export const applyRspackOptionsDefaults = ( deferImport: options.experiments.deferImport, }); - applyOutputDefaults(options.output, { + applyOutputDefaults(options, { context: options.context!, targetProperties, isAffectedByBrowserslist: @@ -505,7 +505,7 @@ const applyModuleDefaults = ( }; const applyOutputDefaults = ( - output: OutputNormalized, + options: RspackOptionsNormalized, { context, outputModule, @@ -520,6 +520,7 @@ const applyOutputDefaults = ( entry: EntryNormalized; }, ) => { + const { output } = options; const getLibraryName = (library: Library): string => { const libraryName = typeof library === 'object' && library && !Array.isArray(library) @@ -835,6 +836,9 @@ const applyOutputDefaults = ( enabledLibraryTypes.push(desc.library.type); } }); + if (enabledLibraryTypes.includes('modern-module')) { + applyLimits(options); + } return enabledLibraryTypes; }); A(output, 'enabledChunkLoadingTypes', () => { diff --git a/packages/rspack/src/config/types.ts b/packages/rspack/src/config/types.ts index a72c4dd4b31c..7351ca817d6b 100644 --- a/packages/rspack/src/config/types.ts +++ b/packages/rspack/src/config/types.ts @@ -154,6 +154,11 @@ export type LibraryOptions = { * Otherwise, an anonymous define is used. * */ umdNamedDefine?: UmdNamedDefine; + + /** + * PreserveModules only works for `modern-module` + */ + preserveModules?: string; }; /** Options for library. */ diff --git a/packages/rspack/src/rspackOptionsApply.ts b/packages/rspack/src/rspackOptionsApply.ts index 91c2ae12c201..207583ccc2c2 100644 --- a/packages/rspack/src/rspackOptionsApply.ts +++ b/packages/rspack/src/rspackOptionsApply.ts @@ -33,6 +33,7 @@ import { EnableLibraryPlugin, EnableWasmLoadingPlugin, EnsureChunkConditionsPlugin, + EsmLibraryPlugin, EvalDevToolModulePlugin, EvalSourceMapDevToolPlugin, ExternalsPlugin, @@ -287,8 +288,35 @@ export class RspackOptionsApply { options.output.enabledLibraryTypes && options.output.enabledLibraryTypes.length > 0 ) { + let modernModuleCount = 0; for (const type of options.output.enabledLibraryTypes) { - new EnableLibraryPlugin(type).apply(compiler); + if (type === 'modern-module') { + modernModuleCount++; + } + } + + if (options.output.library?.preserveModules && modernModuleCount > 0) { + throw new Error( + 'preserveModules only works for `modern-module` library type', + ); + } + + if (modernModuleCount > 0) { + // ESM format has impact on chunkLoading and chunkFormat, which is not compatible with + // other library types + if (modernModuleCount !== options.output.enabledLibraryTypes.length) { + throw new Error( + '`modern-module` cannot used together with other library types', + ); + } + + new EsmLibraryPlugin({ + preserveModules: options.output.library?.preserveModules, + }).apply(compiler); + } else { + for (const type of options.output.enabledLibraryTypes) { + new EnableLibraryPlugin(type).apply(compiler); + } } } if (options.optimization.splitChunks) { diff --git a/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case1.txt b/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case1.txt index 62901c728488..126a7d99da03 100644 --- a/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case1.txt +++ b/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case1.txt @@ -1,4 +1,33 @@ -export * from "external1-alias"; -export * from "external2-alias"; +import * as __rspack_external_external2_alias_e5239a01 from "external2-alias"; +import { __webpack_require__ } from "./runtime~0.mjs"; +import "./906.mjs"; + +__webpack_require__.add({ +42(__unused_rspack_module, __webpack_exports__, __webpack_require__) { +__webpack_require__.r(__webpack_exports__); +/* import */ var external1__rspack_import_0 = __webpack_require__(825); + +/* reexport */ var __rspack_reexport = {}; +/* reexport */ for( const __rspack_import_key in external1__rspack_import_0) if(__rspack_import_key !== "default") __rspack_reexport[__rspack_import_key] =() => external1__rspack_import_0[__rspack_import_key] +/* reexport */ __webpack_require__.d(__webpack_exports__, __rspack_reexport); +/* import */ var external2__rspack_import_1 = __webpack_require__(908); + +/* reexport */ var __rspack_reexport = {}; +/* reexport */ for( const __rspack_import_key in external2__rspack_import_1) if(__rspack_import_key !== "default") __rspack_reexport[__rspack_import_key] =() => external2__rspack_import_1[__rspack_import_key] +/* reexport */ __webpack_require__.d(__webpack_exports__, __rspack_reexport); + + -;// CONCATENATED MODULE: ./case1.js \ No newline at end of file + +}, +908(module) { + +module.exports = __rspack_external_external2_alias_e5239a01; + + +}, +}); +__webpack_require__("42"); + +export * from "external1-alias"; +export * from "external2-alias"; \ No newline at end of file diff --git a/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case2.txt b/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case2.txt index 5e76d442dfe7..7e9c350e73f2 100644 --- a/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case2.txt +++ b/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case2.txt @@ -1,15 +1,14 @@ -export * from "external1-alias"; -import * as __rspack_external_external1_alias_bc4b12e4 from "external1-alias"; +import { __webpack_require__ } from "./runtime~0.mjs"; +import "./906.mjs"; -;// CONCATENATED MODULE: external "external1-alias" +const external_external1_alias_ = __webpack_require__("825"); +var a = external_external1_alias_.a; +var b = external_external1_alias_.b; -;// CONCATENATED MODULE: ./case2.js - -var __webpack_exports__a = __rspack_external_external1_alias_bc4b12e4.a; -var __webpack_exports__b = __rspack_external_external1_alias_bc4b12e4.b; -export { __rspack_external_external1_alias_bc4b12e4 as n1, __webpack_exports__a as a, __webpack_exports__b as b }; \ No newline at end of file +export { a, b, external_external1_alias_ as n1 }; +export * from "external1-alias"; \ No newline at end of file diff --git a/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case3.txt b/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case3.txt index 36cdfc34c1ca..31270af20c79 100644 --- a/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case3.txt +++ b/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case3.txt @@ -1,12 +1,8 @@ -import "external1-alias"; +import "./906.mjs"; -;// CONCATENATED MODULE: external "external1-alias" - -;// CONCATENATED MODULE: ./case3/foo.js const foo = 2 -;// CONCATENATED MODULE: ./case3/index.js const bar = 1 diff --git a/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case4.txt b/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case4.txt index 2f0ceaebc4de..fc892425889c 100644 --- a/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case4.txt +++ b/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case4.txt @@ -1,3 +1,6 @@ -export * from "external1-alias"; +import "./906.mjs"; -;// CONCATENATED MODULE: ./case4.js \ No newline at end of file + + + +export * from "external1-alias"; \ No newline at end of file diff --git a/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case5.txt b/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case5.txt index c20430223ebc..bcc7f9e651b6 100644 --- a/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case5.txt +++ b/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case5.txt @@ -1,14 +1,13 @@ -import { foo } from "external1-alias"; -export * from "external1-alias"; +import { __webpack_require__ } from "./runtime~0.mjs"; +import "./906.mjs"; -;// CONCATENATED MODULE: external "external1-alias" +const external_external1_alias_ = __webpack_require__("825"); -;// CONCATENATED MODULE: ./case5.js +const bar = external_external1_alias_.foo + 1 -const bar = foo + 1 - -export { bar }; \ No newline at end of file +export { bar }; +export * from "external1-alias"; \ No newline at end of file diff --git a/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case6.txt b/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case6.txt index a1283ed97e19..a06f0d90eff4 100644 --- a/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case6.txt +++ b/tests/rspack-test/configCases/externals/reexport-star/__snapshot__/case6.txt @@ -1,6 +1,9 @@ -import "external1-alias"; -export * from "external1-alias"; +import { __webpack_require__ } from "./runtime~0.mjs"; +import "./906.mjs"; -;// CONCATENATED MODULE: external "external1-alias" +__webpack_require__("825"); -;// CONCATENATED MODULE: ./case6.js \ No newline at end of file + + + +export * from "external1-alias"; \ No newline at end of file diff --git a/tests/rspack-test/configCases/library/modern-module-asset-entry/rspack.config.js b/tests/rspack-test/configCases/library/modern-module-asset-entry/rspack.config.js index 8cf4737d2d82..39077c3ba51b 100644 --- a/tests/rspack-test/configCases/library/modern-module-asset-entry/rspack.config.js +++ b/tests/rspack-test/configCases/library/modern-module-asset-entry/rspack.config.js @@ -52,7 +52,7 @@ module.exports = { ); assert(preseveImport); const hasExports = - /export\s{\simg_namespaceObject\sas\sdefault\s}/.test(jsContent); + /export\sdefault\simg_namespaceObject/.test(jsContent); assert(hasExports); }); }); diff --git a/tests/rspack-test/configCases/library/modern-module-dynamic-import-runtime/rspack.config.js b/tests/rspack-test/configCases/library/modern-module-dynamic-import-runtime/rspack.config.js index 7ea361f6b980..ee6e631fa3c2 100644 --- a/tests/rspack-test/configCases/library/modern-module-dynamic-import-runtime/rspack.config.js +++ b/tests/rspack-test/configCases/library/modern-module-dynamic-import-runtime/rspack.config.js @@ -9,9 +9,6 @@ const basic = { library: { type: "modern-module" }, - iife: false, - chunkFormat: "module", - chunkLoading: "import" }, externals: { react: "react-alias", @@ -54,7 +51,11 @@ module.exports = [ index: "./index.js" }, output: { - filename: "index.js" + module: true, + filename: "index.mjs" + }, + experiments: { + outputModule: true } } ]; diff --git a/tests/rspack-test/configCases/library/modern-module-dynamic-import-runtime/test.config.js b/tests/rspack-test/configCases/library/modern-module-dynamic-import-runtime/test.config.js index 1aaab67601fb..1c5003ff2436 100644 --- a/tests/rspack-test/configCases/library/modern-module-dynamic-import-runtime/test.config.js +++ b/tests/rspack-test/configCases/library/modern-module-dynamic-import-runtime/test.config.js @@ -1,6 +1,6 @@ /** @type {import('@rspack/test-tools').TConfigCaseConfig} */ module.exports = { findBundle: (i, options) => { - return ["index.js"]; + return ["index.mjs"]; } }; diff --git a/tests/rspack-test/configCases/library/modern-module-export-char/rspack.config.js b/tests/rspack-test/configCases/library/modern-module-export-char/rspack.config.js index d0816bb54366..6db0b8e59d48 100644 --- a/tests/rspack-test/configCases/library/modern-module-export-char/rspack.config.js +++ b/tests/rspack-test/configCases/library/modern-module-export-char/rspack.config.js @@ -16,9 +16,7 @@ module.exports = { }, externals: "external-module", optimization: { - avoidEntryIife: true, - concatenateModules: true, - minimize: false + runtimeChunk: false }, plugins: [ function () { @@ -30,10 +28,10 @@ module.exports = { compilation.hooks.afterProcessAssets.tap("testcase", assets => { const bundle = Object.values(assets)[0]._value; expect(bundle) - .toContain(`var __webpack_exports__cjsInterop = (foo_default()); -export { external_module as defaultImport, namedImport, __webpack_exports__cjsInterop as cjsInterop };`); + .toContain(`var foo_default = /*#__PURE__*/__webpack_require__.n(foo);\nvar foo_default_0 = foo_default();`); + expect(bundle).toContain('foo_default_0 as cjsInterop') expect(bundle).toContain( - 'import external_module, { namedImport } from "external-module";' + 'export { default as defaultImport, namedImport } from "external-module";' ); }); }; diff --git a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/a.js.txt b/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/a.js.txt index 4ba79ff030ca..3820325eb9ce 100644 --- a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/a.js.txt +++ b/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/a.js.txt @@ -1,4 +1,3 @@ -;// CONCATENATED MODULE: ./a.js const a = 'a' export { a }; \ No newline at end of file diff --git a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/b.js.txt b/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/b.js.txt index 8338cb342c7f..321e05fa4b89 100644 --- a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/b.js.txt +++ b/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/b.js.txt @@ -1,34 +1,8 @@ -var __webpack_modules__ = ({ +import { __webpack_require__ } from "./runtime~0.js"; +__webpack_require__.add({ 917(module) { module.exports = 'b' }, - -}); -// The module cache -var __webpack_module_cache__ = {}; - -// The require function -function __webpack_require__(moduleId) { - -// Check if module is in cache -var cachedModule = __webpack_module_cache__[moduleId]; -if (cachedModule !== undefined) { -return cachedModule.exports; -} -// Create a new module (and put it into the cache) -var module = (__webpack_module_cache__[moduleId] = { -exports: {} }); -// Execute the module function -__webpack_modules__[moduleId](module, module.exports, __webpack_require__); - -// Return the exports of the module -return module.exports; - -} - -// startup -// Load entry module and return exports -// This entry module is referenced by other modules so it can't be inlined -var __webpack_exports__ = __webpack_require__(917); \ No newline at end of file +__webpack_require__("917"); \ No newline at end of file diff --git a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/d.js.txt b/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/d.js.txt index a313ae4e4925..3d39c2e2d9b0 100644 --- a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/d.js.txt +++ b/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/d.js.txt @@ -1,2 +1 @@ -;// CONCATENATED MODULE: ./d.mjs const d = 'd' \ No newline at end of file diff --git a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/e.js.txt b/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/e.js.txt index c2fd4ad68b28..c3253dfbd9b1 100644 --- a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/e.js.txt +++ b/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/e.js.txt @@ -1,69 +1,17 @@ -var __webpack_modules__ = ({ +import { __webpack_require__ } from "./runtime~0.js"; +__webpack_require__.add({ 100(module) { module.exports = 'bar' }, - }); -// The module cache -var __webpack_module_cache__ = {}; - -// The require function -function __webpack_require__(moduleId) { - -// Check if module is in cache -var cachedModule = __webpack_module_cache__[moduleId]; -if (cachedModule !== undefined) { -return cachedModule.exports; -} -// Create a new module (and put it into the cache) -var module = (__webpack_module_cache__[moduleId] = { -exports: {} -}); -// Execute the module function -__webpack_modules__[moduleId](module, module.exports, __webpack_require__); - -// Return the exports of the module -return module.exports; - -} - -// webpack/runtime/compat_get_default_export -(() => { -// getDefaultExport function for compatibility with non-ESM modules -__webpack_require__.n = (module) => { - var getter = module && module.__esModule ? - () => (module['default']) : - () => (module); - __webpack_require__.d(getter, { a: getter }); - return getter; -}; - -})(); -// webpack/runtime/define_property_getters -(() => { -__webpack_require__.d = (exports, definition) => { - for(var key in definition) { - if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { - Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); - } - } -}; -})(); -// webpack/runtime/has_own_property -(() => { -__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) -})(); - -// EXTERNAL MODULE: ./e/bar.cjs -var bar = __webpack_require__(100); +const bar = __webpack_require__("100"); var bar_default = /*#__PURE__*/__webpack_require__.n(bar); -;// CONCATENATED MODULE: ./e/index.js +var bar_default_0 = bar_default(); -var __webpack_exports__bar = (bar_default()); -var __webpack_exports__foo = (/* inlined export .foo */"foo"); -export { __webpack_exports__bar as bar, __webpack_exports__foo as foo }; \ No newline at end of file +var e_foo = (/* inlined export .foo */"foo"); +export { bar_default_0 as bar, e_foo as foo }; \ No newline at end of file diff --git a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/f.js.txt b/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/f.js.txt index c25ead578b63..4520ba787fba 100644 --- a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/f.js.txt +++ b/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/f.js.txt @@ -1,6 +1,7 @@ import { createRequire as __rspack_createRequire } from "node:module"; const __rspack_createRequire_require = __rspack_createRequire(import.meta.url); -var __webpack_modules__ = ({ +import { __webpack_require__ } from "./runtime~0.js"; +__webpack_require__.add({ 928(module) { module.exports = __rspack_createRequire_require("path"); @@ -12,62 +13,9 @@ module.exports = path.sep }, - }); -// The module cache -var __webpack_module_cache__ = {}; - -// The require function -function __webpack_require__(moduleId) { - -// Check if module is in cache -var cachedModule = __webpack_module_cache__[moduleId]; -if (cachedModule !== undefined) { -return cachedModule.exports; -} -// Create a new module (and put it into the cache) -var module = (__webpack_module_cache__[moduleId] = { -exports: {} -}); -// Execute the module function -__webpack_modules__[moduleId](module, module.exports, __webpack_require__); - -// Return the exports of the module -return module.exports; - -} - -// webpack/runtime/compat_get_default_export -(() => { -// getDefaultExport function for compatibility with non-ESM modules -__webpack_require__.n = (module) => { - var getter = module && module.__esModule ? - () => (module['default']) : - () => (module); - __webpack_require__.d(getter, { a: getter }); - return getter; -}; - -})(); -// webpack/runtime/define_property_getters -(() => { -__webpack_require__.d = (exports, definition) => { - for(var key in definition) { - if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { - Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); - } - } -}; -})(); -// webpack/runtime/has_own_property -(() => { -__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) -})(); - -// EXTERNAL MODULE: ./f/bar.cjs -var bar = __webpack_require__(227); +const bar = __webpack_require__("227"); var bar_default = /*#__PURE__*/__webpack_require__.n(bar); -;// CONCATENATED MODULE: ./f/index.js diff --git a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/g.js.txt b/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/g.js.txt index b75a4297c89d..603b9455fbed 100644 --- a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/g.js.txt +++ b/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/g.js.txt @@ -1,68 +1,16 @@ -var __webpack_modules__ = ({ +import { __webpack_require__ } from "./runtime~0.js"; +__webpack_require__.add({ 547(module) { module.exports = 'foo' }, - }); -// The module cache -var __webpack_module_cache__ = {}; - -// The require function -function __webpack_require__(moduleId) { - -// Check if module is in cache -var cachedModule = __webpack_module_cache__[moduleId]; -if (cachedModule !== undefined) { -return cachedModule.exports; -} -// Create a new module (and put it into the cache) -var module = (__webpack_module_cache__[moduleId] = { -exports: {} -}); -// Execute the module function -__webpack_modules__[moduleId](module, module.exports, __webpack_require__); - -// Return the exports of the module -return module.exports; - -} - -// webpack/runtime/compat_get_default_export -(() => { -// getDefaultExport function for compatibility with non-ESM modules -__webpack_require__.n = (module) => { - var getter = module && module.__esModule ? - () => (module['default']) : - () => (module); - __webpack_require__.d(getter, { a: getter }); - return getter; -}; - -})(); -// webpack/runtime/define_property_getters -(() => { -__webpack_require__.d = (exports, definition) => { - for(var key in definition) { - if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { - Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); - } - } -}; -})(); -// webpack/runtime/has_own_property -(() => { -__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) -})(); - -// EXTERNAL MODULE: ./g/foo.js -var foo = __webpack_require__(547); +const foo = __webpack_require__("547"); var foo_default = /*#__PURE__*/__webpack_require__.n(foo); -;// CONCATENATED MODULE: ./g/index.js +var foo_default_0 = foo_default(); -var __webpack_exports__foo = (foo_default()); -export { __webpack_exports__foo as foo }; \ No newline at end of file +export { foo_default_0 as foo }; \ No newline at end of file diff --git a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/h.js.txt b/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/h.js.txt deleted file mode 100644 index 497614a5b0af..000000000000 --- a/tests/rspack-test/configCases/library/modern-module-force-concaten/__snapshot__/h.js.txt +++ /dev/null @@ -1,33 +0,0 @@ -// The module cache -var __webpack_module_cache__ = {}; - -// The require function -function __webpack_require__(moduleId) { - -// Check if module is in cache -var cachedModule = __webpack_module_cache__[moduleId]; -if (cachedModule !== undefined) { -return cachedModule.exports; -} -// Create a new module (and put it into the cache) -var module = (__webpack_module_cache__[moduleId] = { -exports: {} -}); -// Execute the module function -__webpack_modules__[moduleId](module, module.exports, __webpack_require__); - -// Return the exports of the module -return module.exports; - -} - -/************************************************************************/ -// webpack/runtime/public_path -(() => { -__webpack_require__.p = ""; -})(); -/************************************************************************/ - -;// CONCATENATED MODULE: ./h/file.png -const file_namespaceObject = __webpack_require__.p + "fc90103f80b6abc6.png"; -export { file_namespaceObject as default }; \ No newline at end of file diff --git a/tests/rspack-test/configCases/library/modern-module-force-concaten/rspack.config.js b/tests/rspack-test/configCases/library/modern-module-force-concaten/rspack.config.js index 89d20e28bbe0..74ee8dbf2858 100644 --- a/tests/rspack-test/configCases/library/modern-module-force-concaten/rspack.config.js +++ b/tests/rspack-test/configCases/library/modern-module-force-concaten/rspack.config.js @@ -34,8 +34,6 @@ module.exports = { outputModule: true }, optimization: { - concatenateModules: true, - avoidEntryIife: true, minimize: false }, plugins: [ @@ -74,7 +72,7 @@ module.exports = { path.join(__dirname, "__snapshot__", "g.js.txt"), "harmony export should concat, even with bailout reason" ); - expect(assets["h.js"]).toBeUndefined(); + expect(assets["h.js"]).toBeDefined(); }); }; this.hooks.compilation.tap("testcase", handler); diff --git a/tests/rspack-test/configCases/library/modern-module-iife/foo.mjs b/tests/rspack-test/configCases/library/modern-module-iife/foo.mjs deleted file mode 100644 index f4596d54061a..000000000000 --- a/tests/rspack-test/configCases/library/modern-module-iife/foo.mjs +++ /dev/null @@ -1 +0,0 @@ -export const foo = 'foo'; \ No newline at end of file diff --git a/tests/rspack-test/configCases/library/modern-module-iife/index.js b/tests/rspack-test/configCases/library/modern-module-iife/index.js deleted file mode 100644 index be5c506adf85..000000000000 --- a/tests/rspack-test/configCases/library/modern-module-iife/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import { foo } from './foo.mjs'; -console.log('foo: ', foo); -export { foo }; diff --git a/tests/rspack-test/configCases/library/modern-module-iife/rspack.config.js b/tests/rspack-test/configCases/library/modern-module-iife/rspack.config.js deleted file mode 100644 index 6f41a8d885b4..000000000000 --- a/tests/rspack-test/configCases/library/modern-module-iife/rspack.config.js +++ /dev/null @@ -1,35 +0,0 @@ -/** @type {import("@rspack/core").Configuration} */ -module.exports = { - entry: { - index: "./index.js" - }, - output: { - filename: `[name].js`, - iife: true, - asyncChunks: false, - library: { - type: "modern-module" - } - }, - optimization: { - minimize: true, - moduleIds: "named" - }, - plugins: [ - function () { - /** - * @param {import("@rspack/core").Compilation} compilation compilation - * @returns {void} - */ - const handler = compilation => { - compilation.hooks.afterProcessAssets.tap("testcase", assets => { - const bundle = Object.values(assets)[0]._value; - expect(bundle).toContain( - `(()=>{"use strict";console.log("foo: ","foo")})();` - ); - }); - }; - this.hooks.compilation.tap("testcase", handler); - } - ] -}; diff --git a/tests/rspack-test/configCases/library/modern-module-json-entry/rspack.config.js b/tests/rspack-test/configCases/library/modern-module-json-entry/rspack.config.js index c50e5ccceeca..43538a51e7a0 100644 --- a/tests/rspack-test/configCases/library/modern-module-json-entry/rspack.config.js +++ b/tests/rspack-test/configCases/library/modern-module-json-entry/rspack.config.js @@ -16,9 +16,6 @@ module.exports ={ } } }, - optimization: { - concatenateModules: true, - }, experiments: { outputModule: true } diff --git a/tests/rspack-test/configCases/library/modern-module-named-import-externals/rspack.config.js b/tests/rspack-test/configCases/library/modern-module-named-import-externals/rspack.config.js index 250c05ec7572..99161f0a23e0 100644 --- a/tests/rspack-test/configCases/library/modern-module-named-import-externals/rspack.config.js +++ b/tests/rspack-test/configCases/library/modern-module-named-import-externals/rspack.config.js @@ -33,23 +33,17 @@ module.exports = { compilation.hooks.processAssets.tap("testcase", assets => { const source = assets["test.js"].source(); expect(source).toMatchInlineSnapshot(` + import * as __rspack_external_externals3 from "externals3"; import { HomeLayout as external_externals0_HomeLayout, a } from "externals0"; import { a as external_externals1_a } from "externals1"; import externals2 from "externals2"; import "externals4"; - import * as __rspack_external_externals3 from "externals3"; - ;// CONCATENATED MODULE: external "externals0" - ;// CONCATENATED MODULE: external "externals1" - ;// CONCATENATED MODULE: external "externals2" - ;// CONCATENATED MODULE: external "externals3" - ;// CONCATENATED MODULE: external "externals4" - ;// CONCATENATED MODULE: ./lib.js (function Layout(props) { @@ -57,7 +51,6 @@ module.exports = { call({ HomeLayout }); })() - ;// CONCATENATED MODULE: ./test.js // re export diff --git a/tests/rspack-test/configCases/library/modern-module-reexport-type/rspack.config.js b/tests/rspack-test/configCases/library/modern-module-reexport-type/rspack.config.js index 8b72c1821d67..5f152069b791 100644 --- a/tests/rspack-test/configCases/library/modern-module-reexport-type/rspack.config.js +++ b/tests/rspack-test/configCases/library/modern-module-reexport-type/rspack.config.js @@ -16,6 +16,7 @@ module.exports = { library: { type: "modern-module" }, + filename: '[name].mjs', chunkFormat: "module" }, experiments: { diff --git a/tests/rspack-test/configCases/library/modern-module-reexport-type/test.config.js b/tests/rspack-test/configCases/library/modern-module-reexport-type/test.config.js new file mode 100644 index 000000000000..7710ebfb7fb8 --- /dev/null +++ b/tests/rspack-test/configCases/library/modern-module-reexport-type/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle() { + return ['main.mjs'] + } +} \ No newline at end of file diff --git a/tests/rspack-test/configCases/output/library-truthy/index.js b/tests/rspack-test/configCases/output/library-truthy/index.js index c39bb0d24e65..9e5f20fcdeb1 100644 --- a/tests/rspack-test/configCases/output/library-truthy/index.js +++ b/tests/rspack-test/configCases/output/library-truthy/index.js @@ -1,6 +1,6 @@ it('should not inject bundlerInfo when library is truthy', () => { const content = require('fs').readFileSync( - require('path').resolve(__dirname, "bundle0.js"), + require('path').resolve(__dirname, "bundle0.mjs"), "utf-8" ); expect(content).not.toContain('__webpack_require__' + '.rv') diff --git a/tests/rspack-test/configCases/output/library-truthy/rspack.config.js b/tests/rspack-test/configCases/output/library-truthy/rspack.config.js index 81dac1fd613d..91be1203067c 100644 --- a/tests/rspack-test/configCases/output/library-truthy/rspack.config.js +++ b/tests/rspack-test/configCases/output/library-truthy/rspack.config.js @@ -6,6 +6,10 @@ module.exports = { } }, optimization: { + runtimeChunk: false, avoidEntryIife: true + }, + experiments: { + outputModule: true } }; diff --git a/tests/rspack-test/configCases/parsing/commonjs/rspack.config.js b/tests/rspack-test/configCases/parsing/commonjs/rspack.config.js index dc5887b98085..85641ae5f163 100644 --- a/tests/rspack-test/configCases/parsing/commonjs/rspack.config.js +++ b/tests/rspack-test/configCases/parsing/commonjs/rspack.config.js @@ -1,6 +1,7 @@ /** @type {import("@rspack/core").Configuration} */ module.exports = [ { + name: 'module1', entry: "./module1.js", target: "node", node: { @@ -23,7 +24,8 @@ module.exports = [ }, }, { - entry: "./module2.js", + name: 'module2', + entry: {bundle1: "./module2.js"}, target: "node", node: { __filename: false, @@ -36,18 +38,17 @@ module.exports = [ node: false }, output: { - iife: false, module: true, library: { type: "modern-module" } }, - optimization: { - avoidEntryIife: true, - }, experiments: { outputModule: true }, + optimization: { + // minimize: false + }, module: { parser: { javascript: { @@ -59,6 +60,7 @@ module.exports = [ }, }, { + name: 'test', entry: "./test.js", externals: { "./bundle0.js": "commonjs ./bundle0.js", @@ -72,5 +74,5 @@ module.exports = [ __filename: false, __dirname: false } - } + }, ]; diff --git a/tests/rspack-test/configCases/parsing/commonjs/test.config.js b/tests/rspack-test/configCases/parsing/commonjs/test.config.js index c52ee9fc4cdb..5b76388db63b 100644 --- a/tests/rspack-test/configCases/parsing/commonjs/test.config.js +++ b/tests/rspack-test/configCases/parsing/commonjs/test.config.js @@ -1,6 +1,8 @@ module.exports = { findBundle: function (i, options) { - return ["test.js"]; + if (i === 2) { + return ["test.js"]; + } } }; diff --git a/tests/rspack-test/configCases/parsing/jsx-enabled/__snapshot__/bundle0.jsx.txt b/tests/rspack-test/configCases/parsing/jsx-enabled/__snapshot__/bundle0.jsx.txt index abf24a3b89c7..b641f0fe7f2e 100644 --- a/tests/rspack-test/configCases/parsing/jsx-enabled/__snapshot__/bundle0.jsx.txt +++ b/tests/rspack-test/configCases/parsing/jsx-enabled/__snapshot__/bundle0.jsx.txt @@ -1,11 +1,8 @@ import { App, App1A, App1B, App1C, app1cProps } from "./App1"; import { App2, app2Props } from "./App2"; -;// CONCATENATED MODULE: external "./App1" -;// CONCATENATED MODULE: external "./App2" -;// CONCATENATED MODULE: ./index.jsx @@ -93,4 +90,4 @@ function Root() { ; } -export { Root as default }; \ No newline at end of file +export default Root; \ No newline at end of file diff --git a/tests/rspack-test/configCases/parsing/jsx-enabled/rspack.config.js b/tests/rspack-test/configCases/parsing/jsx-enabled/rspack.config.js index 89467dc60948..3f8509105420 100644 --- a/tests/rspack-test/configCases/parsing/jsx-enabled/rspack.config.js +++ b/tests/rspack-test/configCases/parsing/jsx-enabled/rspack.config.js @@ -24,7 +24,6 @@ const baseConfig = { new rspack.experiments.RslibPlugin() ], optimization: { - avoidEntryIife: true, minimize: false, }, module: { @@ -102,9 +101,13 @@ module.exports = [ }, }, { + experiments: { + outputModule: true, + }, name: "test-output", entry: "./test.js", output: { + ...baseConfig.output, filename: "test.js" } } diff --git a/tests/rspack-test/configCases/parsing/jsx-enabled/test.js b/tests/rspack-test/configCases/parsing/jsx-enabled/test.js index 6418f3029fd3..ced664ec5b6c 100644 --- a/tests/rspack-test/configCases/parsing/jsx-enabled/test.js +++ b/tests/rspack-test/configCases/parsing/jsx-enabled/test.js @@ -1,5 +1,5 @@ -const fs = require("fs"); -const path = require("path"); +const fs = __non_webpack_require__("fs"); +const path = __non_webpack_require__("path"); it("should keep jsx in output when parser jsx is enabled", () => { const bundle = fs.readFileSync(path.join(__dirname, "bundle0.jsx"), "utf-8"); diff --git a/tests/rspack-test/configCases/rslib/hashbang-and-chmod/rspack.config.js b/tests/rspack-test/configCases/rslib/hashbang-and-chmod/rspack.config.js index ce3ea905f62a..5d488d24539b 100644 --- a/tests/rspack-test/configCases/rslib/hashbang-and-chmod/rspack.config.js +++ b/tests/rspack-test/configCases/rslib/hashbang-and-chmod/rspack.config.js @@ -3,21 +3,21 @@ const { } = require("@rspack/core"); /** @type {import("@rspack/core").Configuration} */ -const baseConfig = { +const baseConfig = (i, mjs = false) => ({ entry: { - index: "./index.js" + index: {import: "./index.js", filename: `bundle${i}${mjs ? '.mjs' : '.js'}`}, }, target: "node", node: { __filename: false, __dirname: false } -}; +}); module.exports = [ // CJS output { - ...baseConfig, + ...baseConfig(0), output: { library: { type: "commonjs" @@ -25,9 +25,9 @@ module.exports = [ }, plugins: [new RslibPlugin()] }, - // ESM output (without EsmLibraryPlugin) + // ESM output { - ...baseConfig, + ...baseConfig(1, true), experiments: { outputModule: true }, @@ -42,23 +42,6 @@ module.exports = [ }, plugins: [new RslibPlugin()] }, - // ESM output (with EsmLibraryPlugin) - { - ...baseConfig, - experiments: { - outputModule: true - }, - externals: { - os: "module os" - }, - output: { - module: true, - library: { - type: "modern-module" - } - }, - plugins: [new RslibPlugin(), new EsmLibraryPlugin()] - }, // Test entry { entry: "./test.js", diff --git a/tests/rspack-test/configCases/rslib/hashbang-and-chmod/test.config.js b/tests/rspack-test/configCases/rslib/hashbang-and-chmod/test.config.js index 24d78d0dbeb9..f245bfd422dd 100644 --- a/tests/rspack-test/configCases/rslib/hashbang-and-chmod/test.config.js +++ b/tests/rspack-test/configCases/rslib/hashbang-and-chmod/test.config.js @@ -1,6 +1,8 @@ /** @type {import("../../../..").TConfigCaseConfig} */ module.exports = { findBundle: function (i, options) { - return ["./bundle3.js"]; + if (i === 2) { + return ["./bundle2.js"]; + } } }; diff --git a/tests/rspack-test/configCases/rslib/hashbang-and-chmod/test.js b/tests/rspack-test/configCases/rslib/hashbang-and-chmod/test.js index d61c3583bd70..d2e4fd47db30 100644 --- a/tests/rspack-test/configCases/rslib/hashbang-and-chmod/test.js +++ b/tests/rspack-test/configCases/rslib/hashbang-and-chmod/test.js @@ -4,7 +4,6 @@ const fs = require('fs'); const testCases = [ { name: 'CJS', file: 'bundle0.js' }, { name: 'ESM', file: 'bundle1.mjs' }, - { name: 'ESM (with EsmLibraryPlugin)', file: 'bundle2.mjs' } ]; testCases.forEach(({ name, file }) => { diff --git a/tests/rspack-test/configCases/rslib/hashbang-and-extract-comments/rspack.config.js b/tests/rspack-test/configCases/rslib/hashbang-and-extract-comments/rspack.config.js index c1da8c325390..297d53982e1b 100644 --- a/tests/rspack-test/configCases/rslib/hashbang-and-extract-comments/rspack.config.js +++ b/tests/rspack-test/configCases/rslib/hashbang-and-extract-comments/rspack.config.js @@ -1,15 +1,16 @@ const { rspack, - experiments: { RslibPlugin, EsmLibraryPlugin } + experiments: { RslibPlugin, EsmLibraryPlugin }, + experiments } = require("@rspack/core"); /** @type {import("@rspack/core").Configuration} */ -const baseConfig = { +const baseConfig = (i, mjs = false) => ({ entry: { - index: "./index.js" + index: {import: "./index.js", filename: `bundle${i}${mjs?'.mjs':'.js'}`}, }, target: "node", - node: { + node: mjs ? {} : { __filename: false, __dirname: false }, @@ -21,12 +22,12 @@ const baseConfig = { }) ] } -}; +}); module.exports = [ // CJS output { - ...baseConfig, + ...baseConfig(0), output: { library: { type: "commonjs" @@ -34,9 +35,9 @@ module.exports = [ }, plugins: [new RslibPlugin()] }, - // ESM output (without EsmLibraryPlugin) + // ESM output { - ...baseConfig, + ...baseConfig(1, true), experiments: { outputModule: true }, @@ -47,34 +48,19 @@ module.exports = [ module: true, library: { type: "modern-module" - } + }, }, plugins: [new RslibPlugin()] }, - // ESM output (with EsmLibraryPlugin) - { - ...baseConfig, - experiments: { - outputModule: true - }, - externals: { - os: "module os" - }, - output: { - module: true, - library: { - type: "modern-module" - } - }, - plugins: [new RslibPlugin(), new EsmLibraryPlugin()] - }, // Test entry { entry: "./test.js", target: "node", - node: { - __filename: false, - __dirname: false + output: { + module: true, + }, + experiments: { + outputModule: true, } } ]; \ No newline at end of file diff --git a/tests/rspack-test/configCases/rslib/hashbang-and-extract-comments/test.config.js b/tests/rspack-test/configCases/rslib/hashbang-and-extract-comments/test.config.js index 24d78d0dbeb9..0c87c45646df 100644 --- a/tests/rspack-test/configCases/rslib/hashbang-and-extract-comments/test.config.js +++ b/tests/rspack-test/configCases/rslib/hashbang-and-extract-comments/test.config.js @@ -1,6 +1,8 @@ /** @type {import("../../../..").TConfigCaseConfig} */ module.exports = { findBundle: function (i, options) { - return ["./bundle3.js"]; + if (i===2) { + return ["./bundle2.mjs"]; + } } }; diff --git a/tests/rspack-test/configCases/rslib/hashbang-and-extract-comments/test.js b/tests/rspack-test/configCases/rslib/hashbang-and-extract-comments/test.js index 63a437742e13..c118acddc455 100644 --- a/tests/rspack-test/configCases/rslib/hashbang-and-extract-comments/test.js +++ b/tests/rspack-test/configCases/rslib/hashbang-and-extract-comments/test.js @@ -4,7 +4,6 @@ const fs = require('fs'); const testCases = [ { name: 'CJS', file: 'bundle0.js' }, { name: 'ESM', file: 'bundle1.mjs' }, - { name: 'ESM (with EsmLibraryPlugin)', file: 'bundle2.mjs' } ]; testCases.forEach(({ name, file }) => { diff --git a/tests/rspack-test/configCases/rslib/plugin-api/rspack.config.js b/tests/rspack-test/configCases/rslib/plugin-api/rspack.config.js index a7cc8dcfd522..c28caa065949 100644 --- a/tests/rspack-test/configCases/rslib/plugin-api/rspack.config.js +++ b/tests/rspack-test/configCases/rslib/plugin-api/rspack.config.js @@ -6,7 +6,7 @@ const { module.exports = [ { entry: { - index: "./index.js", + index: {import: "./index.js", filename: 'bundle0.js'}, }, target: "node", node: { @@ -26,7 +26,7 @@ module.exports = [ }, { entry: { - index: "./module.js", + index: {import: "./module.js", filename: 'bundle1.mjs'}, }, target: "node", node: { diff --git a/tests/rspack-test/configCases/rslib/plugin-api/test.js b/tests/rspack-test/configCases/rslib/plugin-api/test.js index 7a15581a4ebf..b7b7bd2c049c 100644 --- a/tests/rspack-test/configCases/rslib/plugin-api/test.js +++ b/tests/rspack-test/configCases/rslib/plugin-api/test.js @@ -18,14 +18,6 @@ console.log(typeof module) it ('`typeof module` should be intercepted by Rslib Plugin', () => { const file = path.resolve(__dirname, 'bundle1.mjs') const content = fs.readFileSync(file, 'utf-8'); - expect(content).toBe(`import node_module from "node:module"; - -;// CONCATENATED MODULE: external "node:module" - -;// CONCATENATED MODULE: ./module.js - - -console.log(typeof node_module) - -`) + expect(content).toContain(`import node_module from "node:module";`) + expect(content).toContain(`console.log(typeof node_module)`) }) diff --git a/tests/rspack-test/configCases/rslib/react-directives/rspack.config.js b/tests/rspack-test/configCases/rslib/react-directives/rspack.config.js index f386564fece0..21db468f89b6 100644 --- a/tests/rspack-test/configCases/rslib/react-directives/rspack.config.js +++ b/tests/rspack-test/configCases/rslib/react-directives/rspack.config.js @@ -3,21 +3,24 @@ const { } = require("@rspack/core"); /** @type {import("@rspack/core").Configuration} */ -const baseConfig = { +const baseConfig = (index, mjs = false) => ({ entry: { - index: "./index.js" + index: { + import: './index.js', + filename: `bundle${index}${mjs? '.mjs' : '.js'}` + } }, target: "node", node: { __filename: false, __dirname: false } -}; +}); module.exports = [ // CJS output { - ...baseConfig, + ...baseConfig(0), externals: { react: "react" }, @@ -30,7 +33,7 @@ module.exports = [ }, // ESM output (without EsmLibraryPlugin) { - ...baseConfig, + ...baseConfig(1, true), experiments: { outputModule: true }, @@ -47,7 +50,7 @@ module.exports = [ }, // ESM output (with EsmLibraryPlugin) { - ...baseConfig, + ...baseConfig(2, true), experiments: { outputModule: true }, @@ -66,6 +69,9 @@ module.exports = [ { entry: "./test.js", target: "node", + output: { + filename: 'bundle3.js' + }, node: { __filename: false, __dirname: false diff --git a/tests/rspack-test/configCases/rslib/react-directives/test.config.js b/tests/rspack-test/configCases/rslib/react-directives/test.config.js index 24d78d0dbeb9..b819a538bf6a 100644 --- a/tests/rspack-test/configCases/rslib/react-directives/test.config.js +++ b/tests/rspack-test/configCases/rslib/react-directives/test.config.js @@ -1,6 +1,8 @@ /** @type {import("../../../..").TConfigCaseConfig} */ module.exports = { findBundle: function (i, options) { - return ["./bundle3.js"]; + if (i === 3) { + return ["./bundle3.js"]; + } } }; diff --git a/tests/rspack-test/configCases/source-map/default-filename-extensions-mjs/index.js b/tests/rspack-test/configCases/source-map/default-filename-extensions-mjs/index.js index b7d629860813..0670ee0b30fc 100644 --- a/tests/rspack-test/configCases/source-map/default-filename-extensions-mjs/index.js +++ b/tests/rspack-test/configCases/source-map/default-filename-extensions-mjs/index.js @@ -1,4 +1,4 @@ -it("creates source maps for .mjs output files by default", function() { +it("creates source maps for .mjs output files by default", () => { var fs = require("fs"); var source = fs.readFileSync(__filename, "utf-8"); var match = /sourceMappingURL\s*=\s*(.*)/.exec(source); diff --git a/tests/rspack-test/configCases/source-map/default-filename-extensions-mjs/rspack.config.js b/tests/rspack-test/configCases/source-map/default-filename-extensions-mjs/rspack.config.js index a60b301872d4..f40ce5f3e221 100644 --- a/tests/rspack-test/configCases/source-map/default-filename-extensions-mjs/rspack.config.js +++ b/tests/rspack-test/configCases/source-map/default-filename-extensions-mjs/rspack.config.js @@ -2,11 +2,11 @@ module.exports = { mode: "development", output: { - filename: "bundle0.mjs" + filename: "bundle0.mjs", + module: true, }, - node: { - __dirname: false, - __filename: false + experiments: { + module: true, }, devtool: "source-map" }; diff --git a/website/docs/en/config/output.mdx b/website/docs/en/config/output.mdx index 81dc3c1152d1..cf9dc2406608 100644 --- a/website/docs/en/config/output.mdx +++ b/website/docs/en/config/output.mdx @@ -1546,6 +1546,30 @@ The AMD module will be: define('MyLibrary', [], factory); ``` +### output.library.preserveModules + +- **Type:** `string` +- **Default:** `undefined` + +:::info +Only available when `library.type` is set to `modern-module`. +::: + +When enabled, Rspack will preserve the original directory structure of modules within the specified directory. + +```js +import path from 'path'; +module.exports = { + //... + output: { + library: { + type: 'modern-module', + preserveModules: path.resolve('./src'), + }, + }, +}; +``` + ## output.module - **Type:** `boolean` diff --git a/website/docs/zh/config/output.mdx b/website/docs/zh/config/output.mdx index 7dc0fcefe7d3..0373377f8d74 100644 --- a/website/docs/zh/config/output.mdx +++ b/website/docs/zh/config/output.mdx @@ -1538,6 +1538,30 @@ AMD module 将会是这样: define('MyLibrary', [], factory); ``` +### output.library.preserveModules + +- **类型:** `string` +- **默认值:** `undefined` + +:::info +仅在 `library.type` 为 `modern-module` 时生效。 +::: + +当启用后,Rspack 会保留传入目录下模块的原始文件结构。 + +```js +import path from 'path'; +module.exports = { + //... + output: { + library: { + type: 'modern-module', + preserveModules: path.resolve('./src'), + }, + }, +}; +``` + ## output.module - **类型:** `boolean`