Skip to content

Commit

Permalink
feat(storybook): add configureStaticServe option (#15688)
Browse files Browse the repository at this point in the history
  • Loading branch information
barbados-clemens committed Mar 22, 2023
1 parent b124b97 commit b3dd65a
Show file tree
Hide file tree
Showing 20 changed files with 198 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
"default": true,
"x-priority": "important"
},
"configureStaticServe": {
"type": "boolean",
"description": "Specifies whether to configure a static file server target for serving storybook. Helpful for speeding up CI build/test times.",
"x-prompt": "Configure a static file server for the storybook instance?",
"default": true,
"x-priority": "important"
},
"cypressDirectory": {
"type": "string",
"description": "A directory where the Cypress project will be placed. Placed at the root by default."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
"default": true,
"x-priority": "important"
},
"configureStaticServe": {
"type": "boolean",
"description": "Specifies whether to configure a static file server target for serving storybook. Helpful for speeding up CI build/test times.",
"x-prompt": "Configure a static file server for the storybook instance?",
"default": true,
"x-priority": "important"
},
"cypressDirectory": {
"type": "string",
"description": "A directory where the Cypress project will be placed. Placed at the root by default."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@
"default": true,
"x-deprecated": "Nx only supports standaloneConfig"
},
"configureStaticServe": {
"type": "boolean",
"description": "Add a static-storybook to serve the static storybook built files.",
"default": false
},
"configureTestRunner": {
"type": "boolean",
"description": "Add a Storybook Test-Runner target."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@
"type": "boolean",
"default": true,
"x-deprecated": "Nx only supports standaloneConfig"
},
"ciTargetName": {
"type": "string",
"description": "The name of the devServerTarget to use for the Cypress CI configuration. Used to control if using <storybook-project>:static-storybook:ci or <storybook-project>:storybook:ci",
"x-priority": "internal"
}
},
"required": ["name"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ export async function generateStorybookConfiguration(
tsConfiguration: options.tsConfiguration,
configureTestRunner: options.configureTestRunner,
storybook7Configuration: options.storybook7Configuration,
configureStaticServe: options.configureStaticServe,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Linter } from '@nrwl/linter';

export interface StorybookConfigurationOptions {
configureCypress: boolean;
configureStaticServe?: boolean;
generateCypressSpecs: boolean;
generateStories: boolean;
linter: Linter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
"default": true,
"x-priority": "important"
},
"configureStaticServe": {
"type": "boolean",
"description": "Specifies whether to configure a static file server target for serving storybook. Helpful for speeding up CI build/test times.",
"x-prompt": "Configure a static file server for the storybook instance?",
"default": true,
"x-priority": "important"
},
"cypressDirectory": {
"type": "string",
"description": "A directory where the Cypress project will be placed. Placed at the root by default."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export async function storybookConfigurationGenerator(
standaloneConfig: schema.standaloneConfig,
tsConfiguration: schema.tsConfiguration,
configureTestRunner: schema.configureTestRunner,
configureStaticServe: schema.configureStaticServe,
bundler,
storybook7Configuration: schema.storybook7Configuration,
storybook7UiFramework:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export interface StorybookConfigureSchema {
ignorePaths?: string[];
bundler?: 'webpack' | 'vite';
configureTestRunner?: boolean;
configureStaticServe?: boolean;
storybook7Configuration?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
"default": true,
"x-priority": "important"
},
"configureStaticServe": {
"type": "boolean",
"description": "Specifies whether to configure a static file server target for serving storybook. Helpful for speeding up CI build/test times.",
"x-prompt": "Configure a static file server for the storybook instance?",
"default": true,
"x-priority": "important"
},
"cypressDirectory": {
"type": "string",
"description": "A directory where the Cypress project will be placed. Placed at the root by default."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';

import { Linter } from '@nrwl/linter';
import { libraryGenerator } from '@nrwl/workspace/generators';
import { nxVersion } from '../../utils/versions';
import { TsConfig } from '../../utils/utilities';
import configurationGenerator from './configuration';
import * as workspaceConfiguration from './test-configs/workspace-conifiguration.json';
Expand Down Expand Up @@ -42,6 +43,7 @@ describe('@nrwl/storybook:configuration', () => {
devDependencies: {
'@storybook/addon-essentials': '~6.2.9',
'@storybook/react': '~6.2.9',
'@nrwl/web': nxVersion,
},
});
});
Expand Down Expand Up @@ -328,6 +330,82 @@ describe('@nrwl/storybook:configuration', () => {
},
});
});

