Skip to content

Commit e2aac62

Browse files
authored
Merge pull request #29027 from storybookjs/yann/require-wrapper-in-sb-add
CLI: Handle Yarn PnP wrapper scenario when adding an addon
2 parents f3a34cb + 57af7c0 commit e2aac62

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

code/lib/cli-storybook/src/add.test.ts

+42-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
import { describe, expect, test, vi } from 'vitest';
1+
import { beforeEach, describe, expect, test, vi } from 'vitest';
22

33
import { add, getVersionSpecifier } from './add';
44

55
const MockedConfig = vi.hoisted(() => {
66
return {
77
appendValueToArray: vi.fn(),
8+
getFieldNode: vi.fn(),
9+
valueToNode: vi.fn(),
10+
appendNodeToArray: vi.fn(),
811
};
912
});
1013
const MockedPackageManager = vi.hoisted(() => {
@@ -20,6 +23,12 @@ const MockedPostInstall = vi.hoisted(() => {
2023
postinstallAddon: vi.fn(),
2124
};
2225
});
26+
const MockWrapRequireUtils = vi.hoisted(() => {
27+
return {
28+
getRequireWrapperName: vi.fn(),
29+
wrapValueWithRequireWrapper: vi.fn(),
30+
};
31+
});
2332
const MockedConsole = {
2433
log: vi.fn(),
2534
warn: vi.fn(),
@@ -35,6 +44,9 @@ vi.mock('storybook/internal/csf-tools', () => {
3544
vi.mock('./postinstallAddon', () => {
3645
return MockedPostInstall;
3746
});
47+
vi.mock('./automigrate/fixes/wrap-require-utils', () => {
48+
return MockWrapRequireUtils;
49+
});
3850
vi.mock('storybook/internal/common', () => {
3951
return {
4052
getStorybookInfo: vi.fn(() => ({ mainConfig: {}, configDir: '' })),
@@ -103,6 +115,35 @@ describe('add', () => {
103115
});
104116

105117
describe('add (extra)', () => {
118+
beforeEach(() => {
119+
vi.clearAllMocks();
120+
});
121+
test('should not add a "wrap require" to the addon when not needed', async () => {
122+
MockedConfig.getFieldNode.mockReturnValue({});
123+
MockWrapRequireUtils.getRequireWrapperName.mockReturnValue(null);
124+
await add(
125+
'@storybook/addon-docs',
126+
{ packageManager: 'npm', skipPostinstall: true },
127+
MockedConsole
128+
);
129+
130+
expect(MockWrapRequireUtils.wrapValueWithRequireWrapper).not.toHaveBeenCalled();
131+
expect(MockedConfig.appendValueToArray).toHaveBeenCalled();
132+
expect(MockedConfig.appendNodeToArray).not.toHaveBeenCalled();
133+
});
134+
test('should add a "wrap require" to the addon when applicable', async () => {
135+
MockedConfig.getFieldNode.mockReturnValue({});
136+
MockWrapRequireUtils.getRequireWrapperName.mockReturnValue('require');
137+
await add(
138+
'@storybook/addon-docs',
139+
{ packageManager: 'npm', skipPostinstall: true },
140+
MockedConsole
141+
);
142+
143+
expect(MockWrapRequireUtils.wrapValueWithRequireWrapper).toHaveBeenCalled();
144+
expect(MockedConfig.appendValueToArray).not.toHaveBeenCalled();
145+
expect(MockedConfig.appendNodeToArray).toHaveBeenCalled();
146+
});
106147
test('not warning when installing the correct version of storybook', async () => {
107148
await add(
108149
'@storybook/addon-docs',

code/lib/cli-storybook/src/add.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ import { readConfig, writeConfig } from 'storybook/internal/csf-tools';
1313
import SemVer from 'semver';
1414
import { dedent } from 'ts-dedent';
1515

16+
import {
17+
getRequireWrapperName,
18+
wrapValueWithRequireWrapper,
19+
} from './automigrate/fixes/wrap-require-utils';
1620
import { postinstallAddon } from './postinstallAddon';
1721

1822
export interface PostinstallOptions {
@@ -136,7 +140,16 @@ export async function add(
136140
await packageManager.addDependencies({ installAsDevDependencies: true }, [addonWithVersion]);
137141

138142
logger.log(`Adding '${addon}' to main.js addons field.`);
139-
main.appendValueToArray(['addons'], addonName);
143+
144+
const mainConfigAddons = main.getFieldNode(['addons']);
145+
if (mainConfigAddons && getRequireWrapperName(main) !== null) {
146+
const addonNode = main.valueToNode(addonName);
147+
main.appendNodeToArray(['addons'], addonNode as any);
148+
wrapValueWithRequireWrapper(main, addonNode as any);
149+
} else {
150+
main.appendValueToArray(['addons'], addonName);
151+
}
152+
140153
await writeConfig(main);
141154

142155
if (!skipPostinstall && isCoreAddon(addonName)) {

0 commit comments

Comments
 (0)