diff --git a/npm-packages/meteor-rspack/rspack.config.js b/npm-packages/meteor-rspack/rspack.config.js index 609a8bacbe..66f4eb1a1a 100644 --- a/npm-packages/meteor-rspack/rspack.config.js +++ b/npm-packages/meteor-rspack/rspack.config.js @@ -43,7 +43,7 @@ function createCacheStrategy(mode) { } // SWC loader rule (JSX/JS) -function createSwcConfig({ isRun, isTypescriptEnabled, isJsxEnabled, isTsxEnabled }) { +function createSwcConfig({ isRun, isTypescriptEnabled, isJsxEnabled, isTsxEnabled, externalHelpers }) { const defaultConfig = { jsc: { baseUrl: process.cwd(), @@ -60,6 +60,7 @@ function createSwcConfig({ isRun, isTypescriptEnabled, isJsxEnabled, isTsxEnable refresh: isRun, }, }, + externalHelpers, }, }; const customConfig = getMeteorAppSwcConfig() || {}; @@ -117,6 +118,7 @@ export default function (inMeteor = {}, argv = {}) { const isRun = Meteor.isRun; const isReactEnabled = Meteor.isReactEnabled; const isTestModule = Meteor.isTestModule; + const swcExternalHelpers = Meteor.swcExternalHelpers; const mode = isProd ? 'production' : 'development'; const isTypescriptEnabled = Meteor.isTypescriptEnabled || false; @@ -159,6 +161,7 @@ export default function (inMeteor = {}, argv = {}) { isTypescriptEnabled, isJsxEnabled, isTsxEnabled, + externalHelpers: swcExternalHelpers, }); const externals = [ /^meteor.*/, diff --git a/packages/rspack/lib/constants.js b/packages/rspack/lib/constants.js index 63a410051e..d11d20d398 100644 --- a/packages/rspack/lib/constants.js +++ b/packages/rspack/lib/constants.js @@ -15,6 +15,7 @@ export const DEFAULT_METEOR_RSPACK_COFFEE_LOADER_VERSION = '5.0.0'; export const DEFAULT_METEOR_RSPACK_SWC_LOADER_VERSION = '0.2.6'; +export const DEFAULT_METEOR_RSPACK_SWC_HELPERS_VERSION = '0.5.17'; /** * Global state keys used for storing and retrieving state across the application * @constant {Object} diff --git a/packages/rspack/lib/dependencies.js b/packages/rspack/lib/dependencies.js index bad61df757..473b943280 100644 --- a/packages/rspack/lib/dependencies.js +++ b/packages/rspack/lib/dependencies.js @@ -2,6 +2,7 @@ * @module dependencies * @description Functions for managing dependencies for RSPack plugin */ +import { DEFAULT_METEOR_RSPACK_SWC_HELPERS_VERSION } from "./constants"; const { getGlobalState, @@ -51,7 +52,7 @@ async function ensureDependenciesInstalled(dependencies, globalStateKey, package const appDir = getMeteorAppDir(); // Filter dependencies that need to be installed (missing or wrong version) - const depsToInstall = dependencies.filter(dep => + const allDepsToInstall = dependencies.filter(dep => !checkNpmDependencyExists(dep.name, { cwd: appDir }) || !checkNpmDependencyVersion(dep.name, { cwd: appDir, @@ -61,20 +62,36 @@ async function ensureDependenciesInstalled(dependencies, globalStateKey, package ); // Format dependencies for installation - const dependencyStrings = depsToInstall.map(dep => `${dep.name}@${dep.version}`); + const dependencyStrings = allDepsToInstall.map(dep => `${dep.name}@${dep.version}`); - if (depsToInstall.length > 0) { + if (allDepsToInstall.length > 0) { + let success; logProgress( - `Some ${packageName} dependencies need to be installed. Installing ${joinWithAnd(dependencyStrings)}...`, + `${packageName} dependencies need to be installed. Installing ${joinWithAnd(dependencyStrings)}...`, ); - const success = await installNpmDependency(dependencyStrings, { - cwd: appDir, - dev: true, - }); + // Install dev dependencies + const devDepsToInstall = allDepsToInstall.filter(dep => dep.dev === true || dep.dev == null); + if (devDepsToInstall.length > 0) { + const devDepsStrings = devDepsToInstall.map(dep => `${dep.name}@${dep.version}`); + success = await installNpmDependency(devDepsStrings, { + cwd: appDir, + dev: true, + }); + } + + const depsToInstall = allDepsToInstall.filter(dep => dep.dev === false); + if (depsToInstall.length > 0) { + const depsStrings = depsToInstall.map(dep => `${dep.name}@${dep.version}`); + const depsSuccess = await installNpmDependency(depsStrings, { + cwd: appDir, + dev: false, + }); + success = success && depsSuccess; + } if (!success) { throw new Error( - `Failed to install ${packageName} dependencies. Please install them manually with: meteor npm install -D ${joinWithAnd(dependencyStrings)}` + `Failed to install ${packageName} dependencies. Please install them manually with: meteor npm install -D ${joinWithAnd(allDepsToInstall)}` ); } @@ -94,13 +111,14 @@ export async function ensureRSPackInstalled() { const dependencies = [ { name: '@rspack/cli', version: DEFAULT_RSPACK_VERSION, semverCondition: 'gte' }, { name: '@rspack/core', version: DEFAULT_RSPACK_VERSION, semverCondition: 'gte' }, - { name: '@meteorjs/rspack', version: DEFAULT_METEOR_RSPACK_VERSION, semverCondition: 'gte' } + { name: '@meteorjs/rspack', version: DEFAULT_METEOR_RSPACK_VERSION, semverCondition: 'gte' }, + { name: '@swc/helpers', version: DEFAULT_METEOR_RSPACK_SWC_HELPERS_VERSION, semverCondition: 'gte', dev: false }, ]; await ensureDependenciesInstalled( dependencies, GLOBAL_STATE_KEYS.RSPACK_INSTALLATION_CHECKED, - 'RSPack' + 'RSPack', ); } diff --git a/packages/rspack/lib/processes.js b/packages/rspack/lib/processes.js index 1dfc4c2d98..e3bedb3141 100644 --- a/packages/rspack/lib/processes.js +++ b/packages/rspack/lib/processes.js @@ -2,6 +2,7 @@ * @module processes * @description Functions for managing RSPack processes */ +import { checkNpmDependencyExists } from "../../tools-core/lib/npm"; const { spawnProcess, @@ -85,6 +86,8 @@ export function getRSPackEnv({ isClient, isServer }) { const isTsxEnabled = inputFilePath.endsWith('.tsx'); const isJsxEnabled = inputFilePath.endsWith('.jsx'); + const swcExternalHelpers = checkNpmDependencyExists('@swc/helpers'); + const pairs = [ ['isDevelopment', isMeteorAppDevelopment()], ['isProduction', isMeteorAppProduction()], @@ -118,6 +121,7 @@ export function getRSPackEnv({ isClient, isServer }) { ['isTsxEnabled', isTsxEnabled], ['isJsxEnabled', isJsxEnabled], ['isCoffeescriptEnabled', process.env.METEOR_COFFEESCRIPT_ENABLED], + ['swcExternalHelpers', swcExternalHelpers], ]; return pairs.flatMap(([key, val]) => [ '--env',