fix: automated tests

This commit is contained in:
Nathan Walker
2025-08-23 20:37:59 -07:00
parent ac7bcfbbf6
commit 9cce7578bd
5 changed files with 160 additions and 90 deletions

42
package-lock.json generated
View File

@@ -75,6 +75,7 @@
"postcss-loader": "^8.0.0", "postcss-loader": "^8.0.0",
"prettier": "^3.2.5", "prettier": "^3.2.5",
"sass": "^1.72.0", "sass": "^1.72.0",
"sass-loader": "^16.0.0",
"shady-css-parser": "^0.1.0", "shady-css-parser": "^0.1.0",
"terser-webpack-plugin": "^5.0.0", "terser-webpack-plugin": "^5.0.0",
"tree-kill": "^1.2.2", "tree-kill": "^1.2.2",
@@ -24218,6 +24219,47 @@
"@parcel/watcher": "^2.4.1" "@parcel/watcher": "^2.4.1"
} }
}, },
"node_modules/sass-loader": {
"version": "16.0.5",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.5.tgz",
"integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==",
"dev": true,
"license": "MIT",
"dependencies": {
"neo-async": "^2.6.2"
},
"engines": {
"node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"@rspack/core": "0.x || 1.x",
"node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
"sass": "^1.3.0",
"sass-embedded": "*",
"webpack": "^5.0.0"
},
"peerDependenciesMeta": {
"@rspack/core": {
"optional": true
},
"node-sass": {
"optional": true
},
"sass": {
"optional": true
},
"sass-embedded": {
"optional": true
},
"webpack": {
"optional": true
}
}
},
"node_modules/sass/node_modules/chokidar": { "node_modules/sass/node_modules/chokidar": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz",

View File

@@ -82,6 +82,7 @@
"postcss-loader": "^8.0.0", "postcss-loader": "^8.0.0",
"prettier": "^3.2.5", "prettier": "^3.2.5",
"sass": "^1.72.0", "sass": "^1.72.0",
"sass-loader": "^16.0.0",
"shady-css-parser": "^0.1.0", "shady-css-parser": "^0.1.0",
"terser-webpack-plugin": "^5.0.0", "terser-webpack-plugin": "^5.0.0",
"tree-kill": "^1.2.2", "tree-kill": "^1.2.2",

View File

@@ -1,10 +1,5 @@
import { extname, relative, resolve } from 'path'; import { extname, relative, resolve } from 'path';
import { import { ContextExclusionPlugin, HotModuleReplacementPlugin } from 'webpack';
ContextExclusionPlugin,
DefinePlugin,
HotModuleReplacementPlugin,
BannerPlugin,
} from 'webpack';
import Config from 'webpack-chain'; import Config from 'webpack-chain';
import { satisfies } from 'semver'; import { satisfies } from 'semver';
import { existsSync } from 'fs'; import { existsSync } from 'fs';
@@ -23,6 +18,7 @@ import { PlatformSuffixPlugin } from '../plugins/PlatformSuffixPlugin';
import { applyFileReplacements } from '../helpers/fileReplacements'; import { applyFileReplacements } from '../helpers/fileReplacements';
import { addCopyRule, applyCopyRules } from '../helpers/copyRules'; import { addCopyRule, applyCopyRules } from '../helpers/copyRules';
import { WatchStatePlugin } from '../plugins/WatchStatePlugin'; import { WatchStatePlugin } from '../plugins/WatchStatePlugin';
import { CompatDefinePlugin } from '../plugins/CompatDefinePlugin';
import { applyDotEnvPlugin } from '../helpers/dotEnv'; import { applyDotEnvPlugin } from '../helpers/dotEnv';
import { env as _env, IWebpackEnv } from '../index'; import { env as _env, IWebpackEnv } from '../index';
import { getValue } from '../helpers/config'; import { getValue } from '../helpers/config';
@@ -545,7 +541,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
config config
.plugin('ContextExclusionPlugin|Other_Platforms') .plugin('ContextExclusionPlugin|Other_Platforms')
.use(ContextExclusionPlugin, [ .use(ContextExclusionPlugin, [
new RegExp(`\\.(${otherPlatformsRE})\\.(\\w+)$`), new RegExp(`\.(${otherPlatformsRE})\.(\w+)$`),
]); ]);
// Filter common undesirable warnings // Filter common undesirable warnings
@@ -565,7 +561,9 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
); );
// todo: refine defaults // todo: refine defaults
config.plugin('DefinePlugin').use(DefinePlugin, [ config.plugin('DefinePlugin').use(
CompatDefinePlugin as any,
[
{ {
__DEV__: mode === 'development', __DEV__: mode === 'development',
__NS_WEBPACK__: true, __NS_WEBPACK__: true,
@@ -585,11 +583,9 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
platform === 'ios' || platform === 'visionos', platform === 'ios' || platform === 'visionos',
/* for compat only */ 'global.isVisionOS': platform === 'visionos', /* for compat only */ 'global.isVisionOS': platform === 'visionos',
process: 'global.process', process: 'global.process',
// todo: ?!?!
// profile: '() => {}',
}, },
]); ] as any,
);
// enable DotEnv // enable DotEnv
applyDotEnvPlugin(config); applyDotEnvPlugin(config);

