diff --git a/npm-packages/meteor-rspack/index.d.ts b/npm-packages/meteor-rspack/index.d.ts index 64f8822a3f..37104cd1a6 100644 --- a/npm-packages/meteor-rspack/index.d.ts +++ b/npm-packages/meteor-rspack/index.d.ts @@ -43,7 +43,7 @@ type MeteorEnv = Record & { * @param options - Optional configuration options * @returns A config object with module rules configuration */ - compileWithRspack: (deps: RuleSetConditions) => Record; + compileWithRspack: (deps: RuleSetConditions, options?: SwcLoaderOptions) => Record; /** * Enable or disable Rspack cache config. * @param enabled - Whether to enable caching @@ -61,6 +61,11 @@ type MeteorEnv = Record & { * @returns A config object with SWC loader config */ extendSwcConfig: (swcConfig: SwcLoaderOptions) => Record; + /** + * Extend Rspack configs. + * @returns A config object with merged configs + */ + extendConfig: (...configs: Record[]) => Record; } export type ConfigFactory = ( diff --git a/npm-packages/meteor-rspack/plugins/RequireExtenalsPlugin.js b/npm-packages/meteor-rspack/plugins/RequireExtenalsPlugin.js index 205863dbad..fb400a4382 100644 --- a/npm-packages/meteor-rspack/plugins/RequireExtenalsPlugin.js +++ b/npm-packages/meteor-rspack/plugins/RequireExtenalsPlugin.js @@ -443,13 +443,18 @@ class RequireExternalsPlugin { _ensureGlobalThisModule() { const block = [ - `/* Polyfill globalThis.module & exports */`, - `if (typeof globalThis.module === 'undefined') {`, - ` globalThis.module = { exports: {} };`, + `/* Polyfill globalThis.module, exports & module for legacy */`, + `if (typeof globalThis !== 'undefined') {`, + ` if (typeof globalThis.module === 'undefined') {`, + ` globalThis.module = { exports: {} };`, + ` }`, + ` if (typeof globalThis.exports === 'undefined') {`, + ` globalThis.exports = globalThis.module.exports;`, + ` }`, + `}`, + `if (typeof window.module === 'undefined') {`, + ` window.module = { exports: {} };`, `}`, - `if (typeof globalThis.exports === 'undefined') {`, - ` globalThis.exports = globalThis.module.exports;`, - `}` ].join('\n') + '\n'; let content = ''; diff --git a/npm-packages/meteor-rspack/rspack.config.js b/npm-packages/meteor-rspack/rspack.config.js index 47948866dd..238f13dad8 100644 --- a/npm-packages/meteor-rspack/rspack.config.js +++ b/npm-packages/meteor-rspack/rspack.config.js @@ -274,9 +274,9 @@ module.exports = async function (inMeteor = {}, argv = {}) { // Expose Meteor's helpers to expand Rspack configs Meteor.compileWithMeteor = deps => compileWithMeteor(deps); - Meteor.compileWithRspack = deps => + Meteor.compileWithRspack = (deps, options = {}) => compileWithRspack(deps, { - options: Meteor.swcConfigOptions, + options: mergeSplitOverlap(Meteor.swcConfigOptions, options), }); Meteor.setCache = enabled => setCache( @@ -285,6 +285,7 @@ module.exports = async function (inMeteor = {}, argv = {}) { ); Meteor.splitVendorChunk = () => splitVendorChunk(); Meteor.extendSwcConfig = (customSwcConfig) => extendSwcConfig(customSwcConfig); + Meteor.extendConfig = (...configs) => mergeSplitOverlap(...configs); // Add HtmlRspackPlugin function to Meteor Meteor.HtmlRspackPlugin = (options = {}) => { diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index 4de21d2f79..0de0637df2 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -142,16 +142,6 @@ BCp.initializeMeteorAppSwcrc = function () { return lastModifiedSwcConfig; }; -let lastModifiedSwcLegacyConfig; -BCp.initializeMeteorAppLegacyConfig = function () { - const swcLegacyConfig = convertBabelTargetsForSwc(Babel.getMinimumModernBrowserVersions()); - if (this.isVerbose() && !lastModifiedSwcLegacyConfig) { - logConfigBlock('SWC Legacy Config', swcLegacyConfig); - } - lastModifiedSwcLegacyConfig = swcLegacyConfig; - return lastModifiedSwcConfig; -}; - // Helper function to check if @swc/helpers is available function hasSwcHelpers() { return fs.existsSync(`${getMeteorAppDir()}/node_modules/@swc/helpers`); @@ -196,7 +186,6 @@ BCp.processFilesForTarget = function (inputFiles) { this.initializeMeteorAppConfig(); this.initializeMeteorAppSwcrc(); - this.initializeMeteorAppLegacyConfig(); this.initializeMeteorAppSwcHelpersAvailable(); inputFiles.forEach(function (inputFile) { @@ -242,11 +231,13 @@ BCp.processOneFileForTarget = function (inputFile, source) { sourceMap: null, bare: !! fileOptions.bare }; + const arch = inputFile.getArch(); + const isLegacyWebArch = arch.includes('legacy'); // Check if the file is a Rspack output file // If it is, bypass SWC/Babel and just read the file and its map file // as the contents are already transpiled by Rspack. -if (Plugin?.rspackHelpers?.isRspackOutputFile(inputFilePath)) { + if (Plugin?.rspackHelpers?.isRspackOutputFile(inputFilePath) && !isLegacyWebArch) { try { // Get the full path to the file const fullPath = inputFile.getPathInPackage(); @@ -290,7 +281,6 @@ if (Plugin?.rspackHelpers?.isRspackOutputFile(inputFilePath)) { ! excludedFileExtensionPattern.test(inputFilePath)) { const features = Object.assign({}, this.extraFeatures); - const arch = inputFile.getArch(); const isNodeTarget = arch.startsWith("os."); if (isNodeTarget) { @@ -381,7 +371,22 @@ if (Plugin?.rspackHelpers?.isRspackOutputFile(inputFilePath)) { filename, sourceFileName: filename, ...(isLegacyWebArch && { - env: { targets: lastModifiedSwcLegacyConfig || {} }, + env: { + targets: { + chrome: '49', + edge: '15', + firefox: '30', + safari: '10', + ios: '10', + android: '5', + opera: '42', + ie: '11', + node: '8', + electron: '1.6', + }, + mode: 'entry', + coreJs: '3.37', + }, }), }; @@ -414,7 +419,6 @@ if (Plugin?.rspackHelpers?.isRspackOutputFile(inputFilePath)) { const isNodeModulesCode = packageName == null && inputFilePath.includes("node_modules/"); const isAppCode = packageName == null && !isNodeModulesCode; const isPackageCode = packageName != null; - const isLegacyWebArch = arch.includes('legacy'); const transpConfig = getMeteorConfig()?.modern?.transpiler; const hasModernTranspiler = transpConfig != null && transpConfig !== false; diff --git a/packages/standard-minifier-js/plugin/minify-js.js b/packages/standard-minifier-js/plugin/minify-js.js index 0fe5ca613f..58bac3f119 100644 --- a/packages/standard-minifier-js/plugin/minify-js.js +++ b/packages/standard-minifier-js/plugin/minify-js.js @@ -49,6 +49,7 @@ export class MeteorMinifier { const NODE_ENV = process.env.NODE_ENV || 'development'; let content = file.getContentsAsString(); + const isLegacyWebArch = file?._arch === 'web.browser.legacy'; return swc.minifySync( content, @@ -60,6 +61,7 @@ export class MeteorMinifier { unused: true, dead_code: true, typeofs: false, + ...(isLegacyWebArch && { defaults: false }), global_defs: { 'process.env.NODE_ENV': NODE_ENV, diff --git a/tools/tests/modern.js b/tools/tests/modern.js index 2b1fdff0e8..374c219a15 100644 --- a/tools/tests/modern.js +++ b/tools/tests/modern.js @@ -235,7 +235,6 @@ selftest.define("modern build stack - transpiler boolean-like options", async fu /* check verbose logs */ await run.match(/SWC Custom Config/, false, true); - await run.match(/SWC Legacy Config/, false, true); await run.match(/Meteor Config/, false, true); /* check transpiler options */ @@ -331,7 +330,6 @@ console.log('Loaded NPM package "config"', require('config').id);`); /* check verbose logs */ await run.match(/SWC Custom Config/, false, true); - await run.match(/SWC Legacy Config/, false, true); await run.match(/Meteor Config/, false, true); /* check transpiler options */ diff --git a/v3-docs/docs/about/modern-build-stack/rspack-bundler-integration.md b/v3-docs/docs/about/modern-build-stack/rspack-bundler-integration.md index 6639589d04..d91600e6b7 100644 --- a/v3-docs/docs/about/modern-build-stack/rspack-bundler-integration.md +++ b/v3-docs/docs/about/modern-build-stack/rspack-bundler-integration.md @@ -141,23 +141,24 @@ module.exports = defineConfig(Meteor => { You can use flags to control the final configuration based on the environment. The available flags are passed in the `Meteor` parameter. -| Flag | Type | Description | -|---------------------| -------- |-----------------------------------------------------------------------------------------------------------| -| `isDevelopment` | boolean | True when running in development mode | -| `isProduction` | boolean | True when running in production mode | -| `isClient` | boolean | True when building or running client code | -| `isServer` | boolean | True when building or running server code | -| `isTest` | boolean | True when running in test mode | -| `isDebug` | boolean | True when debug mode is enabled | -| `isRun` | boolean | True when running the project with `meteor run` | -| `isBuild` | boolean | True when building the project with `meteor build` | -| `swcConfigOptions` | object | Project-level SWC config available for reusing | -| `HtmlRspackPlugin` | function | Custom HtmlRspackPlugin function for extending the config | -| `compileWithMeteor` | function | Forces given npm deps ([Condition](https://rspack.rs/config/module#condition)[]) to be compiled by Meteor | -| `compileWithRspack` | function | Forces given npm deps ([Condition](https://rspack.rs/config/module#condition)[]) to be compiled by Rspack | -| `setCache` | function | Enables or disables cache. Accepts true (persistent, default), false, or 'memory' | -| `splitVendorChunk` | function | Splits vendor libraries so they are automatically served from a separate chunk | -| `extendSwcConfig` | function | Extends the [SWC loader configuration](https://rspack.rs/guide/features/builtin-swc-loader#options) to apply only to the app code | +| Flag | Type | Description | +|---------------------| -------- |-----------------------------------------------------------------------------------------------------------------------------------| +| `isDevelopment` | boolean | True when running in development mode | +| `isProduction` | boolean | True when running in production mode | +| `isClient` | boolean | True when building or running client code | +| `isServer` | boolean | True when building or running server code | +| `isTest` | boolean | True when running in test mode | +| `isDebug` | boolean | True when debug mode is enabled | +| `isRun` | boolean | True when running the project with `meteor run` | +| `isBuild` | boolean | True when building the project with `meteor build` | +| `swcConfigOptions` | object | Project-level SWC config available for reusing | +| `HtmlRspackPlugin` | function | Custom HtmlRspackPlugin function for extending the config | +| `compileWithMeteor` | function | Forces given npm deps ([Condition](https://rspack.rs/config/module#condition)[]) to be compiled by Meteor | +| `compileWithRspack` | function | Forces given npm deps ([Condition](https://rspack.rs/config/module#condition)[]) to be compiled by Rspack | +| `setCache` | function | Enables or disables cache. Accepts true (persistent, default), false, or 'memory' | +| `splitVendorChunk` | function | Splits vendor libraries so they are automatically served from a separate chunk | +| `extendSwcConfig` | function | Extends the [SWC loader configuration](https://rspack.rs/guide/features/builtin-swc-loader#options) to apply only to the app code | +| `extendConfig` | function | Extends the config by applying merged object configs | Some configurations in the Rspack config are reserved for the Meteor-Rspack setup to work, such as Rspack options inside the `entry` and `output` objects. These will trigger warnings if modified. All other settings can be overridden, giving you the flexibility to make any setup compatible with the modern bundler. @@ -520,7 +521,7 @@ You can still use HTML files near your Meteor client entry point to define custo ### Delegating Dependencies to Rspack -**Meteor.compileWithRspack(deps: [Condition](https://rspack.rs/config/module#condition)[])** +**Meteor.compileWithRspack(deps: [Condition](https://rspack.rs/config/module#condition)[], options?: [SwcLoaderOptions](https://v0.rspack.dev/guide/features/builtin-swc-loader#options))** This helper forces **Rspack (via SWC and custom loaders)** to parse and transpile specific npm dependencies during the build. @@ -536,6 +537,8 @@ const { defineConfig } = require('@meteorjs/rspack'); module.exports = defineConfig(Meteor => ({ // Force-compile modern or local packages via SWC ...Meteor.compileWithRspack(['grubba-rpc']), + // Force-compile zod with ES5 target + ...Meteor.compileWithRspack(['zod'], { jsc: { target: 'es5' } }), })); ```