it('should add static-storybook target', async () => {
await configurationGenerator(tree, {
name: 'test-ui-lib',
uiFramework: '@storybook/react',
configureStaticServe: true,
});

expect(
readProjectConfiguration(tree, 'test-ui-lib').targets[
'static-storybook'
]
).toMatchInlineSnapshot(`
Object {
"configurations": Object {
"ci": Object {
"buildTarget": "test-ui-lib:build-storybook:ci",
},
},
"executor": "@nrwl/web:file-server",
"options": Object {
"buildTarget": "test-ui-lib:build-storybook",
"staticFilePath": "dist/storybook/test-ui-lib",
},
}
`);
expect(
readJson(tree, 'package.json').devDependencies['@nrwl/web']
).toBeTruthy();
});
it('should use static-storybook:ci in cypress project', async () => {
await configurationGenerator(tree, {
name: 'test-ui-lib',
uiFramework: '@storybook/react',
configureStaticServe: true,
configureCypress: true,
});

expect(
readProjectConfiguration(tree, 'test-ui-lib').targets[
'static-storybook'
]
).toMatchInlineSnapshot(`
Object {
"configurations": Object {
"ci": Object {
"buildTarget": "test-ui-lib:build-storybook:ci",
},
},
"executor": "@nrwl/web:file-server",
"options": Object {
"buildTarget": "test-ui-lib:build-storybook",
"staticFilePath": "dist/storybook/test-ui-lib",
},
}
`);
expect(readProjectConfiguration(tree, 'test-ui-lib-e2e').targets.e2e)
.toMatchInlineSnapshot(`
Object {
"configurations": Object {
"ci": Object {
"devServerTarget": "test-ui-lib:static-storybook:ci",
},
},
"executor": "@nrwl/cypress:cypress",
"options": Object {
"cypressConfig": "apps/test-ui-lib-e2e/cypress.config.ts",
"devServerTarget": "test-ui-lib:storybook",
"testingType": "e2e",
},
}
`);
expect(
readJson(tree, 'package.json').devDependencies['@nrwl/web']
).toBeTruthy();
});
});

