|
1 | 1 | import sucrase from '@rollup/plugin-sucrase';
|
2 | 2 | import virtual from '@rollup/plugin-virtual';
|
| 3 | +import { escapeStringForRegex } from '@sentry/utils'; |
3 | 4 | import * as path from 'path';
|
4 | 5 | import type { InputOptions as RollupInputOptions, OutputOptions as RollupOutputOptions } from 'rollup';
|
5 | 6 | import { rollup } from 'rollup';
|
@@ -76,18 +77,24 @@ export async function rollupize(templateCode: string, userModulePath: string): P
|
76 | 77 | // The module at index 0 is always the entrypoint, which in this case is the proxy module.
|
77 | 78 | let { code } = finalBundle.output[0];
|
78 | 79 |
|
79 |
| - // Rollup does a few things to the code we *don't* want. Undo those changes before returning the code. |
| 80 | + // In addition to doing the desired work, Rollup also does a few things we *don't* want. Specifically, in messes up |
| 81 | + // the path in both `import * as origModule from '<userModulePath>'` and `export * from '<userModulePath>'`. |
80 | 82 | //
|
81 |
| - // Nextjs uses square brackets surrounding a path segment to denote a parameter in the route, but Rollup turns those |
82 |
| - // square brackets into underscores. Further, Rollup adds file extensions to bare-path-type import and export sources. |
83 |
| - // Because it assumes that everything will have already been processed, it always uses `.js` as the added extension. |
84 |
| - // We need to restore the original name and extension so that Webpack will be able to find the wrapped file. |
85 |
| - const userModuleFilename = path.basename(userModulePath); |
86 |
| - const mutatedUserModuleFilename = userModuleFilename |
87 |
| - // `[\\[\\]]` is the character class containing `[` and `]` |
88 |
| - .replace(new RegExp('[\\[\\]]', 'g'), '_') |
89 |
| - .replace(/(jsx?|tsx?)$/, 'js'); |
90 |
| - code = code.replace(new RegExp(mutatedUserModuleFilename, 'g'), userModuleFilename); |
| 83 | + // - It turns the square brackets surrounding each parameterized path segment into underscores. |
| 84 | + // - It always adds `.js` to the end of the filename. |
| 85 | + // - It converts the path from aboslute to relative, which would be fine except that when used with the virual plugin, |
| 86 | + // it uses an incorrect (and not entirely predicable) base for that relative path. |
| 87 | + // |
| 88 | + // To fix this, we overwrite the messed up path with what we know it should be: `./<userModulePathBasename>`. (We can |
| 89 | + // find the value of the messed up path by looking at what `import * as origModule from '<userModulePath>'` becomes. |
| 90 | + // Because it's the first line of the template, it's also the first line of the result, and is therefore easy to |
| 91 | + // find.) |
| 92 | + |
| 93 | + const importStarStatement = code.split('\n')[0]; |
| 94 | + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
| 95 | + const messedUpPath = /^import \* as .* from '(.*)';$/.exec(importStarStatement)![1]; |
| 96 | + |
| 97 | + code = code.replace(new RegExp(escapeStringForRegex(messedUpPath), 'g'), `./${path.basename(userModulePath)}`); |
91 | 98 |
|
92 | 99 | return code;
|
93 | 100 | }
|
0 commit comments