Skip to content

Commit

Permalink
fix(storybook): find the correct targets for build and storybook
Browse files Browse the repository at this point in the history
  • Loading branch information
mandarini committed Jan 17, 2022
1 parent 552efe2 commit 252594b
Show file tree
Hide file tree
Showing 9 changed files with 685 additions and 318 deletions.
122 changes: 51 additions & 71 deletions packages/storybook/src/executors/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import {
parseTargetString,
readTargetOptions,
} from '@nrwl/devkit';
import { Workspaces } from '@nrwl/tao/src/shared/workspace';
import {
TargetConfiguration,
Workspaces,
} from '@nrwl/tao/src/shared/workspace';
import { checkAndCleanWithSemver } from '@nrwl/workspace/src/utilities/version-utils';
import 'dotenv/config';
import { existsSync, readFileSync } from 'fs';
Expand Down Expand Up @@ -205,91 +208,39 @@ export function resolveCommonStorybookOptionMapper(

storybookOptions.angularBrowserTarget = targetString;
} else {
const buildable =
!!context?.workspace?.projects?.[context.projectName]?.targets?.build;

const storybookBuildTarget =
!!context?.workspace?.projects?.[context.projectName]?.targets?.[
'build-storybook'
];

// to preserve the backwards compatibility for our users Nx resolves the
// default project just as Storybook used to before

const ws = new Workspaces(context.root);
const defaultProjectName = ws.calculateDefaultProjectName(
context.cwd,
context.workspace
);

buildProjectName = defaultProjectName;

if (defaultProjectName) {
logger.warn(
`
No projectBuildConfig was provided. Nx will use the defaultProject as set in your workspace configuration
to build Storybook. This can lead to compilation errors for Storybook.

If you want to change this, you can run the command by providing the projectBuildConfig flag as follows:

nx ${context.targetName ? context.targetName : 'storybook'} ${
context.projectName
} --projectBuildConfig=${context.projectName}${
!buildable && storybookBuildTarget ? ':build-storybook' : ''
}

Alternatively, in your project configuration, under the "${
context.targetName ? context.targetName : 'storybook'
}" target options, you can
set the "projectBuildConfig" property to the name of the project of which you want to use
the build configuration for Storybook.
`
const { storybookBuildTarget, storybookTarget, buildTarget } =
findStorybookAndBuildTargets(
context?.workspace?.projects?.[context.projectName]?.targets
);
} else {
logger.warn(
`

logger.warn(
`
No projectBuildConfig was provided and Nx could not find a defaultProject in your workspace configuration.

To fix this, you can try one of the following options:

1. Specify a defaultProject in your nx.json

2. You can run the ${
context.targetName ? context.targetName : 'storybook'
1. You can run the ${
context.targetName ? context.targetName : storybookTarget
} executor by providing the projectBuildConfig flag as follows:

nx ${context.targetName ? context.targetName : 'storybook'} ${
context.projectName
} --projectBuildConfig=${context.projectName}${
!buildable && storybookBuildTarget ? ':build-storybook' : ''
}
nx ${context.targetName ? context.targetName : storybookTarget} ${
context.projectName
} --projectBuildConfig=${context.projectName}${
!buildTarget && storybookBuildTarget ? `:${storybookBuildTarget}` : ''
}

3. In your project configuration, under the "${
context.targetName ? context.targetName : 'storybook'
2. In your project configuration, under the "${
context.targetName ? context.targetName : storybookTarget
}" target options, you can
set the "projectBuildConfig" property to the name of the project of which you want to use
the build configuration for Storybook.
`
);
throw new Error(
'No default project was found in your workspace configuration.'
);
}

targetOptions = readTargetOptions(
{
project: defaultProjectName,
target: targetName,
configuration: '',
},
context
);

storybookOptions.angularBrowserTarget = normalizeTargetString(
defaultProjectName,
targetName
throw new Error(
'No default project was found in your workspace configuration.'
);
}

const project = context.workspace.projects[buildProjectName];

const angularDevkitCompatibleLogger = {
Expand Down Expand Up @@ -340,3 +291,32 @@ function isStorybookGTE6_4() {
'6.4.0-rc.1'
);
}

export function findStorybookAndBuildTargets(targets: {
[targetName: string]: TargetConfiguration;
}): {
storybookBuildTarget?: string;
storybookTarget?: string;
buildTarget?: string;
} {
const returnObject: {
storybookBuildTarget?: string;
storybookTarget?: string;
buildTarget?: string;
} = {};
Object.entries(targets).forEach(([target, targetConfig]) => {
if (targetConfig.executor === '@nrwl/storybook:storybook') {
returnObject.storybookTarget = target;
}
if (targetConfig.executor === '@nrwl/storybook:build') {
returnObject.storybookBuildTarget = target;
}
if (
targetConfig.executor === '@angular-devkit/build-angular:browser' ||
targetConfig.executor === '@nrwl/angular:ng-packagr-lite'
) {
returnObject.buildTarget = target;
}
});
return returnObject;
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ describe('@nrwl/storybook:configuration', () => {
expect(tree.read('.storybook/main.js', 'utf-8')).toEqual(newContents);
});

it('should update workspace file', async () => {
it('should update workspace file for react libs', async () => {
await configurationGenerator(tree, {
name: 'test-ui-lib',
uiFramework: '@storybook/react',
Expand All @@ -153,7 +153,6 @@ describe('@nrwl/storybook:configuration', () => {
},
options: {
port: 4400,
projectBuildConfig: 'test-ui-lib:build-storybook',
uiFramework: '@storybook/react',
config: {
configFolder: 'libs/test-ui-lib/.storybook',
Expand All @@ -170,6 +169,45 @@ describe('@nrwl/storybook:configuration', () => {
});
});

it('should update workspace file for angular libs', async () => {
// Setup a new lib
await libraryGenerator(tree, {
name: 'test-ui-lib-2',
standaloneConfig: false,
});
await configurationGenerator(tree, {
name: 'test-ui-lib-2',
uiFramework: '@storybook/angular',
standaloneConfig: false,
});
const project = readProjectConfiguration(tree, 'test-ui-lib-2');

expect(project.targets.storybook).toEqual({
executor: '@nrwl/storybook:storybook',
configurations: {
ci: {
quiet: true,
},
},
options: {
port: 4400,
projectBuildConfig: 'test-ui-lib-2:build-storybook',
uiFramework: '@storybook/angular',
config: {
configFolder: 'libs/test-ui-lib-2/.storybook',
},
},
});

expect(project.targets.lint).toEqual({
executor: '@nrwl/linter:eslint',
outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['libs/test-ui-lib-2/**/*.ts'],
},
});
});

it('should update `tsconfig.lib.json` file', async () => {
await configurationGenerator(tree, {
name: 'test-ui-lib',
Expand Down
26 changes: 16 additions & 10 deletions packages/storybook/src/generators/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ import {
} from '../../utils/utilities';
import { cypressProjectGenerator } from '../cypress-project/cypress-project';
import { StorybookConfigureSchema } from './schema';
import { storybookVersion } from '../../utils/versions';
import { initGenerator } from '../init/init';
import { checkAndCleanWithSemver } from '@nrwl/workspace/src/utilities/version-utils';
import { gte } from 'semver';
import { findStorybookAndBuildTargets } from '../../executors/utils';

export async function configurationGenerator(
tree: Tree,
Expand All @@ -43,7 +43,7 @@ export async function configurationGenerator(

const { projectType, targets } = readProjectConfiguration(tree, schema.name);

const buildable = !!targets?.build;
const { buildTarget } = findStorybookAndBuildTargets(targets);

const initTask = await initGenerator(tree, {
uiFramework: schema.uiFramework,
Expand All @@ -61,7 +61,7 @@ export async function configurationGenerator(
configureTsProjectConfig(tree, schema);
configureTsSolutionConfig(tree, schema);
updateLintConfig(tree, schema);
addStorybookTask(tree, schema.name, schema.uiFramework, buildable);
addStorybookTask(tree, schema.name, schema.uiFramework, buildTarget);
if (schema.configureCypress) {
if (projectType !== 'application') {
const cypressTask = await cypressProjectGenerator(tree, {
Expand Down Expand Up @@ -303,7 +303,7 @@ function addStorybookTask(
tree: Tree,
projectName: string,
uiFramework: string,
buildable: boolean
buildTargetForAngularProjects: string
) {
const projectConfig = readProjectConfiguration(tree, projectName);
projectConfig.targets['storybook'] = {
Expand All @@ -314,9 +314,12 @@ function addStorybookTask(
config: {
configFolder: `${projectConfig.root}/.storybook`,
},
projectBuildConfig: buildable
? projectName
: `${projectName}:build-storybook`,
projectBuildConfig:
uiFramework === '@storybook/angular'
? buildTargetForAngularProjects
? projectName
: `${projectName}:build-storybook`
: undefined,
},
configurations: {
ci: {
Expand All @@ -333,9 +336,12 @@ function addStorybookTask(
config: {
configFolder: `${projectConfig.root}/.storybook`,
},
projectBuildConfig: buildable
? projectName
: `${projectName}:build-storybook`,
projectBuildConfig:
uiFramework === '@storybook/angular'
? buildTargetForAngularProjects
? projectName
: `${projectName}:build-storybook`
: undefined,
},
configurations: {
ci: {
Expand Down

0 comments on commit 252594b

Please sign in to comment.