mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
support full-app test mode
This commit is contained in:
9
npm-packages/meteor-rspack/entries/eager-app-tests.js
Normal file
9
npm-packages/meteor-rspack/entries/eager-app-tests.js
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
const ctx = import.meta.webpackContext('/', {
|
||||
recursive: true,
|
||||
regExp: /\.app-?(?:test|spec)s?\.[^.]+$/,
|
||||
exclude: /(^|\/)(node_modules|\.meteor|_build)(\/|$)/,
|
||||
mode: 'eager',
|
||||
});
|
||||
ctx.keys().forEach(ctx);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
const ctx = import.meta.webpackContext('/', {
|
||||
recursive: true,
|
||||
regExp: /\.(?:app-)?(?:test|spec)s?\.[^.]+$/,
|
||||
regExp: /\.(?:test|spec)s?\.[^.]+$/,
|
||||
exclude: /(^|\/)(node_modules|\.meteor|_build)(\/|$)/,
|
||||
mode: 'eager',
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ export function loadHtmlRspackPluginFromHost(compiler) {
|
||||
|
||||
/**
|
||||
* Rspack plugin to:
|
||||
* 1. Remove the injected `client-rspack.js` script tag
|
||||
* 1. Remove the injected `*-rspack.js` script tags
|
||||
* 2. Strip <!doctype> and <html>…</html> wrappers from the final HTML
|
||||
*/
|
||||
export default class RspackMeteorHtmlPlugin {
|
||||
@@ -26,11 +26,11 @@ export default class RspackMeteorHtmlPlugin {
|
||||
compiler.hooks.compilation.tap('RspackMeteorHtmlPlugin', compilation => {
|
||||
const hooks = HtmlRspackPlugin.getCompilationHooks(compilation);
|
||||
|
||||
// remove <script src=".../client-rspack.js">
|
||||
// remove <script src="...*-rspack.js">
|
||||
hooks.alterAssetTags.tap('RspackMeteorHtmlPlugin', data => {
|
||||
data.assetTags.scripts = data.assetTags.scripts.filter(t => {
|
||||
const src = t.attributes?.src || t.asset || '';
|
||||
return !(t.tagName === 'script' && /(?:^|\/)client-rspack\.js$/i.test(src));
|
||||
return !(t.tagName === 'script' && /(?:^|\/)[^\/]*-rspack\.js$/i.test(src));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { DefinePlugin, BannerPlugin } from '@rspack/core';
|
||||
import fs from 'fs';
|
||||
import { createRequire } from 'module';
|
||||
import { inspect } from 'node:util';
|
||||
import path from 'path';
|
||||
import { merge } from 'webpack-merge';
|
||||
import { inspect } from "node:util";
|
||||
|
||||
import { RequireExternalsPlugin } from './plugins/RequireExtenalsPlugin.js';
|
||||
import { getMeteorAppSwcConfig } from "./lib/swc.js";
|
||||
import { mergeSplitOverlap } from './lib/mergeRulesSplitOverlap.js';
|
||||
import CleanBuildAssetsPlugin from "./plugins/CleanBuildAssetsPlugin.js";
|
||||
import { getMeteorAppSwcConfig } from './lib/swc.js';
|
||||
import CleanBuildAssetsPlugin from './plugins/CleanBuildAssetsPlugin.js';
|
||||
import HtmlRspackPlugin from './plugins/HtmlRspackPlugin.js';
|
||||
import { RequireExternalsPlugin } from './plugins/RequireExtenalsPlugin.js';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
@@ -46,7 +46,13 @@ function createCacheStrategy(mode) {
|
||||
}
|
||||
|
||||
// SWC loader rule (JSX/JS)
|
||||
function createSwcConfig({ isTypescriptEnabled, isJsxEnabled, isTsxEnabled, externalHelpers, isDevEnvironment }) {
|
||||
function createSwcConfig({
|
||||
isTypescriptEnabled,
|
||||
isJsxEnabled,
|
||||
isTsxEnabled,
|
||||
externalHelpers,
|
||||
isDevEnvironment,
|
||||
}) {
|
||||
const defaultConfig = {
|
||||
jsc: {
|
||||
baseUrl: process.cwd(),
|
||||
@@ -122,6 +128,7 @@ export default function (inMeteor = {}, argv = {}) {
|
||||
const isReactEnabled = Meteor.isReactEnabled;
|
||||
const isTestModule = Meteor.isTestModule;
|
||||
const isTestEager = Meteor.isTestEager;
|
||||
const isTestFullApp = Meteor.isTestFullApp;
|
||||
const swcExternalHelpers = Meteor.swcExternalHelpers;
|
||||
const mode = isProd ? 'production' : 'development';
|
||||
|
||||
@@ -179,21 +186,22 @@ export default function (inMeteor = {}, argv = {}) {
|
||||
<% } %>
|
||||
</body>
|
||||
`,
|
||||
...options
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// Set watch options
|
||||
const watchOptions = {
|
||||
...defaultWatchOptions,
|
||||
...isTest && isTestEager && {
|
||||
ignored: [
|
||||
...defaultWatchOptions.ignored,
|
||||
'**/_build/**',
|
||||
'**/.meteor/local/**',
|
||||
'**/node_modules/**',
|
||||
],
|
||||
},
|
||||
...(isTest &&
|
||||
isTestEager && {
|
||||
ignored: [
|
||||
...defaultWatchOptions.ignored,
|
||||
'**/_build/**',
|
||||
'**/.meteor/local/**',
|
||||
'**/node_modules/**',
|
||||
],
|
||||
}),
|
||||
};
|
||||
|
||||
if (Meteor.isDebug || Meteor.isVerbose) {
|
||||
@@ -235,21 +243,25 @@ export default function (inMeteor = {}, argv = {}) {
|
||||
: []),
|
||||
];
|
||||
|
||||
const reactRefreshModule = isReactEnabled ? safeRequire('@rspack/plugin-react-refresh') : null;
|
||||
const reactRefreshModule = isReactEnabled
|
||||
? safeRequire('@rspack/plugin-react-refresh')
|
||||
: null;
|
||||
|
||||
const requireExternalsPlugin = new RequireExternalsPlugin({
|
||||
filePath: path.join(buildContext, runPath),
|
||||
...(Meteor.isBlazeEnabled && {
|
||||
externals: /\.html$/,
|
||||
isEagerImport: (module) => module.endsWith('.html'),
|
||||
...isProd && {
|
||||
isEagerImport: module => module.endsWith('.html'),
|
||||
...(isProd && {
|
||||
lastImports: [`./${outputFilename}`],
|
||||
},
|
||||
}),
|
||||
}),
|
||||
enableGlobalPolyfill: isDevEnvironment,
|
||||
});
|
||||
|
||||
const clientNameConfig = `[${isTest && 'test-' || ''}${isTestModule && 'module' || 'client'}-rspack]`;
|
||||
const clientNameConfig = `[${(isTest && 'test-') || ''}${
|
||||
(isTestModule && 'module') || 'client'
|
||||
}-rspack]`;
|
||||
// Base client config
|
||||
let clientConfig = {
|
||||
name: clientNameConfig,
|
||||
@@ -293,9 +305,13 @@ export default function (inMeteor = {}, argv = {}) {
|
||||
resolve: { extensions, alias },
|
||||
externals,
|
||||
plugins: [
|
||||
...(isProd ? [
|
||||
new CleanBuildAssetsPlugin({ verbose: Meteor.isDebug || Meteor.isVerbose }),
|
||||
] : []),
|
||||
...(isProd
|
||||
? [
|
||||
new CleanBuildAssetsPlugin({
|
||||
verbose: Meteor.isDebug || Meteor.isVerbose,
|
||||
}),
|
||||
]
|
||||
: []),
|
||||
...[
|
||||
...(isReactEnabled && reactRefreshModule && isDevEnvironment
|
||||
? [new reactRefreshModule()]
|
||||
@@ -325,7 +341,7 @@ export default function (inMeteor = {}, argv = {}) {
|
||||
...(Meteor.isBlazeEnabled && { hot: false }),
|
||||
port: Meteor.devServerPort || 8080,
|
||||
devMiddleware: {
|
||||
writeToDisk: (filePath) =>
|
||||
writeToDisk: filePath =>
|
||||
/\.(html)$/.test(filePath) && !filePath.includes('.hot-update.'),
|
||||
},
|
||||
},
|
||||
@@ -333,15 +349,21 @@ export default function (inMeteor = {}, argv = {}) {
|
||||
experiments: { css: true },
|
||||
};
|
||||
|
||||
const serverNameConfig = `[${isTest && 'test-' || ''}${isTestModule && 'module' || 'server'}-rspack]`;
|
||||
const serverEntry =
|
||||
isTest && isTestEager && isTestFullApp
|
||||
? 'node_modules/@meteorjs/rspack/entries/eager-app-tests.js'
|
||||
: isTest && isTestEager
|
||||
? 'node_modules/@meteorjs/rspack/entries/eager-tests.js'
|
||||
: path.resolve(process.cwd(), buildContext, entryPath);
|
||||
const serverNameConfig = `[${(isTest && 'test-') || ''}${
|
||||
(isTestModule && 'module') || 'server'
|
||||
}-rspack]`;
|
||||
// Base server config
|
||||
let serverConfig = {
|
||||
name: serverNameConfig,
|
||||
target: 'node',
|
||||
mode,
|
||||
entry: isTest && isTestEager
|
||||
? "node_modules/@meteorjs/rspack/entries/eager-tests.js"
|
||||
: path.resolve(process.cwd(), buildContext, entryPath),
|
||||
entry: serverEntry,
|
||||
output: {
|
||||
path: serverOutputDir,
|
||||
filename: () => `../${buildContext}/${outputPath}`,
|
||||
@@ -370,16 +392,16 @@ export default function (inMeteor = {}, argv = {}) {
|
||||
new DefinePlugin(
|
||||
isTest && (isTestModule || isTestEager)
|
||||
? {
|
||||
"Meteor.isTest": JSON.stringify(isTest),
|
||||
"Meteor.isDevelopment": JSON.stringify(isDev),
|
||||
'Meteor.isTest': JSON.stringify(isTest),
|
||||
'Meteor.isDevelopment': JSON.stringify(isDev),
|
||||
}
|
||||
: {
|
||||
"Meteor.isClient": JSON.stringify(false),
|
||||
"Meteor.isServer": JSON.stringify(true),
|
||||
"Meteor.isTest": JSON.stringify(isTest),
|
||||
"Meteor.isDevelopment": JSON.stringify(isDev),
|
||||
"Meteor.isProduction": JSON.stringify(isProd),
|
||||
}
|
||||
'Meteor.isClient': JSON.stringify(false),
|
||||
'Meteor.isServer': JSON.stringify(true),
|
||||
'Meteor.isTest': JSON.stringify(isTest),
|
||||
'Meteor.isDevelopment': JSON.stringify(isDev),
|
||||
'Meteor.isProduction': JSON.stringify(isProd),
|
||||
},
|
||||
),
|
||||
new BannerPlugin({
|
||||
banner: bannerOutput,
|
||||
@@ -389,9 +411,8 @@ export default function (inMeteor = {}, argv = {}) {
|
||||
],
|
||||
watchOptions,
|
||||
devtool: isDevEnvironment || isTest ? 'source-map' : 'hidden-source-map',
|
||||
...((isDevEnvironment || isTest && !isTestEager) &&
|
||||
createCacheStrategy(mode)
|
||||
),
|
||||
...((isDevEnvironment || (isTest && !isTestEager)) &&
|
||||
createCacheStrategy(mode)),
|
||||
};
|
||||
|
||||
// Load and apply project-level overrides for the selected build
|
||||
|
||||
Reference in New Issue
Block a user