feat(storybook): add configureStaticServe option (#15688)
This commit is contained in:
parent
b124b97c36
commit
b3dd65adbc
@ -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."
|
||||
|
||||
@ -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."
|
||||
|
||||
@ -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."
|
||||
|
||||
@ -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"],
|
||||
|
||||
@ -19,5 +19,6 @@ export async function generateStorybookConfiguration(
|
||||
tsConfiguration: options.tsConfiguration,
|
||||
configureTestRunner: options.configureTestRunner,
|
||||
storybook7Configuration: options.storybook7Configuration,
|
||||
configureStaticServe: options.configureStaticServe,
|
||||
});
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ import type { Linter } from '@nrwl/linter';
|
||||
|
||||
export interface StorybookConfigurationOptions {
|
||||
configureCypress: boolean;
|
||||
configureStaticServe?: boolean;
|
||||
generateCypressSpecs: boolean;
|
||||
generateStories: boolean;
|
||||
linter: Linter;
|
||||
|
||||
@ -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."
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -13,5 +13,6 @@ export interface StorybookConfigureSchema {
|
||||
ignorePaths?: string[];
|
||||
bundler?: 'webpack' | 'vite';
|
||||
configureTestRunner?: boolean;
|
||||
configureStaticServe?: boolean;
|
||||
storybook7Configuration?: boolean;
|
||||
}
|
||||
|
||||
@ -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."
|
||||
|
||||
@ -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';
|
||||
@ -42,6 +43,7 @@ describe('@nrwl/storybook:configuration', () => {
|
||||
devDependencies: {
|
||||
'@storybook/addon-essentials': '~6.2.9',
|
||||
'@storybook/react': '~6.2.9',
|
||||
'@nrwl/web': nxVersion,
|
||||
},
|
||||
});
|
||||
});
|
||||
@ -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', () => {
|
||||
|
||||
@ -16,6 +16,7 @@ import { initGenerator } from '../init/init';
|
||||
import {
|
||||
addAngularStorybookTask,
|
||||
addBuildStorybookToCacheableOperations,
|
||||
addStaticTarget,
|
||||
addStorybookTask,
|
||||
addStorybookToNamedInputs,
|
||||
configureTsProjectConfig,
|
||||
@ -32,6 +33,7 @@ import {
|
||||
isStorybookV7,
|
||||
} from '../../utils/utilities';
|
||||
import {
|
||||
nxVersion,
|
||||
storybookNextAddonVersion,
|
||||
storybookSwcAddonVersion,
|
||||
storybookTestRunnerVersion,
|
||||
@ -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, {
|
||||
@ -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 {
|
||||
@ -196,57 +205,31 @@ export async function configurationGenerator(
|
||||
);
|
||||
}
|
||||
|
||||
if (schema.tsConfiguration) {
|
||||
tasks.push(
|
||||
addDependenciesToPackageJson(
|
||||
tree,
|
||||
{},
|
||||
{
|
||||
['@storybook/core-common']: storybookVersion,
|
||||
['ts-node']: tsNodeVersion,
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
const devDeps = {};
|
||||
|
||||
if (schema.tsConfiguration) {
|
||||
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);
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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."
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import {
|
||||
createProjectGraphAsync,
|
||||
ensurePackage,
|
||||
generateFiles,
|
||||
joinPathFragments,
|
||||
logger,
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -30,6 +30,7 @@ export interface CypressConfigureSchema {
|
||||
directory?: string;
|
||||
linter: Linter;
|
||||
standaloneConfig?: boolean;
|
||||
ciTargetName?: string;
|
||||
}
|
||||
|
||||
export async function cypressProjectGenerator(
|
||||
@ -65,7 +66,11 @@ export async function cypressProjectGenerator(
|
||||
);
|
||||
removeUnneededFiles(tree, generatedCypressProjectName, schema.js);
|
||||
addBaseUrlToCypressConfig(tree, generatedCypressProjectName);
|
||||
updateAngularJsonBuilder(tree, generatedCypressProjectName, schema.name);
|
||||
updateAngularJsonBuilder(tree, {
|
||||
e2eProjectName: generatedCypressProjectName,
|
||||
targetProjectName: schema.name,
|
||||
ciTargetName: schema.ciTargetName,
|
||||
});
|
||||
|
||||
await formatFiles(tree);
|
||||
|
||||
@ -107,24 +112,29 @@ function addBaseUrlToCypressConfig(tree: Tree, projectName: string) {
|
||||
|
||||
function updateAngularJsonBuilder(
|
||||
tree: Tree,
|
||||
e2eProjectName: string,
|
||||
targetProjectName: string
|
||||
opts: {
|
||||
e2eProjectName: string;
|
||||
targetProjectName: string;
|
||||
ciTargetName?: string;
|
||||
}
|
||||
) {
|
||||
const project = readProjectConfiguration(tree, e2eProjectName);
|
||||
const project = readProjectConfiguration(tree, opts.e2eProjectName);
|
||||
const e2eTarget = project.targets.e2e;
|
||||
project.targets.e2e = {
|
||||
...e2eTarget,
|
||||
options: <any>{
|
||||
...e2eTarget.options,
|
||||
devServerTarget: `${targetProjectName}:storybook`,
|
||||
devServerTarget: `${opts.targetProjectName}:storybook`,
|
||||
},
|
||||
configurations: {
|
||||
ci: {
|
||||
devServerTarget: `${targetProjectName}:storybook:ci`,
|
||||
devServerTarget: opts.ciTargetName
|
||||
? `${opts.targetProjectName}:${opts.ciTargetName}:ci`
|
||||
: `${opts.targetProjectName}:storybook:ci`,
|
||||
},
|
||||
},
|
||||
};
|
||||
updateProjectConfiguration(tree, e2eProjectName, project);
|
||||
updateProjectConfiguration(tree, opts.e2eProjectName, project);
|
||||
}
|
||||
|
||||
function projectAlreadyHasCypress(tree: Tree): boolean {
|
||||
|
||||
@ -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"]
|
||||
|
||||
@ -74,6 +74,7 @@ describe('migrate-stories-to-6-2 schematic', () => {
|
||||
await runAngularStorybookSchematic(appTree, {
|
||||
name: 'test-ui-lib',
|
||||
configureCypress: true,
|
||||
configureStaticServe: false,
|
||||
});
|
||||
|
||||
appTree.write(
|
||||
|
||||
@ -67,6 +67,7 @@ describe('testing utilities', () => {
|
||||
await runAngularStorybookSchematic(appTree, {
|
||||
name: 'test-ui-lib',
|
||||
configureCypress: true,
|
||||
configureStaticServe: false,
|
||||
});
|
||||
|
||||
appTree.write(
|
||||
|
||||
@ -127,6 +127,8 @@ const IGNORE_MATCHES_IN_PACKAGE = {
|
||||
'@storybook/core',
|
||||
'@storybook/core-server',
|
||||
'@storybook/types',
|
||||
// lazy installed with ensurePackage
|
||||
'@nrwl/web',
|
||||
'rxjs',
|
||||
],
|
||||
nx: [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user