add SWC external helpers detection

This commit is contained in:
Nacho Codoñer
2025-07-28 18:53:19 +02:00
parent a5951315d2
commit 4d552de1a0
4 changed files with 38 additions and 12 deletions

View File

@@ -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.*/,

View File

@@ -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}

View File

@@ -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',
);
}

View File

@@ -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',