From 781e177a06a80af471632f057f1f1bb4d212780c Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Tue, 12 May 2026 20:24:34 +0300 Subject: [PATCH] add cjs support to webpack --- webpack.config.js | 65 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/webpack.config.js b/webpack.config.js index 15667f3960..371421474f 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -18,6 +18,55 @@ const reactNativeWebWebviewConfiguration = { }, } +// Walk a rule tree and wrap source-map-loader's filterSourceMappingUrl to +// drop sourcemap references matching the given path pattern. Mutates in place. +function patchSourceMapFilter(rules, pathPattern) { + if (!rules) return + for (const rule of rules) { + if (!rule || typeof rule !== 'object') continue + if (rule.oneOf) patchSourceMapFilter(rule.oneOf, pathPattern) + if (rule.rules) patchSourceMapFilter(rule.rules, pathPattern) + const uses = Array.isArray(rule.use) ? rule.use : rule.use ? [rule.use] : [] + for (const use of uses) { + if (!use?.loader?.includes('source-map-loader')) continue + const prev = use.options?.filterSourceMappingUrl + use.options = { + ...use.options, + filterSourceMappingUrl(url, resourcePath) { + if (pathPattern.test(resourcePath)) return 'remove' + return prev ? prev(url, resourcePath) : true + }, + } + } + } +} + +// Walk a rule tree and add `.cjs` support everywhere the config assumes only +// `.js|.mjs|.jsx|.ts|.tsx`. Mutates in place. +function patchCjsSupport(rules) { + if (!rules) return + const addCjs = pattern => { + if (!(pattern instanceof RegExp)) return pattern + if (pattern.source.includes('cjs')) return pattern + return new RegExp( + pattern.source.replace(/\|tsx\)/g, '|tsx|cjs)'), + pattern.flags, + ) + } + const patch = value => { + if (value instanceof RegExp) return addCjs(value) + if (Array.isArray(value)) return value.map(patch) + return value + } + for (const rule of rules) { + if (!rule || typeof rule !== 'object') continue + if (rule.oneOf) patchCjsSupport(rule.oneOf) + if (rule.rules) patchCjsSupport(rule.rules) + if (rule.test !== undefined) rule.test = patch(rule.test) + if (rule.exclude !== undefined) rule.exclude = patch(rule.exclude) + } +} + module.exports = async function (env, argv) { env.babel = { dangerouslyAddModulePathsToTranspile: ['@bsky.app/expo'], @@ -26,16 +75,18 @@ module.exports = async function (env, argv) { config = withAlias(config, { 'react-native$': 'react-native-web', 'react-native-webview': 'react-native-web-webview', - // Force ESM version - 'unicode-segmenter/grapheme': require - .resolve('unicode-segmenter/grapheme') - .replace(/\.cjs$/, '.js'), - // Force ESM version - zod's main/exports.require point to index.cjs which - // Expo's webpack config treats as a static asset, breaking `require('zod')` - zod$: require.resolve('zod').replace(/\.cjs$/, '.js'), 'react-native-gesture-handler': false, // RNGH should not be used on web, so let's cause a build error if it sneaks in '@sentry-internal/replay': false, // not used, ~300kb of dead weight }) + // TEMP HACK: hopefully won't be an issue when we switch to metro + // @expo/webpack-config's babel-loader and source-map-loader tests do not + // include .cjs, and its fallback "asset/resource" loader doesn't exclude + // .cjs — so any dependency whose `require` entrypoint is a .cjs file + // (e.g. zod 3.24+, unicode-segmenter) gets served as a static asset URL + // instead of a module. Patch the tests to cover .cjs. + patchCjsSupport(config.module.rules) + // react-native-uuid ships sourceMappingURL comments but no .map files. + patchSourceMapFilter(config.module.rules, /react-native-uuid/) config.module.rules = [ ...(config.module.rules || []), reactNativeWebWebviewConfiguration,