|
1 | 1 | import MagicString from 'magic-string' |
2 | 2 | import type { Plugin } from 'vite' |
3 | 3 |
|
| 4 | +/** |
| 5 | + * Replace `__webpack_require__` references with safe alternatives. |
| 6 | + * |
| 7 | + * - `__webpack_require__.u` → `({}).u` (avoid import side-effect access) |
| 8 | + * - `__webpack_require__` → `__vite_rsc_require__` |
| 9 | + * |
| 10 | + * Returns `{ code, map }` with a proper sourcemap so the Rollup sourcemap |
| 11 | + * chain stays intact, or `undefined` if no replacements were made. |
| 12 | + */ |
| 13 | +export function patchWebpackRequire( |
| 14 | + code: string, |
| 15 | + id: string, |
| 16 | +): { code: string; map: ReturnType<MagicString['generateMap']> } | undefined { |
| 17 | + if (!code.includes('__webpack_require__')) return |
| 18 | + |
| 19 | + const s = new MagicString(code) |
| 20 | + |
| 21 | + // Match `__webpack_require__.u` first (longer pattern), then bare |
| 22 | + // `__webpack_require__`, in a single left-to-right pass to avoid |
| 23 | + // overlapping overwrites into MagicString. |
| 24 | + const re = /__webpack_require__(?:\.u)?/g |
| 25 | + let match: RegExpExecArray | null |
| 26 | + while ((match = re.exec(code)) !== null) { |
| 27 | + const { index } = match |
| 28 | + if (match[0] === '__webpack_require__.u') { |
| 29 | + // avoid accessing `__webpack_require__` on import side effect |
| 30 | + // https://github.com/facebook/react/blob/a9bbe34622885ef5667d33236d580fe7321c0d8b/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackBrowser.js#L16-L17 |
| 31 | + s.overwrite(index, index + match[0].length, '({}).u') |
| 32 | + } else { |
| 33 | + // the existance of `__webpack_require__` global can break some packages |
| 34 | + // https://github.com/TooTallNate/node-bindings/blob/c8033dcfc04c34397384e23f7399a30e6c13830d/bindings.js#L90-L94 |
| 35 | + s.overwrite(index, index + match[0].length, '__vite_rsc_require__') |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + if (s.hasChanged()) { |
| 40 | + return { |
| 41 | + code: s.toString(), |
| 42 | + map: s.generateMap({ hires: true, source: id }), |
| 43 | + } |
| 44 | + } |
| 45 | +} |
| 46 | + |
4 | 47 | export default function vitePluginRscCore(): Plugin[] { |
5 | 48 | return [ |
6 | 49 | { |
7 | 50 | name: 'rsc:patch-react-server-dom-webpack', |
8 | 51 | transform: { |
9 | 52 | filter: { code: '__webpack_require__' }, |
10 | 53 | handler(code, id, _options) { |
11 | | - if (!code.includes('__webpack_require__')) return |
12 | | - |
13 | | - // Use MagicString to perform replacements with a proper sourcemap, |
14 | | - // so the Rollup sourcemap chain stays intact and doesn't emit |
15 | | - // 'Can't resolve original location of error' warnings for every |
16 | | - // file processed by this transform (e.g. all "use client" modules). |
17 | | - const s = new MagicString(code) |
18 | | - |
19 | | - // Match `__webpack_require__.u` first (longer pattern), then bare |
20 | | - // `__webpack_require__`, in a single left-to-right pass to avoid |
21 | | - // overlapping overwrites into MagicString. |
22 | | - const re = /__webpack_require__(?:\.u)?/g |
23 | | - let match: RegExpExecArray | null |
24 | | - while ((match = re.exec(code)) !== null) { |
25 | | - const { index } = match |
26 | | - if (match[0] === '__webpack_require__.u') { |
27 | | - // avoid accessing `__webpack_require__` on import side effect |
28 | | - // https://github.com/facebook/react/blob/a9bbe34622885ef5667d33236d580fe7321c0d8b/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackBrowser.js#L16-L17 |
29 | | - s.overwrite(index, index + match[0].length, '({}).u') |
30 | | - } else { |
31 | | - // the existance of `__webpack_require__` global can break some packages |
32 | | - // https://github.com/TooTallNate/node-bindings/blob/c8033dcfc04c34397384e23f7399a30e6c13830d/bindings.js#L90-L94 |
33 | | - s.overwrite( |
34 | | - index, |
35 | | - index + match[0].length, |
36 | | - '__vite_rsc_require__', |
37 | | - ) |
38 | | - } |
39 | | - } |
40 | | - |
41 | | - if (s.hasChanged()) { |
42 | | - return { |
43 | | - code: s.toString(), |
44 | | - map: s.generateMap({ hires: true, source: id }), |
45 | | - } |
46 | | - } |
| 54 | + return patchWebpackRequire(code, id) |
47 | 55 | }, |
48 | 56 | }, |
49 | 57 | }, |
|
0 commit comments