Skip to content

Commit 5d4791c

Browse files
authored
Merge pull request #28984 from storybookjs/valentin/fix-missing-source-map-warning-second-attempt
Vite: Fix missing source map warning
2 parents dbf8ea1 + 06b3056 commit 5d4791c

File tree

7 files changed

+100
-55
lines changed

7 files changed

+100
-55
lines changed

code/builders/builder-vite/src/codegen-modern-iframe-script.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { getFrameworkName, loadPreviewOrConfigFile } from 'storybook/internal/co
22
import type { Options, PreviewAnnotation } from 'storybook/internal/types';
33

44
import { processPreviewAnnotation } from './utils/process-preview-annotation';
5-
import { virtualAddonSetupFile, virtualStoriesFile } from './virtual-file-names';
5+
import { SB_VIRTUAL_FILES, getResolvedVirtualModuleId } from './virtual-file-names';
66

77
export async function generateModernIframeScriptCode(options: Options, projectRoot: string) {
88
const { presets, configDir } = options;
@@ -45,7 +45,7 @@ export async function generateModernIframeScriptCode(options: Options, projectRo
4545

4646
return `
4747
if (import.meta.hot) {
48-
import.meta.hot.accept('${virtualStoriesFile}', (newModule) => {
48+
import.meta.hot.accept('${getResolvedVirtualModuleId(SB_VIRTUAL_FILES.VIRTUAL_STORIES_FILE)}', (newModule) => {
4949
// importFn has changed so we need to patch the new one in
5050
window.__STORYBOOK_PREVIEW__.onStoriesChanged({ importFn: newModule.importFn });
5151
});
@@ -68,8 +68,8 @@ export async function generateModernIframeScriptCode(options: Options, projectRo
6868
*/
6969
const code = `
7070
import { composeConfigs, PreviewWeb, ClientApi } from 'storybook/internal/preview-api';
71-
import '${virtualAddonSetupFile}';
72-
import { importFn } from '${virtualStoriesFile}';
71+
import '${SB_VIRTUAL_FILES.VIRTUAL_ADDON_SETUP_FILE}';
72+
import { importFn } from '${SB_VIRTUAL_FILES.VIRTUAL_STORIES_FILE}';
7373
7474
${getPreviewAnnotationsFunction}
7575

code/builders/builder-vite/src/plugins/code-generator-plugin.ts

+19-20
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@ import { generateImportFnScriptCode } from '../codegen-importfn-script';
88
import { generateModernIframeScriptCode } from '../codegen-modern-iframe-script';
99
import { generateAddonSetupCode } from '../codegen-set-addon-channel';
1010
import { transformIframeHtml } from '../transform-iframe-html';
11-
import {
12-
virtualAddonSetupFile,
13-
virtualFileId,
14-
virtualPreviewFile,
15-
virtualStoriesFile,
16-
} from '../virtual-file-names';
11+
import { SB_VIRTUAL_FILES, getResolvedVirtualModuleId } from '../virtual-file-names';
1712

1813
export function codeGeneratorPlugin(options: Options): Plugin {
1914
const iframePath = require.resolve('@storybook/builder-vite/input/iframe.html');
@@ -28,11 +23,15 @@ export function codeGeneratorPlugin(options: Options): Plugin {
2823
// invalidate the whole vite-app.js script on every file change.
2924
// (this might be a little too aggressive?)
3025
server.watcher.on('change', () => {
31-
const appModule = server.moduleGraph.getModuleById(virtualFileId);
26+
const appModule = server.moduleGraph.getModuleById(
27+
getResolvedVirtualModuleId(SB_VIRTUAL_FILES.VIRTUAL_APP_FILE)
28+
);
3229
if (appModule) {
3330
server.moduleGraph.invalidateModule(appModule);
3431
}
35-
const storiesModule = server.moduleGraph.getModuleById(virtualStoriesFile);
32+
const storiesModule = server.moduleGraph.getModuleById(
33+
getResolvedVirtualModuleId(SB_VIRTUAL_FILES.VIRTUAL_STORIES_FILE)
34+
);
3635
if (storiesModule) {
3736
server.moduleGraph.invalidateModule(storiesModule);
3837
}
@@ -45,7 +44,7 @@ export function codeGeneratorPlugin(options: Options): Plugin {
4544
// TODO maybe use the stories declaration in main
4645
if (/\.stories\.([tj])sx?$/.test(path) || /\.mdx$/.test(path)) {
4746
// We need to emit a change event to trigger HMR
48-
server.watcher.emit('change', virtualStoriesFile);
47+
server.watcher.emit('change', SB_VIRTUAL_FILES.VIRTUAL_STORIES_FILE);
4948
}
5049
});
5150
},
@@ -69,34 +68,34 @@ export function codeGeneratorPlugin(options: Options): Plugin {
6968
iframeId = `${config.root}/iframe.html`;
7069
},
7170
resolveId(source) {
72-
if (source === virtualFileId) {
73-
return `${virtualFileId}`;
71+
if (source === SB_VIRTUAL_FILES.VIRTUAL_APP_FILE) {
72+
return getResolvedVirtualModuleId(SB_VIRTUAL_FILES.VIRTUAL_APP_FILE);
7473
}
7574
if (source === iframePath) {
7675
return iframeId;
7776
}
78-
if (source === virtualStoriesFile) {
79-
return `${virtualStoriesFile}`;
77+
if (source === SB_VIRTUAL_FILES.VIRTUAL_STORIES_FILE) {
78+
return getResolvedVirtualModuleId(SB_VIRTUAL_FILES.VIRTUAL_STORIES_FILE);
8079
}
81-
if (source === virtualPreviewFile) {
82-
return virtualPreviewFile;
80+
if (source === SB_VIRTUAL_FILES.VIRTUAL_PREVIEW_FILE) {
81+
return getResolvedVirtualModuleId(SB_VIRTUAL_FILES.VIRTUAL_PREVIEW_FILE);
8382
}
84-
if (source === virtualAddonSetupFile) {
85-
return `${virtualAddonSetupFile}`;
83+
if (source === SB_VIRTUAL_FILES.VIRTUAL_ADDON_SETUP_FILE) {
84+
return getResolvedVirtualModuleId(SB_VIRTUAL_FILES.VIRTUAL_ADDON_SETUP_FILE);
8685
}
8786

8887
return undefined;
8988
},
9089
async load(id, config) {
91-
if (id === `${virtualStoriesFile}`) {
90+
if (id === getResolvedVirtualModuleId(SB_VIRTUAL_FILES.VIRTUAL_STORIES_FILE)) {
9291
return generateImportFnScriptCode(options);
9392
}
9493

95-
if (id === `${virtualAddonSetupFile}`) {
94+
if (id === getResolvedVirtualModuleId(SB_VIRTUAL_FILES.VIRTUAL_ADDON_SETUP_FILE)) {
9695
return generateAddonSetupCode();
9796
}
9897

99-
if (id === `${virtualFileId}`) {
98+
if (id === getResolvedVirtualModuleId(SB_VIRTUAL_FILES.VIRTUAL_APP_FILE)) {
10099
return generateModernIframeScriptCode(options, projectRoot);
101100
}
102101

code/builders/builder-vite/src/plugins/external-globals-plugin.test.ts

+16
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@ const cases = [
1212
input: `import { Rain, Jour as Day, Nuit as Night, Sun } from "${packageName}"`,
1313
output: `const { Rain, Jour: Day, Nuit: Night, Sun } = ${globals[packageName]}`,
1414
},
15+
{
16+
globals,
17+
packageName,
18+
input: `import {
19+
Rain,
20+
Jour as Day,
21+
Nuit as Night,
22+
Sun
23+
} from "${packageName}"`,
24+
output: `const {
25+
Rain,
26+
Jour: Day,
27+
Nuit: Night,
28+
Sun
29+
} = ${globals[packageName]}`,
30+
},
1531
{
1632
globals,
1733
packageName,

code/builders/builder-vite/src/plugins/external-globals-plugin.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,7 @@ export async function externalGlobalsPlugin(externals: Record<string, string>) {
9191

9292
return {
9393
code: src.toString(),
94-
map: src.generateMap({
95-
source: id,
96-
hires: true,
97-
}),
94+
map: null,
9895
};
9996
},
10097
} satisfies Plugin;

code/builders/builder-vite/src/plugins/webpack-stats-plugin.ts

+45-22
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ import type { BuilderStats } from 'storybook/internal/types';
66
import slash from 'slash';
77
import type { Plugin } from 'vite';
88

9+
import {
10+
SB_VIRTUAL_FILES,
11+
getOriginalVirtualModuleId,
12+
getResolvedVirtualModuleId,
13+
} from '../virtual-file-names';
14+
915
/*
1016
* Reason, Module are copied from chromatic types
1117
* https://github.com/chromaui/chromatic-cli/blob/145a5e295dde21042e96396c7e004f250d842182/bin-src/types.ts#L265-L276
@@ -34,11 +40,18 @@ function stripQueryParams(filePath: string): string {
3440

3541
/** We only care about user code, not node_modules, vite files, or (most) virtual files. */
3642
function isUserCode(moduleName: string) {
43+
if (!moduleName) {
44+
return false;
45+
}
46+
47+
// keep Storybook's virtual files because they import the story files, so they are essential to the module graph
48+
if (Object.values(SB_VIRTUAL_FILES).includes(getOriginalVirtualModuleId(moduleName))) {
49+
return true;
50+
}
51+
3752
return Boolean(
38-
moduleName &&
39-
!moduleName.startsWith('vite/') &&
40-
!moduleName.startsWith('\x00') &&
41-
!moduleName.startsWith('\u0000') &&
53+
!moduleName.startsWith('vite/') &&
54+
!moduleName.startsWith('\0') &&
4255
moduleName !== 'react/jsx-runtime' &&
4356
!moduleName.match(/node_modules\//)
4457
);
@@ -53,6 +66,14 @@ export function pluginWebpackStats({ workingDir }: WebpackStatsPluginOptions): W
5366
if (filename.startsWith('/virtual:')) {
5467
return filename;
5568
}
69+
// ! Maintain backwards compatibility with the old virtual file names
70+
// ! to ensure that the stats file doesn't change between the versions
71+
// ! Turbosnap is also only compatible with the old virtual file names
72+
// ! the old virtual file names did not start with the obligatory \0 character
73+
if (Object.values(SB_VIRTUAL_FILES).includes(getOriginalVirtualModuleId(filename))) {
74+
return getOriginalVirtualModuleId(filename);
75+
}
76+
5677
// Otherwise, we need them in the format `./path/to/file.js`.
5778
else {
5879
const relativePath = relative(workingDir, stripQueryParams(filename));
@@ -82,25 +103,27 @@ export function pluginWebpackStats({ workingDir }: WebpackStatsPluginOptions): W
82103
// We want this to run after the vite build plugins (https://vitejs.dev/guide/api-plugin.html#plugin-ordering)
83104
enforce: 'post',
84105
moduleParsed: function (mod) {
85-
if (isUserCode(mod.id)) {
86-
mod.importedIds
87-
.concat(mod.dynamicallyImportedIds)
88-
.filter((name) => isUserCode(name))
89-
.forEach((depIdUnsafe) => {
90-
const depId = normalize(depIdUnsafe);
91-
if (statsMap.has(depId)) {
92-
const m = statsMap.get(depId);
93-
if (m) {
94-
m.reasons = (m.reasons ?? [])
95-
.concat(createReasons([mod.id]))
96-
.filter((r) => r.moduleName !== depId);
97-
statsMap.set(depId, m);
98-
}
99-
} else {
100-
statsMap.set(depId, createStatsMapModule(depId, [mod.id]));
101-
}
102-
});
106+
if (!isUserCode(mod.id)) {
107+
return;
103108
}
109+
mod.importedIds
110+
.concat(mod.dynamicallyImportedIds)
111+
.filter((name) => isUserCode(name))
112+
.forEach((depIdUnsafe) => {
113+
const depId = normalize(depIdUnsafe);
114+
if (!statsMap.has(depId)) {
115+
statsMap.set(depId, createStatsMapModule(depId, [mod.id]));
116+
return;
117+
}
118+
const m = statsMap.get(depId);
119+
if (!m) {
120+
return;
121+
}
122+
m.reasons = (m.reasons ?? [])
123+
.concat(createReasons([mod.id]))
124+
.filter((r) => r.moduleName !== depId);
125+
statsMap.set(depId, m);
126+
});
104127
},
105128

106129
storybookGetStats() {
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
export const virtualFileId = '/virtual:/@storybook/builder-vite/vite-app.js';
2-
export const virtualStoriesFile = '/virtual:/@storybook/builder-vite/storybook-stories.js';
3-
export const virtualPreviewFile = '/virtual:/@storybook/builder-vite/preview-entry.js';
4-
export const virtualAddonSetupFile = '/virtual:/@storybook/builder-vite/setup-addons.js';
1+
export const SB_VIRTUAL_FILES = {
2+
VIRTUAL_APP_FILE: '/virtual:/@storybook/builder-vite/vite-app.js',
3+
VIRTUAL_STORIES_FILE: '/virtual:/@storybook/builder-vite/storybook-stories.js',
4+
VIRTUAL_PREVIEW_FILE: '/virtual:/@storybook/builder-vite/preview-entry.js',
5+
VIRTUAL_ADDON_SETUP_FILE: '/virtual:/@storybook/builder-vite/setup-addons.js',
6+
};
7+
8+
export function getResolvedVirtualModuleId(virtualModuleId: string) {
9+
return `\0${virtualModuleId}`;
10+
}
11+
12+
export function getOriginalVirtualModuleId(resolvedVirtualModuleId: string) {
13+
return resolvedVirtualModuleId.slice(1);
14+
}

code/frameworks/vue3-vite/src/plugins/vue-component-meta.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export async function vueComponentMeta(tsconfigPath = 'tsconfig.json'): Promise<
2626

2727
// exclude stories, virtual modules and storybook internals
2828
const exclude =
29-
/\.stories\.(ts|tsx|js|jsx)$|^\/virtual:|^\/sb-preview\/|\.storybook\/.*\.(ts|js)$/;
29+
/\.stories\.(ts|tsx|js|jsx)$|^\0\/virtual:|^\/virtual:|^\/sb-preview\/|\.storybook\/.*\.(ts|js)$/;
3030
const include = /\.(vue|ts|js|tsx|jsx)$/;
3131
const filter = createFilter(include, exclude);
3232

0 commit comments

Comments
 (0)