Skip to content

Commit 3070788

Browse files
committed
feat(angular): add angular builder to build storybook
The builder allows to add a "architect" in angular.json to build storybook config ex : ``` "build-storybook": { "builder": "@storybook/angular:build-storybook", "options": { "browserTarget": "angular-cli:build" } } ``` cmd : `ng run angular-cli:build-storybook` With this solution it is possible to have several angular projects using different assets and style
1 parent 79debc6 commit 3070788

File tree

6 files changed

+150
-1
lines changed

6 files changed

+150
-1
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { Architect } from '@angular-devkit/architect';
2+
import { TestingArchitectHost } from '@angular-devkit/architect/testing';
3+
import { schema } from '@angular-devkit/core';
4+
import * as path from 'path';
5+
6+
const buildStandaloneMock = jest.fn().mockImplementation((_options: unknown) => Promise.resolve());
7+
8+
jest.mock('@storybook/angular/standalone', () => buildStandaloneMock);
9+
10+
describe('Build Storybook Builder', () => {
11+
let architect: Architect;
12+
let architectHost: TestingArchitectHost;
13+
14+
beforeEach(async () => {
15+
const registry = new schema.CoreSchemaRegistry();
16+
registry.addPostTransform(schema.transforms.addUndefinedDefaults);
17+
18+
architectHost = new TestingArchitectHost();
19+
architect = new Architect(architectHost, registry);
20+
21+
// This will either take a Node package name, or a path to the directory
22+
// for the package.json file.
23+
await architectHost.addBuilderFromPackage(path.join(__dirname, '../../..'));
24+
});
25+
26+
it('should work', async () => {
27+
const run = await architect.scheduleBuilder('@storybook/angular:build-storybook', {
28+
browserTarget: 'angular-cli:build-2',
29+
});
30+
31+
const output = await run.result;
32+
33+
await run.stop();
34+
35+
expect(output.success).toBeTruthy();
36+
expect(buildStandaloneMock).toHaveBeenCalledWith({
37+
angularBrowserTarget: 'angular-cli:build-2',
38+
browserTarget: 'angular-cli:build-2',
39+
configDir: '.storybook',
40+
docs: false,
41+
loglevel: undefined,
42+
quiet: false,
43+
outputDir: 'storybook-static',
44+
staticDir: [],
45+
mode: 'static',
46+
});
47+
});
48+
});
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
2+
import { JsonObject } from '@angular-devkit/core';
3+
import { from, Observable, of } from 'rxjs';
4+
import { CLIOptions } from '@storybook/core-common';
5+
import { map, switchMap, tap } from 'rxjs/operators';
6+
7+
// eslint-disable-next-line import/no-extraneous-dependencies
8+
import buildStandalone, { StandaloneOptions } from '@storybook/angular/standalone';
9+
10+
export type StorybookBuilderOptions = JsonObject & {
11+
browserTarget: string;
12+
} & Pick<
13+
// makes sure the option exists
14+
CLIOptions,
15+
'staticDir' | 'outputDir' | 'configDir' | 'loglevel' | 'quiet' | 'docs'
16+
>;
17+
18+
export type StorybookBuilderOutput = JsonObject & BuilderOutput & {};
19+
20+
export default createBuilder(commandBuilder);
21+
22+
function commandBuilder(
23+
options: StorybookBuilderOptions,
24+
_context: BuilderContext
25+
): Observable<StorybookBuilderOutput> {
26+
return of({}).pipe(
27+
map(() => ({
28+
...options,
29+
angularBrowserTarget: options.browserTarget,
30+
})),
31+
switchMap((standaloneOptions) => runInstance({ ...standaloneOptions, mode: 'static' })),
32+
map(() => {
33+
return { success: true };
34+
})
35+
);
36+
}
37+
38+
function runInstance(options: StandaloneOptions) {
39+
return from(buildStandalone(options));
40+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"$schema": "http://json-schema.org/schema",
3+
"title": "Build Storybook",
4+
"description": "Serve up storybook in development mode.",
5+
"type": "object",
6+
"properties": {
7+
"browserTarget": {
8+
"type": "string",
9+
"description": "Build target to be served in project-name:builder:config format. Should generally target on the builder: '@angular-devkit/build-angular:browser'. Useful for Storybook to use options (styles, assets, ...).",
10+
"pattern": "^[^:\\s]+:[^:\\s]+(:[^\\s]+)?$"
11+
},
12+
"staticDir": {
13+
"type": "array",
14+
"description": "Directory where to load static files from, array of strings.",
15+
"items": {
16+
"type": "string"
17+
}
18+
},
19+
"outputDir": {
20+
"type": "string",
21+
"description": "Directory where to store built files.",
22+
"default": "storybook-static"
23+
},
24+
"configDir": {
25+
"type": "string",
26+
"description": "Directory where to load Storybook configurations from.",
27+
"default": ".storybook"
28+
},
29+
"loglevel": {
30+
"type": "string",
31+
"description": "Controls level of logging during build. Can be one of: [silly, verbose, info (default), warn, error, silent].",
32+
"pattern": "(silly|verbose|info|warn|silent)"
33+
},
34+
"quiet": {
35+
"type": "boolean",
36+
"description": "Suppress verbose build output.",
37+
"default": false
38+
},
39+
"docs": {
40+
"type": "boolean",
41+
"description": "Starts Storybook in documentation mode. Learn more about it : https://storybook.js.org/docs/react/writing-docs/build-documentation#preview-storybooks-documentation.",
42+
"default": false
43+
}
44+
},
45+
"additionalProperties": false,
46+
"required": ["browserTarget"]
47+
}

app/angular/src/builders/builders.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
{
22
"builders": {
3+
"build-storybook": {
4+
"implementation": "./build-storybook",
5+
"schema": "./build-storybook/schema.json",
6+
"description": "Build storybook"
7+
},
38
"start-storybook": {
49
"implementation": "./start-storybook",
510
"schema": "./start-storybook/schema.json",

app/angular/standalone.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export type StandaloneOptions = Partial<
44
CLIOptions &
55
LoadOptions &
66
BuilderOptions & {
7+
mode?: 'static' | 'dev';
78
angularBrowserTarget: string;
89
}
910
>;

examples/angular-cli/angular.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,15 @@
7979
"builder": "@storybook/angular:start-storybook",
8080
"options": {
8181
"browserTarget": "angular-cli:build",
82-
"port": 4400
82+
"port": 4400,
83+
"staticDir": ["src/assets"]
84+
}
85+
},
86+
"build-storybook": {
87+
"builder": "@storybook/angular:build-storybook",
88+
"options": {
89+
"browserTarget": "angular-cli:build",
90+
"staticDir": ["src/assets"]
8391
}
8492
}
8593
}

0 commit comments

Comments
 (0)