Skip to content

Commit f6ff58c

Browse files
committed
fix import/export path fix
1 parent 72e8307 commit f6ff58c

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

packages/nextjs/src/config/loaders/rollup.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import sucrase from '@rollup/plugin-sucrase';
22
import virtual from '@rollup/plugin-virtual';
3+
import { escapeStringForRegex } from '@sentry/utils';
34
import * as path from 'path';
45
import type { InputOptions as RollupInputOptions, OutputOptions as RollupOutputOptions } from 'rollup';
56
import { rollup } from 'rollup';
@@ -76,18 +77,24 @@ export async function rollupize(templateCode: string, userModulePath: string): P
7677
// The module at index 0 is always the entrypoint, which in this case is the proxy module.
7778
let { code } = finalBundle.output[0];
7879

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>'`.
8082
//
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)}`);
9198

9299
return code;
93100
}

0 commit comments

Comments
 (0)