Skip to content

Commit fa26d4d

Browse files
ndelangenstorybook-bot
authored andcommitted
Merge pull request #32893 from storybookjs/yann/fix-preset-path-joining-windows
Core: Improve file path resolution on Windows (cherry picked from commit dd000a8)
1 parent 91b06a6 commit fa26d4d

File tree

6 files changed

+34
-25
lines changed

6 files changed

+34
-25
lines changed

code/builders/builder-webpack5/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { cp } from 'node:fs/promises';
2-
import { dirname, join, parse } from 'node:path';
32
import { fileURLToPath } from 'node:url';
43

54
import { PREVIEW_BUILDER_PROGRESS } from 'storybook/internal/core-events';
@@ -13,6 +12,7 @@ import type { Builder, Options } from 'storybook/internal/types';
1312

1413
import { checkWebpackVersion } from '@storybook/core-webpack';
1514

15+
import { dirname, join, parse } from 'pathe';
1616
import prettyTime from 'pretty-hrtime';
1717
import sirv from 'sirv';
1818
import type { Configuration, Stats, StatsOptions } from 'webpack';

code/core/src/core-server/build-dev.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { readFile } from 'node:fs/promises';
2-
import { join, relative, resolve } from 'node:path';
32

43
import {
54
JsPackageManagerFactory,
@@ -20,6 +19,7 @@ import type { BuilderOptions, CLIOptions, LoadOptions, Options } from 'storybook
2019

2120
import { global } from '@storybook/global';
2221

22+
import { join, relative, resolve } from 'pathe';
2323
import prompts from 'prompts';
2424
import invariant from 'tiny-invariant';
2525
import { dedent } from 'ts-dedent';

code/core/src/core-server/build-static.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { cp, mkdir } from 'node:fs/promises';
22
import { rm } from 'node:fs/promises';
3-
import { join, relative, resolve } from 'node:path';
43

54
import {
65
loadAllPresets,
@@ -15,6 +14,7 @@ import type { BuilderOptions, CLIOptions, LoadOptions, Options } from 'storybook
1514

1615
import { global } from '@storybook/global';
1716

17+
import { join, relative, resolve } from 'pathe';
1818
import picocolors from 'picocolors';
1919

2020
import { resolvePackageDir } from '../shared/utils/module';

code/core/src/core-server/load.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { join, relative, resolve } from 'node:path';
2-
31
import {
42
getProjectRoot,
53
loadAllPresets,
@@ -12,6 +10,8 @@ import type { BuilderOptions, CLIOptions, LoadOptions, Options } from 'storybook
1210

1311
import { global } from '@storybook/global';
1412

13+
import { join, relative, resolve } from 'pathe';
14+
1515
import { resolvePackageDir } from '../shared/utils/module';
1616

1717
export async function loadStorybook(

code/core/src/core-server/presets/common-preset.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { existsSync } from 'node:fs';
22
import { readFile } from 'node:fs/promises';
3-
import { isAbsolute, join } from 'node:path';
43
import { fileURLToPath } from 'node:url';
54

65
import type { Channel } from 'storybook/internal/channels';
@@ -26,6 +25,7 @@ import type {
2625
PresetPropertyFn,
2726
} from 'storybook/internal/types';
2827

28+
import { isAbsolute, join } from 'pathe';
2929
import * as pathe from 'pathe';
3030
import { dedent } from 'ts-dedent';
3131

code/core/src/core-server/presets/favicon.test.ts

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import * as fs from 'node:fs';
2-
import { dirname, join } from 'node:path';
32

43
import { expect, it, vi } from 'vitest';
54

65
import { logger } from 'storybook/internal/node-logger';
76

7+
import { dirname, join, normalize } from 'pathe';
8+
89
import * as m from './common-preset';
910

1011
// mock src/core-server/utils/constants.ts:8:27
@@ -75,67 +76,73 @@ it('with no staticDirs favicon should return default', async () => {
7576
it('with staticDirs referencing a favicon.ico directly should return the found favicon', async () => {
7677
const location = 'favicon.ico';
7778
existsSyncMock.mockImplementation((p) => {
78-
return p === createPath(location);
79+
return normalize(String(p)) === normalize(createPath(location));
7980
});
8081
statSyncMock.mockImplementation((p) => {
8182
return {
82-
isFile: () => p === createPath('favicon.ico'),
83+
isFile: () => normalize(String(p)) === normalize(createPath('favicon.ico')),
8384
} as any;
8485
});
8586
const options = createOptions([location]);
8687

87-
expect(await m.favicon(undefined, options)).toBe(createPath('favicon.ico'));
88+
expect(normalize(await m.favicon(undefined, options))).toBe(normalize(createPath('favicon.ico')));
8889
});
8990

9091
it('with staticDirs containing a single favicon.ico should return the found favicon', async () => {
9192
const location = 'static';
9293
existsSyncMock.mockImplementation((p) => {
93-
if (p === createPath(location)) {
94+
if (normalize(String(p)) === normalize(createPath(location))) {
9495
return true;
9596
}
96-
if (p === createPath(location, 'favicon.ico')) {
97+
if (normalize(String(p)) === normalize(createPath(location, 'favicon.ico'))) {
9798
return true;
9899
}
99100
return false;
100101
});
101102
const options = createOptions([location]);
102103

103-
expect(await m.favicon(undefined, options)).toBe(createPath(location, 'favicon.ico'));
104+
expect(normalize(await m.favicon(undefined, options))).toBe(
105+
normalize(createPath(location, 'favicon.ico'))
106+
);
104107
});
105108

106109
it('with staticDirs containing a single favicon.svg should return the found favicon', async () => {
107110
const location = 'static';
108111
existsSyncMock.mockImplementation((p) => {
109-
if (p === createPath(location)) {
112+
if (normalize(String(p)) === normalize(createPath(location))) {
110113
return true;
111114
}
112-
if (p === createPath(location, 'favicon.svg')) {
115+
if (normalize(String(p)) === normalize(createPath(location, 'favicon.svg'))) {
113116
return true;
114117
}
115118
return false;
116119
});
117120
const options = createOptions([location]);
118121

119-
expect(await m.favicon(undefined, options)).toBe(createPath(location, 'favicon.svg'));
122+
expect(normalize(await m.favicon(undefined, options))).toBe(
123+
normalize(createPath(location, 'favicon.svg'))
124+
);
120125
});
121126

122127
it('with staticDirs containing a multiple favicons should return the first favicon and warn', async () => {
123128
const location = 'static';
124129
existsSyncMock.mockImplementation((p) => {
125-
if (p === createPath(location)) {
130+
if (normalize(String(p)) === normalize(createPath(location))) {
126131
return true;
127132
}
128-
if (p === createPath(location, 'favicon.ico')) {
133+
if (normalize(String(p)) === normalize(createPath(location, 'favicon.ico'))) {
129134
return true;
130135
}
131-
if (p === createPath(location, 'favicon.svg')) {
136+
if (normalize(String(p)) === normalize(createPath(location, 'favicon.svg'))) {
132137
return true;
133138
}
134139
return false;
135140
});
136141
const options = createOptions([location]);
137142

138-
expect(await m.favicon(undefined, options)).toBe(createPath(location, 'favicon.svg'));
143+
expect(normalize(await m.favicon(undefined, options))).toBe(
144+
normalize(createPath(location, 'favicon.svg'))
145+
);
139146

140147
expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('multiple favicons'));
141148
});
@@ -144,23 +151,25 @@ it('with multiple staticDirs containing a multiple favicons should return the fi
144151
const locationA = 'static-a';
145152
const locationB = 'static-b';
146153
existsSyncMock.mockImplementation((p) => {
147-
if (p === createPath(locationA)) {
154+
if (normalize(String(p)) === normalize(createPath(locationA))) {
148155
return true;
149156
}
150-
if (p === createPath(locationB)) {
157+
if (normalize(String(p)) === normalize(createPath(locationB))) {
151158
return true;
152159
}
153-
if (p === createPath(locationA, 'favicon.ico')) {
160+
if (normalize(String(p)) === normalize(createPath(locationA, 'favicon.ico'))) {
154161
return true;
155162
}
156-
if (p === createPath(locationB, 'favicon.svg')) {
163+
if (normalize(String(p)) === normalize(createPath(locationB, 'favicon.svg'))) {
157164
return true;
158165
}
159166
return false;
160167
});
161168
const options = createOptions([locationA, locationB]);
162169

163-
expect(await m.favicon(undefined, options)).toBe(createPath(locationA, 'favicon.ico'));
170+
expect(normalize(await m.favicon(undefined, options))).toBe(
171+
normalize(createPath(locationA, 'favicon.ico'))
172+
);
164173

165174
expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('multiple favicons'));
166175
});

0 commit comments

Comments
 (0)