From 28823c6f60faa3e56f1b73826490b3906b515d81 Mon Sep 17 00:00:00 2001 From: Juri Date: Sun, 10 Jan 2021 15:51:33 +0100 Subject: [PATCH] feat(storybook): specify projectBuildConfig Allows to specify the `projectBuildConfig` on the storybook config in the workspace.json --- docs/angular/api-storybook/executors/build.md | 6 ++++ .../api-storybook/executors/storybook.md | 6 ++++ docs/node/api-storybook/executors/build.md | 6 ++++ .../node/api-storybook/executors/storybook.md | 6 ++++ docs/react/api-storybook/executors/build.md | 6 ++++ .../api-storybook/executors/storybook.md | 6 ++++ .../build-storybook.impl.spec.ts | 25 ++++++++++++-- .../build-storybook/build-storybook.impl.ts | 6 ++-- .../src/builders/build-storybook/schema.json | 4 +++ .../src/builders/storybook/schema.json | 4 +++ .../src/builders/storybook/storybook.impl.ts | 6 ++-- packages/storybook/src/utils/utils.ts | 33 +++++++++++++++++++ 12 files changed, 107 insertions(+), 7 deletions(-) diff --git a/docs/angular/api-storybook/executors/build.md b/docs/angular/api-storybook/executors/build.md index fca3f6db6e109..15d9ae88d290e 100644 --- a/docs/angular/api-storybook/executors/build.md +++ b/docs/angular/api-storybook/executors/build.md @@ -20,6 +20,12 @@ Type: `string` The output path of the generated files. +### projectBuildConfig + +Type: `string` + +Workspace project where Storybook reads the Webpack config from + ### quiet Default: `true` diff --git a/docs/angular/api-storybook/executors/storybook.md b/docs/angular/api-storybook/executors/storybook.md index 02fd65cbcac9a..43d622c83c6ec 100644 --- a/docs/angular/api-storybook/executors/storybook.md +++ b/docs/angular/api-storybook/executors/storybook.md @@ -30,6 +30,12 @@ Type: `number` Port to listen on. +### projectBuildConfig + +Type: `string` + +Workspace project where Storybook reads the Webpack config from + ### quiet Default: `true` diff --git a/docs/node/api-storybook/executors/build.md b/docs/node/api-storybook/executors/build.md index 984c55d270bf4..0f6fa69367eeb 100644 --- a/docs/node/api-storybook/executors/build.md +++ b/docs/node/api-storybook/executors/build.md @@ -21,6 +21,12 @@ Type: `string` The output path of the generated files. +### projectBuildConfig + +Type: `string` + +Workspace project where Storybook reads the Webpack config from + ### quiet Default: `true` diff --git a/docs/node/api-storybook/executors/storybook.md b/docs/node/api-storybook/executors/storybook.md index a864bf33bcfd2..b3b9ee99445c0 100644 --- a/docs/node/api-storybook/executors/storybook.md +++ b/docs/node/api-storybook/executors/storybook.md @@ -31,6 +31,12 @@ Type: `number` Port to listen on. +### projectBuildConfig + +Type: `string` + +Workspace project where Storybook reads the Webpack config from + ### quiet Default: `true` diff --git a/docs/react/api-storybook/executors/build.md b/docs/react/api-storybook/executors/build.md index 2b0183c8c1f90..f8f494951961b 100644 --- a/docs/react/api-storybook/executors/build.md +++ b/docs/react/api-storybook/executors/build.md @@ -21,6 +21,12 @@ Type: `string` The output path of the generated files. +### projectBuildConfig + +Type: `string` + +Workspace project where Storybook reads the Webpack config from + ### quiet Default: `true` diff --git a/docs/react/api-storybook/executors/storybook.md b/docs/react/api-storybook/executors/storybook.md index cd37b08d589fb..8254ba75297be 100644 --- a/docs/react/api-storybook/executors/storybook.md +++ b/docs/react/api-storybook/executors/storybook.md @@ -31,6 +31,12 @@ Type: `number` Port to listen on. +### projectBuildConfig + +Type: `string` + +Workspace project where Storybook reads the Webpack config from + ### quiet Default: `true` diff --git a/packages/storybook/src/builders/build-storybook/build-storybook.impl.spec.ts b/packages/storybook/src/builders/build-storybook/build-storybook.impl.spec.ts index 11f298ca71824..562185d017346 100644 --- a/packages/storybook/src/builders/build-storybook/build-storybook.impl.spec.ts +++ b/packages/storybook/src/builders/build-storybook/build-storybook.impl.spec.ts @@ -1,17 +1,35 @@ import { join } from 'path'; - import * as storybook from '@storybook/core/dist/server/build-static'; - import { MockBuilderContext } from '@nrwl/workspace/testing'; - import { getMockContext } from '../../utils/testing'; import { run as storybookBuilder } from './build-storybook.impl'; +jest.mock('@nrwl/workspace/src/core/project-graph'); +import { createProjectGraph } from '@nrwl/workspace/src/core/project-graph'; + describe('Build storybook', () => { let context: MockBuilderContext; + let mockCreateProjectGraph: jest.Mock> = createProjectGraph as any; beforeEach(async () => { context = await getMockContext(); + context.target = { + project: 'testui', + target: 'build', + }; + + mockCreateProjectGraph.mockReturnValue({ + nodes: { + testui: { + name: 'testui', + type: 'lib', + data: null, + }, + }, + dependencies: null, + }); }); it('should call the storybook static standalone build', async () => { @@ -21,6 +39,7 @@ describe('Build storybook', () => { storybook, 'buildStaticStandalone' ).and.returnValue(Promise.resolve(true)); + const result = await storybookBuilder( { uiFramework: uiFramework, diff --git a/packages/storybook/src/builders/build-storybook/build-storybook.impl.ts b/packages/storybook/src/builders/build-storybook/build-storybook.impl.ts index 4c6495bb261ad..83ff7f6f16747 100644 --- a/packages/storybook/src/builders/build-storybook/build-storybook.impl.ts +++ b/packages/storybook/src/builders/build-storybook/build-storybook.impl.ts @@ -13,8 +13,8 @@ import { mkdtempSync, statSync, copyFileSync, constants } from 'fs'; //import { buildStaticStandalone } from '@storybook/core/dist/server/build-static'; import * as build from '@storybook/core/standalone'; -import { NodeJsSyncHost } from '@angular-devkit/core/node'; import { getRoot } from '../../utils/root'; +import { setStorybookAppProject } from '../../utils/utils'; export interface StorybookConfig extends JsonObject { configFolder?: string; @@ -25,6 +25,7 @@ export interface StorybookConfig extends JsonObject { export interface StorybookBuilderOptions extends JsonObject { uiFramework: string; + projectBuildConfig?: string; config: StorybookConfig; quiet?: boolean; outputPath?: string; @@ -76,6 +77,8 @@ async function storybookOptionMapper( frameworkOptions: any, context: BuilderContext ) { + setStorybookAppProject(context, builderOptions.projectBuildConfig); + const storybookConfig = await findOrCreateConfig( builderOptions.config, context @@ -97,7 +100,6 @@ async function findOrCreateConfig( config: StorybookConfig, context: BuilderContext ): Promise { - process.env.STORYBOOK_ANGULAR_PROJECT = context.target.project; if (config.configFolder && statSync(config.configFolder).isDirectory()) { return config.configFolder; } else if ( diff --git a/packages/storybook/src/builders/build-storybook/schema.json b/packages/storybook/src/builders/build-storybook/schema.json index a3fad2d53e891..01b1c2f8e07de 100644 --- a/packages/storybook/src/builders/build-storybook/schema.json +++ b/packages/storybook/src/builders/build-storybook/schema.json @@ -13,6 +13,10 @@ "type": "string", "description": "The output path of the generated files." }, + "projectBuildConfig": { + "type": "string", + "description": "Workspace project where Storybook reads the Webpack config from" + }, "config": { "type": "object", "description": ".storybook configuration", diff --git a/packages/storybook/src/builders/storybook/schema.json b/packages/storybook/src/builders/storybook/schema.json index 5670b29e9ea31..6bca266848868 100644 --- a/packages/storybook/src/builders/storybook/schema.json +++ b/packages/storybook/src/builders/storybook/schema.json @@ -44,6 +44,10 @@ "type": "string" } }, + "projectBuildConfig": { + "type": "string", + "description": "Workspace project where Storybook reads the Webpack config from" + }, "config": { "type": "object", "description": ".storybook configuration", diff --git a/packages/storybook/src/builders/storybook/storybook.impl.ts b/packages/storybook/src/builders/storybook/storybook.impl.ts index 0ca5551c9af55..529354f61583b 100644 --- a/packages/storybook/src/builders/storybook/storybook.impl.ts +++ b/packages/storybook/src/builders/storybook/storybook.impl.ts @@ -12,8 +12,8 @@ import { mkdtempSync, statSync, copyFileSync, constants } from 'fs'; import { buildDevStandalone } from '@storybook/core/dist/server/build-dev'; -import { NodeJsSyncHost } from '@angular-devkit/core/node'; import { getRoot } from '../../utils/root'; +import { setStorybookAppProject } from '../../utils/utils'; export interface StorybookConfig extends JsonObject { configFolder?: string; @@ -24,6 +24,7 @@ export interface StorybookConfig extends JsonObject { export interface StorybookBuilderOptions extends JsonObject { uiFramework: string; + projectBuildConfig?: string; config: StorybookConfig; host?: string; port?: number; @@ -77,6 +78,8 @@ async function storybookOptionMapper( frameworkOptions: any, context: BuilderContext ) { + setStorybookAppProject(context, builderOptions.projectBuildConfig); + const storybookConfig = await findOrCreateConfig( builderOptions.config, context @@ -96,7 +99,6 @@ async function findOrCreateConfig( config: StorybookConfig, context: BuilderContext ): Promise { - process.env.STORYBOOK_ANGULAR_PROJECT = context.target.project; const sourceRoot = await getRoot(context); if (config.configFolder && statSync(config.configFolder).isDirectory()) { diff --git a/packages/storybook/src/utils/utils.ts b/packages/storybook/src/utils/utils.ts index 4caf11c542b9f..379ef62e2dac1 100644 --- a/packages/storybook/src/utils/utils.ts +++ b/packages/storybook/src/utils/utils.ts @@ -1,3 +1,4 @@ +import { BuilderContext } from '@angular-devkit/architect'; import { JsonParseMode, join, @@ -17,6 +18,10 @@ import { apply, forEach, } from '@angular-devkit/schematics'; +import { + createProjectGraph, + ProjectType, +} from '@nrwl/workspace/src/core/project-graph'; import { get } from 'http'; import { @@ -31,6 +36,34 @@ export interface NodePackage { version: string; } +// see: https://github.com/storybookjs/storybook/pull/12565 +// TODO: this should really be passed as a param to the CLI rather than env +export function setStorybookAppProject( + context: BuilderContext, + leadStorybookProject: string +) { + const projGraph = createProjectGraph(); + + let leadingProject: string; + // for libs we check whether the build config should be fetched + // from some app + if (projGraph.nodes[context.target.project].type === ProjectType.lib) { + // we have a lib so let's try to see whether the app has + // been set from which we want to get the build config + if (leadStorybookProject) { + leadingProject = leadStorybookProject; + } else { + // do nothing + return; + } + } else { + // ..for apps we just use the app target itself + leadingProject = context.target.project; + } + + process.env.STORYBOOK_ANGULAR_PROJECT = leadingProject; +} + export const Constants = { addonDependencies: ['@storybook/addons'], tsConfigExclusions: ['stories', '**/*.stories.ts'],