View File

@@ -0,0 +1,14 @@
export class CompatDefinePlugin {
private readonly definitions: Record<string, any>;
constructor(definitions: Record<string, any>) {
this.definitions = definitions || {};
}
apply(compiler: any) {
// Use the same webpack instance as the compiler to avoid version mismatches
const wp = compiler?.webpack || require('webpack');
const DefinePlugin = wp.DefinePlugin || require('webpack').DefinePlugin;
new DefinePlugin(this.definitions).apply(compiler);
}
}

View File

@@ -37,7 +37,9 @@ export class PlatformSuffixPlugin {
// require.context // require.context
compiler.hooks.contextModuleFactory.tap(id, (cmf) => { compiler.hooks.contextModuleFactory.tap(id, (cmf) => {
// @ts-ignore // @ts-ignore
cmf.hooks.alternativeRequests.tap(id, (modules, options) => { const altHook = (cmf as any).hooks?.alternativeRequests;
if (altHook && typeof altHook.tap === 'function') {
altHook.tap(id, (modules: any[], options: any) => {
const additionalModules = []; const additionalModules = [];
// we are looking for modules that are platform specific (something.<platform>.ext) // we are looking for modules that are platform specific (something.<platform>.ext)
// and we are duplicating them without the platform suffix // and we are duplicating them without the platform suffix
@@ -53,6 +55,10 @@ export class PlatformSuffixPlugin {
} }
modules.push(...additionalModules); modules.push(...additionalModules);
}); });
} else {
// Hook may be absent on some webpack versions; skip gracefully
// console.log(`[${id}] alternativeRequests hook not available; skipping.`)
}
}); });
compiler.resolverFactory.hooks.resolver compiler.resolverFactory.hooks.resolver
@@ -73,9 +79,22 @@ export class PlatformSuffixPlugin {
// }); // });
// }) // })
resolver.hooks.normalResolve.tapAsync( const normalResolveHook = (resolver as any).hooks?.normalResolve;
id, const ensureHook = (name: string) => {
(request_, resolveContext, callback) => { return typeof (resolver as any).ensureHook === 'function'
? (resolver as any).ensureHook(name)
: (resolver as any).hooks?.[name];
};
if (
!normalResolveHook ||
typeof normalResolveHook.tapAsync !== 'function'
) {
// Missing or incompatible hook; skip to avoid crashes
return;
}
normalResolveHook.tapAsync(id, (request_, resolveContext, callback) => {
for (const platform of this.extensions) { for (const platform of this.extensions) {
const { path, request } = request_; const { path, request } = request_;
const ext = request && extname(request); const ext = request && extname(request);
@@ -96,8 +115,7 @@ export class PlatformSuffixPlugin {
// we want to resolve that file instead // we want to resolve that file instead
if (existsSync(extPath)) { if (existsSync(extPath)) {
const message = `resolving "${request}" to "${platformRequest}"`; const message = `resolving "${request}" to "${platformRequest}"`;
const hook = resolver.ensureHook('normalResolve'); const hook = ensureHook('normalResolve');
console.log(message);
// here we are creating a new resolve object and replacing the path // here we are creating a new resolve object and replacing the path
// with the .<platform>.<ext> suffix // with the .<platform>.<ext> suffix
@@ -111,19 +129,18 @@ export class PlatformSuffixPlugin {
}; };
// we call to the actual resolver to do the resolving of this new file // we call to the actual resolver to do the resolving of this new file
return resolver.doResolve( return (resolver as any).doResolve(
hook, hook as any,
obj, obj,
message, message,
resolveContext, resolveContext,
callback callback,
); );
} }
} }
} }
callback(); callback();
} });
);
// resolver.hooks.rawFile.tap(id, (request, resolveContext, callback) => { // resolver.hooks.rawFile.tap(id, (request, resolveContext, callback) => {
// if(request.path && !/\.ios\..+$/.test(request.path)) { // if(request.path && !/\.ios\..+$/.test(request.path)) {
// const { ext } = parse(request.path) // const { ext } = parse(request.path)