From 5987ed70ad287e7360266dfc2154483de672f93a Mon Sep 17 00:00:00 2001 From: Welkin Wong Date: Tue, 22 Apr 2025 14:34:58 +0800 Subject: [PATCH 001/148] Add TypeScript declarations for isModern and getMinimumBrowserVersions functions --- packages/modern-browsers/modern.d.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/modern-browsers/modern.d.ts b/packages/modern-browsers/modern.d.ts index 69f1268f74..efa33b82e8 100644 --- a/packages/modern-browsers/modern.d.ts +++ b/packages/modern-browsers/modern.d.ts @@ -1,4 +1,12 @@ +export declare function isModern( + browser: { name: string, major: number, minor?: number, patch?: number } +): boolean; + export declare function setMinimumBrowserVersions( versions: Record, - source: string + source?: string ): void; + +export declare function getMinimumBrowserVersions(): Record>; + +export declare function calculateHashOfMinimumVersions(): string; \ No newline at end of file From 4f7bfbfff3fd8eb43605e4cf154363a2bab4c196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 8 May 2025 17:30:09 +0200 Subject: [PATCH 002/148] Revert "Revert "Bump mongodb dependency to version 6.16.0 in npm-mongo package (#13710)"" This reverts commit 86fc826b9379c86c51ef1334c5d679b12c60150a. --- packages/npm-mongo/package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/npm-mongo/package.js b/packages/npm-mongo/package.js index 8b45db0032..fad1d65554 100644 --- a/packages/npm-mongo/package.js +++ b/packages/npm-mongo/package.js @@ -8,7 +8,7 @@ Package.describe({ }); Npm.depends({ - mongodb: "6.9.0" + mongodb: "6.16.0" }); Package.onUse(function (api) { From e35ec4872aaa00db3c9f142ffda6710dd60a7d6d Mon Sep 17 00:00:00 2001 From: Welkin Wong Date: Fri, 25 Apr 2025 23:26:37 +0800 Subject: [PATCH 003/148] Bump mongodb dependency to version 6.16.0 in npm-mongo package --- packages/npm-mongo/package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/npm-mongo/package.js b/packages/npm-mongo/package.js index 8b45db0032..fad1d65554 100644 --- a/packages/npm-mongo/package.js +++ b/packages/npm-mongo/package.js @@ -8,7 +8,7 @@ Package.describe({ }); Npm.depends({ - mongodb: "6.9.0" + mongodb: "6.16.0" }); Package.onUse(function (api) { From 0335287388479ed70eb6b19aa36f5a9a69ef3258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Fri, 9 May 2025 19:43:44 +0200 Subject: [PATCH 004/148] ensure npm-mongo-legacy approach to ensure upgrades for legacy projects --- packages/npm-mongo-legacy/README.md | 4 ++++ packages/npm-mongo-legacy/index.d.ts | 3 +++ packages/npm-mongo-legacy/package.js | 18 ++++++++++++++++++ packages/npm-mongo-legacy/wrapper.js | 11 +++++++++++ packages/npm-mongo/package.js | 1 + packages/npm-mongo/wrapper.js | 15 +++++++++++++-- 6 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 packages/npm-mongo-legacy/README.md create mode 100644 packages/npm-mongo-legacy/index.d.ts create mode 100644 packages/npm-mongo-legacy/package.js create mode 100644 packages/npm-mongo-legacy/wrapper.js diff --git a/packages/npm-mongo-legacy/README.md b/packages/npm-mongo-legacy/README.md new file mode 100644 index 0000000000..4776f34fbc --- /dev/null +++ b/packages/npm-mongo-legacy/README.md @@ -0,0 +1,4 @@ +# npm-mongo +[Source code of released version](https://github.com/meteor/meteor/tree/master/packages/npm-mongo) | [Source code of development version](https://github.com/meteor/meteor/tree/devel/packages/npm-mongo) +*** + diff --git a/packages/npm-mongo-legacy/index.d.ts b/packages/npm-mongo-legacy/index.d.ts new file mode 100644 index 0000000000..d7ab3d7558 --- /dev/null +++ b/packages/npm-mongo-legacy/index.d.ts @@ -0,0 +1,3 @@ +import * as NpmModuleMongodb from 'mongodb'; +declare const NpmModuleMongodbVersion: string; +export { NpmModuleMongodb, NpmModuleMongodbVersion }; diff --git a/packages/npm-mongo-legacy/package.js b/packages/npm-mongo-legacy/package.js new file mode 100644 index 0000000000..9f924773d6 --- /dev/null +++ b/packages/npm-mongo-legacy/package.js @@ -0,0 +1,18 @@ +// This has been moved out of the `mongo` package so it can be used by the tool +// via isopacket, without having to also load ddp-server. + +Package.describe({ + summary: "Wrapper around the mongo npm package", + version: "6.10.2", + documentation: null, +}); + +Npm.depends({ + mongodb: "6.9.0", +}); + +Package.onUse(function (api) { + api.addFiles("wrapper.js", "server"); + api.export(["NpmModuleMongodb", "NpmModuleMongodbVersion"], "server"); + api.addAssets("index.d.ts", "server"); +}); diff --git a/packages/npm-mongo-legacy/wrapper.js b/packages/npm-mongo-legacy/wrapper.js new file mode 100644 index 0000000000..e341493895 --- /dev/null +++ b/packages/npm-mongo-legacy/wrapper.js @@ -0,0 +1,11 @@ +const oldNoDeprecationValue = process.noDeprecation; +try { + // Silence deprecation warnings introduced in a patch update to mongodb: + // https://github.com/meteor/meteor/pull/9942#discussion_r218564879 + process.noDeprecation = true; + NpmModuleMongodb = Npm.require('mongodb'); +} finally { + process.noDeprecation = oldNoDeprecationValue; +} + +NpmModuleMongodbVersion = Npm.require('mongodb/package.json').version; diff --git a/packages/npm-mongo/package.js b/packages/npm-mongo/package.js index fad1d65554..480a757a67 100644 --- a/packages/npm-mongo/package.js +++ b/packages/npm-mongo/package.js @@ -12,6 +12,7 @@ Npm.depends({ }); Package.onUse(function (api) { + api.use(['npm-mongo-legacy', "ecmascript"], "server"); api.addFiles("wrapper.js", "server"); api.export(["NpmModuleMongodb", "NpmModuleMongodbVersion"], "server"); api.addAssets("index.d.ts", "server"); diff --git a/packages/npm-mongo/wrapper.js b/packages/npm-mongo/wrapper.js index e341493895..6e3671bc66 100644 --- a/packages/npm-mongo/wrapper.js +++ b/packages/npm-mongo/wrapper.js @@ -1,11 +1,22 @@ +import { + NpmModuleMongodb as NpmModuleMongodbLegacy, + NpmModuleMongodbVersion as NpmModuleMongodbVersionLegacy +} from 'meteor/npm-mongo-legacy'; + +const useLegacyMongo = process.env.METEOR_USE_LEGACY_MONGO; + const oldNoDeprecationValue = process.noDeprecation; try { // Silence deprecation warnings introduced in a patch update to mongodb: // https://github.com/meteor/meteor/pull/9942#discussion_r218564879 process.noDeprecation = true; - NpmModuleMongodb = Npm.require('mongodb'); + NpmModuleMongodb = useLegacyMongo + ? NpmModuleMongodbLegacy + : Npm.require('mongodb'); } finally { process.noDeprecation = oldNoDeprecationValue; } -NpmModuleMongodbVersion = Npm.require('mongodb/package.json').version; +NpmModuleMongodbVersion = useLegacyMongo + ? NpmModuleMongodbVersionLegacy + : Npm.require('mongodb/package.json').version; From eca1382f70f29c05b41537c1de92f5926eac1ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Fri, 9 May 2025 19:51:37 +0200 Subject: [PATCH 005/148] ensure better npm-mongo-legacy approach to ensure upgrades for legacy projects --- packages/npm-mongo/package.js | 1 - packages/npm-mongo/wrapper.js | 11 +++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/npm-mongo/package.js b/packages/npm-mongo/package.js index 480a757a67..fad1d65554 100644 --- a/packages/npm-mongo/package.js +++ b/packages/npm-mongo/package.js @@ -12,7 +12,6 @@ Npm.depends({ }); Package.onUse(function (api) { - api.use(['npm-mongo-legacy', "ecmascript"], "server"); api.addFiles("wrapper.js", "server"); api.export(["NpmModuleMongodb", "NpmModuleMongodbVersion"], "server"); api.addAssets("index.d.ts", "server"); diff --git a/packages/npm-mongo/wrapper.js b/packages/npm-mongo/wrapper.js index 6e3671bc66..7df43c3385 100644 --- a/packages/npm-mongo/wrapper.js +++ b/packages/npm-mongo/wrapper.js @@ -1,9 +1,4 @@ -import { - NpmModuleMongodb as NpmModuleMongodbLegacy, - NpmModuleMongodbVersion as NpmModuleMongodbVersionLegacy -} from 'meteor/npm-mongo-legacy'; - -const useLegacyMongo = process.env.METEOR_USE_LEGACY_MONGO; +const useLegacyMongo = !!Package['npm-mongo-legacy']; const oldNoDeprecationValue = process.noDeprecation; try { @@ -11,12 +6,12 @@ try { // https://github.com/meteor/meteor/pull/9942#discussion_r218564879 process.noDeprecation = true; NpmModuleMongodb = useLegacyMongo - ? NpmModuleMongodbLegacy + ? Package['npm-mongo-legacy'].NpmModuleMongodb : Npm.require('mongodb'); } finally { process.noDeprecation = oldNoDeprecationValue; } NpmModuleMongodbVersion = useLegacyMongo - ? NpmModuleMongodbVersionLegacy + ? Package['npm-mongo-legacy'].NpmModuleMongodbVersion : Npm.require('mongodb/package.json').version; From ef28617c580f457d0ea7b4507a8fd2f99d76b8c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Fri, 9 May 2025 20:03:14 +0200 Subject: [PATCH 006/148] ensure better npm-mongo-legacy approach to ensure upgrades for legacy projects --- packages/npm-mongo-legacy/package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/npm-mongo-legacy/package.js b/packages/npm-mongo-legacy/package.js index 9f924773d6..6a5106c95f 100644 --- a/packages/npm-mongo-legacy/package.js +++ b/packages/npm-mongo-legacy/package.js @@ -2,7 +2,7 @@ // via isopacket, without having to also load ddp-server. Package.describe({ - summary: "Wrapper around the mongo npm package", + summary: "Wrapper around the mongo npm package (legacy)", version: "6.10.2", documentation: null, }); From 28cd192c36ccabb8b3926da492804c6174c32db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Sat, 10 May 2025 11:54:53 +0200 Subject: [PATCH 007/148] Update README.md --- packages/npm-mongo-legacy/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/npm-mongo-legacy/README.md b/packages/npm-mongo-legacy/README.md index 4776f34fbc..39675814ec 100644 --- a/packages/npm-mongo-legacy/README.md +++ b/packages/npm-mongo-legacy/README.md @@ -1,4 +1,4 @@ -# npm-mongo -[Source code of released version](https://github.com/meteor/meteor/tree/master/packages/npm-mongo) | [Source code of development version](https://github.com/meteor/meteor/tree/devel/packages/npm-mongo) +# npm-mongo-legacy +[Source code of released version](https://github.com/meteor/meteor/tree/devel/packages/npm-mongo-legacy) *** From 833ba0247d738c0754fbb9b64c7d86264200335b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Mon, 12 May 2025 16:54:37 +0200 Subject: [PATCH 008/148] ensure default id generation strategy --- packages/mongo/collection/collection.js | 9 ++++++--- packages/mongo/collection/collection_utils.js | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/mongo/collection/collection.js b/packages/mongo/collection/collection.js index 28776c9a93..5e248c389b 100644 --- a/packages/mongo/collection/collection.js +++ b/packages/mongo/collection/collection.js @@ -3,7 +3,9 @@ import { AsyncMethods } from './methods_async'; import { SyncMethods } from './methods_sync'; import { IndexMethods } from './methods_index'; import { - ID_GENERATORS, normalizeOptions, + ID_GENERATION_DEFAULT, + ID_GENERATORS, + normalizeOptions, setupAutopublish, setupConnection, setupDriver, @@ -41,7 +43,9 @@ Mongo.Collection = function Collection(name, options) { options = normalizeOptions(options); - this._makeNewID = ID_GENERATORS[options.idGeneration]?.(name); + this._makeNewID = ( + ID_GENERATORS[options.idGeneration] || ID_GENERATION_DEFAULT + )?.(name); this._transform = LocalCollection.wrapTransform(options.transform); this.resolverType = options.resolverType; @@ -265,4 +269,3 @@ Meteor.Collection = Mongo.Collection; // Allow deny stuff is now in the allow-deny package Object.assign(Mongo.Collection.prototype, AllowDeny.CollectionPrototype); - diff --git a/packages/mongo/collection/collection_utils.js b/packages/mongo/collection/collection_utils.js index a0f7442ded..1105c0f209 100644 --- a/packages/mongo/collection/collection_utils.js +++ b/packages/mongo/collection/collection_utils.js @@ -13,6 +13,8 @@ export const ID_GENERATORS = { } }; +export const ID_GENERATION_DEFAULT = ID_GENERATORS.STRING; + export function setupConnection(name, options) { if (!name || options.connection === null) return null; if (options.connection) return options.connection; From aa81324fa7936bcbc847be21438290996e8fcfd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Mon, 12 May 2025 17:10:25 +0200 Subject: [PATCH 009/148] ensure default id generation strategy --- packages/mongo/collection/collection.js | 4 +- packages/mongo/collection/collection_utils.js | 9 ++- packages/mongo/tests/collection_tests.js | 55 +++++++++++++++++++ 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/packages/mongo/collection/collection.js b/packages/mongo/collection/collection.js index 5e248c389b..7d6eac5a6a 100644 --- a/packages/mongo/collection/collection.js +++ b/packages/mongo/collection/collection.js @@ -43,9 +43,7 @@ Mongo.Collection = function Collection(name, options) { options = normalizeOptions(options); - this._makeNewID = ( - ID_GENERATORS[options.idGeneration] || ID_GENERATION_DEFAULT - )?.(name); + this._makeNewID = ID_GENERATORS[options.idGeneration]?.(name); this._transform = LocalCollection.wrapTransform(options.transform); this.resolverType = options.resolverType; diff --git a/packages/mongo/collection/collection_utils.js b/packages/mongo/collection/collection_utils.js index 1105c0f209..e6c79646d5 100644 --- a/packages/mongo/collection/collection_utils.js +++ b/packages/mongo/collection/collection_utils.js @@ -13,8 +13,6 @@ export const ID_GENERATORS = { } }; -export const ID_GENERATION_DEFAULT = ID_GENERATORS.STRING; - export function setupConnection(name, options) { if (!name || options.connection === null) return null; if (options.connection) return options.connection; @@ -90,12 +88,17 @@ export function normalizeOptions(options) { options.connection = options.manager; } + const cleanedOptions = Object.fromEntries( + Object.entries(options || {}).filter(([_, v]) => v !== undefined), + ); + + // 2) Spread defaults first, then only the defined overrides return { connection: undefined, idGeneration: 'STRING', transform: null, _driver: undefined, _preventAutopublish: false, - ...options, + ...cleanedOptions, }; } diff --git a/packages/mongo/tests/collection_tests.js b/packages/mongo/tests/collection_tests.js index a0e9e7fecf..1d10431c7f 100644 --- a/packages/mongo/tests/collection_tests.js +++ b/packages/mongo/tests/collection_tests.js @@ -485,3 +485,58 @@ Meteor.isServer && Tinytest.addAsync('collection - simple add', async function(t test.equal((await collection.findOneAsync(id)).a, 2); await collection.removeAsync({}); }); + +Tinytest.addAsync('collection - default idGeneration when not provided', async function(test) { + if (!Meteor.isServer) { + return; + } + // Create a collection without specifying idGeneration option + var collectionName = 'defaultIdGeneration' + test.id; + var collection = new Mongo.Collection(collectionName); + + // Insert a document + var id = await collection.insertAsync({a: 1}); + + // Verify that the _id is a string (since ID_GENERATION_DEFAULT is ID_GENERATORS.STRING) + test.isTrue(typeof id === 'string', 'Document _id should be a string when no idGeneration option is provided'); + test.isFalse(id instanceof Mongo.ObjectID, 'Document _id should not be a Mongo.ObjectID when no idGeneration option is provided'); + + // Clean up + await collection.removeAsync({}); +}); + +Tinytest.addAsync('collection - compare default idGeneration with explicit idGeneration', async function(test) { + if (!Meteor.isServer) { + return; + } + // Create a collection without specifying idGeneration option (should use ID_GENERATION_DEFAULT) + var defaultCollectionName = 'defaultIdGeneration2' + test.id; + var defaultCollection = new Mongo.Collection(defaultCollectionName); + + // Create a collection with explicit STRING idGeneration + var stringCollectionName = 'stringIdGeneration' + test.id; + var stringCollection = new Mongo.Collection(stringCollectionName, { idGeneration: 'STRING' }); + + // Create a collection with MONGO idGeneration + var mongoCollectionName = 'mongoIdGeneration' + test.id; + var mongoCollection = new Mongo.Collection(mongoCollectionName, { idGeneration: 'MONGO' }); + + // Insert documents + var defaultId = await defaultCollection.insertAsync({a: 1}); + var stringId = await stringCollection.insertAsync({a: 1}); + var mongoId = await mongoCollection.insertAsync({a: 1}); + + // Verify default behaves like STRING + test.isTrue(typeof defaultId === 'string', 'Default idGeneration should produce string IDs'); + test.isTrue(typeof stringId === 'string', 'STRING idGeneration should produce string IDs'); + test.isFalse(defaultId instanceof Mongo.ObjectID, 'Default idGeneration should not produce Mongo.ObjectID'); + test.isFalse(stringId instanceof Mongo.ObjectID, 'STRING idGeneration should not produce Mongo.ObjectID'); + + // Verify MONGO produces ObjectIDs + test.isTrue(mongoId instanceof Mongo.ObjectID, 'MONGO idGeneration should produce Mongo.ObjectID'); + + // Clean up + await defaultCollection.removeAsync({}); + await stringCollection.removeAsync({}); + await mongoCollection.removeAsync({}); +}); From 9ea72dd5f43fbd073159f5160d7296678cde020e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Mon, 12 May 2025 17:12:48 +0200 Subject: [PATCH 010/148] ensure default id generation strategy --- packages/mongo/tests/collection_tests.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mongo/tests/collection_tests.js b/packages/mongo/tests/collection_tests.js index 1d10431c7f..dd78eb58b3 100644 --- a/packages/mongo/tests/collection_tests.js +++ b/packages/mongo/tests/collection_tests.js @@ -492,7 +492,7 @@ Tinytest.addAsync('collection - default idGeneration when not provided', async f } // Create a collection without specifying idGeneration option var collectionName = 'defaultIdGeneration' + test.id; - var collection = new Mongo.Collection(collectionName); + var collection = new Mongo.Collection(collectionName, { idGeneration: undefined }); // Insert a document var id = await collection.insertAsync({a: 1}); @@ -511,7 +511,7 @@ Tinytest.addAsync('collection - compare default idGeneration with explicit idGen } // Create a collection without specifying idGeneration option (should use ID_GENERATION_DEFAULT) var defaultCollectionName = 'defaultIdGeneration2' + test.id; - var defaultCollection = new Mongo.Collection(defaultCollectionName); + var defaultCollection = new Mongo.Collection(defaultCollectionName, { idGeneration: undefined }); // Create a collection with explicit STRING idGeneration var stringCollectionName = 'stringIdGeneration' + test.id; From fd9b8443b0597e48403734435cb819edbf6a3cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Mon, 12 May 2025 18:08:18 +0200 Subject: [PATCH 011/148] clean references of ID_GENERATION_DEFAULT as not used --- packages/mongo/collection/collection.js | 1 - packages/mongo/tests/collection_tests.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/mongo/collection/collection.js b/packages/mongo/collection/collection.js index 7d6eac5a6a..e587f398d0 100644 --- a/packages/mongo/collection/collection.js +++ b/packages/mongo/collection/collection.js @@ -3,7 +3,6 @@ import { AsyncMethods } from './methods_async'; import { SyncMethods } from './methods_sync'; import { IndexMethods } from './methods_index'; import { - ID_GENERATION_DEFAULT, ID_GENERATORS, normalizeOptions, setupAutopublish, diff --git a/packages/mongo/tests/collection_tests.js b/packages/mongo/tests/collection_tests.js index dd78eb58b3..e8841c5892 100644 --- a/packages/mongo/tests/collection_tests.js +++ b/packages/mongo/tests/collection_tests.js @@ -497,7 +497,7 @@ Tinytest.addAsync('collection - default idGeneration when not provided', async f // Insert a document var id = await collection.insertAsync({a: 1}); - // Verify that the _id is a string (since ID_GENERATION_DEFAULT is ID_GENERATORS.STRING) + // Verify that the _id is a string test.isTrue(typeof id === 'string', 'Document _id should be a string when no idGeneration option is provided'); test.isFalse(id instanceof Mongo.ObjectID, 'Document _id should not be a Mongo.ObjectID when no idGeneration option is provided'); @@ -509,7 +509,7 @@ Tinytest.addAsync('collection - compare default idGeneration with explicit idGen if (!Meteor.isServer) { return; } - // Create a collection without specifying idGeneration option (should use ID_GENERATION_DEFAULT) + // Create a collection without specifying idGeneration option var defaultCollectionName = 'defaultIdGeneration2' + test.id; var defaultCollection = new Mongo.Collection(defaultCollectionName, { idGeneration: undefined }); From 4543eb2bab8f77429d34551dea035df8f9301720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 13 May 2025 09:03:22 +0200 Subject: [PATCH 012/148] ensure global.meteorConfig to spread on package definition --- packages/babel-compiler/babel-compiler.js | 3 +++ tools/cli/commands.js | 1 + tools/project-context.js | 3 +++ 3 files changed, 7 insertions(+) diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index b0c3c96a98..d07c6e88e6 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -121,6 +121,9 @@ let modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); let lastModifiedMeteorConfig; let lastModifiedMeteorConfigTime; BCp.initializeMeteorAppConfig = function () { + if (global.meteorConfig) { + return global.meteorConfig; + } if (!lastModifiedMeteorConfig && !fs.existsSync(`${getMeteorAppDir()}/package.json`)) { return; } diff --git a/tools/cli/commands.js b/tools/cli/commands.js index d9efdf9d5c..cff7455e29 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -293,6 +293,7 @@ function getMeteorConfig(appDir) { const packageJsonFile = files.readFile(packageJsonPath, 'utf8'); const packageJson = JSON.parse(packageJsonFile); meteorConfig = packageJson?.meteor; + global.meteorConfig = packageJson?.meteor; return meteorConfig; } diff --git a/tools/project-context.js b/tools/project-context.js index 0dce0164eb..65f49c1eef 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -492,6 +492,9 @@ Object.assign(ProjectContext.prototype, { self.meteorConfig = new MeteorConfig({ appDirectory: self.projectDir, }); + self.meteorConfig._ensureInitialized(); + global.meteorConfig = self.meteorConfig?._config; + if (buildmessage.jobHasMessages()) { return; } From f11b0518130389df013798cf3a4dcf7b2c178738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 13 May 2025 09:36:31 +0200 Subject: [PATCH 013/148] provide global.meteorConfig --- packages/babel-compiler/babel-compiler.js | 52 +++-------------------- tools/cli/commands.js | 28 +++++------- tools/cli/main.js | 4 +- tools/fs/safe-watcher.ts | 6 +-- tools/project-context.js | 7 ++- 5 files changed, 28 insertions(+), 69 deletions(-) diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index d07c6e88e6..0c6220643e 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -99,50 +99,12 @@ function compileWithSwc(source, swcOptions = {}, { inputFilePath, filename, sour }; }); } -const DEFAULT_MODERN = { - transpiler: true, -}; -const normalizeModern = (r = false) => Object.fromEntries( - Object.entries(DEFAULT_MODERN).map(([k, def]) => [ - k, - r === true - ? def - : r === false || r?.[k] === false - ? false - : typeof r?.[k] === 'object' - ? { ...r[k] } - : def, - ]), -); - -let modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); - -let lastModifiedMeteorConfig; -let lastModifiedMeteorConfigTime; BCp.initializeMeteorAppConfig = function () { - if (global.meteorConfig) { - return global.meteorConfig; + if (global.meteorConfig?.modern?.transpiler?.verbose) { + logConfigBlock('Meteor Config', global.meteorConfig); } - if (!lastModifiedMeteorConfig && !fs.existsSync(`${getMeteorAppDir()}/package.json`)) { - return; - } - const currentLastModifiedConfigTime = fs - .statSync(`${getMeteorAppDir()}/package.json`) - ?.mtime?.getTime(); - if (currentLastModifiedConfigTime !== lastModifiedMeteorConfigTime) { - lastModifiedMeteorConfigTime = currentLastModifiedConfigTime; - lastModifiedMeteorConfig = getMeteorAppPackageJson()?.meteor; - lastModifiedMeteorConfig = lastModifiedMeteorConfig != null ? { - ...lastModifiedMeteorConfig, - modern: normalizeModern(modernForced || lastModifiedMeteorConfig?.modern), - } : {}; - - if (lastModifiedMeteorConfig?.modern?.transpiler?.verbose) { - logConfigBlock('Meteor Config', lastModifiedMeteorConfig); - } - } - return lastModifiedMeteorConfig; + return global.meteorConfig; }; let lastModifiedSwcConfig; @@ -163,7 +125,7 @@ BCp.initializeMeteorAppSwcrc = function () { lastModifiedSwcConfig.jsc.baseUrl = path.resolve(process.cwd(), lastModifiedSwcConfig.jsc.baseUrl); } - if (lastModifiedMeteorConfig?.modern?.transpiler?.verbose) { + if (global.meteorConfig?.modern?.transpiler?.verbose) { logConfigBlock('SWC Config', lastModifiedSwcConfig); } } @@ -173,7 +135,7 @@ BCp.initializeMeteorAppSwcrc = function () { let lastModifiedSwcLegacyConfig; BCp.initializeMeteorAppLegacyConfig = function () { const swcLegacyConfig = convertBabelTargetsForSwc(Babel.getMinimumModernBrowserVersions()); - if (lastModifiedMeteorConfig?.modern?.transpiler?.verbose && !lastModifiedSwcLegacyConfig) { + if (global.meteorConfig?.modern?.transpiler?.verbose && !lastModifiedSwcLegacyConfig) { logConfigBlock('SWC Legacy Config', swcLegacyConfig); } lastModifiedSwcLegacyConfig = swcLegacyConfig; @@ -307,8 +269,8 @@ BCp.processOneFileForTarget = function (inputFile, source) { const isPackageCode = packageName != null; const isLegacyWebArch = arch.includes('legacy'); - const config = lastModifiedMeteorConfig?.modern?.transpiler; - const hasModernTranspiler = lastModifiedMeteorConfig?.modern?.transpiler !== false; + const config = global.meteorConfig?.modern?.transpiler; + const hasModernTranspiler = global.meteorConfig?.modern?.transpiler !== false; const shouldSkipSwc = !hasModernTranspiler || (isAppCode && config?.excludeApp === true) || diff --git a/tools/cli/commands.js b/tools/cli/commands.js index cff7455e29..efb5475b6d 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -266,6 +266,7 @@ const DEFAULT_MODERN = { webArchOnly: true, watcher: true, }; +global.DEFAULT_MODERN = DEFAULT_MODERN; const normalizeModern = (r = false) => Object.fromEntries( Object.entries(DEFAULT_MODERN).map(([k, def]) => [ @@ -279,32 +280,25 @@ const normalizeModern = (r = false) => Object.fromEntries( : def, ]), ); - +global.normalizeModern = normalizeModern; let modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); -let meteorConfig; +global.modernForced = modernForced; function getMeteorConfig(appDir) { - if (meteorConfig) return meteorConfig; + if (global.meteorConfig) return global.meteorConfig; const packageJsonPath = files.pathJoin(appDir, 'package.json'); if (!files.exists(packageJsonPath)) { return false; } const packageJsonFile = files.readFile(packageJsonPath, 'utf8'); const packageJson = JSON.parse(packageJsonFile); - meteorConfig = packageJson?.meteor; - global.meteorConfig = packageJson?.meteor; - return meteorConfig; -} - -function isModernArchsOnlyEnabled(appDir) { - const meteorConfig = getMeteorConfig(appDir); - return normalizeModern(modernForced || meteorConfig?.modern).webArchOnly !== false; -} - -export function isModernWatcherEnabled(appDir) { - const meteorConfig = getMeteorConfig(appDir); - return normalizeModern(modernForced || meteorConfig?.modern).watcher !== false; + const meteorConfig = { + ...(packageJson?.meteor || {}), + modern: normalizeModern(modernForced || packageJson?.meteor?.modern), + }; + global.meteorConfig = meteorConfig; + return global.meteorConfig; } function filterWebArchs(webArchs, excludeArchsOption, appDir, options) { @@ -326,7 +320,7 @@ function filterWebArchs(webArchs, excludeArchsOption, appDir, options) { if (!isCordovaDev) { const excludeArchsOptions = excludeArchsOption ? excludeArchsOption.trim().split(/\s*,\s*/) : []; const hasExcludeArchsOptions = (excludeArchsOptions?.length || 0) > 0; - const hasModernArchsOnlyEnabled = appDir && isModernArchsOnlyEnabled(appDir); + const hasModernArchsOnlyEnabled = appDir && global.meteorConfig?.modern?.webArchOnly !== false; if (hasExcludeArchsOptions && hasModernArchsOnlyEnabled) { console.warn('modern.webArchOnly and --exclude-archs are both active. If both are set, --exclude-archs takes priority.'); } diff --git a/tools/cli/main.js b/tools/cli/main.js index 6888765ad9..92e75c7bbe 100644 --- a/tools/cli/main.js +++ b/tools/cli/main.js @@ -287,7 +287,7 @@ main.captureAndExit = async function (header, title, f) { // NB: files required up to this point may not define commands -const { isModernWatcherEnabled } = require('./commands.js'); +const { getMeteorConfig } = require('./commands.js'); require('./commands-packages.js'); require('./commands-packages-query.js'); require('./commands-cordova.js'); @@ -865,7 +865,7 @@ makeGlobalAsyncLocalStorage().run({}, async function () { var appDir = files.findAppDir(); if (appDir) { appDir = files.pathResolve(appDir); - global.modernWatcher = isModernWatcherEnabled(appDir); + global.meteorConfig = getMeteorConfig(appDir); } await require('../tool-env/isopackets.js').ensureIsopacketsLoadable(); diff --git a/tools/fs/safe-watcher.ts b/tools/fs/safe-watcher.ts index 3e9bda0ab4..93dcea1b89 100644 --- a/tools/fs/safe-watcher.ts +++ b/tools/fs/safe-watcher.ts @@ -377,7 +377,7 @@ function startNewEntry(absPath: string): Entry { */ export function watch (absPath: string, callback: ChangeCallback): SafeWatcher { // @ts-ignore - if (!global.modernWatcher) { + if (!global.meteorConfig?.modern?.watcher) { // @ts-ignore return watchLegacy(absPath, callback); } @@ -441,7 +441,7 @@ const watchModern = */ export function addWatchRoot(absPath: string) { // @ts-ignore - if (!global.modernWatcher) { + if (!global.meteorConfig?.modern?.watcher) { // @ts-ignore return addWatchRootLegacy(absPath); } @@ -474,7 +474,7 @@ async function safeUnsubscribeSub(root: string) { export async function closeAllWatchers() { // @ts-ignore - if (!global.modernWatcher) { + if (!global.meteorConfig?.modern?.watcher) { // @ts-ignore return closeAllWatchersLegacy(); } diff --git a/tools/project-context.js b/tools/project-context.js index 65f49c1eef..6d64a5a81b 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -493,7 +493,6 @@ Object.assign(ProjectContext.prototype, { appDirectory: self.projectDir, }); self.meteorConfig._ensureInitialized(); - global.meteorConfig = self.meteorConfig?._config; if (buildmessage.jobHasMessages()) { return; @@ -1814,7 +1813,11 @@ export class MeteorConfig { }, }), } : this._config; - + this._config = { + ...(this._config || {}), + modern: global.normalizeModern(global.modernForced || global.meteorConfig?.modern), + }; + global.meteorConfig = this._config; return this._config; } From ca4b126ea6f9a8d92a2ea3d0677477185a8f2a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 13 May 2025 09:37:22 +0200 Subject: [PATCH 014/148] provide global.meteorConfig --- tools/cli/commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cli/commands.js b/tools/cli/commands.js index efb5475b6d..e357a79e98 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -285,7 +285,7 @@ global.normalizeModern = normalizeModern; let modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); global.modernForced = modernForced; -function getMeteorConfig(appDir) { +export function getMeteorConfig(appDir) { if (global.meteorConfig) return global.meteorConfig; const packageJsonPath = files.pathJoin(appDir, 'package.json'); if (!files.exists(packageJsonPath)) { From b7fff86f1a59547f5c22c843be7cd4fae6531d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 13 May 2025 10:25:44 +0200 Subject: [PATCH 015/148] provide global.meteorConfig --- tools/project-context.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/project-context.js b/tools/project-context.js index 6d64a5a81b..9e2a757036 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -1815,7 +1815,7 @@ export class MeteorConfig { } : this._config; this._config = { ...(this._config || {}), - modern: global.normalizeModern(global.modernForced || global.meteorConfig?.modern), + modern: global.normalizeModern(global.modernForced || this._config?.modern), }; global.meteorConfig = this._config; return this._config; From a2593302463e55cdfffd441a953c31ff4b87bbd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 13 May 2025 10:37:31 +0200 Subject: [PATCH 016/148] update docs --- tools/cli/main.js | 1 + tools/project-context.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/tools/cli/main.js b/tools/cli/main.js index 92e75c7bbe..48c5e4e16a 100644 --- a/tools/cli/main.js +++ b/tools/cli/main.js @@ -865,6 +865,7 @@ makeGlobalAsyncLocalStorage().run({}, async function () { var appDir = files.findAppDir(); if (appDir) { appDir = files.pathResolve(appDir); + // Initialize meteorConfig globally for command context global.meteorConfig = getMeteorConfig(appDir); } diff --git a/tools/project-context.js b/tools/project-context.js index 9e2a757036..51322c5406 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -1817,6 +1817,8 @@ export class MeteorConfig { ...(this._config || {}), modern: global.normalizeModern(global.modernForced || this._config?.modern), }; + // Reinitialize meteorConfig globally for project context + // Updates config when package.json changes trigger rebuilds global.meteorConfig = this._config; return this._config; } From d83e85929908d003d4dcfbba8ee46e1a28a8db23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 13 May 2025 11:25:47 +0200 Subject: [PATCH 017/148] update meteorConfig including modern normalization --- tools/project-context.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/project-context.js b/tools/project-context.js index 51322c5406..63e7064635 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -1813,13 +1813,12 @@ export class MeteorConfig { }, }), } : this._config; - this._config = { + // Reinitialize meteorConfig globally for project context + // Updates config when package.json changes trigger rebuilds + global.meteorConfig = { ...(this._config || {}), modern: global.normalizeModern(global.modernForced || this._config?.modern), }; - // Reinitialize meteorConfig globally for project context - // Updates config when package.json changes trigger rebuilds - global.meteorConfig = this._config; return this._config; } From 7abf1cbfdaa6c62b696fad4cd11abbed026510a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 13 May 2025 12:03:46 +0200 Subject: [PATCH 018/148] fix self-test tests --- tools/cli/commands.js | 26 +------------------------- tools/project-context.js | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/tools/cli/commands.js b/tools/cli/commands.js index e357a79e98..10e6c52229 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -261,30 +261,6 @@ export function parseRunTargets(targets) { }); }; -const DEFAULT_MODERN = { - transpiler: true, - webArchOnly: true, - watcher: true, -}; -global.DEFAULT_MODERN = DEFAULT_MODERN; - -const normalizeModern = (r = false) => Object.fromEntries( - Object.entries(DEFAULT_MODERN).map(([k, def]) => [ - k, - r === true - ? def - : r === false || r?.[k] === false - ? false - : typeof r?.[k] === 'object' - ? { ...r[k] } - : def, - ]), -); -global.normalizeModern = normalizeModern; - -let modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); -global.modernForced = modernForced; - export function getMeteorConfig(appDir) { if (global.meteorConfig) return global.meteorConfig; const packageJsonPath = files.pathJoin(appDir, 'package.json'); @@ -295,7 +271,7 @@ export function getMeteorConfig(appDir) { const packageJson = JSON.parse(packageJsonFile); const meteorConfig = { ...(packageJson?.meteor || {}), - modern: normalizeModern(modernForced || packageJson?.meteor?.modern), + modern: projectContextModule.normalizeModern(projectContextModule.modernForced || packageJson?.meteor?.modern), }; global.meteorConfig = meteorConfig; return global.meteorConfig; diff --git a/tools/project-context.js b/tools/project-context.js index 63e7064635..31075cc4ce 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -1769,6 +1769,27 @@ Object.assign(exports.FinishedUpgraders.prototype, { } }); +const DEFAULT_MODERN = { + transpiler: true, + webArchOnly: true, + watcher: true, +}; + +export const normalizeModern = (r = false) => Object.fromEntries( + Object.entries(DEFAULT_MODERN).map(([k, def]) => [ + k, + r === true + ? def + : r === false || r?.[k] === false + ? false + : typeof r?.[k] === 'object' + ? { ...r[k] } + : def, + ]), +); + +export const modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); + export class MeteorConfig { constructor({ appDirectory, @@ -1817,7 +1838,7 @@ export class MeteorConfig { // Updates config when package.json changes trigger rebuilds global.meteorConfig = { ...(this._config || {}), - modern: global.normalizeModern(global.modernForced || this._config?.modern), + modern: normalizeModern(modernForced || this._config?.modern), }; return this._config; } From c3631d7baf2d91b76c503bb7af41eb820d3194fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 13 May 2025 16:57:59 +0200 Subject: [PATCH 019/148] fix self-test tests --- tools/cli/commands.js | 19 +++++++++++-------- tools/cli/main.js | 4 ++-- tools/project-context.js | 5 ++--- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/tools/cli/commands.js b/tools/cli/commands.js index 10e6c52229..ef9d4f1810 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -263,17 +263,20 @@ export function parseRunTargets(targets) { export function getMeteorConfig(appDir) { if (global.meteorConfig) return global.meteorConfig; - const packageJsonPath = files.pathJoin(appDir, 'package.json'); - if (!files.exists(packageJsonPath)) { - return false; + let packageJson; + if (appDir) { + const packageJsonPath = files.pathJoin(appDir, 'package.json'); + if (!files.exists(packageJsonPath)) { + return false; + } + const packageJsonFile = files.readFile(packageJsonPath, 'utf8'); + packageJson = JSON.parse(packageJsonFile); } - const packageJsonFile = files.readFile(packageJsonPath, 'utf8'); - const packageJson = JSON.parse(packageJsonFile); - const meteorConfig = { + const modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); + global.meteorConfig = { ...(packageJson?.meteor || {}), - modern: projectContextModule.normalizeModern(projectContextModule.modernForced || packageJson?.meteor?.modern), + modern: projectContextModule.normalizeModern(modernForced || packageJson?.meteor?.modern || false), }; - global.meteorConfig = meteorConfig; return global.meteorConfig; } diff --git a/tools/cli/main.js b/tools/cli/main.js index 48c5e4e16a..f890f272a4 100644 --- a/tools/cli/main.js +++ b/tools/cli/main.js @@ -865,9 +865,9 @@ makeGlobalAsyncLocalStorage().run({}, async function () { var appDir = files.findAppDir(); if (appDir) { appDir = files.pathResolve(appDir); - // Initialize meteorConfig globally for command context - global.meteorConfig = getMeteorConfig(appDir); } + // Initialize meteorConfig globally for command context + global.meteorConfig = getMeteorConfig(appDir); await require('../tool-env/isopackets.js').ensureIsopacketsLoadable(); diff --git a/tools/project-context.js b/tools/project-context.js index 31075cc4ce..481279439e 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -1788,8 +1788,6 @@ export const normalizeModern = (r = false) => Object.fromEntries( ]), ); -export const modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); - export class MeteorConfig { constructor({ appDirectory, @@ -1834,11 +1832,12 @@ export class MeteorConfig { }, }), } : this._config; + const modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); // Reinitialize meteorConfig globally for project context // Updates config when package.json changes trigger rebuilds global.meteorConfig = { ...(this._config || {}), - modern: normalizeModern(modernForced || this._config?.modern), + modern: normalizeModern(modernForced || this._config?.modern || false), }; return this._config; } From 7e23a8c426f463ee58e3898baea76e1be9adffa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 27 May 2025 19:19:39 +0200 Subject: [PATCH 020/148] fix --- packages/babel-compiler/babel-compiler.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index fd27d83d63..fdd9a26328 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -26,7 +26,7 @@ var excludedFileExtensionPattern = /\.(es5|min)\.js$/i; var hasOwn = Object.prototype.hasOwnProperty; // Check if verbose mode is enabled either in the provided config or in extraFeatures -BCp.isVerbose = function(config) { +BCp.isVerbose = function(config = global.meteorConfig) { if (config?.modern?.transpiler?.verbose) { return true; } @@ -82,7 +82,7 @@ function compileWithSwc(source, swcOptions = {}, { features }) { } BCp.initializeMeteorAppConfig = function () { - if (this.isVerbose(lastModifiedMeteorConfig)) { + if (this.isVerbose(global.meteorConfig)) { logConfigBlock('Meteor Config', global.meteorConfig); } return global.meteorConfig; @@ -123,7 +123,7 @@ BCp.initializeMeteorAppSwcrc = function () { lastModifiedSwcConfigTime = currentLastModifiedConfigTime; lastModifiedSwcConfig = getMeteorAppSwcrc(swcFile); - if (this.isVerbose(lastModifiedMeteorConfig)) { + if (this.isVerbose(global.meteorConfig)) { logConfigBlock('SWC Config', lastModifiedSwcConfig); } } @@ -133,7 +133,7 @@ BCp.initializeMeteorAppSwcrc = function () { let lastModifiedSwcLegacyConfig; BCp.initializeMeteorAppLegacyConfig = function () { const swcLegacyConfig = convertBabelTargetsForSwc(Babel.getMinimumModernBrowserVersions()); - if (this.isVerbose(lastModifiedMeteorConfig) && !lastModifiedSwcLegacyConfig) { + if (this.isVerbose(global.meteorConfig) && !lastModifiedSwcLegacyConfig) { logConfigBlock('SWC Legacy Config', swcLegacyConfig); } lastModifiedSwcLegacyConfig = swcLegacyConfig; From ac353c0a8e89cb30d93eb811c4885261a7080730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 27 May 2025 19:35:28 +0200 Subject: [PATCH 021/148] fix --- packages/babel-compiler/babel-compiler.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index fdd9a26328..e91ec6fd39 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -82,7 +82,7 @@ function compileWithSwc(source, swcOptions = {}, { features }) { } BCp.initializeMeteorAppConfig = function () { - if (this.isVerbose(global.meteorConfig)) { + if (this.isVerbose()) { logConfigBlock('Meteor Config', global.meteorConfig); } return global.meteorConfig; @@ -123,7 +123,7 @@ BCp.initializeMeteorAppSwcrc = function () { lastModifiedSwcConfigTime = currentLastModifiedConfigTime; lastModifiedSwcConfig = getMeteorAppSwcrc(swcFile); - if (this.isVerbose(global.meteorConfig)) { + if (this.isVerbose()) { logConfigBlock('SWC Config', lastModifiedSwcConfig); } } @@ -133,7 +133,7 @@ BCp.initializeMeteorAppSwcrc = function () { let lastModifiedSwcLegacyConfig; BCp.initializeMeteorAppLegacyConfig = function () { const swcLegacyConfig = convertBabelTargetsForSwc(Babel.getMinimumModernBrowserVersions()); - if (this.isVerbose(global.meteorConfig) && !lastModifiedSwcLegacyConfig) { + if (this.isVerbose() && !lastModifiedSwcLegacyConfig) { logConfigBlock('SWC Legacy Config', swcLegacyConfig); } lastModifiedSwcLegacyConfig = swcLegacyConfig; @@ -367,7 +367,7 @@ BCp.processOneFileForTarget = function (inputFile, source) { compilation = this.readFromSwcCache({ cacheKey }); // Return cached result if found. if (compilation) { - if (this.isVerbose(config)) { + if (this.isVerbose()) { logTranspilation({ usedSwc: true, inputFilePath, @@ -397,7 +397,7 @@ BCp.processOneFileForTarget = function (inputFile, source) { usedSwc = false; } - if (this.isVerbose(config)) { + if (this.isVerbose()) { logTranspilation({ usedSwc, inputFilePath, @@ -413,7 +413,7 @@ BCp.processOneFileForTarget = function (inputFile, source) { babelOptions = setupBabelOptions(); compilation = compileWithBabel(source, babelOptions, cacheOptions); - if (this.isVerbose(config)) { + if (this.isVerbose()) { logTranspilation({ usedSwc: false, inputFilePath, From b626ddf05ed2b071063d62b50c757d29b94ac980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 27 May 2025 22:22:00 +0200 Subject: [PATCH 022/148] attempt to use legacy watcher in a specific test --- tools/tests/compiler-plugins.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/tests/compiler-plugins.js b/tools/tests/compiler-plugins.js index 37a37535cb..8bcb21c0e3 100644 --- a/tools/tests/compiler-plugins.js +++ b/tools/tests/compiler-plugins.js @@ -384,6 +384,10 @@ selftest.define("compiler plugin caching - local plugin", async function () { // Tests that SwcCompiler properly applies SWC compilation on JS files selftest.define("compiler plugin caching - local plugin with SwcCompiler", async function () { + // Enable legacy watcher for testing. + const currentMeteorModern = process.env.METEOR_MODERN; + process.env.METEOR_MODERN = '{ "watcher": false }'; + var s = new Sandbox({ fakeMongo: true }); await s.init(); @@ -488,10 +492,16 @@ Package.onUse(function (api) { await run.match("SwcJsCompiler invocation 3", false, true); await run.stop(); + + process.env.METEOR_MODERN = currentMeteorModern; }); // Test error on duplicate compiler plugins. selftest.define("compiler plugins - duplicate extension", async () => { + // Enable legacy watcher for testing. + const currentMeteorModern = process.env.METEOR_MODERN; + process.env.METEOR_MODERN = '{ "watcher": false }'; + const s = new Sandbox({ fakeMongo: true }); await s.init(); @@ -510,6 +520,7 @@ selftest.define("compiler plugins - duplicate extension", async () => { run.waitSecs(30); await run.stop(); + process.env.METEOR_MODERN = currentMeteorModern; }); // Test error when a source file no longer has an active plugin. From 5148fccc533fa6eeb649593dc23161493a173587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 28 May 2025 08:38:15 +0200 Subject: [PATCH 023/148] ensure global context initializes early to affect watcher --- tools/cli/main.js | 8 ++++++-- tools/tests/compiler-plugins.js | 11 ----------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/tools/cli/main.js b/tools/cli/main.js index f890f272a4..6e98f38fd4 100644 --- a/tools/cli/main.js +++ b/tools/cli/main.js @@ -293,6 +293,9 @@ require('./commands-packages-query.js'); require('./commands-cordova.js'); require('./commands-aliases.js'); +// Initialize meteorConfig globally +global.meteorConfig = getMeteorConfig(); + /////////////////////////////////////////////////////////////////////////////// // Record all the top-level commands as JSON /////////////////////////////////////////////////////////////////////////////// @@ -865,9 +868,10 @@ makeGlobalAsyncLocalStorage().run({}, async function () { var appDir = files.findAppDir(); if (appDir) { appDir = files.pathResolve(appDir); + + // Renitialize meteorConfig globally when having appDir context + global.meteorConfig = getMeteorConfig(appDir); } - // Initialize meteorConfig globally for command context - global.meteorConfig = getMeteorConfig(appDir); await require('../tool-env/isopackets.js').ensureIsopacketsLoadable(); diff --git a/tools/tests/compiler-plugins.js b/tools/tests/compiler-plugins.js index 8bcb21c0e3..37a37535cb 100644 --- a/tools/tests/compiler-plugins.js +++ b/tools/tests/compiler-plugins.js @@ -384,10 +384,6 @@ selftest.define("compiler plugin caching - local plugin", async function () { // Tests that SwcCompiler properly applies SWC compilation on JS files selftest.define("compiler plugin caching - local plugin with SwcCompiler", async function () { - // Enable legacy watcher for testing. - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = '{ "watcher": false }'; - var s = new Sandbox({ fakeMongo: true }); await s.init(); @@ -492,16 +488,10 @@ Package.onUse(function (api) { await run.match("SwcJsCompiler invocation 3", false, true); await run.stop(); - - process.env.METEOR_MODERN = currentMeteorModern; }); // Test error on duplicate compiler plugins. selftest.define("compiler plugins - duplicate extension", async () => { - // Enable legacy watcher for testing. - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = '{ "watcher": false }'; - const s = new Sandbox({ fakeMongo: true }); await s.init(); @@ -520,7 +510,6 @@ selftest.define("compiler plugins - duplicate extension", async () => { run.waitSecs(30); await run.stop(); - process.env.METEOR_MODERN = currentMeteorModern; }); // Test error when a source file no longer has an active plugin. From f987305587d31ba86720fd608719fbbc2105679b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 28 May 2025 09:21:50 +0200 Subject: [PATCH 024/148] adapt minifier to use reefactored global config --- packages/standard-minifier-js/plugin/minify-js.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/packages/standard-minifier-js/plugin/minify-js.js b/packages/standard-minifier-js/plugin/minify-js.js index e3fb61182d..f75b5e64a9 100644 --- a/packages/standard-minifier-js/plugin/minify-js.js +++ b/packages/standard-minifier-js/plugin/minify-js.js @@ -1,16 +1,7 @@ import { extractModuleSizesTree } from "./stats.js"; -import fs from 'fs'; export function getConfig() { - try{ - const meteorAppDir = process.cwd(); - const packageJson = fs.readFileSync(`${meteorAppDir}/package.json`, 'utf8'); - const meteorConfig = JSON.parse(packageJson).meteor; - return meteorConfig; - } catch (error) { - console.log(error); - return {}; - } + return global.meteorConfig; }; const statsEnabled = process.env.DISABLE_CLIENT_STATS !== 'true' From 409a13c00e5fd7acdd707e3bf94773087e33867d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 28 May 2025 09:24:09 +0200 Subject: [PATCH 025/148] ensure reinstantation config will work --- tools/cli/commands.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/cli/commands.js b/tools/cli/commands.js index 1df2867416..566f485238 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -262,7 +262,6 @@ export function parseRunTargets(targets) { }; export function getMeteorConfig(appDir) { - if (global.meteorConfig) return global.meteorConfig; let packageJson; if (appDir) { const packageJsonPath = files.pathJoin(appDir, 'package.json'); From a8a407c7e24120efda6f0e3896a4ca657b37cf96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 28 May 2025 09:41:42 +0200 Subject: [PATCH 026/148] fix minifier config --- .../standard-minifier-js/plugin/minify-js.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/packages/standard-minifier-js/plugin/minify-js.js b/packages/standard-minifier-js/plugin/minify-js.js index f75b5e64a9..f491fcbc96 100644 --- a/packages/standard-minifier-js/plugin/minify-js.js +++ b/packages/standard-minifier-js/plugin/minify-js.js @@ -1,9 +1,5 @@ import { extractModuleSizesTree } from "./stats.js"; -export function getConfig() { - return global.meteorConfig; -}; - const statsEnabled = process.env.DISABLE_CLIENT_STATS !== 'true' @@ -45,11 +41,6 @@ if (typeof Plugin !== 'undefined') { } export class MeteorMinifier { - - constructor() { - this.config = getConfig(); - } - _minifyWithSWC(file) { return Profile('_minifyWithSWC', () => { swc = swc || require('@meteorjs/swc-core'); @@ -111,9 +102,13 @@ export class MeteorMinifier { minifyOneFile(file) { return Profile('minifyOneFile', () => { - const modern = this.config && (this.config.modern === true || (this.config.modern && this.config.modern.minifier === true)); + const modern = + global.meteorConfig && + (global.meteorConfig.modern === true || + (global.meteorConfig.modern && + global.meteorConfig.modern.minifier === true)); // check if config is an empty object - if(this.config && Object.keys(this.config).length === 0 || !modern) { + if(global.meteorConfig && Object.keys(global.meteorConfig).length === 0 || !modern) { Meteor._debug(`Minifying using Terser | file: ${file.getPathInBundle()}`); return this._minifyWithTerser(file); } From 29f3ba243541e850f7403933eebc912cd47a88fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 28 May 2025 09:44:50 +0200 Subject: [PATCH 027/148] fix minifier config --- packages/standard-minifier-js/plugin/minify-js.js | 6 +++--- tools/project-context.js | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/standard-minifier-js/plugin/minify-js.js b/packages/standard-minifier-js/plugin/minify-js.js index f491fcbc96..85abdb397c 100644 --- a/packages/standard-minifier-js/plugin/minify-js.js +++ b/packages/standard-minifier-js/plugin/minify-js.js @@ -104,9 +104,9 @@ export class MeteorMinifier { return Profile('minifyOneFile', () => { const modern = global.meteorConfig && - (global.meteorConfig.modern === true || - (global.meteorConfig.modern && - global.meteorConfig.modern.minifier === true)); + (global.meteorConfig?.modern === true || + (global.meteorConfig?.modern && + global.meteorConfig?.modern?.minifier === true)); // check if config is an empty object if(global.meteorConfig && Object.keys(global.meteorConfig).length === 0 || !modern) { Meteor._debug(`Minifying using Terser | file: ${file.getPathInBundle()}`); diff --git a/tools/project-context.js b/tools/project-context.js index 189ebe4219..db9552a7c3 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -1771,6 +1771,7 @@ Object.assign(exports.FinishedUpgraders.prototype, { const DEFAULT_MODERN = { transpiler: true, + minifier: true, webArchOnly: true, watcher: true, }; From d132eeaa55d7614a96055f8b15ebf8e9faa1c669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 5 Jun 2025 09:14:31 +0200 Subject: [PATCH 028/148] add meteor config as part of the plugin api --- packages/babel-compiler/babel-compiler.js | 5 +++-- .../standard-minifier-js/plugin/minify-js.js | 19 +++++++++++-------- tools/isobuild/isopack.js | 3 +++ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index e91ec6fd39..a5d2476b30 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -82,10 +82,11 @@ function compileWithSwc(source, swcOptions = {}, { features }) { } BCp.initializeMeteorAppConfig = function () { + const meteorConfig = Plugin?.meteorConfig || global.meteorConfig; if (this.isVerbose()) { - logConfigBlock('Meteor Config', global.meteorConfig); + logConfigBlock('Meteor Config', meteorConfig); } - return global.meteorConfig; + return meteorConfig; }; let lastModifiedSwcConfig; diff --git a/packages/standard-minifier-js/plugin/minify-js.js b/packages/standard-minifier-js/plugin/minify-js.js index 85abdb397c..d5f6f29b3c 100644 --- a/packages/standard-minifier-js/plugin/minify-js.js +++ b/packages/standard-minifier-js/plugin/minify-js.js @@ -13,9 +13,7 @@ const Meteor = typeof global.Meteor !== 'undefined' ? global.Meteor : { // Profile for test and production environments let Profile; -if (typeof global.Profile !== 'undefined') { - Profile = global.Profile; -} else if (typeof Plugin !== 'undefined' && Plugin.Profile) { +if (typeof Plugin !== 'undefined' && Plugin.Profile) { Profile = Plugin.Profile; } else { Profile = function (label, func) { @@ -28,6 +26,10 @@ if (typeof global.Profile !== 'undefined') { } } +function getMeteorConfig() { + return Plugin?.meteorConfig || global?.meteorConfig || {}; +} + let swc; // Register the minifier only when Plugin is available (not in tests) @@ -102,13 +104,14 @@ export class MeteorMinifier { minifyOneFile(file) { return Profile('minifyOneFile', () => { + const meteorConfig = getMeteorConfig(); const modern = - global.meteorConfig && - (global.meteorConfig?.modern === true || - (global.meteorConfig?.modern && - global.meteorConfig?.modern?.minifier === true)); + meteorConfig && + (meteorConfig?.modern === true || + (meteorConfig?.modern && + meteorConfig?.modern?.minifier === true)); // check if config is an empty object - if(global.meteorConfig && Object.keys(global.meteorConfig).length === 0 || !modern) { + if(meteorConfig && Object.keys(meteorConfig).length === 0 || !modern) { Meteor._debug(`Minifying using Terser | file: ${file.getPathInBundle()}`); return this._minifyWithTerser(file); } diff --git a/tools/isobuild/isopack.js b/tools/isobuild/isopack.js index 99549c5d25..c03c53a811 100644 --- a/tools/isobuild/isopack.js +++ b/tools/isobuild/isopack.js @@ -514,6 +514,9 @@ Object.assign(Isopack.prototype, { var Plugin = { name: pluginName, + // Share the meteorConfig with the plugin + meteorConfig: global.meteorConfig || {}, + // 'extension' is a file extension without the separation dot // (eg 'js', 'coffee', 'coffee.md') // From 057f09375b7bd1ac60fbeb423e94f283437ee715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 5 Jun 2025 09:22:58 +0200 Subject: [PATCH 029/148] fix meteor config when no package.json file --- tools/cli/commands.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/cli/commands.js b/tools/cli/commands.js index 566f485238..22c553dfa8 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -262,16 +262,19 @@ export function parseRunTargets(targets) { }; export function getMeteorConfig(appDir) { + const modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); let packageJson; if (appDir) { const packageJsonPath = files.pathJoin(appDir, 'package.json'); if (!files.exists(packageJsonPath)) { - return false; + global.meteorConfig = { + modern: projectContextModule.normalizeModern(modernForced || false), + }; + return global.meteorConfig; } const packageJsonFile = files.readFile(packageJsonPath, 'utf8'); packageJson = JSON.parse(packageJsonFile); } - const modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); global.meteorConfig = { ...(packageJson?.meteor || {}), modern: projectContextModule.normalizeModern(modernForced || packageJson?.meteor?.modern || false), From 78a1560a814d4789654b137fec1c0572289c8296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 5 Jun 2025 09:36:40 +0200 Subject: [PATCH 030/148] refactor --- packages/babel-compiler/babel-compiler.js | 36 +++++++++++++---------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index a5d2476b30..d708d67c19 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -25,8 +25,12 @@ var BCp = BabelCompiler.prototype; var excludedFileExtensionPattern = /\.(es5|min)\.js$/i; var hasOwn = Object.prototype.hasOwnProperty; +function getMeteorConfig() { + return Plugin?.meteorConfig || global?.meteorConfig || {}; +} + // Check if verbose mode is enabled either in the provided config or in extraFeatures -BCp.isVerbose = function(config = global.meteorConfig) { +BCp.isVerbose = function(config = getMeteorConfig()) { if (config?.modern?.transpiler?.verbose) { return true; } @@ -82,7 +86,7 @@ function compileWithSwc(source, swcOptions = {}, { features }) { } BCp.initializeMeteorAppConfig = function () { - const meteorConfig = Plugin?.meteorConfig || global.meteorConfig; + const meteorConfig = getMeteorConfig(); if (this.isVerbose()) { logConfigBlock('Meteor Config', meteorConfig); } @@ -321,31 +325,31 @@ BCp.processOneFileForTarget = function (inputFile, source) { const isPackageCode = packageName != null; const isLegacyWebArch = arch.includes('legacy'); - const config = global.meteorConfig?.modern?.transpiler; - const hasModernTranspiler = config != null && config !== false; + const transpConfig = getMeteorConfig()?.modern?.transpiler; + const hasModernTranspiler = transpConfig != null && transpConfig !== false; const shouldSkipSwc = !hasModernTranspiler || - (isAppCode && config?.excludeApp === true) || - (isNodeModulesCode && config?.excludeNodeModules === true) || - (isPackageCode && config?.excludePackages === true) || - (isLegacyWebArch && config?.excludeLegacy === true) || + (isAppCode && transpConfig?.excludeApp === true) || + (isNodeModulesCode && transpConfig?.excludeNodeModules === true) || + (isPackageCode && transpConfig?.excludePackages === true) || + (isLegacyWebArch && transpConfig?.excludeLegacy === true) || (isAppCode && - Array.isArray(config?.excludeApp) && - isExcludedConfig(inputFilePath, config?.excludeApp || [])) || + Array.isArray(transpConfig?.excludeApp) && + isExcludedConfig(inputFilePath, transpConfig?.excludeApp || [])) || (isNodeModulesCode && - Array.isArray(config?.excludeNodeModules) && - (isExcludedConfig(inputFilePath, config?.excludeNodeModules || []) || + Array.isArray(transpConfig?.excludeNodeModules) && + (isExcludedConfig(inputFilePath, transpConfig?.excludeNodeModules || []) || isExcludedConfig( inputFilePath.replace('node_modules/', ''), - config?.excludeNodeModules || [], + transpConfig?.excludeNodeModules || [], true, ))) || (isPackageCode && - Array.isArray(config?.excludePackages) && - (isExcludedConfig(packageName, config?.excludePackages || []) || + Array.isArray(transpConfig?.excludePackages) && + (isExcludedConfig(packageName, transpConfig?.excludePackages || []) || isExcludedConfig( `${packageName}/${inputFilePath}`, - config?.excludePackages || [], + transpConfig?.excludePackages || [], ))); const cacheKey = [ From 0b49b1ab5c1ed73bd80c0c1e61078d1ff8a7a636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 5 Jun 2025 09:45:17 +0200 Subject: [PATCH 031/148] use global variable as it can respect changes on meteorConfig --- packages/babel-compiler/babel-compiler.js | 2 +- packages/standard-minifier-js/plugin/minify-js.js | 2 +- tools/isobuild/isopack.js | 3 --- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index d708d67c19..712b341886 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -26,7 +26,7 @@ var excludedFileExtensionPattern = /\.(es5|min)\.js$/i; var hasOwn = Object.prototype.hasOwnProperty; function getMeteorConfig() { - return Plugin?.meteorConfig || global?.meteorConfig || {}; + return global?.meteorConfig || {}; } // Check if verbose mode is enabled either in the provided config or in extraFeatures diff --git a/packages/standard-minifier-js/plugin/minify-js.js b/packages/standard-minifier-js/plugin/minify-js.js index d5f6f29b3c..98e45adce1 100644 --- a/packages/standard-minifier-js/plugin/minify-js.js +++ b/packages/standard-minifier-js/plugin/minify-js.js @@ -27,7 +27,7 @@ if (typeof Plugin !== 'undefined' && Plugin.Profile) { } function getMeteorConfig() { - return Plugin?.meteorConfig || global?.meteorConfig || {}; + return global?.meteorConfig || {}; } let swc; diff --git a/tools/isobuild/isopack.js b/tools/isobuild/isopack.js index c03c53a811..99549c5d25 100644 --- a/tools/isobuild/isopack.js +++ b/tools/isobuild/isopack.js @@ -514,9 +514,6 @@ Object.assign(Isopack.prototype, { var Plugin = { name: pluginName, - // Share the meteorConfig with the plugin - meteorConfig: global.meteorConfig || {}, - // 'extension' is a file extension without the separation dot // (eg 'js', 'coffee', 'coffee.md') // From 37a9ce2d037e5083892e3b4bad0df81a9fc12cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 5 Jun 2025 10:52:03 +0200 Subject: [PATCH 032/148] expose meteor config helper for plugin api --- packages/babel-compiler/babel-compiler.js | 2 +- packages/standard-minifier-js/plugin/minify-js.js | 2 +- tools/isobuild/isopack.js | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index 712b341886..248fdca86d 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -26,7 +26,7 @@ var excludedFileExtensionPattern = /\.(es5|min)\.js$/i; var hasOwn = Object.prototype.hasOwnProperty; function getMeteorConfig() { - return global?.meteorConfig || {}; + return Plugin?.getMeteorConfig() || {}; } // Check if verbose mode is enabled either in the provided config or in extraFeatures diff --git a/packages/standard-minifier-js/plugin/minify-js.js b/packages/standard-minifier-js/plugin/minify-js.js index 98e45adce1..0fe5ca613f 100644 --- a/packages/standard-minifier-js/plugin/minify-js.js +++ b/packages/standard-minifier-js/plugin/minify-js.js @@ -27,7 +27,7 @@ if (typeof Plugin !== 'undefined' && Plugin.Profile) { } function getMeteorConfig() { - return global?.meteorConfig || {}; + return Plugin?.getMeteorConfig() || {}; } let swc; diff --git a/tools/isobuild/isopack.js b/tools/isobuild/isopack.js index 99549c5d25..83c5a03d12 100644 --- a/tools/isobuild/isopack.js +++ b/tools/isobuild/isopack.js @@ -514,6 +514,11 @@ Object.assign(Isopack.prototype, { var Plugin = { name: pluginName, + // Share the meteorConfig object as part of plugin API + getMeteorConfig: function () { + return global.meteorConfig || {}; + }, + // 'extension' is a file extension without the separation dot // (eg 'js', 'coffee', 'coffee.md') // From 4341fbbd8f8c6d3ff471009a17e5e5e2aae7cfbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 5 Jun 2025 11:26:40 +0200 Subject: [PATCH 033/148] remove global usage by adding a new context for the meteor config init and import --- tools/cli/commands.js | 25 ++-------- tools/cli/main.js | 7 +-- tools/fs/safe-watcher.ts | 7 +-- tools/isobuild/isopack.js | 6 +-- tools/project-context.js | 28 ++--------- tools/tool-env/meteor-config.js | 85 +++++++++++++++++++++++++++++++++ 6 files changed, 104 insertions(+), 54 deletions(-) create mode 100644 tools/tool-env/meteor-config.js diff --git a/tools/cli/commands.js b/tools/cli/commands.js index 22c553dfa8..50c75559eb 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -1,3 +1,5 @@ +import { getMeteorConfig } from "../tool-env/meteor-config"; + var main = require('./main.js'); var _ = require('underscore'); var files = require('../fs/files'); @@ -261,27 +263,6 @@ export function parseRunTargets(targets) { }); }; -export function getMeteorConfig(appDir) { - const modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); - let packageJson; - if (appDir) { - const packageJsonPath = files.pathJoin(appDir, 'package.json'); - if (!files.exists(packageJsonPath)) { - global.meteorConfig = { - modern: projectContextModule.normalizeModern(modernForced || false), - }; - return global.meteorConfig; - } - const packageJsonFile = files.readFile(packageJsonPath, 'utf8'); - packageJson = JSON.parse(packageJsonFile); - } - global.meteorConfig = { - ...(packageJson?.meteor || {}), - modern: projectContextModule.normalizeModern(modernForced || packageJson?.meteor?.modern || false), - }; - return global.meteorConfig; -} - function filterWebArchs(webArchs, excludeArchsOption, appDir, options) { const platforms = (options.platforms || []); const isBuildMode = platforms?.length > 0; @@ -301,7 +282,7 @@ function filterWebArchs(webArchs, excludeArchsOption, appDir, options) { if (!isCordovaDev) { const excludeArchsOptions = excludeArchsOption ? excludeArchsOption.trim().split(/\s*,\s*/) : []; const hasExcludeArchsOptions = (excludeArchsOptions?.length || 0) > 0; - const hasModernArchsOnlyEnabled = appDir && global.meteorConfig?.modern?.webArchOnly !== false; + const hasModernArchsOnlyEnabled = appDir && getMeteorConfig()?.modern?.webArchOnly !== false; if (hasExcludeArchsOptions && hasModernArchsOnlyEnabled) { console.warn('modern.webArchOnly and --exclude-archs are both active. If both are set, --exclude-archs takes priority.'); } diff --git a/tools/cli/main.js b/tools/cli/main.js index 6e98f38fd4..b73e2b7868 100644 --- a/tools/cli/main.js +++ b/tools/cli/main.js @@ -287,14 +287,15 @@ main.captureAndExit = async function (header, title, f) { // NB: files required up to this point may not define commands -const { getMeteorConfig } = require('./commands.js'); +const { initMeteorConfig } = require('../tool-env/meteor-config'); +require('./commands.js'); require('./commands-packages.js'); require('./commands-packages-query.js'); require('./commands-cordova.js'); require('./commands-aliases.js'); // Initialize meteorConfig globally -global.meteorConfig = getMeteorConfig(); +initMeteorConfig(); /////////////////////////////////////////////////////////////////////////////// // Record all the top-level commands as JSON @@ -870,7 +871,7 @@ makeGlobalAsyncLocalStorage().run({}, async function () { appDir = files.pathResolve(appDir); // Renitialize meteorConfig globally when having appDir context - global.meteorConfig = getMeteorConfig(appDir); + initMeteorConfig(appDir); } await require('../tool-env/isopackets.js').ensureIsopacketsLoadable(); diff --git a/tools/fs/safe-watcher.ts b/tools/fs/safe-watcher.ts index 7a3b813f94..07fe605fb7 100644 --- a/tools/fs/safe-watcher.ts +++ b/tools/fs/safe-watcher.ts @@ -4,6 +4,7 @@ import { watch as watchLegacy, addWatchRoot as addWatchRootLegacy, closeAllWatch import { Profile } from "../tool-env/profile"; import { statOrNull, lstat, toPosixPath, convertToOSPath, pathRelative, watchFile, unwatchFile, pathResolve, pathDirname } from "./files"; +import { getMeteorConfig } from "../tool-env/meteor-config"; // Register process exit handlers to ensure subscriptions are properly cleaned up const registerExitHandlers = () => { @@ -380,7 +381,7 @@ function startNewEntry(absPath: string): Entry { */ export function watch (absPath: string, callback: ChangeCallback): SafeWatcher { // @ts-ignore - if (!global.meteorConfig?.modern?.watcher) { + if (!getMeteorConfig()?.modern?.watcher) { // @ts-ignore return watchLegacy(absPath, callback); } @@ -444,7 +445,7 @@ const watchModern = */ export function addWatchRoot(absPath: string) { // @ts-ignore - if (!global.meteorConfig?.modern?.watcher) { + if (!getMeteorConfig()?.modern?.watcher) { // @ts-ignore return addWatchRootLegacy(absPath); } @@ -477,7 +478,7 @@ async function safeUnsubscribeSub(root: string) { export async function closeAllWatchers() { // @ts-ignore - if (!global.meteorConfig?.modern?.watcher) { + if (!getMeteorConfig()?.modern?.watcher) { // @ts-ignore return closeAllWatchersLegacy(); } diff --git a/tools/isobuild/isopack.js b/tools/isobuild/isopack.js index 83c5a03d12..aa397e0a80 100644 --- a/tools/isobuild/isopack.js +++ b/tools/isobuild/isopack.js @@ -1,3 +1,5 @@ +import { getMeteorConfig } from "../tool-env/meteor-config"; + var compiler = require('./compiler.js'); var archinfo = require('../utils/archinfo'); var _ = require('underscore'); @@ -515,9 +517,7 @@ Object.assign(Isopack.prototype, { name: pluginName, // Share the meteorConfig object as part of plugin API - getMeteorConfig: function () { - return global.meteorConfig || {}; - }, + getMeteorConfig: getMeteorConfig, // 'extension' is a file extension without the separation dot // (eg 'js', 'coffee', 'coffee.md') diff --git a/tools/project-context.js b/tools/project-context.js index db9552a7c3..d5022d997a 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -1,3 +1,4 @@ +import { normalizeModernConfig, setMeteorConfig } from "./tool-env/meteor-config"; var assert = require("assert"); var _ = require('underscore'); @@ -1769,26 +1770,6 @@ Object.assign(exports.FinishedUpgraders.prototype, { } }); -const DEFAULT_MODERN = { - transpiler: true, - minifier: true, - webArchOnly: true, - watcher: true, -}; - -export const normalizeModern = (r = false) => Object.fromEntries( - Object.entries(DEFAULT_MODERN).map(([k, def]) => [ - k, - r === true - ? def - : r === false || r?.[k] === false - ? false - : typeof r?.[k] === 'object' - ? { ...r[k] } - : def, - ]), -); - export class MeteorConfig { constructor({ appDirectory, @@ -1836,10 +1817,11 @@ export class MeteorConfig { const modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); // Reinitialize meteorConfig globally for project context // Updates config when package.json changes trigger rebuilds - global.meteorConfig = { + setMeteorConfig({ ...(this._config || {}), - modern: normalizeModern(modernForced || this._config?.modern || false), - }; + modern: normalizeModernConfig(modernForced || this._config?.modern || false), + }); + return this._config; } diff --git a/tools/tool-env/meteor-config.js b/tools/tool-env/meteor-config.js new file mode 100644 index 0000000000..4083a0a371 --- /dev/null +++ b/tools/tool-env/meteor-config.js @@ -0,0 +1,85 @@ +import files from "../fs/files"; + +/** + * Global configuration object for Meteor. + * @type {Object} + */ +export let meteorConfig; + +/** + * Default configuration for modern mode features. + * @type {Object} + * @property {boolean} transpiler - Whether to use the modern transpiler. + * @property {boolean} minifier - Whether to use the modern minifier. + * @property {boolean} webArchOnly - Whether to use modern features only for web architecture. + * @property {boolean} watcher - Whether to use the modern watcher. + */ +const DEFAULT_MODERN = { + transpiler: true, + minifier: true, + webArchOnly: true, + watcher: true, +}; + +/** + * Normalizes the modern configuration by applying default values. + * @param {boolean|Object} r - The input modern configuration. If true, uses all defaults. + * If false, disables all modern features. If an object, merges with defaults. + * @returns {Object} - The normalized modern configuration object. + */ +export const normalizeModernConfig = (r = false) => Object.fromEntries( + Object.entries(DEFAULT_MODERN).map(([k, def]) => [ + k, + r === true + ? def + : r === false || r?.[k] === false + ? false + : typeof r?.[k] === 'object' + ? { ...r[k] } + : def, + ]), +); + +/** + * Initializes the Meteor configuration based on the application directory. + * Reads configuration from package.json if available, and applies environment variables. + * + * @param {string|null} appDir - The application directory path. If null, only environment variables are used. + * @returns {Object} - The initialized Meteor configuration object. + */ +export function initMeteorConfig(appDir) { + const modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); + let packageJson; + if (appDir) { + const packageJsonPath = files.pathJoin(appDir, 'package.json'); + if (!files.exists(packageJsonPath)) { + setMeteorConfig({ + modern: normalizeModernConfig(modernForced || false), + }); + return meteorConfig; + } + const packageJsonFile = files.readFile(packageJsonPath, 'utf8'); + packageJson = JSON.parse(packageJsonFile); + } + setMeteorConfig({ + ...(packageJson?.meteor || {}), + modern: normalizeModernConfig(modernForced || packageJson?.meteor?.modern || false), + }); + return meteorConfig; +} + +/** + * Gets the current Meteor configuration. + * @returns {Object} - The current Meteor configuration object. + */ +export function getMeteorConfig() { + return meteorConfig; +} + +/** + * Sets the Meteor configuration to a new value. + * @param {Object} config - The new configuration object to set. + */ +export function setMeteorConfig(config) { + meteorConfig = config; +} From e726a2bdbb1a9349c504f925f138da9864a931e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 24 Jun 2025 14:45:24 +0200 Subject: [PATCH 034/148] ensure edges cases on swc config invalidation --- packages/babel-compiler/babel-compiler.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index 506f865117..618ea628a3 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -139,7 +139,9 @@ BCp.initializeMeteorAppSwcrc = function () { let currentLastModifiedConfigTime; if (hasSwcJs) { // For dynamic JS files, first get the resolved configuration - const resolvedConfig = lastModifiedSwcConfig || getMeteorAppSwcrc(swcFile); + const resolvedConfig = lastModifiedSwcConfigTime?.includes(`${fileModTime}`) + ? lastModifiedSwcConfig || getMeteorAppSwcrc(swcFile) + : getMeteorAppSwcrc(swcFile); // Calculate a hash of the resolved configuration to detect changes const contentHash = crypto .createHash('sha256') @@ -161,6 +163,8 @@ BCp.initializeMeteorAppSwcrc = function () { if (this.isVerbose(lastModifiedMeteorConfig)) { logConfigBlock('SWC Config', lastModifiedSwcConfig); } + + this._swcIncompatible = {}; } return lastModifiedSwcConfig; }; From 159d1148e5a9072a325ef17194dc76d31aa43394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 24 Jun 2025 17:45:06 +0200 Subject: [PATCH 035/148] fix regression on recompile behavior --- tools/project-context.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tools/project-context.js b/tools/project-context.js index c14dce5cfa..a04089db88 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -1821,13 +1821,17 @@ export class MeteorConfig { let config = this._ensureInitialized(); let filteredConfig = keys.length ? {} : config; if (config) { - keys.every(key => { - if (config && _.has(config, key)) { - filteredConfig = config[key]; - return true; - } - return false; - }); + const subConfig = config[keys[0]]; + if (subConfig) { + filteredConfig = subConfig; + const [, ...subConfigKeys] = keys; + subConfigKeys.every(key => { + if (filteredConfig && _.has(filteredConfig, key)) { + filteredConfig = filteredConfig[key]; + return true; + } + }); + } return filteredConfig; } } From 0ee4c0dc07f13731decd6f38ab78647d0ee9b60c Mon Sep 17 00:00:00 2001 From: Jan Dvorak Date: Wed, 25 Jun 2025 09:34:08 +0200 Subject: [PATCH 036/148] Node v22.17.0 https://nodejs.org/en/blog/release/v22.17.0 --- .travis.yml | 2 +- meteor | 2 +- scripts/build-dev-bundle-common.sh | 2 +- v3-docs/v3-migration-docs/index.md | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 622ed6cadd..3e63726f4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ dist: jammy sudo: required services: xvfb node_js: - - "22.16.0" + - "22.17.0" cache: directories: - ".meteor" diff --git a/meteor b/meteor index e452f7b273..bc655c6fd9 100755 --- a/meteor +++ b/meteor @@ -1,6 +1,6 @@ #!/usr/bin/env bash -BUNDLE_VERSION=22.16.0.1 +BUNDLE_VERSION=22.17.0.0 # OS Check. Put here because here is where we download the precompiled # bundles that are arch specific. diff --git a/scripts/build-dev-bundle-common.sh b/scripts/build-dev-bundle-common.sh index a00f7e4f2b..cea7b94ae6 100644 --- a/scripts/build-dev-bundle-common.sh +++ b/scripts/build-dev-bundle-common.sh @@ -5,7 +5,7 @@ set -u UNAME=$(uname) ARCH=$(uname -m) -NODE_VERSION=22.16.0 +NODE_VERSION=22.17.0 MONGO_VERSION_64BIT=7.0.16 MONGO_VERSION_32BIT=3.2.22 NPM_VERSION=10.9.2 diff --git a/v3-docs/v3-migration-docs/index.md b/v3-docs/v3-migration-docs/index.md index ea5839cdab..f101014964 100644 --- a/v3-docs/v3-migration-docs/index.md +++ b/v3-docs/v3-migration-docs/index.md @@ -1,6 +1,6 @@ --- -meteor_version: 3.3 -node_version: 22.16.0 +meteor_version: 3.3.1 +node_version: 22.17.0 npm_version: 10.9.2 --- # Meteor 3.0 Migration Guide From a0c46057423f7b39a0f506c976903cdde4ad21d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 25 Jun 2025 14:31:11 +0200 Subject: [PATCH 037/148] provide more test coverage and correct meteor config --- tools/project-context.js | 24 +++++--------- tools/tests/app-config.js | 68 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/tools/project-context.js b/tools/project-context.js index a04089db88..116778a673 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -1818,22 +1818,14 @@ export class MeteorConfig { // General utility for querying the "meteor" section of package.json. // TODO Implement an API for setting these values? get(...keys) { - let config = this._ensureInitialized(); - let filteredConfig = keys.length ? {} : config; - if (config) { - const subConfig = config[keys[0]]; - if (subConfig) { - filteredConfig = subConfig; - const [, ...subConfigKeys] = keys; - subConfigKeys.every(key => { - if (filteredConfig && _.has(filteredConfig, key)) { - filteredConfig = filteredConfig[key]; - return true; - } - }); - } - return filteredConfig; - } + const config = this._ensureInitialized(); + if (!config) return undefined; + + return keys.reduce((cur, key) => { + return (cur != null && _.has(cur, key)) + ? cur[key] + : undefined; + }, config); } getNodeModulesToRecompileByArch() { diff --git a/tools/tests/app-config.js b/tools/tests/app-config.js index 7a7cd3832b..1ff476a01e 100644 --- a/tools/tests/app-config.js +++ b/tools/tests/app-config.js @@ -199,3 +199,71 @@ selftest.define("testModule", async function () { await run.stop(); }); + +async function writeModernConfig(s, run, modernConfig, errorPattern) { + const json = JSON.parse(s.read("package.json")); + + json.meteor = { + // Make sure the tests.js module is always loaded eagerly. + testModule: "tests.js" + }; + + if (typeof modernConfig === "undefined") { + delete json.meteor.modern; + } else { + json.meteor.modern = modernConfig; + } + + s.write("package.json", JSON.stringify(json, null, 2) + "\n"); + + run.waitSecs(10); + + if (errorPattern instanceof RegExp) { + await run.match(errorPattern); + } else { + run.forbid(" 0 passing "); + await run.match("SERVER FAILURES: 0"); + await run.match("CLIENT FAILURES: 0"); + } +} + +selftest.define("modernConfig", async function () { + const s = new Sandbox(); + await s.init(); + + await s.createApp("app-config-modernConfig", "app-config"); + await s.cd("app-config-modernConfig"); + + // For meteortesting:mocha to work we must set test broswer driver + // See https://github.com/meteortesting/meteor-mocha + s.set("TEST_BROWSER_DRIVER", "puppeteer"); + + const run = s.run( + "test", + "--full-app", + "--driver-package", "meteortesting:mocha" + ); + + run.waitSecs(60); + await run.match("App running at"); + + function check(modernConfig) { + return writeModernConfig(s, run, modernConfig); + } + + // Test with modern disabled + await check(false); + + // Test with modern enabled + await check(true); + + // Test with combined options + await check({ + transpiler: true, + watcher: true, + webArchOnly: true, + minifier: true, + }); + + await run.stop(); +}); From 77b2e4490ff46f6b5a8e22bf5fb360863c735d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 25 Jun 2025 15:29:15 +0200 Subject: [PATCH 038/148] add recompile checks for modern build stack --- tools/tests/apps/modern/package.json | 1 + tools/tests/modern.js | 87 ++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/tools/tests/apps/modern/package.json b/tools/tests/apps/modern/package.json index a7fe68949f..2b1fe578bf 100644 --- a/tools/tests/apps/modern/package.json +++ b/tools/tests/apps/modern/package.json @@ -6,6 +6,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "config": "file:../config-package", "meteor-node-stubs": "^1.2.12", "react": "^18.3.1" }, diff --git a/tools/tests/modern.js b/tools/tests/modern.js index 8f3986d9b0..b3a84e66b6 100644 --- a/tools/tests/modern.js +++ b/tools/tests/modern.js @@ -188,9 +188,35 @@ selftest.define("modern build stack - transpiler boolean-like options", async fu const s = new Sandbox(); await s.init(); + s.mkdir("config-package"); + s.cd("config-package"); + + s.write( + "package.json", + JSON.stringify({ + name: "config", + version: "1.2.3", + "private": true, + main: "index.js" + }, null, 2) + "\n" + ); + + s.write( + "index.js", + "exports.id = module.id;\n" + ); + + s.cd(s.home); + await s.createApp("modern", "modern"); await s.cd("modern"); + s.append( + "server/main.js", + `if (require('config')) { + console.log('Loaded NPM package "config"', require('config').id); +}`); + process.env.METEOR_DISABLE_COLORS = true; await writeModernConfig(s, { @@ -204,6 +230,9 @@ selftest.define("modern build stack - transpiler boolean-like options", async fu run.waitSecs(waitToStart); await run.match("App running at"); + /* check appended NPM package require */ + await run.match(/Loaded NPM package "config"/, false, true); + /* check verbose logs */ await run.match(/SWC Config/, false, true); await run.match(/SWC Legacy Config/, false, true); @@ -212,6 +241,7 @@ selftest.define("modern build stack - transpiler boolean-like options", async fu /* check transpiler options */ await run.match(/\[Transpiler] Used SWC.*\(app\)/, false, true); await run.match(/\[Transpiler] Used SWC.*\(package\)/, false, true); + run.forbid(/\[Transpiler] Used SWC.*\(node_modules\)/, false, true); await writeModernConfig(s, { transpiler: { @@ -229,6 +259,20 @@ selftest.define("modern build stack - transpiler boolean-like options", async fu }); await run.match(/\[Transpiler] Used Babel.*\(package\)/, false, true); + await writeConfig(s, { + modern: { + transpiler: { + verbose: true, + }, + }, + nodeModules: { + recompile: { + config: true, + }, + }, + }); + await run.match(/\[Transpiler] Used SWC.*\(node_modules\)/, false, true); + await run.stop(); process.env.METEOR_MODERN = currentMeteorModern; @@ -241,9 +285,34 @@ selftest.define("modern build stack - transpiler string-like options", async fun const s = new Sandbox(); await s.init(); + s.mkdir("config-package"); + s.cd("config-package"); + + s.write( + "package.json", + JSON.stringify({ + name: "config", + version: "1.2.3", + "private": true, + main: "index.js" + }, null, 2) + "\n" + ); + + s.write( + "index.js", + "exports.id = module.id;\n" + ); + + s.cd(s.home); + await s.createApp("modern", "modern"); await s.cd("modern"); + s.append( + "server/main.js", + `import { id } from 'config'; +console.log('Loaded NPM package "config"', require('config').id);`); + process.env.METEOR_DISABLE_COLORS = true; await writeModernConfig(s, { @@ -257,6 +326,9 @@ selftest.define("modern build stack - transpiler string-like options", async fun run.waitSecs(waitToStart); await run.match("App running at"); + /* check appended NPM package imported */ + await run.match(/Loaded NPM package "config"/, false, true); + /* check verbose logs */ await run.match(/SWC Config/, false, true); await run.match(/SWC Legacy Config/, false, true); @@ -265,6 +337,7 @@ selftest.define("modern build stack - transpiler string-like options", async fun /* check transpiler options */ await run.match(/\[Transpiler] Used SWC.*\(app\)/, false, true); await run.match(/\[Transpiler] Used SWC.*\(package\)/, false, true); + run.forbid(/\[Transpiler] Used SWC.*\(node_modules\)/, false, true); await writeModernConfig(s, { transpiler: { @@ -282,6 +355,20 @@ selftest.define("modern build stack - transpiler string-like options", async fun }); await run.match(/\[Transpiler] Used Babel.*\(package\)/, false, true); + await writeConfig(s, { + modern: { + transpiler: { + verbose: true, + }, + }, + nodeModules: { + recompile: { + config: true, + }, + }, + }); + await run.match(/\[Transpiler] Used SWC.*\(node_modules\)/, false, true); + await run.stop(); process.env.METEOR_MODERN = currentMeteorModern; From 5f997b83877e29a74fbf874250e1f07075ef0194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 26 Jun 2025 11:27:27 +0200 Subject: [PATCH 039/148] update docs to add more migration topics --- .../modern-build-stack/transpiler-swc.md | 86 +++++++++++++++++-- 1 file changed, 79 insertions(+), 7 deletions(-) diff --git a/v3-docs/docs/about/modern-build-stack/transpiler-swc.md b/v3-docs/docs/about/modern-build-stack/transpiler-swc.md index 7fb8458375..0a5e66756b 100644 --- a/v3-docs/docs/about/modern-build-stack/transpiler-swc.md +++ b/v3-docs/docs/about/modern-build-stack/transpiler-swc.md @@ -104,7 +104,7 @@ Most apps will benefit just by enabling `modern: true`. Most Meteor packages sho You can use `.swcrc` config in the root of your project to describe specific [SWC plugins](https://github.com/swc-project/plugins) there, that will be applied to compile the entire files of your project. -You can also configure other options using the `.swcrc` format. One common case is when your project uses `.js` files for React code. React typically uses `.jsx` for components. We still recommend following that convention for compatibility, but if you prefer `.js`, you can provide a custom `.swcrc` like this: +You can also configure other options using the `.swcrc` format. ``` json { @@ -117,13 +117,14 @@ You can also configure other options using the `.swcrc` format. One common case } ``` -> You can also configure it for TypeScript, make sure to set `"syntax": "typescript"` and `"tsx": true` instead. - -This overrides Meteor's internal SWC config to apply your settings, ensuring SWC processes `.js` or `.ts` files with React components without falling back to Babel. - Use `swc.config.js` in your project root for dynamic configuration. Meteor will import and apply the SWC config automatically. This lets you choose a config based on environment variables or other runtime factors. -Explore additional custom SWC configs, including ["Import Aliases"](#import-aliases) and ["React Runtime"](#react-runtime). +For custom SWC configs, see the [SWC configuration API](https://swc.rs/docs/configuration/compilation). You can also review these migration topics: + +- [Import Aliases](#import-aliases) +- [JSX Syntax in JS files](#jsx-syntax-in-js-files) +- [React Runtime](#react-runtime) +- [Transform Imports](#transform-imports) ## Config API @@ -252,11 +253,32 @@ SWC resolve aliases for imports correctly, but require calls won’t. For requir SWC has no [module-resolver plugin like Babel’s](https://www.npmjs.com/package/babel-plugin-module-resolver) yet, which could affect require calls in the future. +### JSX Syntax in JS files + +When migrating your app to use SWC, Meteor SWC falls back to Babel if you include JSX in `.js` files, since JSX is only recognized in `.jsx` files. + +To enable JSX in `.js` files, create a [`.swcrc`](#custom-swcrc) file with this config: + +``` json +{ + "jsc": { + "parser": { + "syntax": "ecmascript", + "jsx": true + } + } +} +``` + +> For TypeScript, set "syntax": "typescript" and "tsx": true instead. + +This overrides Meteor’s internal SWC config so SWC handles `.js` and `.ts` files with React components instead of falling back to Babel. + ### React Runtime Meteor Babel lets you skip importing React in your files by using the [`@babel/plugin-transform-react-jsx`](https://www.npmjs.com/package/@babel/plugin-transform-react-jsx) runtime config. -To use the same config in SWC, add it to your [.swcrc](#custom-swcrc): +To use the same config in SWC, add it to your [`.swcrc`](#custom-swcrc): ```json { @@ -270,6 +292,56 @@ To use the same config in SWC, add it to your [.swcrc](#custom-swcrc): } ``` +### Transform Imports + +You might have used Meteor Babel with the [`babel-plugin-transform-imports`](https://www.npmjs.com/package/babel-plugin-transform-imports) plugin to rewrite imports in your app. + +SWC offers a similar plugin: [`@swc/plugin-transform-imports`](https://www.npmjs.com/package/@swc/plugin-transform-imports). + +To switch to SWC, install the plugin: + +```bash +meteor npm install -D @swc/plugin-transform-imports +``` + +and add it to your [`.swcrc`](#custom-swcrc): + +```json +{ + "jsc": { + "experimental": { + "plugins": [ + [ + "@swc/plugin-transform-imports", + { + "lodash": { + "transform": "lodash/{{member}}", + "preventFullImport": true + } + } + ] + ] + } + } +} +``` + +This tells SWC to replace, for example, + +``` javascript +import { map } from "lodash" +``` + +with + +``` javascript +import map from "lodash/map" +``` + +avoiding full-package imports and reducing bundle size. + +You can use advanced import transformations. [See the test suite for examples.](https://github.com/swc-project/plugins/blob/main/packages/transform-imports/__tests__/wasm.test.ts#L12-L63) + ## Troubleshotting If you run into issues, try `meteor reset` or delete the `.meteor/local` folder in the project root. From b332b45b66efef522b659a3ecde138bed271552b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 26 Jun 2025 11:32:57 +0200 Subject: [PATCH 040/148] update docs to highlight modern syntax with private properties --- .../modern-build-stack/transpiler-swc.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/v3-docs/docs/about/modern-build-stack/transpiler-swc.md b/v3-docs/docs/about/modern-build-stack/transpiler-swc.md index 0a5e66756b..cb333b5ead 100644 --- a/v3-docs/docs/about/modern-build-stack/transpiler-swc.md +++ b/v3-docs/docs/about/modern-build-stack/transpiler-swc.md @@ -125,6 +125,7 @@ For custom SWC configs, see the [SWC configuration API](https://swc.rs/docs/conf - [JSX Syntax in JS files](#jsx-syntax-in-js-files) - [React Runtime](#react-runtime) - [Transform Imports](#transform-imports) +- [Private Properties](#private-properties) ## Config API @@ -342,6 +343,29 @@ avoiding full-package imports and reducing bundle size. You can use advanced import transformations. [See the test suite for examples.](https://github.com/swc-project/plugins/blob/main/packages/transform-imports/__tests__/wasm.test.ts#L12-L63) + +### Private Properties + +SWC supports many of the most modern JS systax features, including private class properties, which Meteor Babel doesn’t. + +Just by enabling SWC, Meteor will parse properly code like: + +``` javascript +class ClassWithPrivate { + #privateField; + #privateFieldWithInitializer = 42; + + #privateMethod() {} + + static #privateStaticField; + static #privateStaticFieldWithInitializer = 42; + + static #privateStaticMethod() {} +} +``` + +You can opt-out of [private properties in SWC options with "privateMethod" setting](https://swc.rs/docs/configuration/compilation#ecmascript) with the [`.swcrc`](#custom-swcrc) file. + ## Troubleshotting If you run into issues, try `meteor reset` or delete the `.meteor/local` folder in the project root. From fc5e75e4fae7ee54a7a0ae44a5c0dc7e89828e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 26 Jun 2025 11:38:14 +0200 Subject: [PATCH 041/148] Revert "update docs to highlight modern syntax with private properties" This reverts commit b332b45b66efef522b659a3ecde138bed271552b. --- .../modern-build-stack/transpiler-swc.md | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/v3-docs/docs/about/modern-build-stack/transpiler-swc.md b/v3-docs/docs/about/modern-build-stack/transpiler-swc.md index cb333b5ead..0a5e66756b 100644 --- a/v3-docs/docs/about/modern-build-stack/transpiler-swc.md +++ b/v3-docs/docs/about/modern-build-stack/transpiler-swc.md @@ -125,7 +125,6 @@ For custom SWC configs, see the [SWC configuration API](https://swc.rs/docs/conf - [JSX Syntax in JS files](#jsx-syntax-in-js-files) - [React Runtime](#react-runtime) - [Transform Imports](#transform-imports) -- [Private Properties](#private-properties) ## Config API @@ -343,29 +342,6 @@ avoiding full-package imports and reducing bundle size. You can use advanced import transformations. [See the test suite for examples.](https://github.com/swc-project/plugins/blob/main/packages/transform-imports/__tests__/wasm.test.ts#L12-L63) - -### Private Properties - -SWC supports many of the most modern JS systax features, including private class properties, which Meteor Babel doesn’t. - -Just by enabling SWC, Meteor will parse properly code like: - -``` javascript -class ClassWithPrivate { - #privateField; - #privateFieldWithInitializer = 42; - - #privateMethod() {} - - static #privateStaticField; - static #privateStaticFieldWithInitializer = 42; - - static #privateStaticMethod() {} -} -``` - -You can opt-out of [private properties in SWC options with "privateMethod" setting](https://swc.rs/docs/configuration/compilation#ecmascript) with the [`.swcrc`](#custom-swcrc) file. - ## Troubleshotting If you run into issues, try `meteor reset` or delete the `.meteor/local` folder in the project root. From 0c12f4a16e08ad2146683677e32df9d9014f861f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 26 Jun 2025 11:38:20 +0200 Subject: [PATCH 042/148] Revert "update docs to add more migration topics" This reverts commit 5f997b83877e29a74fbf874250e1f07075ef0194. --- .../modern-build-stack/transpiler-swc.md | 86 ++----------------- 1 file changed, 7 insertions(+), 79 deletions(-) diff --git a/v3-docs/docs/about/modern-build-stack/transpiler-swc.md b/v3-docs/docs/about/modern-build-stack/transpiler-swc.md index 0a5e66756b..7fb8458375 100644 --- a/v3-docs/docs/about/modern-build-stack/transpiler-swc.md +++ b/v3-docs/docs/about/modern-build-stack/transpiler-swc.md @@ -104,7 +104,7 @@ Most apps will benefit just by enabling `modern: true`. Most Meteor packages sho You can use `.swcrc` config in the root of your project to describe specific [SWC plugins](https://github.com/swc-project/plugins) there, that will be applied to compile the entire files of your project. -You can also configure other options using the `.swcrc` format. +You can also configure other options using the `.swcrc` format. One common case is when your project uses `.js` files for React code. React typically uses `.jsx` for components. We still recommend following that convention for compatibility, but if you prefer `.js`, you can provide a custom `.swcrc` like this: ``` json { @@ -117,14 +117,13 @@ You can also configure other options using the `.swcrc` format. } ``` +> You can also configure it for TypeScript, make sure to set `"syntax": "typescript"` and `"tsx": true` instead. + +This overrides Meteor's internal SWC config to apply your settings, ensuring SWC processes `.js` or `.ts` files with React components without falling back to Babel. + Use `swc.config.js` in your project root for dynamic configuration. Meteor will import and apply the SWC config automatically. This lets you choose a config based on environment variables or other runtime factors. -For custom SWC configs, see the [SWC configuration API](https://swc.rs/docs/configuration/compilation). You can also review these migration topics: - -- [Import Aliases](#import-aliases) -- [JSX Syntax in JS files](#jsx-syntax-in-js-files) -- [React Runtime](#react-runtime) -- [Transform Imports](#transform-imports) +Explore additional custom SWC configs, including ["Import Aliases"](#import-aliases) and ["React Runtime"](#react-runtime). ## Config API @@ -253,32 +252,11 @@ SWC resolve aliases for imports correctly, but require calls won’t. For requir SWC has no [module-resolver plugin like Babel’s](https://www.npmjs.com/package/babel-plugin-module-resolver) yet, which could affect require calls in the future. -### JSX Syntax in JS files - -When migrating your app to use SWC, Meteor SWC falls back to Babel if you include JSX in `.js` files, since JSX is only recognized in `.jsx` files. - -To enable JSX in `.js` files, create a [`.swcrc`](#custom-swcrc) file with this config: - -``` json -{ - "jsc": { - "parser": { - "syntax": "ecmascript", - "jsx": true - } - } -} -``` - -> For TypeScript, set "syntax": "typescript" and "tsx": true instead. - -This overrides Meteor’s internal SWC config so SWC handles `.js` and `.ts` files with React components instead of falling back to Babel. - ### React Runtime Meteor Babel lets you skip importing React in your files by using the [`@babel/plugin-transform-react-jsx`](https://www.npmjs.com/package/@babel/plugin-transform-react-jsx) runtime config. -To use the same config in SWC, add it to your [`.swcrc`](#custom-swcrc): +To use the same config in SWC, add it to your [.swcrc](#custom-swcrc): ```json { @@ -292,56 +270,6 @@ To use the same config in SWC, add it to your [`.swcrc`](#custom-swcrc): } ``` -### Transform Imports - -You might have used Meteor Babel with the [`babel-plugin-transform-imports`](https://www.npmjs.com/package/babel-plugin-transform-imports) plugin to rewrite imports in your app. - -SWC offers a similar plugin: [`@swc/plugin-transform-imports`](https://www.npmjs.com/package/@swc/plugin-transform-imports). - -To switch to SWC, install the plugin: - -```bash -meteor npm install -D @swc/plugin-transform-imports -``` - -and add it to your [`.swcrc`](#custom-swcrc): - -```json -{ - "jsc": { - "experimental": { - "plugins": [ - [ - "@swc/plugin-transform-imports", - { - "lodash": { - "transform": "lodash/{{member}}", - "preventFullImport": true - } - } - ] - ] - } - } -} -``` - -This tells SWC to replace, for example, - -``` javascript -import { map } from "lodash" -``` - -with - -``` javascript -import map from "lodash/map" -``` - -avoiding full-package imports and reducing bundle size. - -You can use advanced import transformations. [See the test suite for examples.](https://github.com/swc-project/plugins/blob/main/packages/transform-imports/__tests__/wasm.test.ts#L12-L63) - ## Troubleshotting If you run into issues, try `meteor reset` or delete the `.meteor/local` folder in the project root. From da7ea207a26cc8426866a10c7e44db3c31379dee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 1 Jul 2025 10:30:06 +0200 Subject: [PATCH 043/148] ensure @swc/helpers usage to optimize bundle size and performance --- packages/babel-compiler/babel-compiler.js | 44 ++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index 248fdca86d..fcf231e3d1 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -34,6 +34,9 @@ BCp.isVerbose = function(config = getMeteorConfig()) { if (config?.modern?.transpiler?.verbose) { return true; } + if (config?.modern?.verbose) { + return true; + } if (config?.verbose) { return true; } @@ -129,7 +132,7 @@ BCp.initializeMeteorAppSwcrc = function () { lastModifiedSwcConfig = getMeteorAppSwcrc(swcFile); if (this.isVerbose()) { - logConfigBlock('SWC Config', lastModifiedSwcConfig); + logConfigBlock('SWC Custom Config', lastModifiedSwcConfig); } } return lastModifiedSwcConfig; @@ -145,6 +148,42 @@ BCp.initializeMeteorAppLegacyConfig = function () { return lastModifiedSwcConfig; }; +// Helper function to check if @swc/helpers is available +function hasSwcHelpers() { + return fs.existsSync(`${getMeteorAppDir()}/node_modules/@swc/helpers`); +} + +// Helper function to log friendly messages about SWC helpers +function logSwcHelpersStatus(isAvailable) { + const label = color('[SWC Helpers]', 36); + + if (isAvailable) { + // Green message for when helpers are available + console.log(`${label} ${color('✓ @swc/helpers is available in your project!', 32)}`); + console.log(` ${color('Benefits:', 32)}`); + console.log(` ${color('• Smaller bundle size: External helpers reduce code duplication', 32)}`); + console.log(` ${color('• Faster loads: less code to parse on first download', 32)}`); + console.log(` ${color('• Optional caching: separate vendor chunk can be cached by browsers', 32)}`); + } else { + // Yellow message for when helpers are not available + console.log(`${label} ${color('⚠ @swc/helpers is not available in your project', 33)}`); + console.log(` ${color('Suggestion:', 33)}`); + console.log(` ${color('• Add @swc/helpers to your project:', 33)}`); + console.log(` ${color('meteor npm install --save @swc/helpers', 33)}`); + console.log(` ${color('• This will reduce bundle size and improve performance', 33)}`); + } + console.log(); +} + +let hasSwcHelpersAvailable = false; +BCp.initializeMeteorAppSwcHelpersAvailable = function () { + hasSwcHelpersAvailable = hasSwcHelpers(); + if (this.isVerbose()) { + logSwcHelpersStatus(hasSwcHelpersAvailable); + } + return hasSwcHelpersAvailable; +}; + BCp.processFilesForTarget = function (inputFiles) { var compiler = this; @@ -154,6 +193,7 @@ BCp.processFilesForTarget = function (inputFiles) { this.initializeMeteorAppConfig(); this.initializeMeteorAppSwcrc(); this.initializeMeteorAppLegacyConfig(); + this.initializeMeteorAppSwcHelpersAvailable(); inputFiles.forEach(function (inputFile) { if (inputFile.supportsLazyCompilation) { @@ -284,6 +324,7 @@ BCp.processOneFileForTarget = function (inputFile, source) { jsx: hasJSXSupport, tsx: hasTSXSupport, }, + ...(hasSwcHelpersAvailable && { externalHelpers: true }), }, module: { type: 'es6' }, minify: false, @@ -356,6 +397,7 @@ BCp.processOneFileForTarget = function (inputFile, source) { toBeAdded.hash, lastModifiedSwcConfigTime, isLegacyWebArch ? 'legacy' : '', + hasSwcHelpersAvailable, ] .filter(Boolean) .join('-'); From 78b3a2a7efcf94dd9b4b3080e8aaf16063b401a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 1 Jul 2025 10:54:26 +0200 Subject: [PATCH 044/148] add @swc/helpers to optimize bundle size and performance --- tools/static-assets/skel-apollo/package.json | 1 + tools/static-assets/skel-blaze/package.json | 1 + tools/static-assets/skel-chakra-ui/package.json | 1 + tools/static-assets/skel-full/package.json | 8 ++++++++ tools/static-assets/skel-minimal/package.json | 1 + tools/static-assets/skel-react/package.json | 1 + tools/static-assets/skel-solid/package.json | 1 + tools/static-assets/skel-svelte/package.json | 1 + tools/static-assets/skel-tailwind/package.json | 1 + tools/static-assets/skel-typescript/package.json | 1 + tools/static-assets/skel-vue/package.json | 1 + 11 files changed, 18 insertions(+) diff --git a/tools/static-assets/skel-apollo/package.json b/tools/static-assets/skel-apollo/package.json index 211e19310a..8af983a7cb 100644 --- a/tools/static-assets/skel-apollo/package.json +++ b/tools/static-assets/skel-apollo/package.json @@ -11,6 +11,7 @@ "@apollo/client": "^3.9.2", "@apollo/server": "^4.10.0", "@babel/runtime": "^7.23.9", + "@swc/helpers": "^0.5.17", "graphql": "^16.8.1", "meteor-node-stubs": "^1.2.12", "react": "^18.2.0", diff --git a/tools/static-assets/skel-blaze/package.json b/tools/static-assets/skel-blaze/package.json index 3845c0046d..e197964537 100644 --- a/tools/static-assets/skel-blaze/package.json +++ b/tools/static-assets/skel-blaze/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "jquery": "^3.7.1", "meteor-node-stubs": "^1.2.12" }, diff --git a/tools/static-assets/skel-chakra-ui/package.json b/tools/static-assets/skel-chakra-ui/package.json index fdcb9c2717..99b3e13d76 100644 --- a/tools/static-assets/skel-chakra-ui/package.json +++ b/tools/static-assets/skel-chakra-ui/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "@chakra-ui/icons": "^1.1.7", "@chakra-ui/react": "^1.8.8", "@emotion/react": "^11.9.3", diff --git a/tools/static-assets/skel-full/package.json b/tools/static-assets/skel-full/package.json index 953198e35f..1abdbdd683 100644 --- a/tools/static-assets/skel-full/package.json +++ b/tools/static-assets/skel-full/package.json @@ -7,10 +7,18 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "jquery": "^3.7.1", "meteor-node-stubs": "^1.2.12" }, "devDependencies": { "chai": "^4.2.0" + }, + "meteor": { + "mainModule": { + "client": "client/main.js", + "server": "server/main.js" + }, + "modern": true } } diff --git a/tools/static-assets/skel-minimal/package.json b/tools/static-assets/skel-minimal/package.json index 903c3e9bb7..74d5a9b271 100644 --- a/tools/static-assets/skel-minimal/package.json +++ b/tools/static-assets/skel-minimal/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "meteor-node-stubs": "^1.2.12" }, "meteor": { diff --git a/tools/static-assets/skel-react/package.json b/tools/static-assets/skel-react/package.json index b49bf5903e..ee33ff775c 100644 --- a/tools/static-assets/skel-react/package.json +++ b/tools/static-assets/skel-react/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "meteor-node-stubs": "^1.2.12", "react": "^18.2.0", "react-dom": "^18.2.0" diff --git a/tools/static-assets/skel-solid/package.json b/tools/static-assets/skel-solid/package.json index bb50ecbd9b..17401d9c1b 100644 --- a/tools/static-assets/skel-solid/package.json +++ b/tools/static-assets/skel-solid/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.9", + "@swc/helpers": "^0.5.17", "meteor-node-stubs": "^1.2.12", "picocolors": "^1.1.1", "solid-js": "^1.9.4" diff --git a/tools/static-assets/skel-svelte/package.json b/tools/static-assets/skel-svelte/package.json index c1d703791d..0929124049 100644 --- a/tools/static-assets/skel-svelte/package.json +++ b/tools/static-assets/skel-svelte/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "meteor-node-stubs": "^1.2.12", "svelte": "^3.59.2" }, diff --git a/tools/static-assets/skel-tailwind/package.json b/tools/static-assets/skel-tailwind/package.json index e4b556a821..73971202ba 100644 --- a/tools/static-assets/skel-tailwind/package.json +++ b/tools/static-assets/skel-tailwind/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "autoprefixer": "^10.4.4", "meteor-node-stubs": "^1.2.12", "postcss": "^8.4.12", diff --git a/tools/static-assets/skel-typescript/package.json b/tools/static-assets/skel-typescript/package.json index 90c078b082..77ff7934bf 100644 --- a/tools/static-assets/skel-typescript/package.json +++ b/tools/static-assets/skel-typescript/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "meteor-node-stubs": "^1.2.12", "react": "^18.2.0", "react-dom": "^18.2.0" diff --git a/tools/static-assets/skel-vue/package.json b/tools/static-assets/skel-vue/package.json index 560c8a23a5..09146eee03 100644 --- a/tools/static-assets/skel-vue/package.json +++ b/tools/static-assets/skel-vue/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "meteor-node-stubs": "^1.2.12", "vue": "^3.3.9", "vue-meteor-tracker": "^3.0.0-beta.7", From 598abb72b391bb5040c2b931bd87296078e79554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 1 Jul 2025 11:02:16 +0200 Subject: [PATCH 045/148] add conditional external helpers for @swc/helpers --- packages/babel-compiler/babel-compiler.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index fcf231e3d1..3fc9b355a4 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -324,7 +324,11 @@ BCp.processOneFileForTarget = function (inputFile, source) { jsx: hasJSXSupport, tsx: hasTSXSupport, }, - ...(hasSwcHelpersAvailable && { externalHelpers: true }), + ...(hasSwcHelpersAvailable && + (packageName == null || + !['modules-runtime'].includes(packageName)) && { + externalHelpers: true, + }), }, module: { type: 'es6' }, minify: false, From 7bcca0e38ea1b1ee237e316876b6de9ca966c22f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 1 Jul 2025 17:01:42 +0200 Subject: [PATCH 046/148] add docs for external helpers for @swc/helpers --- .../about/modern-build-stack/transpiler-swc.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/v3-docs/docs/about/modern-build-stack/transpiler-swc.md b/v3-docs/docs/about/modern-build-stack/transpiler-swc.md index 40e366d250..c0a9153411 100644 --- a/v3-docs/docs/about/modern-build-stack/transpiler-swc.md +++ b/v3-docs/docs/about/modern-build-stack/transpiler-swc.md @@ -100,6 +100,20 @@ Most apps will benefit just by enabling `modern: true`. Most Meteor packages sho > Remember to turn off verbosity when you're done with optimizations. +## Externalize SWC Helpers + +By default, SWC inlines transformation helpers (e.g. _extends, _objectSpread) into every file that uses them. While this ensures compatibility out of the box, it can lead to duplicated code across your bundles increasing bundle size. + +To centralize these helpers and keep your client builds lean, you can add the `@swc/helpers` in your app project. + +``` bash +meteor npm install --save @swc/helpers +``` + +> This package is installed by default for new apps. + +Meteor’s build tool comes pre-configured to externalize SWC helpers for you, no extra setup or .swcrc tweaks are needed. As soon as you install @swc/helpers, Meteor’s SWC pipeline will automatically emit imports for shared helper functions rather than inlining them, ensuring your app ships each helper just once. + ## Custom .swcrc You can use `.swcrc` config in the root of your project to describe specific [SWC plugins](https://github.com/swc-project/plugins) there, that will be applied to compile the entire files of your project. From 50c649556528d78875f5c97c04aad598ef9bb986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 2 Jul 2025 11:30:14 +0200 Subject: [PATCH 047/148] re-run checks From a26cc0abf98c57bc8d40f42e6f71be83efb89f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 2 Jul 2025 12:27:31 +0200 Subject: [PATCH 048/148] add git clone fallback with tar for performance repo cloning with volumes --- tools/cli/commands.js | 46 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/tools/cli/commands.js b/tools/cli/commands.js index 50c75559eb..a1a751dbf4 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -3407,6 +3407,7 @@ const setupBenchmarkSuite = async (profilingPath) => { const repoUrl = "https://github.com/meteor/performance"; const branch = "v3.3.0"; + const gitCommand = [ `mkdir -p ${profilingPath}`, `git clone --no-checkout --depth 1 --filter=tree:0 --sparse --progress --branch ${branch} --single-branch ${repoUrl} ${profilingPath}`, @@ -3414,15 +3415,48 @@ const setupBenchmarkSuite = async (profilingPath) => { `git sparse-checkout init --cone`, `git sparse-checkout set scripts`, `git checkout ${branch}`, - `find ${profilingPath} -maxdepth 1 -type f -delete`, + `find ${profilingPath} -maxdepth 1 -type f -delete` ].join(" && "); - const [, errClone] = await bash`${gitCommand}`; + + const [okClone, errClone] = await bash`${gitCommand}`; const errorMessage = errClone && typeof errClone === "string" ? errClone : errClone?.message; - if (errorMessage && errorMessage.includes("Cloning into")) { - throw new Error("error cloning benchmark"); + + if (errorMessage && errorMessage.includes("fatal:")) { + Console.warn("Standard git clone failed. Trying tar fallback..."); + + // Check if tar is available + const [okTar, errTar] = await bash`tar --version`; + if (errTar) { + throw new Error(`git clone failed and tar is not installed:\n${errorMessage}`); + } + + const tempDir = "/tmp/performance-fallback"; + const fallbackCommand = [ + `rm -rf ${tempDir}`, + `git clone --no-checkout --depth 1 --filter=tree:0 --sparse --progress --branch ${branch} --single-branch ${repoUrl} ${tempDir}`, + `cd ${tempDir}`, + `git sparse-checkout init --cone`, + `git sparse-checkout set scripts`, + `git checkout ${branch}`, + `mkdir -p ${profilingPath}/scripts`, + `tar --exclude=".*" -czf /tmp/scripts.tar.gz -C ./scripts .`, + `tar -xzf /tmp/scripts.tar.gz -C ${profilingPath}/scripts`, + `rm -rf ${tempDir}`, + `rm -f /tmp/scripts.tar.gz` + ].join(" && "); + + const [okFallback, errFallback] = await bash`${fallbackCommand}`; + if (errFallback) { + throw new Error(`git clone failed and tar fallback also failed:\n${errorMessage}\n\n${errFallback}`); + } } - // remove .git folder from the example - await files.rm_recursive_async(files.pathJoin(profilingPath, ".git")); + + // remove .git folder if exists (in fallback it won't) + const gitDir = files.pathJoin(profilingPath, ".git"); + if (await files.exists(gitDir)) { + await files.rm_recursive_async(gitDir); + } + Console.info( "Meteor profiling suite cloned to: " + Console.path(profilingPath), ); From 51bf3110e76eb6b3bf96d979e3a9bb327abe792f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 2 Jul 2025 12:34:40 +0200 Subject: [PATCH 049/148] fix --- tools/cli/commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cli/commands.js b/tools/cli/commands.js index a1a751dbf4..293b839a90 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -3439,7 +3439,7 @@ const setupBenchmarkSuite = async (profilingPath) => { `git sparse-checkout set scripts`, `git checkout ${branch}`, `mkdir -p ${profilingPath}/scripts`, - `tar --exclude=".*" -czf /tmp/scripts.tar.gz -C ./scripts .`, + `tar -czf /tmp/scripts.tar.gz -C ./scripts .`, `tar -xzf /tmp/scripts.tar.gz -C ${profilingPath}/scripts`, `rm -rf ${tempDir}`, `rm -f /tmp/scripts.tar.gz` From 7fb76dd9eeddeffaf3d7f3fa2658e0c06611be0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 2 Jul 2025 12:51:06 +0200 Subject: [PATCH 050/148] prefer tar approach when available --- tools/cli/commands.js | 82 ++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/tools/cli/commands.js b/tools/cli/commands.js index 293b839a90..b4d9d9d567 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -3393,45 +3393,32 @@ const setupBenchmarkSuite = async (profilingPath) => { if (await files.exists(profilingPath)) { return; } + + // Check git availability and version const [okGitVersion, errGitVersion] = await bash`git --version`; if (errGitVersion) throw new Error("git is not installed"); - const parsedGitVersion = semver.coerce(okGitVersion.match(/\d+\.\d+\.\d+/)[0] || '')?.version; - const checkInvalidGitVersion = parsedGitVersion == null || semver.lt(parsedGitVersion, '2.25.0'); - if (checkInvalidGitVersion) { + const parsedGitVersion = semver.coerce(okGitVersion.match(/\d+\.\d+\.\d+/)?.[0] || '')?.version; + if (!parsedGitVersion || semver.lt(parsedGitVersion, '2.25.0')) { throw new Error("git version is too old. Please upgrade to at least 2.25"); } - // Set GIT_TERMINAL_PROMPT=0 to disable prompting + // Check tar availability + const [okTar, errTar] = await bash`tar --version`; + const hasTar = !errTar; + + // Disable interactive git prompts process.env.GIT_TERMINAL_PROMPT = 0; const repoUrl = "https://github.com/meteor/performance"; const branch = "v3.3.0"; - const gitCommand = [ - `mkdir -p ${profilingPath}`, - `git clone --no-checkout --depth 1 --filter=tree:0 --sparse --progress --branch ${branch} --single-branch ${repoUrl} ${profilingPath}`, - `cd ${profilingPath}`, - `git sparse-checkout init --cone`, - `git sparse-checkout set scripts`, - `git checkout ${branch}`, - `find ${profilingPath} -maxdepth 1 -type f -delete` - ].join(" && "); + let tarFailed = false; - const [okClone, errClone] = await bash`${gitCommand}`; - const errorMessage = errClone && typeof errClone === "string" ? errClone : errClone?.message; - - if (errorMessage && errorMessage.includes("fatal:")) { - Console.warn("Standard git clone failed. Trying tar fallback..."); - - // Check if tar is available - const [okTar, errTar] = await bash`tar --version`; - if (errTar) { - throw new Error(`git clone failed and tar is not installed:\n${errorMessage}`); - } - - const tempDir = "/tmp/performance-fallback"; - const fallbackCommand = [ + // If tar is available, prefer tar-based extraction + if (hasTar) { + const tempDir = "/tmp/meteor-performance-benchmark-suite"; + const tarCommand = [ `rm -rf ${tempDir}`, `git clone --no-checkout --depth 1 --filter=tree:0 --sparse --progress --branch ${branch} --single-branch ${repoUrl} ${tempDir}`, `cd ${tempDir}`, @@ -3445,21 +3432,42 @@ const setupBenchmarkSuite = async (profilingPath) => { `rm -f /tmp/scripts.tar.gz` ].join(" && "); - const [okFallback, errFallback] = await bash`${fallbackCommand}`; - if (errFallback) { - throw new Error(`git clone failed and tar fallback also failed:\n${errorMessage}\n\n${errFallback}`); + const [okTarClone, errTarClone] = await bash`${tarCommand}`; + if (!errTarClone) { + Console.info("Meteor profiling suite cloned to: " + Console.path(profilingPath)); + return; + } else { + Console.warn("Tar-based cloning failed. Will attempt standard git clone..."); + tarFailed = errTarClone; } + } else { + Console.warn("Tar not available. Will use standard git clone..."); } - // remove .git folder if exists (in fallback it won't) - const gitDir = files.pathJoin(profilingPath, ".git"); - if (await files.exists(gitDir)) { - await files.rm_recursive_async(gitDir); + // Fallback to plain git clone + const gitCommand = [ + `mkdir -p ${profilingPath}`, + `git clone --no-checkout --depth 1 --filter=tree:0 --sparse --progress --branch ${branch} --single-branch ${repoUrl} ${profilingPath}`, + `cd ${profilingPath}`, + `git sparse-checkout init --cone`, + `git sparse-checkout set scripts`, + `git checkout ${branch}`, + `find ${profilingPath} -maxdepth 1 -type f -delete` + ].join(" && "); + + const [okClone, errClone] = await bash`${gitCommand}`; + if (errClone) { + let combinedMessage = "Git clone failed."; + if (tarFailed) { + combinedMessage = `Tar-based cloning also failed:\n${tarFailed}\n\nGit fallback failed:\n${errClone}`; + } + throw new Error(combinedMessage); } - Console.info( - "Meteor profiling suite cloned to: " + Console.path(profilingPath), - ); + // Remove .git folder if present + await files.rm_recursive_async(files.pathJoin(profilingPath, ".git")); + + Console.info("Meteor profiling suite cloned to: " + Console.path(profilingPath)); }; async function doBenchmarkCommand(options) { From 394a2cefa352c8c0d9f4d765bcabe43aad775d8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 2 Jul 2025 14:12:30 +0200 Subject: [PATCH 051/148] fix tests --- tools/tests/modern.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/tests/modern.js b/tools/tests/modern.js index b3a84e66b6..2b1fdff0e8 100644 --- a/tools/tests/modern.js +++ b/tools/tests/modern.js @@ -234,7 +234,7 @@ selftest.define("modern build stack - transpiler boolean-like options", async fu await run.match(/Loaded NPM package "config"/, false, true); /* check verbose logs */ - await run.match(/SWC Config/, false, true); + await run.match(/SWC Custom Config/, false, true); await run.match(/SWC Legacy Config/, false, true); await run.match(/Meteor Config/, false, true); @@ -330,7 +330,7 @@ console.log('Loaded NPM package "config"', require('config').id);`); await run.match(/Loaded NPM package "config"/, false, true); /* check verbose logs */ - await run.match(/SWC Config/, false, true); + await run.match(/SWC Custom Config/, false, true); await run.match(/SWC Legacy Config/, false, true); await run.match(/Meteor Config/, false, true); From 282272494ba51bdf1f864de2aa7858a2c8c5e291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 2 Jul 2025 15:40:03 +0200 Subject: [PATCH 052/148] bump bundle version --- meteor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meteor b/meteor index e452f7b273..10a5ebce8b 100755 --- a/meteor +++ b/meteor @@ -1,6 +1,6 @@ #!/usr/bin/env bash -BUNDLE_VERSION=22.16.0.1 +BUNDLE_VERSION=22.16.0.2 # OS Check. Put here because here is where we download the precompiled # bundles that are arch specific. From 442b831416665aa76fafbb55aa096bc4e408e328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 3 Jul 2025 11:51:10 +0200 Subject: [PATCH 053/148] re-run checks From f99d068988dccb370e0ef870f71999a833f2105c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 3 Jul 2025 14:14:48 +0200 Subject: [PATCH 054/148] re-run checks From 649f020d87540996ad5a4f462e2fd52c4b5b8882 Mon Sep 17 00:00:00 2001 From: Saksham Goel Date: Thu, 5 Jun 2025 22:00:17 +0530 Subject: [PATCH 055/148] Update hook.js Issue:#13781 Removed the forEachAsync written twice. --- packages/callback-hook/hook.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/packages/callback-hook/hook.js b/packages/callback-hook/hook.js index ecc9c2ccfb..d1156f79fd 100644 --- a/packages/callback-hook/hook.js +++ b/packages/callback-hook/hook.js @@ -124,20 +124,6 @@ export class Hook { } } - async forEachAsync(iterator) { - const ids = Object.keys(this.callbacks); - for (let i = 0; i < ids.length; ++i) { - const id = ids[i]; - // check to see if the callback was removed during iteration - if (hasOwn.call(this.callbacks, id)) { - const callback = this.callbacks[id]; - if (!await iterator(callback)) { - break; - } - } - } - } - /** * For each registered callback, call the passed iterator function with the callback. * From 1164ac728db43d088ffbec0d2590b0137089deee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Vatle?= Date: Sun, 6 Jul 2025 19:03:13 +0300 Subject: [PATCH 056/148] Add note about purpose of entry-meteor.js files. --- tools/static-assets/skel-vue/client/entry-meteor.js | 8 ++++++++ tools/static-assets/skel-vue/server/entry-meteor.js | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/tools/static-assets/skel-vue/client/entry-meteor.js b/tools/static-assets/skel-vue/client/entry-meteor.js index e69de29bb2..418b5a55cb 100644 --- a/tools/static-assets/skel-vue/client/entry-meteor.js +++ b/tools/static-assets/skel-vue/client/entry-meteor.js @@ -0,0 +1,8 @@ +// Entrypoint for the Meteor client +// Generally, this file can be left empty. Vite will add imports for +// lazy-loaded Meteor packages to this file to ensure they are included in your +// final production bundle. + +// This can also be a good place to put code that you don't want Vite to +// process, for example, if you run into a compatability issue or need to use +// nested imports. \ No newline at end of file diff --git a/tools/static-assets/skel-vue/server/entry-meteor.js b/tools/static-assets/skel-vue/server/entry-meteor.js index e69de29bb2..48af245a74 100644 --- a/tools/static-assets/skel-vue/server/entry-meteor.js +++ b/tools/static-assets/skel-vue/server/entry-meteor.js @@ -0,0 +1,8 @@ +// Entrypoint for the Meteor server +// Generally, this file can be left empty. Vite will add imports for +// lazy-loaded Meteor packages to this file to ensure they are included in your +// final production bundle. + +// This can also be a good place to put code that you don't want Vite to +// process, for example, if you run into a compatability issue or need to use +// nested imports. \ No newline at end of file From a29af3f4d64abf34e808a4ef90f8d5b775f678ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Vatle?= Date: Sun, 6 Jul 2025 19:05:32 +0300 Subject: [PATCH 057/148] Fix unused 'client/main.js' file, using a more consistent main module directory structure --- tools/static-assets/skel-vue/client/main.js | 2 +- tools/static-assets/skel-vue/vite.config.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/static-assets/skel-vue/client/main.js b/tools/static-assets/skel-vue/client/main.js index 97d382a9bd..44bcc64d55 100644 --- a/tools/static-assets/skel-vue/client/main.js +++ b/tools/static-assets/skel-vue/client/main.js @@ -1 +1 @@ -// main entry point is in imports/ui/main.jsx +import '../imports/ui/main'; \ No newline at end of file diff --git a/tools/static-assets/skel-vue/vite.config.js b/tools/static-assets/skel-vue/vite.config.js index dd08ccf69d..5c0ecc62ba 100644 --- a/tools/static-assets/skel-vue/vite.config.js +++ b/tools/static-assets/skel-vue/vite.config.js @@ -6,7 +6,7 @@ export default defineConfig({ plugins: [ vue(), meteor({ - clientEntry: 'imports/ui/main.js', + clientEntry: 'client/main.js', serverEntry: 'server/main.js', enableExperimentalFeatures: true, stubValidation: { From 24dbc8a911ea29c197075ed457c8695e59579d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Vatle?= Date: Sun, 6 Jul 2025 19:12:45 +0300 Subject: [PATCH 058/148] Upgrade Tailwind to v4 in Vue skeleton --- tools/static-assets/skel-vue/client/main.css | 4 +--- tools/static-assets/skel-vue/package.json | 5 ++--- tools/static-assets/skel-vue/vite.config.js | 4 +++- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/static-assets/skel-vue/client/main.css b/tools/static-assets/skel-vue/client/main.css index b5c61c9567..a461c505f1 100644 --- a/tools/static-assets/skel-vue/client/main.css +++ b/tools/static-assets/skel-vue/client/main.css @@ -1,3 +1 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; \ No newline at end of file diff --git a/tools/static-assets/skel-vue/package.json b/tools/static-assets/skel-vue/package.json index 560c8a23a5..1f573e0e5b 100644 --- a/tools/static-assets/skel-vue/package.json +++ b/tools/static-assets/skel-vue/package.json @@ -24,11 +24,10 @@ }, "devDependencies": { "@types/meteor": "^2.9.7", + "@tailwindcss/vite": "^4.1.11", "@vitejs/plugin-vue": "^5.2.1", - "autoprefixer": "^10.4.16", "meteor-vite": "^3.2.1", - "postcss": "^8.4.31", - "tailwindcss": "^3.3.5", + "tailwindcss": "^4.1.11", "vite": "^6.0.11" } } diff --git a/tools/static-assets/skel-vue/vite.config.js b/tools/static-assets/skel-vue/vite.config.js index 5c0ecc62ba..01a2ae4903 100644 --- a/tools/static-assets/skel-vue/vite.config.js +++ b/tools/static-assets/skel-vue/vite.config.js @@ -1,10 +1,12 @@ -import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; +import tailwindcss from 'tailwindcss'; +import { defineConfig } from 'vite'; import { meteor } from 'meteor-vite/plugin'; export default defineConfig({ plugins: [ vue(), + tailwindcss(), meteor({ clientEntry: 'client/main.js', serverEntry: 'server/main.js', From 00bc129092baccd28518abf408acf14c1d11dc88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Vatle?= Date: Sun, 6 Jul 2025 19:13:37 +0300 Subject: [PATCH 059/148] Add explicit import for main CSS file in client main module --- tools/static-assets/skel-vue/client/main.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/static-assets/skel-vue/client/main.js b/tools/static-assets/skel-vue/client/main.js index 44bcc64d55..52c40b5d43 100644 --- a/tools/static-assets/skel-vue/client/main.js +++ b/tools/static-assets/skel-vue/client/main.js @@ -1 +1,2 @@ +import './main.css'; import '../imports/ui/main'; \ No newline at end of file From 735aed6c3a1780eab8ef4e0a1b1dbbbf9d4ad578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Vatle?= Date: Sun, 6 Jul 2025 19:14:14 +0300 Subject: [PATCH 060/148] Remove redundant config files from Vue skeleton --- tools/static-assets/skel-vue/postcss.config.js | 6 ------ tools/static-assets/skel-vue/tailwind.config.js | 8 -------- 2 files changed, 14 deletions(-) delete mode 100644 tools/static-assets/skel-vue/postcss.config.js delete mode 100644 tools/static-assets/skel-vue/tailwind.config.js diff --git a/tools/static-assets/skel-vue/postcss.config.js b/tools/static-assets/skel-vue/postcss.config.js deleted file mode 100644 index 33ad091d26..0000000000 --- a/tools/static-assets/skel-vue/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} diff --git a/tools/static-assets/skel-vue/tailwind.config.js b/tools/static-assets/skel-vue/tailwind.config.js deleted file mode 100644 index 72c950fc84..0000000000 --- a/tools/static-assets/skel-vue/tailwind.config.js +++ /dev/null @@ -1,8 +0,0 @@ -/** @type {import('tailwindcss').Config} */ -module.exports = { - content: ['./imports/ui/**/*.{vue,js,ts,jsx,tsx}', './client/*.html'], - theme: { - extend: {}, - }, - plugins: [], -} From 17e8152f24d8872d5e1d19e150885b943811f3f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Vatle?= Date: Sun, 6 Jul 2025 19:15:53 +0300 Subject: [PATCH 061/148] Use .mjs file extension for Vite config to avoid CJS interop exceptions --- tools/static-assets/skel-vue/{vite.config.js => vite.config.mjs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tools/static-assets/skel-vue/{vite.config.js => vite.config.mjs} (100%) diff --git a/tools/static-assets/skel-vue/vite.config.js b/tools/static-assets/skel-vue/vite.config.mjs similarity index 100% rename from tools/static-assets/skel-vue/vite.config.js rename to tools/static-assets/skel-vue/vite.config.mjs From a972460c09cf90a4ee461911be96353245f5b4cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Vatle?= Date: Sun, 6 Jul 2025 19:19:46 +0300 Subject: [PATCH 062/148] Use .mjs file extension for Vite config to avoid CJS interop exceptions --- tools/static-assets/skel-vue/vite.config.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/static-assets/skel-vue/vite.config.mjs b/tools/static-assets/skel-vue/vite.config.mjs index 01a2ae4903..f955234c6a 100644 --- a/tools/static-assets/skel-vue/vite.config.mjs +++ b/tools/static-assets/skel-vue/vite.config.mjs @@ -1,5 +1,5 @@ import vue from '@vitejs/plugin-vue'; -import tailwindcss from 'tailwindcss'; +import tailwindcss from '@tailwindcss/vite'; import { defineConfig } from 'vite'; import { meteor } from 'meteor-vite/plugin'; From e8795c96f8c5d507e6283377483b410c2371a306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Vatle?= Date: Sun, 6 Jul 2025 19:31:19 +0300 Subject: [PATCH 063/148] Move main.css file into UI directory to prevent Meteor from trying to process it in addition to Vite. --- tools/static-assets/skel-vue/client/main.js | 3 +-- tools/static-assets/skel-vue/{client => imports/ui}/main.css | 0 tools/static-assets/skel-vue/imports/ui/main.js | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) rename tools/static-assets/skel-vue/{client => imports/ui}/main.css (100%) diff --git a/tools/static-assets/skel-vue/client/main.js b/tools/static-assets/skel-vue/client/main.js index 52c40b5d43..403d8a2d2a 100644 --- a/tools/static-assets/skel-vue/client/main.js +++ b/tools/static-assets/skel-vue/client/main.js @@ -1,2 +1 @@ -import './main.css'; -import '../imports/ui/main'; \ No newline at end of file +import '../imports/ui/main' \ No newline at end of file diff --git a/tools/static-assets/skel-vue/client/main.css b/tools/static-assets/skel-vue/imports/ui/main.css similarity index 100% rename from tools/static-assets/skel-vue/client/main.css rename to tools/static-assets/skel-vue/imports/ui/main.css diff --git a/tools/static-assets/skel-vue/imports/ui/main.js b/tools/static-assets/skel-vue/imports/ui/main.js index e3500841ea..f568d94ebf 100644 --- a/tools/static-assets/skel-vue/imports/ui/main.js +++ b/tools/static-assets/skel-vue/imports/ui/main.js @@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor' import { createApp } from 'vue' import { VueMeteor } from 'vue-meteor-tracker' +import './main.css' import App from './App.vue' import { router } from './router' From 54e5d26d72acbd51156b976452f33dcea1a8b167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Vatle?= Date: Sun, 6 Jul 2025 19:43:20 +0300 Subject: [PATCH 064/148] Add a clear distinction between components, pages and the app container through a generally accepted Vue directory structure convention. --- tools/static-assets/skel-vue/imports/ui/App.vue | 2 +- .../skel-vue/imports/ui/{ => components}/AppMenu.vue | 0 .../skel-vue/imports/ui/{ => components}/Hello.vue | 0 .../skel-vue/imports/ui/{ => components}/Info.vue | 0 tools/static-assets/skel-vue/imports/ui/router.js | 4 ++-- tools/static-assets/skel-vue/imports/ui/{ => views}/About.vue | 0 tools/static-assets/skel-vue/imports/ui/{ => views}/Home.vue | 4 ++-- 7 files changed, 5 insertions(+), 5 deletions(-) rename tools/static-assets/skel-vue/imports/ui/{ => components}/AppMenu.vue (100%) rename tools/static-assets/skel-vue/imports/ui/{ => components}/Hello.vue (100%) rename tools/static-assets/skel-vue/imports/ui/{ => components}/Info.vue (100%) rename tools/static-assets/skel-vue/imports/ui/{ => views}/About.vue (100%) rename tools/static-assets/skel-vue/imports/ui/{ => views}/Home.vue (60%) diff --git a/tools/static-assets/skel-vue/imports/ui/App.vue b/tools/static-assets/skel-vue/imports/ui/App.vue index 7a775391cb..19a68a1ea1 100644 --- a/tools/static-assets/skel-vue/imports/ui/App.vue +++ b/tools/static-assets/skel-vue/imports/ui/App.vue @@ -1,5 +1,5 @@