describe('for other types of projects - Next.js and the swc compiler', () => {
Expand Down
61 changes: 22 additions & 39 deletions packages/storybook/src/generators/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { initGenerator } from '../init/init';
import {
addAngularStorybookTask,
addBuildStorybookToCacheableOperations,
addStaticTarget,
addStorybookTask,
addStorybookToNamedInputs,
configureTsProjectConfig,
Expand All @@ -32,6 +33,7 @@ import {
isStorybookV7,
} from '../../utils/utilities';
import {
nxVersion,
storybookNextAddonVersion,
storybookSwcAddonVersion,
storybookTestRunnerVersion,
Expand Down Expand Up @@ -180,6 +182,10 @@ export async function configurationGenerator(
);
}

if (schema.configureStaticServe) {
addStaticTarget(tree, schema);
}

const e2eProject = await getE2EProjectName(tree, schema.name);
if (schema.configureCypress && !e2eProject) {
const cypressTask = await cypressProjectGenerator(tree, {
Expand All @@ -188,6 +194,9 @@ export async function configurationGenerator(
linter: schema.linter,
directory: schema.cypressDirectory,
standaloneConfig: schema.standaloneConfig,
ciTargetName: schema.configureStaticServe
? 'static-storybook'
: undefined,
});
tasks.push(cypressTask);
} else {
Expand All @@ -196,57 +205,31 @@ export async function configurationGenerator(
);
}

const devDeps = {};

if (schema.tsConfiguration) {
tasks.push(
addDependenciesToPackageJson(
tree,
{},
{
['@storybook/core-common']: storybookVersion,
['ts-node']: tsNodeVersion,
}
)
);
devDeps['@storybook/core-common'] = storybookVersion;
devDeps['ts-node'] = tsNodeVersion;
}

if (
nextBuildTarget &&
projectType === 'application' &&
!schema.storybook7Configuration
) {
tasks.push(
addDependenciesToPackageJson(
tree,
{},
{
['storybook-addon-next']: storybookNextAddonVersion,
['storybook-addon-swc']: storybookSwcAddonVersion,
}
)
);
devDeps['storybook-addon-next'] = storybookNextAddonVersion;
devDeps['storybook-addon-swc'] = storybookSwcAddonVersion;
} else if (compiler === 'swc') {
tasks.push(
addDependenciesToPackageJson(
tree,
{},
{
['storybook-addon-swc']: storybookSwcAddonVersion,
}
)
);
devDeps['storybook-addon-swc'] = storybookSwcAddonVersion;
}

if (schema.configureTestRunner === true) {
tasks.push(
addDependenciesToPackageJson(
tree,
{},
{
'@storybook/test-runner': storybookTestRunnerVersion,
}
)
);
devDeps['@storybook/test-runner'] = storybookTestRunnerVersion;
}
if (schema.configureStaticServe) {
devDeps['@nrwl/web'] = nxVersion;
}

tasks.push(addDependenciesToPackageJson(tree, {}, devDeps));

await formatFiles(tree);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface StorybookConfigureSchema {
cypressDirectory?: string;
standaloneConfig?: boolean;
configureTestRunner?: boolean;
configureStaticServe?: boolean;
storybook7Configuration?: boolean; // TODO(katerina): Change when Storybook 7
storybook7UiFramework?: UiFramework7; // TODO(katerina): Change when Storybook 7
}
5 changes: 5 additions & 0 deletions packages/storybook/src/generators/configuration/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@
"default": true,
"x-deprecated": "Nx only supports standaloneConfig"
},
"configureStaticServe": {
"type": "boolean",
"description": "Add a static-storybook to serve the static storybook built files.",
"default": false
},
"configureTestRunner": {
"type": "boolean",
"description": "Add a Storybook Test-Runner target."
Expand Down
24 changes: 24 additions & 0 deletions packages/storybook/src/generators/configuration/util-functions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
createProjectGraphAsync,
ensurePackage,
generateFiles,
joinPathFragments,
logger,
Expand All @@ -26,6 +27,7 @@ import {
} from '../../utils/utilities';
import { StorybookConfigureSchema } from './schema';
import { UiFramework, UiFramework7 } from '../../utils/models';
import { nxVersion } from '../../utils/versions';

const DEFAULT_PORT = 4400;

Expand Down Expand Up @@ -140,6 +142,28 @@ export function addAngularStorybookTask(
updateProjectConfiguration(tree, projectName, projectConfig);
}

export function addStaticTarget(tree: Tree, opts: StorybookConfigureSchema) {
const nrwlWeb = ensurePackage<typeof import('@nrwl/web')>(
'@nrwl/web',
nxVersion
);
nrwlWeb.webStaticServeGenerator(tree, {
buildTarget: `${opts.name}:build-storybook`,
outputPath: joinPathFragments('dist/storybook', opts.name),
targetName: 'static-storybook',
});

const projectConfig = readProjectConfiguration(tree, opts.name);

projectConfig.targets['static-storybook'].configurations = {
ci: {
buildTarget: `${opts.name}:build-storybook:ci`,
},
};

updateProjectConfiguration(tree, opts.name, projectConfig);
}

export function configureTsProjectConfig(
tree: Tree,
schema: StorybookConfigureSchema
Expand Down

1 comment on commit b3dd65a

@vercel
Copy link

@vercel vercel bot commented on b3dd65a Mar 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-dev-git-master-nrwl.vercel.app
nx-dev-nrwl.vercel.app
nx-five.vercel.app
nx.dev

Please sign in to comment.