mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Merge branch 'modern-bundler-integration' into release-3.4
This commit is contained in:
@@ -1,33 +1,37 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { WebApp } from 'meteor/webapp';
|
||||
import { WebApp, WebAppInternals } from 'meteor/webapp';
|
||||
import { shuffleString } from 'meteor/tools-core/lib/string';
|
||||
import { createProxyMiddleware } from 'http-proxy-middleware';
|
||||
import path from 'path';
|
||||
import { parse as parseUrl } from 'url';
|
||||
import {
|
||||
RSPACK_CHUNKS_CONTEXT,
|
||||
RSPACK_ASSETS_CONTEXT,
|
||||
RSPACK_HOT_UPDATE_REGEX,
|
||||
} from "./lib/constants";
|
||||
import { isMeteorAppDebug } from "meteor/tools-core/lib/meteor";
|
||||
|
||||
// Define constants for both development and production
|
||||
const rspackChunksContext = process.env.RSPACK_CHUNKS_CONTEXT || RSPACK_CHUNKS_CONTEXT;
|
||||
const rspackAssetsContext = process.env.RSPACK_ASSETS_CONTEXT || RSPACK_ASSETS_CONTEXT;
|
||||
|
||||
/**
|
||||
* Regex pattern for rspack bundles
|
||||
* @constant {RegExp}
|
||||
*/
|
||||
const RSPACK_CHUNKS_REGEX = new RegExp(
|
||||
`^\/${rspackChunksContext}\/(.+)$`,
|
||||
);
|
||||
|
||||
/**
|
||||
* Regex pattern for rspack assets
|
||||
* @constant {RegExp}
|
||||
*/
|
||||
const RSPACK_ASSETS_REGEX = new RegExp(
|
||||
`^\/${rspackAssetsContext}\/(.+)$`,
|
||||
);
|
||||
|
||||
if (Meteor.isDevelopment) {
|
||||
const rspackChunksContext = process.env.RSPACK_CHUNKS_CONTEXT || RSPACK_CHUNKS_CONTEXT;
|
||||
const rspackAssetsContext = process.env.RSPACK_ASSETS_CONTEXT || RSPACK_ASSETS_CONTEXT;
|
||||
|
||||
/**
|
||||
* Regex pattern for rspack bundles
|
||||
* @constant {RegExp}
|
||||
*/
|
||||
const RSPACK_CHUNKS_REGEX = new RegExp(
|
||||
`^\/${rspackChunksContext}\/(.+)$`,
|
||||
);
|
||||
|
||||
/**
|
||||
* Regex pattern for rspack assets
|
||||
* @constant {RegExp}
|
||||
*/
|
||||
const RSPACK_ASSETS_REGEX = new RegExp(
|
||||
`^\/${rspackAssetsContext}\/(.+)$`,
|
||||
);
|
||||
|
||||
// Target URL for the Rspack dev server
|
||||
const target = `http://localhost:${process.env.RSPACK_DEVSERVER_PORT}`;
|
||||
|
||||
@@ -121,3 +125,88 @@ if (Meteor.isDevelopment) {
|
||||
// Enable client reload on server startup
|
||||
enableClientReloadOnServerStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a single rspack static asset with WebAppInternals.staticFilesByArch
|
||||
* @param {string} arch - The architecture to register the asset for
|
||||
* @param {string} pathname - The pathname of the asset
|
||||
* @param {string} filePath - The absolute path to the asset on disk
|
||||
* @returns {Object} The static file info object
|
||||
*/
|
||||
function registerRspackStaticAsset(arch, pathname, filePath) {
|
||||
// Ensure the architecture exists in staticFilesByArch
|
||||
if (!WebAppInternals.staticFilesByArch[arch]) {
|
||||
WebAppInternals.staticFilesByArch[arch] = Object.create(null);
|
||||
}
|
||||
|
||||
// Get the static files object for this architecture
|
||||
const staticFiles = WebAppInternals.staticFilesByArch[arch];
|
||||
|
||||
// Skip if already registered
|
||||
if (staticFiles[pathname]) {
|
||||
// Ensure the entry is marked as cacheable
|
||||
staticFiles[pathname].cacheable = true;
|
||||
|
||||
if (isMeteorAppDebug()) {
|
||||
console.log(`Registering rspack asset: ${archName} ${pathname} cacheable ${staticFiles[pathname].cacheable}`);
|
||||
}
|
||||
return staticFiles[pathname];
|
||||
}
|
||||
|
||||
// Determine file type based on extension
|
||||
const type = pathname.endsWith(".js") ? "js" :
|
||||
pathname.endsWith(".css") ? "css" :
|
||||
pathname.endsWith(".json") ? "json" : undefined;
|
||||
|
||||
// Extract hash from filename (assuming it's the second part after splitting by '.')
|
||||
const filename = pathname.split("/").pop();
|
||||
const hash = filename.split(".")[1];
|
||||
|
||||
// Register the asset
|
||||
staticFiles[pathname] = {
|
||||
absolutePath: filePath,
|
||||
cacheable: true, // Most rspack assets are cacheable
|
||||
hash,
|
||||
type
|
||||
};
|
||||
|
||||
if (isMeteorAppDebug()) {
|
||||
console.log(`Registering rspack asset: ${archName} ${pathname} cacheable ${staticFiles[pathname].cacheable}`);
|
||||
}
|
||||
|
||||
return staticFiles[pathname];
|
||||
}
|
||||
|
||||
// Store the original staticFilesMiddleware
|
||||
const originalStaticFilesMiddleware = WebAppInternals.staticFilesMiddleware;
|
||||
|
||||
// Handle rspack assets on-demand to add Meteor's static files headers
|
||||
WebAppInternals.staticFilesMiddleware = async function(staticFilesByArch, req, res, next) {
|
||||
const pathname = parseUrl(req.url).pathname;
|
||||
|
||||
try {
|
||||
// Check if this is a rspack asset request
|
||||
const chunksMatch = pathname.match(RSPACK_CHUNKS_REGEX);
|
||||
const assetsMatch = pathname.match(RSPACK_ASSETS_REGEX);
|
||||
|
||||
if (chunksMatch || assetsMatch) {
|
||||
const cwd = process.cwd();
|
||||
const architectures = ["web.browser", "web.browser.legacy", "web.cordova"];
|
||||
WebApp.categorizeRequest(req);
|
||||
|
||||
// Try to find the file on disk
|
||||
const context = chunksMatch ? rspackChunksContext : rspackAssetsContext;
|
||||
const filename = (chunksMatch ? chunksMatch[1] : assetsMatch[1]);
|
||||
const filePath = path.join(cwd, context, filename);
|
||||
|
||||
architectures.forEach(archName => {
|
||||
registerRspackStaticAsset(archName, pathname, filePath);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`Error handling rspack asset: ${e.message}`);
|
||||
}
|
||||
|
||||
// Call the original middleware
|
||||
return originalStaticFilesMiddleware(staticFilesByArch, req, res, next);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user