diff --git a/packages/storybook/src/generators/configuration/configuration.ts b/packages/storybook/src/generators/configuration/configuration.ts index 1d3585319e..fc17a2ccfb 100644 --- a/packages/storybook/src/generators/configuration/configuration.ts +++ b/packages/storybook/src/generators/configuration/configuration.ts @@ -66,7 +66,9 @@ export async function configurationGenerator( ); const { compiler } = findStorybookAndBuildTargetsAndCompiler(targets); - const viteConfigFilePath = findViteConfig(tree, root); + const viteConfig = findViteConfig(tree, root); + const viteConfigFilePath = viteConfig?.fullConfigPath; + const viteConfigFileName = viteConfig?.viteConfigFileName; const nextConfigFilePath = findNextConfig(tree, root); if (viteConfigFilePath) { @@ -130,7 +132,9 @@ export async function configurationGenerator( !!nextConfigFilePath, compiler === 'swc', usesVite, - viteConfigFilePath + viteConfigFilePath, + hasPlugin, + viteConfigFileName ); if (schema.uiFramework !== '@storybook/angular') { diff --git a/packages/storybook/src/generators/configuration/lib/util-functions.ts b/packages/storybook/src/generators/configuration/lib/util-functions.ts index a1c121272c..1e76034077 100644 --- a/packages/storybook/src/generators/configuration/lib/util-functions.ts +++ b/packages/storybook/src/generators/configuration/lib/util-functions.ts @@ -536,7 +536,9 @@ export function createProjectStorybookDir( isNextJs?: boolean, usesSwc?: boolean, usesVite?: boolean, - viteConfigFilePath?: string + viteConfigFilePath?: string, + hasPlugin?: boolean, + viteConfigFileName?: string ) { let projectDirectory = projectType === 'application' @@ -579,6 +581,8 @@ export function createProjectStorybookDir( usesVite, isRootProject: projectIsRootProjectInStandaloneWorkspace, viteConfigFilePath, + hasPlugin, + viteConfigFileName, }); if (js) { @@ -699,13 +703,19 @@ export async function getE2EProjectName( export function findViteConfig( tree: Tree, projectRoot: string -): string | undefined { +): { + fullConfigPath: string | undefined; + viteConfigFileName: string | undefined; +} { const allowsExt = ['js', 'mjs', 'ts', 'cjs', 'mts', 'cts']; for (const ext of allowsExt) { const viteConfigPath = joinPathFragments(projectRoot, `vite.config.${ext}`); if (tree.exists(viteConfigPath)) { - return viteConfigPath; + return { + fullConfigPath: viteConfigPath, + viteConfigFileName: `vite.config.${ext}`, + }; } } } diff --git a/packages/storybook/src/generators/configuration/project-files-ts/.storybook/main.ts__tmpl__ b/packages/storybook/src/generators/configuration/project-files-ts/.storybook/main.ts__tmpl__ index 8fda41fc04..85923ed6b0 100644 --- a/packages/storybook/src/generators/configuration/project-files-ts/.storybook/main.ts__tmpl__ +++ b/packages/storybook/src/generators/configuration/project-files-ts/.storybook/main.ts__tmpl__ @@ -14,7 +14,11 @@ const config: StorybookConfig = { framework: { name: '<%= uiFramework %>', options: { - <% if (usesVite && viteConfigFilePath) { %> + <% if (usesVite && viteConfigFilePath && hasPlugin) { %> + builder: { + viteConfigPath: '<%= viteConfigFileName %>', + }, + <% } %><% if (usesVite && viteConfigFilePath && !hasPlugin) { %> builder: { viteConfigPath: '<%= viteConfigFilePath %>', }, diff --git a/packages/storybook/src/generators/configuration/project-files/.storybook/main.js__tmpl__ b/packages/storybook/src/generators/configuration/project-files/.storybook/main.js__tmpl__ index d48266fd31..203e6843cc 100644 --- a/packages/storybook/src/generators/configuration/project-files/.storybook/main.js__tmpl__ +++ b/packages/storybook/src/generators/configuration/project-files/.storybook/main.js__tmpl__ @@ -13,7 +13,12 @@ const config = { framework: { name: '<%= uiFramework %>', options: { - <% if (usesVite && viteConfigFilePath) { %> + <% if (usesVite && viteConfigFilePath && hasPlugin) { %> + builder: { + viteConfigPath: '<%= viteConfigFileName %>', + }, + <% } %> + <% if (usesVite && viteConfigFilePath && !hasPlugin) { %> builder: { viteConfigPath: '<%= viteConfigFilePath %>', }, diff --git a/packages/storybook/src/plugins/plugin.spec.ts b/packages/storybook/src/plugins/plugin.spec.ts index 0f326b8093..40eec3f400 100644 --- a/packages/storybook/src/plugins/plugin.spec.ts +++ b/packages/storybook/src/plugins/plugin.spec.ts @@ -72,10 +72,17 @@ describe('@nx/storybook/plugin', () => { expect( nodes?.['projects']?.['my-app']?.targets?.['build-storybook'] ).toMatchObject({ - command: - 'storybook build --config-dir my-app/.storybook --output-dir dist/storybook/my-app', + command: 'storybook build', + options: { + cwd: 'my-app', + }, cache: true, - outputs: ['{workspaceRoot}/dist/storybook/{projectRoot}'], + outputs: [ + '{workspaceRoot}/{projectRoot}/static-storybook', + '{options.output-dir}', + '{options.outputDir}', + '{options.o}', + ], inputs: [ 'production', '^production', @@ -86,12 +93,12 @@ describe('@nx/storybook/plugin', () => { expect( nodes?.['projects']?.['my-app']?.targets?.['storybook'] ).toMatchObject({ - command: 'storybook dev --config-dir my-app/.storybook', + command: 'storybook dev', }); expect( nodes?.['projects']?.['my-app']?.targets?.['test-storybook'] ).toMatchObject({ - command: 'test-storybook --config-dir my-app/.storybook', + command: 'test-storybook', }); }); @@ -128,13 +135,18 @@ describe('@nx/storybook/plugin', () => { ).toMatchObject({ executor: '@storybook/angular:build-storybook', options: { - outputDir: 'dist/storybook/my-ng-app', + outputDir: 'my-ng-app/static-storybook', configDir: 'my-ng-app/.storybook', browserTarget: 'my-ng-app:build-storybook', compodoc: false, }, cache: true, - outputs: ['{workspaceRoot}/dist/storybook/{projectRoot}'], + outputs: [ + '{workspaceRoot}/{projectRoot}/static-storybook', + '{options.output-dir}', + '{options.outputDir}', + '{options.o}', + ], inputs: [ 'production', '^production', @@ -161,7 +173,7 @@ describe('@nx/storybook/plugin', () => { expect( nodes?.['projects']?.['my-ng-app']?.targets?.['test-storybook'] ).toMatchObject({ - command: 'test-storybook --config-dir my-ng-app/.storybook', + command: 'test-storybook', }); }); }); diff --git a/packages/storybook/src/plugins/plugin.ts b/packages/storybook/src/plugins/plugin.ts index ba4128e861..2915b0f914 100644 --- a/packages/storybook/src/plugins/plugin.ts +++ b/packages/storybook/src/plugins/plugin.ts @@ -64,6 +64,7 @@ export const createNodes: CreateNodes = [ if (projectRoot === '') { projectRoot = '.'; } + // Do not create a project if package.json and project.json isn't there. const siblingFiles = readdirSync(join(context.workspaceRoot, projectRoot)); if ( @@ -101,7 +102,7 @@ export const createNodes: CreateNodes = [ }, }; // For root projects, the name is not inferred from root package.json, so we need to manually set it. - // TODO(jack): We should handle this in core and remove this workaround. + // TODO(katerina): Remove this workaround once Craigory's PR (https://github.com/nrwl/nx/pull/21125) is merged if (projectRoot === '.') { result.projects[projectRoot]['name'] = projectName; } @@ -130,19 +131,20 @@ function buildStorybookTargets( targets[options.buildStorybookTargetName] = buildTarget( namedInputs, buildOutputs, - configFilePath, projectRoot, frameworkIsAngular, - projectName + projectName, + configFilePath ); targets[options.serveStorybookTargetName] = serveTarget( - configFilePath, + projectRoot, frameworkIsAngular, - projectName + projectName, + configFilePath ); - targets[options.testStorybookTargetName] = testTarget(configFilePath); + targets[options.testStorybookTargetName] = testTarget(projectRoot); targets[options.staticStorybookTargetName] = serveStaticTarget( options, @@ -157,23 +159,21 @@ function buildTarget( [inputName: string]: any[]; }, outputs: string[], - configFilePath: string, projectRoot: string, frameworkIsAngular: boolean, - projectName: string + projectName: string, + configFilePath: string ) { - const outputDir = joinPathFragments('dist/storybook', projectRoot); - let targetConfig: TargetConfiguration; if (frameworkIsAngular) { targetConfig = { executor: '@storybook/angular:build-storybook', options: { - outputDir: `${outputDir}`, configDir: `${dirname(configFilePath)}`, browserTarget: `${projectName}:build-storybook`, compodoc: false, + outputDir: joinPathFragments(projectRoot, 'static-storybook'), }, cache: true, outputs, @@ -192,9 +192,8 @@ function buildTarget( }; } else { targetConfig = { - command: `storybook build --config-dir ${dirname( - configFilePath - )} --output-dir ${outputDir}`, + command: `storybook build`, + options: { cwd: projectRoot }, cache: true, outputs, inputs: [ @@ -212,9 +211,10 @@ function buildTarget( } function serveTarget( - configFilePath: string, + projectRoot: string, frameworkIsAngular: boolean, - projectName: string + projectName: string, + configFilePath: string ) { if (frameworkIsAngular) { return { @@ -227,14 +227,16 @@ function serveTarget( }; } else { return { - command: `storybook dev --config-dir ${dirname(configFilePath)}`, + command: `storybook dev`, + options: { cwd: projectRoot }, }; } } -function testTarget(configFilePath: string) { +function testTarget(projectRoot: string) { const targetConfig: TargetConfiguration = { - command: `test-storybook --config-dir ${dirname(configFilePath)}`, + command: `test-storybook`, + options: { cwd: projectRoot }, inputs: [ { externalDependencies: ['storybook', '@storybook/test-runner'], @@ -253,8 +255,7 @@ function serveStaticTarget( executor: '@nx/web:file-server', options: { buildTarget: `${options.buildStorybookTargetName}`, - // TODO(katerina): need to read the output from CLI args - staticFilePath: joinPathFragments('dist/storybook', projectRoot), + staticFilePath: joinPathFragments(projectRoot, 'static-storybook'), }, }; @@ -316,12 +317,14 @@ function getStorybookConfig( } function getOutputs(_projectRoot: string): string[] { - // TODO(katerina): need to read the output from CLI args - // const outputPath = ; - const normalizedOutputPath = normalizeOutputPath(undefined, _projectRoot); - const outputs = [normalizedOutputPath]; + const outputs = [ + normalizedOutputPath, + `{options.output-dir}`, + `{options.outputDir}`, + `{options.o}`, + ]; return outputs; } @@ -330,22 +333,10 @@ function normalizeOutputPath( outputPath: string | undefined, projectRoot: string ): string | undefined { - if (!outputPath) { - if (projectRoot === '.') { - return `{projectRoot}/dist/storybook`; - } else { - return `{workspaceRoot}/dist/storybook/{projectRoot}`; - } + if (projectRoot === '.') { + return `{projectRoot}/static-storybook`; } else { - if (isAbsolute(outputPath)) { - return `{workspaceRoot}/${relative(workspaceRoot, outputPath)}`; - } else { - if (outputPath.startsWith('..')) { - return join('{workspaceRoot}', join(projectRoot, outputPath)); - } else { - return join('{projectRoot}', outputPath); - } - } + return `{workspaceRoot}/{projectRoot}/static-storybook`; } }