Skip to content

Commit 62a884c

Browse files
fix(qwik-nx): storybook updates for qwikCity (#122)
1 parent 5764cae commit 62a884c

File tree

10 files changed

+177
-8
lines changed

10 files changed

+177
-8
lines changed

packages/qwik-nx/src/generators/storybook-configuration/__snapshots__/generator.spec.ts.snap

+68
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ Array [
2626
"path": "apps/test-project/.storybook/main.ts",
2727
"type": "CREATE",
2828
},
29+
Object {
30+
"path": "apps/test-project/.storybook/preview-head.html",
31+
"type": "CREATE",
32+
},
2933
Object {
3034
"path": "apps/test-project/.storybook/preview.ts",
3135
"type": "CREATE",
@@ -148,3 +152,67 @@ Array [
148152
},
149153
]
150154
`;
155+
156+
exports[`storybook-configuration generator should add required targets 2`] = `
157+
"import { mergeConfig, UserConfig } from 'vite';
158+
import { withNx } from 'qwik-nx/storybook';
159+
import viteConfig from './../vite.config';
160+
161+
const config = {
162+
stories: ['../**/*.stories.mdx', '../**/*.stories.@(js|jsx|ts|tsx)'],
163+
addons: ['@storybook/addon-essentials'],
164+
framework: { name: 'storybook-framework-qwik' },
165+
async viteFinal(config: UserConfig) {
166+
const updatedConfig = mergeConfig(config, viteConfig);
167+
return withNx(updatedConfig);
168+
},
169+
};
170+
171+
export default config;
172+
"
173+
`;
174+
175+
exports[`storybook-configuration generator should add required targets 3`] = `
176+
"import { qwikCityDecorator } from 'storybook-framework-qwik/qwik-city-decorator';
177+
export const decorators = [qwikCityDecorator];
178+
"
179+
`;
180+
181+
exports[`storybook-configuration generator should conditionally add qwikCity decorator to preview.ts matches the snapshot when qwikCitySupport is "auto" and project is "test-project" 1`] = `
182+
"import { qwikCityDecorator } from 'storybook-framework-qwik/qwik-city-decorator';
183+
export const decorators = [qwikCityDecorator];
184+
"
185+
`;
186+
187+
exports[`storybook-configuration generator should conditionally add qwikCity decorator to preview.ts matches the snapshot when qwikCitySupport is "auto" and project is "test-project-lib" 1`] = `
188+
"// uncomment this if current project requires qwikCity
189+
// import { qwikCityDecorator } from 'storybook-framework-qwik/qwik-city-decorator';
190+
// export const decorators = [qwikCityDecorator];
191+
"
192+
`;
193+
194+
exports[`storybook-configuration generator should conditionally add qwikCity decorator to preview.ts matches the snapshot when qwikCitySupport is "false" and project is "test-project" 1`] = `
195+
"// uncomment this if current project requires qwikCity
196+
// import { qwikCityDecorator } from 'storybook-framework-qwik/qwik-city-decorator';
197+
// export const decorators = [qwikCityDecorator];
198+
"
199+
`;
200+
201+
exports[`storybook-configuration generator should conditionally add qwikCity decorator to preview.ts matches the snapshot when qwikCitySupport is "false" and project is "test-project-lib" 1`] = `
202+
"// uncomment this if current project requires qwikCity
203+
// import { qwikCityDecorator } from 'storybook-framework-qwik/qwik-city-decorator';
204+
// export const decorators = [qwikCityDecorator];
205+
"
206+
`;
207+
208+
exports[`storybook-configuration generator should conditionally add qwikCity decorator to preview.ts matches the snapshot when qwikCitySupport is "true" and project is "test-project" 1`] = `
209+
"import { qwikCityDecorator } from 'storybook-framework-qwik/qwik-city-decorator';
210+
export const decorators = [qwikCityDecorator];
211+
"
212+
`;
213+
214+
exports[`storybook-configuration generator should conditionally add qwikCity decorator to preview.ts matches the snapshot when qwikCitySupport is "true" and project is "test-project-lib" 1`] = `
215+
"import { qwikCityDecorator } from 'storybook-framework-qwik/qwik-city-decorator';
216+
export const decorators = [qwikCityDecorator];
217+
"
218+
`;

packages/qwik-nx/src/generators/storybook-configuration/files/.storybook/main.__configExtension__.template

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { mergeConfig, UserConfig } from 'vite';
2+
import { withNx } from 'qwik-nx/storybook';
23
import viteConfig from './../vite.config';
34

45
const config = {
@@ -9,7 +10,8 @@ const config = {
910
addons: ['@storybook/addon-essentials'],
1011
framework: { name: 'storybook-framework-qwik', },
1112
async viteFinal(config: UserConfig) {
12-
return mergeConfig(config, viteConfig);
13+
const updatedConfig = mergeConfig(config, viteConfig);
14+
return withNx(updatedConfig);
1315
},
1416
};
1517

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<script>
2+
window.global = window;
3+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<% if(!qwikCitySupportInternal) { %>// uncomment this if current project requires qwikCity <% } %>
2+
<% if(!qwikCitySupportInternal) { %>// <% } %>import { qwikCityDecorator } from 'storybook-framework-qwik/qwik-city-decorator';
3+
<% if(!qwikCitySupportInternal) { %>// <% } %>export const decorators = [qwikCityDecorator];

packages/qwik-nx/src/generators/storybook-configuration/generator.spec.ts

+50
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { storybookConfigurationGenerator } from './generator';
55
import { StorybookConfigurationGeneratorSchema } from './schema';
66
import appGenerator from '../application/generator';
77
import { Linter } from '@nrwl/linter';
8+
import { libraryGenerator } from '../library/generator';
89

910
// eslint-disable-next-line @typescript-eslint/no-var-requires
1011
const devkit = require('@nrwl/devkit');
@@ -68,5 +69,54 @@ describe('storybook-configuration generator', () => {
6869
.sort((a, b) => a.path.localeCompare(b.path))
6970
.map((c) => ({ path: c.path, type: c.type }))
7071
).toMatchSnapshot();
72+
expect(
73+
appTree.read(`apps/${projectName}/.storybook/main.ts`)?.toString()
74+
).toMatchSnapshot();
75+
expect(
76+
appTree.read(`apps/${projectName}/.storybook/preview.ts`)?.toString()
77+
).toMatchSnapshot();
78+
});
79+
80+
describe('should conditionally add qwikCity decorator to preview.ts', () => {
81+
const libProjectName = 'test-project-lib';
82+
83+
beforeEach(async () => {
84+
await libraryGenerator(appTree, {
85+
name: libProjectName,
86+
linter: Linter.None,
87+
skipFormat: true,
88+
strict: true,
89+
style: 'css',
90+
unitTestRunner: 'none',
91+
});
92+
});
93+
94+
test.each`
95+
qwikCitySupport | project
96+
${'true'} | ${libProjectName}
97+
${'false'} | ${libProjectName}
98+
${'auto'} | ${libProjectName}
99+
${'true'} | ${projectName}
100+
${'false'} | ${projectName}
101+
${'auto'} | ${projectName}
102+
`(
103+
'matches the snapshot when qwikCitySupport is "$qwikCitySupport" and project is "$project"',
104+
async ({ qwikCitySupport, project }) => {
105+
await storybookConfigurationGenerator(appTree, {
106+
...options,
107+
qwikCitySupport,
108+
name: project,
109+
});
110+
expect(
111+
appTree
112+
.read(
113+
`${
114+
project === libProjectName ? 'libs' : 'apps'
115+
}/${project}/.storybook/preview.ts`
116+
)
117+
?.toString()
118+
).toMatchSnapshot();
119+
}
120+
);
71121
});
72122
});

packages/qwik-nx/src/generators/storybook-configuration/generator.ts

+22-6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
GeneratorCallback,
77
names,
88
offsetFromRoot,
9+
ProjectConfiguration,
910
readProjectConfiguration,
1011
Tree,
1112
} from '@nrwl/devkit';
@@ -27,9 +28,11 @@ import {
2728
StorybookConfigurationGeneratorSchema,
2829
} from './schema';
2930

30-
function addFiles(tree: Tree, options: StorybookConfigurationGeneratorSchema) {
31-
const { root } = readProjectConfiguration(tree, options.name);
32-
31+
function addFiles(
32+
tree: Tree,
33+
options: StorybookConfigurationGeneratorSchema,
34+
{ root }: ProjectConfiguration
35+
) {
3336
tree.delete(path.join(root, '.storybook/main.js'));
3437

3538
const templateOptions = {
@@ -46,21 +49,34 @@ function addFiles(tree: Tree, options: StorybookConfigurationGeneratorSchema) {
4649
}
4750

4851
function normalizeOptions(
49-
options: StorybookConfigurationGeneratorSchema
52+
options: StorybookConfigurationGeneratorSchema,
53+
projectConfig: ProjectConfiguration
5054
): NormalizedSchema {
55+
let qwikCitySupportInternal: boolean;
56+
if (options.qwikCitySupport === 'auto' || !options.qwikCitySupport) {
57+
// "auto"
58+
qwikCitySupportInternal = projectConfig.projectType === 'application';
59+
} else {
60+
// "true" or "false"
61+
qwikCitySupportInternal = options.qwikCitySupport === 'true';
62+
}
63+
5164
return {
5265
...options,
5366
js: !!options.js,
5467
linter: options.linter ?? Linter.EsLint,
5568
tsConfiguration: options.tsConfiguration ?? true,
69+
qwikCitySupportInternal,
5670
};
5771
}
5872

5973
export async function storybookConfigurationGenerator(
6074
tree: Tree,
6175
options: StorybookConfigurationGeneratorSchema
6276
): Promise<GeneratorCallback> {
63-
const normalizedOptions = normalizeOptions(options);
77+
const projectConfig = readProjectConfiguration(tree, options.name);
78+
79+
const normalizedOptions = normalizeOptions(options, projectConfig);
6480
const nxVersion = getInstalledNxVersion(tree);
6581

6682
ensurePackage('@nrwl/storybook', nxVersion);
@@ -80,7 +96,7 @@ export async function storybookConfigurationGenerator(
8096
storybook7betaConfiguration: true,
8197
});
8298

83-
addFiles(tree, normalizedOptions);
99+
addFiles(tree, normalizedOptions, projectConfig);
84100
await formatFiles(tree);
85101

86102
return addStorybookDependencies(tree);

packages/qwik-nx/src/generators/storybook-configuration/schema.d.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export interface StorybookConfigurationGeneratorSchema {
55
linter?: Linter;
66
js?: boolean;
77
tsConfiguration?: boolean;
8+
qwikCitySupport?: 'true' | 'false' | 'auto';
89
}
910

1011
type NormalizedRequiredPropsNames = 'js' | 'linter' | 'tsConfiguration';
@@ -16,4 +17,6 @@ export type NormalizedSchema = Omit<
1617
StorybookConfigurationGeneratorSchema,
1718
NormalizedRequiredPropsNames
1819
> &
19-
NormalizedRequiredProps;
20+
NormalizedRequiredProps & {
21+
qwikCitySupportInternal: boolean;
22+
};

packages/qwik-nx/src/generators/storybook-configuration/schema.json

+7
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@
3434
"description": "Configure your project with TypeScript. Generate main.ts and preview.ts files, instead of main.js and preview.js.",
3535
"default": true,
3636
"x-priority": "important"
37+
},
38+
"qwikCitySupport": {
39+
"type": "string",
40+
"enum": ["true", "false", "auto"],
41+
"x-priority": "important",
42+
"description": "Whether to add support for the qwik city. By default, it will be added for applications, not libraries.",
43+
"default": "auto"
3744
}
3845
},
3946
"required": ["name"]
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { PluginOption, UserConfig } from 'vite';
2+
3+
/** Updates config for the storybook */
4+
export function withNx(config: UserConfig): UserConfig {
5+
const updated = { ...config };
6+
// logic below has been copied from "storybook-framework-qwik" plugin
7+
// it doesn't work out of the box for Nx applications because base config is not
8+
// Qwik-city plugin may be used in apps, but it has mdx stuff that conflicts with Storybook mdx
9+
// we'll try to only remove the transform code (where the mdx stuff is), and keep everything else.
10+
updated.plugins = updated.plugins?.map((plugin: PluginOption) =>
11+
(plugin as any)?.name === 'vite-plugin-qwik-city'
12+
? ({ ...plugin, transform: () => null } as PluginOption)
13+
: plugin
14+
);
15+
return updated;
16+
}

packages/qwik-nx/storybook.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './src/utils/storybook';

0 commit comments

Comments
 (0)