mirror of
https://github.com/storybookjs/storybook.git
synced 2025-03-31 05:03:21 +08:00
Setup Storybook in Angular workspace via builders
This commit is contained in:
parent
e204a21f65
commit
eb6d514283
11
MIGRATION.md
11
MIGRATION.md
@ -40,6 +40,8 @@
|
||||
- [Stories glob matches MDX files](#stories-glob-matches-mdx-files)
|
||||
- [Add strict mode](#add-strict-mode)
|
||||
- [Removed DLL flags](#removed-dll-flags)
|
||||
- [Angular: Drop support for Angular \< 14](#angular-drop-support-for-angular--14)
|
||||
- [Angular: Drop support for calling storybook directly](#angular-drop-support-for-calling-storybook-directly)
|
||||
- [Docs Changes](#docs-changes)
|
||||
- [Standalone docs files](#standalone-docs-files)
|
||||
- [Referencing stories in docs files](#referencing-stories-in-docs-files)
|
||||
@ -765,6 +767,15 @@ If user code in `.storybook/preview.js` or stories relies on "sloppy" mode behav
|
||||
|
||||
Earlier versions of Storybook used Webpack DLLs as a performance crutch. In 6.1, we've removed Storybook's built-in DLLs and have deprecated the command-line parameters `--no-dll` and `--ui-dll`. In 7.0 those options are removed.
|
||||
|
||||
#### Angular: Drop support for Angular < 14
|
||||
|
||||
Starting in 7.0, we drop support for Angular < 14
|
||||
|
||||
#### Angular: Drop support for calling storybook directly
|
||||
|
||||
In Storybook 6.4 we have deprecated calling Storybook directly (`npm run storybook`) and removed support for it in Storybook 7.0 entirely. Instead you have to set up
|
||||
the Storybook builder in your `angular.json` and execute `ng run <your-project>:storybook` to start Storybook. Please visit https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular to set up Storybook for Angular correctly.
|
||||
|
||||
### Docs Changes
|
||||
|
||||
The information hierarchy of docs in Storybook has changed in 7.0. The main difference is that each docs is listed in the sidebar as a separate entry, rather than attached to individual stories.
|
||||
|
@ -1,5 +1,11 @@
|
||||
# Storybook for Angular
|
||||
|
||||
- [Storybook for Angular](#storybook-for-angular)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Setup Compodoc](#setup-compodoc)
|
||||
- [Support for multi-project workspace](#support-for-multi-project-workspace)
|
||||
- [Run Storybook](#run-storybook)
|
||||
|
||||
Storybook for Angular is a UI development environment for your Angular components.
|
||||
With it, you can visualize different states of your UI components and develop them interactively.
|
||||
|
||||
@ -15,6 +21,66 @@ cd my-angular-app
|
||||
npx storybook init
|
||||
```
|
||||
|
||||
### Setup Compodoc
|
||||
|
||||
When installing, you will be given the option to set up Compodoc, which is a tool for creating documentation for Angular projects.
|
||||
|
||||
You can include JSDoc comments above components, directives, and other parts of your Angular code to include documentation for those elements. Compodoc uses these comments to generate documentation for your application. In Storybook, it is useful to add explanatory comments above @Inputs and @Outputs, since these are the main elements that Storybook displays in its user interface. The @Inputs and @Outputs are the elements that you can interact with in Storybook, such as controls.
|
||||
|
||||
## Support for multi-project workspace
|
||||
|
||||
Storybook supports Angular multi-project workspace. You can setup Storybook for each project in the workspace. When running `npx storybook init` you will be asked for which project Storybook should be set up. Essentially, during initialization, the `angular.json` will be edited to add the Storybook configuration for the selected project. The configuration looks approximately like this:
|
||||
|
||||
```json
|
||||
// angular.json
|
||||
{
|
||||
...
|
||||
"projects": {
|
||||
...
|
||||
"your-project": {
|
||||
...
|
||||
"architect": {
|
||||
...
|
||||
"storybook": {
|
||||
"builder": "@storybook/angular:start-storybook",
|
||||
"options": {
|
||||
"configDir": ".storybook",
|
||||
"browserTarget": "your-project:build",
|
||||
"compodoc": false,
|
||||
"port": 6006
|
||||
}
|
||||
},
|
||||
"build-storybook": {
|
||||
"builder": "@storybook/angular:build-storybook",
|
||||
"options": {
|
||||
"configDir": ".storybook",
|
||||
"browserTarget": "your-project:build",
|
||||
"compodoc": false,
|
||||
"outputDir": "dist/storybook/your-project"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Run Storybook
|
||||
|
||||
To run Storybook for a particular project, please run:
|
||||
|
||||
```sh
|
||||
ng run your-project:storybook
|
||||
```
|
||||
|
||||
To build Storybook, run:
|
||||
|
||||
```sh
|
||||
ng run your-project:build-storybook
|
||||
```
|
||||
|
||||
You will find the output in `dist/storybook/your-project`.
|
||||
|
||||
For more information visit: [storybook.js.org](https://storybook.js.org)
|
||||
|
||||
---
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { BuilderContext } from '@angular-devkit/architect';
|
||||
import { spawn } from 'child_process';
|
||||
import { Observable } from 'rxjs';
|
||||
import * as path from 'path';
|
||||
import { JsPackageManagerFactory } from '@storybook/cli';
|
||||
|
||||
const hasTsConfigArg = (args: string[]) => args.indexOf('-p') !== -1;
|
||||
const hasOutputArg = (args: string[]) =>
|
||||
@ -20,37 +20,22 @@ export const runCompodoc = (
|
||||
return new Observable<void>((observer) => {
|
||||
const tsConfigPath = toRelativePath(tsconfig);
|
||||
const finalCompodocArgs = [
|
||||
'compodoc',
|
||||
// Default options
|
||||
...(hasTsConfigArg(compodocArgs) ? [] : ['-p', tsConfigPath]),
|
||||
...(hasOutputArg(compodocArgs) ? [] : ['-d', `${context.workspaceRoot}`]),
|
||||
...(hasOutputArg(compodocArgs) ? [] : ['-d', `${context.workspaceRoot || '.'}`]),
|
||||
...compodocArgs,
|
||||
];
|
||||
|
||||
const packageManager = JsPackageManagerFactory.getPackageManager();
|
||||
|
||||
try {
|
||||
context.logger.info(finalCompodocArgs.join(' '));
|
||||
const child = spawn('npx', finalCompodocArgs, {
|
||||
cwd: context.workspaceRoot,
|
||||
shell: true,
|
||||
});
|
||||
const stdout = packageManager.runScript('compodoc', finalCompodocArgs, context.workspaceRoot);
|
||||
|
||||
child.stdout.on('data', (data) => {
|
||||
context.logger.info(data.toString());
|
||||
});
|
||||
child.stderr.on('data', (data) => {
|
||||
context.logger.error(data.toString());
|
||||
});
|
||||
|
||||
child.on('close', (code) => {
|
||||
if (code === 0) {
|
||||
observer.next();
|
||||
observer.complete();
|
||||
} else {
|
||||
observer.error();
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
observer.error(error);
|
||||
context.logger.info(stdout);
|
||||
observer.next();
|
||||
observer.complete();
|
||||
} catch (e) {
|
||||
context.logger.error(e);
|
||||
observer.error();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -34,7 +34,7 @@ const prepareMain = (
|
||||
): AngularRenderer['storyResult'] => {
|
||||
let { template } = story;
|
||||
|
||||
const component = story.component ?? context.component;
|
||||
const { component } = context;
|
||||
const userDefinedTemplate = !hasNoTemplate(template);
|
||||
|
||||
if (!userDefinedTemplate && component) {
|
||||
|
@ -22,6 +22,18 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": "Storybook Team",
|
||||
"exports": {
|
||||
".": {
|
||||
"node": "./dist/index.js",
|
||||
"require": "./dist/index.js",
|
||||
"import": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.mjs",
|
||||
"types": "dist/index.d.ts",
|
||||
"bin": {
|
||||
"getstorybook": "./bin/index.js",
|
||||
"sb": "./bin/index.js"
|
||||
@ -93,7 +105,8 @@
|
||||
},
|
||||
"bundler": {
|
||||
"entries": [
|
||||
"./src/generate.ts"
|
||||
"./src/generate.ts",
|
||||
"./src/index.ts"
|
||||
],
|
||||
"platform": "node"
|
||||
},
|
||||
|
@ -344,14 +344,6 @@ describe('Detect', () => {
|
||||
)
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('ALREADY_HAS_STORYBOOK if lib is present', () => {
|
||||
expect(
|
||||
isStorybookInstalled({
|
||||
devDependencies: { '@storybook/react': '4.0.0-alpha.21' },
|
||||
})
|
||||
).toBe(ProjectType.ALREADY_HAS_STORYBOOK);
|
||||
});
|
||||
});
|
||||
|
||||
describe('detectFrameworkPreset should return', () => {
|
||||
|
@ -142,7 +142,7 @@ export function isStorybookInstalled(
|
||||
false
|
||||
)
|
||||
) {
|
||||
return ProjectType.ALREADY_HAS_STORYBOOK;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -194,9 +194,8 @@ export function detect(
|
||||
return ProjectType.UNDETECTED;
|
||||
}
|
||||
|
||||
const storyBookInstalled = isStorybookInstalled(packageJson, options.force);
|
||||
if (storyBookInstalled) {
|
||||
return storyBookInstalled;
|
||||
if (isNxProject(packageJson)) {
|
||||
return ProjectType.NX;
|
||||
}
|
||||
|
||||
if (options.html) {
|
||||
@ -205,3 +204,7 @@ export function detect(
|
||||
|
||||
return detectFrameworkPreset(packageJson || bowerJson);
|
||||
}
|
||||
|
||||
function isNxProject(packageJSON: PackageJson) {
|
||||
return !!packageJSON.devDependencies?.nx || fs.existsSync('nx.json');
|
||||
}
|
||||
|
116
code/lib/cli/src/generators/ANGULAR/helpers.ts
Normal file
116
code/lib/cli/src/generators/ANGULAR/helpers.ts
Normal file
@ -0,0 +1,116 @@
|
||||
import fs from 'fs';
|
||||
import prompts from 'prompts';
|
||||
import dedent from 'ts-dedent';
|
||||
|
||||
import { commandLog } from '../../helpers';
|
||||
|
||||
export const ANGULAR_JSON_PATH = 'angular.json';
|
||||
|
||||
export const compoDocPreviewPrefix = dedent`
|
||||
import { setCompodocJson } from "@storybook/addon-docs/angular";
|
||||
import docJson from "../documentation.json";
|
||||
setCompodocJson(docJson);
|
||||
`.trimStart();
|
||||
|
||||
export const promptForCompoDocs = async (): Promise<boolean> => {
|
||||
const { useCompoDoc } = await prompts({
|
||||
type: 'confirm',
|
||||
name: 'useCompoDoc',
|
||||
message: 'Do you want to use Compodoc for documentation?',
|
||||
});
|
||||
|
||||
return useCompoDoc;
|
||||
};
|
||||
|
||||
export class AngularJSON {
|
||||
json: {
|
||||
projects: Record<string, { root: string; architect: Record<string, any> }>;
|
||||
};
|
||||
|
||||
constructor() {
|
||||
if (!fs.existsSync(ANGULAR_JSON_PATH)) {
|
||||
commandLog(
|
||||
'An angular.json file was not found in the current directory. Storybook needs it to work properly.'
|
||||
);
|
||||
|
||||
throw new Error('No angular.json file found');
|
||||
}
|
||||
|
||||
const jsonContent = fs.readFileSync(ANGULAR_JSON_PATH, 'utf8');
|
||||
this.json = JSON.parse(jsonContent);
|
||||
}
|
||||
|
||||
get projects() {
|
||||
return this.json.projects;
|
||||
}
|
||||
|
||||
getProjectSettingsByName(projectName: string) {
|
||||
return this.projects[projectName];
|
||||
}
|
||||
|
||||
async getProjectName() {
|
||||
const projectKeys = Object.keys(this.projects);
|
||||
|
||||
if (projectKeys.length > 1) {
|
||||
const { projectName } = await prompts({
|
||||
type: 'select',
|
||||
name: 'projectName',
|
||||
message: 'For which project do you want to generate Storybook configuration?',
|
||||
choices: projectKeys.map((name) => ({
|
||||
title: name,
|
||||
value: name,
|
||||
})),
|
||||
});
|
||||
|
||||
return projectName;
|
||||
}
|
||||
|
||||
return Object.keys(this.projects)[0];
|
||||
}
|
||||
|
||||
addStorybookEntries({
|
||||
angularProjectName,
|
||||
storybookFolder,
|
||||
useCompodoc,
|
||||
root,
|
||||
}: {
|
||||
angularProjectName: string;
|
||||
storybookFolder: string;
|
||||
useCompodoc: boolean;
|
||||
root: string;
|
||||
}) {
|
||||
// add an entry to the angular.json file to setup the storybook builders
|
||||
const { architect } = this.projects[angularProjectName];
|
||||
|
||||
const baseOptions = {
|
||||
configDir: storybookFolder,
|
||||
browserTarget: `${angularProjectName}:build`,
|
||||
compodoc: useCompodoc,
|
||||
...(useCompodoc && { compodocArgs: ['-e', 'json', '-d', root || '.'] }),
|
||||
};
|
||||
|
||||
if (!architect.storybook) {
|
||||
architect.storybook = {
|
||||
builder: '@storybook/angular:start-storybook',
|
||||
options: {
|
||||
...baseOptions,
|
||||
port: 6006,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (!architect['build-storybook']) {
|
||||
architect['build-storybook'] = {
|
||||
builder: '@storybook/angular:build-storybook',
|
||||
options: {
|
||||
...baseOptions,
|
||||
outputDir: `dist/storybook/${angularProjectName}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
write() {
|
||||
fs.writeFileSync(ANGULAR_JSON_PATH, JSON.stringify(this.json, null, 2));
|
||||
}
|
||||
}
|
@ -1,37 +1,22 @@
|
||||
import path, { join } from 'path';
|
||||
import { join } from 'path';
|
||||
import semver from 'semver';
|
||||
import {
|
||||
checkForProjects,
|
||||
editStorybookTsConfig,
|
||||
getAngularAppTsConfigJson,
|
||||
getAngularAppTsConfigPath,
|
||||
getBaseTsConfigName,
|
||||
} from './angular-helpers';
|
||||
import { writeFileAsJson, copyTemplate } from '../../helpers';
|
||||
import { getCliDir } from '../../dirs';
|
||||
import fs from 'fs';
|
||||
import dedent from 'ts-dedent';
|
||||
import { baseGenerator } from '../baseGenerator';
|
||||
import type { Generator } from '../types';
|
||||
import { CoreBuilder } from '../../project_types';
|
||||
import { AngularJSON, compoDocPreviewPrefix, promptForCompoDocs } from './helpers';
|
||||
import { getCliDir } from '../../dirs';
|
||||
import { copyTemplate } from '../../helpers';
|
||||
import { isStorybookInstalled } from '../../detect';
|
||||
|
||||
function editAngularAppTsConfig() {
|
||||
const tsConfigJson = getAngularAppTsConfigJson();
|
||||
const glob = '**/*.stories.*';
|
||||
if (!tsConfigJson) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { exclude = [] } = tsConfigJson;
|
||||
if (exclude.includes(glob)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tsConfigJson.exclude = [...exclude, glob];
|
||||
writeFileAsJson(getAngularAppTsConfigPath(), tsConfigJson);
|
||||
}
|
||||
|
||||
const generator: Generator = async (packageManager, npmOptions, options) => {
|
||||
checkForProjects();
|
||||
|
||||
const generator: Generator<{ projectName: string }> = async (
|
||||
packageManager,
|
||||
npmOptions,
|
||||
options,
|
||||
commandOptions
|
||||
) => {
|
||||
const packageJson = packageManager.retrievePackageJson();
|
||||
const angularVersionFromDependencies = semver.coerce(
|
||||
packageManager.retrievePackageJson().dependencies['@angular/core']
|
||||
)?.version;
|
||||
@ -44,60 +29,77 @@ const generator: Generator = async (packageManager, npmOptions, options) => {
|
||||
const isWebpack5 = semver.gte(angularVersion, '12.0.0');
|
||||
const updatedOptions = isWebpack5 ? { ...options, builder: CoreBuilder.Webpack5 } : options;
|
||||
|
||||
const angularJSON = new AngularJSON();
|
||||
const angularProjectName = await angularJSON.getProjectName();
|
||||
const { root } = angularJSON.getProjectSettingsByName(angularProjectName);
|
||||
const { projects } = angularJSON;
|
||||
const useCompodoc = commandOptions.yes ? true : await promptForCompoDocs();
|
||||
const storybookFolder = root ? `${root}/.storybook` : '.storybook';
|
||||
|
||||
if (root !== '') {
|
||||
// create a .storybook folder in the root of the Angular project
|
||||
fs.mkdirSync(storybookFolder, { recursive: true });
|
||||
const rootReferencePathFromStorybookFolder = root
|
||||
.split('/')
|
||||
.map(() => '../')
|
||||
.join('');
|
||||
|
||||
fs.writeFileSync(
|
||||
`${storybookFolder}/main.js`,
|
||||
dedent(`
|
||||
const mainRoot = require('${rootReferencePathFromStorybookFolder}../.storybook/main.js');
|
||||
module.exports = {
|
||||
...mainRoot
|
||||
};
|
||||
`)
|
||||
);
|
||||
}
|
||||
|
||||
angularJSON.addStorybookEntries({
|
||||
angularProjectName,
|
||||
storybookFolder,
|
||||
useCompodoc,
|
||||
root,
|
||||
});
|
||||
angularJSON.write();
|
||||
|
||||
const isSbInstalled = isStorybookInstalled(packageJson, commandOptions.force);
|
||||
|
||||
await baseGenerator(
|
||||
packageManager,
|
||||
npmOptions,
|
||||
updatedOptions,
|
||||
{
|
||||
...updatedOptions,
|
||||
...(useCompodoc && {
|
||||
frameworkPreviewParts: {
|
||||
prefix: compoDocPreviewPrefix,
|
||||
},
|
||||
}),
|
||||
},
|
||||
'angular',
|
||||
{
|
||||
extraPackages: ['@compodoc/compodoc'],
|
||||
...(useCompodoc && { extraPackages: ['@compodoc/compodoc'] }),
|
||||
addScripts: false,
|
||||
componentsDestinationPath: root ? `${root}/src/stories` : undefined,
|
||||
addMainFile: !isSbInstalled,
|
||||
storybookConfigFolder: storybookFolder,
|
||||
},
|
||||
'angular'
|
||||
);
|
||||
|
||||
const templateDir = join(getCliDir(), 'templates', 'angular');
|
||||
copyTemplate(templateDir);
|
||||
|
||||
editAngularAppTsConfig();
|
||||
|
||||
// TODO: we need to add the following:
|
||||
|
||||
/*
|
||||
"storybook": {
|
||||
"builder": "@storybook/angular:start-storybook",
|
||||
"options": {
|
||||
"browserTarget": "angular-cli:build",
|
||||
"port": 4400
|
||||
}
|
||||
},
|
||||
"build-storybook": {
|
||||
"builder": "@storybook/angular:build-storybook",
|
||||
"options": {
|
||||
"browserTarget": "angular-cli:build"
|
||||
}
|
||||
if (Object.keys(projects).length === 1) {
|
||||
packageManager.addScripts({
|
||||
storybook: `ng run ${angularProjectName}:storybook`,
|
||||
'build-storybook': `ng run ${angularProjectName}:build-storybook`,
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
// to the user's angular.json file.
|
||||
const templateDir = join(getCliDir(), 'templates', 'angular');
|
||||
copyTemplate(templateDir, root || undefined);
|
||||
|
||||
// then we want to add these scripts to package.json
|
||||
// packageManager.addScripts({
|
||||
// storybook: 'ng storybook',
|
||||
// 'build-storybook': 'ng build-storybook',
|
||||
// });
|
||||
|
||||
editStorybookTsConfig(path.resolve('./.storybook/tsconfig.json'));
|
||||
|
||||
// edit scripts to generate docs
|
||||
const tsConfigFile = await getBaseTsConfigName();
|
||||
packageManager.addScripts({
|
||||
'docs:json': `compodoc -p ./${tsConfigFile} -e json -d .`,
|
||||
});
|
||||
packageManager.addStorybookCommandInScripts({
|
||||
port: 6006,
|
||||
preCommand: 'docs:json',
|
||||
});
|
||||
return {
|
||||
projectName: angularProjectName,
|
||||
};
|
||||
};
|
||||
|
||||
export default generator;
|
||||
|
@ -17,13 +17,16 @@ const defaultOptions: FrameworkOptions = {
|
||||
extraAddons: [],
|
||||
staticDir: undefined,
|
||||
addScripts: true,
|
||||
addMainFile: true,
|
||||
addComponents: true,
|
||||
addBabel: false,
|
||||
addESLint: false,
|
||||
extraMain: undefined,
|
||||
framework: undefined,
|
||||
extensions: undefined,
|
||||
componentsDestinationPath: undefined,
|
||||
commonJs: false,
|
||||
storybookConfigFolder: '.storybook',
|
||||
};
|
||||
|
||||
const getBuilderDetails = (builder: string) => {
|
||||
@ -106,7 +109,13 @@ const hasFrameworkTemplates = (framework?: SupportedFrameworks) =>
|
||||
export async function baseGenerator(
|
||||
packageManager: JsPackageManager,
|
||||
npmOptions: NpmOptions,
|
||||
{ language, builder = CoreBuilder.Webpack5, pnp, commonJs }: GeneratorOptions,
|
||||
{
|
||||
language,
|
||||
builder = CoreBuilder.Webpack5,
|
||||
pnp,
|
||||
commonJs,
|
||||
frameworkPreviewParts,
|
||||
}: GeneratorOptions,
|
||||
renderer: SupportedRenderers,
|
||||
options: FrameworkOptions = defaultOptions,
|
||||
framework?: SupportedFrameworks
|
||||
@ -116,11 +125,14 @@ export async function baseGenerator(
|
||||
extraPackages,
|
||||
staticDir,
|
||||
addScripts,
|
||||
addMainFile,
|
||||
addComponents,
|
||||
addBabel,
|
||||
addESLint,
|
||||
extraMain,
|
||||
extensions,
|
||||
storybookConfigFolder,
|
||||
componentsDestinationPath,
|
||||
} = {
|
||||
...defaultOptions,
|
||||
...options,
|
||||
@ -194,26 +206,29 @@ export async function baseGenerator(
|
||||
|
||||
const versionedPackages = await packageManager.getVersionedPackages(packages);
|
||||
|
||||
await fse.ensureDir('./.storybook');
|
||||
await fse.ensureDir(`./${storybookConfigFolder}`);
|
||||
|
||||
await configureMain({
|
||||
framework: { name: frameworkInclude, options: options.framework || {} },
|
||||
docs: { autodocs: 'tag' },
|
||||
addons: pnp ? addons.map(wrapForPnp) : addons,
|
||||
extensions,
|
||||
commonJs,
|
||||
...(staticDir ? { staticDirs: [path.join('..', staticDir)] } : null),
|
||||
...extraMain,
|
||||
...(type !== 'framework'
|
||||
? {
|
||||
core: {
|
||||
builder: builderInclude,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
if (addMainFile) {
|
||||
await configureMain({
|
||||
framework: { name: frameworkInclude, options: options.framework || {} },
|
||||
storybookConfigFolder,
|
||||
docs: { autodocs: 'tag' },
|
||||
addons: pnp ? addons.map(wrapForPnp) : addons,
|
||||
extensions,
|
||||
commonJs,
|
||||
...(staticDir ? { staticDirs: [path.join('..', staticDir)] } : null),
|
||||
...extraMain,
|
||||
...(type !== 'framework'
|
||||
? {
|
||||
core: {
|
||||
builder: builderInclude,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
}
|
||||
|
||||
await configurePreview(rendererId);
|
||||
await configurePreview({ frameworkPreviewParts, storybookConfigFolder });
|
||||
|
||||
// FIXME: temporary workaround for https://github.com/storybookjs/storybook/issues/17516
|
||||
if (
|
||||
@ -226,7 +241,9 @@ export async function baseGenerator(
|
||||
window.global = window;
|
||||
</script>
|
||||
`;
|
||||
await fse.writeFile(`.storybook/preview-head.html`, previewHead, { encoding: 'utf8' });
|
||||
await fse.writeFile(`${storybookConfigFolder}/preview-head.html`, previewHead, {
|
||||
encoding: 'utf8',
|
||||
});
|
||||
}
|
||||
|
||||
const babelDependencies =
|
||||
@ -256,6 +273,6 @@ export async function baseGenerator(
|
||||
|
||||
if (addComponents) {
|
||||
const templateLocation = hasFrameworkTemplates(framework) ? framework : rendererId;
|
||||
await copyComponents(templateLocation, language);
|
||||
await copyComponents(templateLocation, language, componentsDestinationPath);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
import fse from 'fs-extra';
|
||||
import { dedent } from 'ts-dedent';
|
||||
import type { SupportedRenderers, SupportedFrameworks } from '../project_types';
|
||||
|
||||
interface ConfigureMainOptions {
|
||||
addons: string[];
|
||||
extensions?: string[];
|
||||
commonJs?: boolean;
|
||||
staticDirs?: string[];
|
||||
storybookConfigFolder: string;
|
||||
/**
|
||||
* Extra values for main.js
|
||||
*
|
||||
@ -19,10 +19,20 @@ interface ConfigureMainOptions {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface FrameworkPreviewParts {
|
||||
prefix: string;
|
||||
}
|
||||
|
||||
interface ConfigurePreviewOptions {
|
||||
frameworkPreviewParts?: FrameworkPreviewParts;
|
||||
storybookConfigFolder: string;
|
||||
}
|
||||
|
||||
export async function configureMain({
|
||||
addons,
|
||||
extensions = ['js', 'jsx', 'ts', 'tsx'],
|
||||
commonJs = false,
|
||||
storybookConfigFolder,
|
||||
...custom
|
||||
}: ConfigureMainOptions) {
|
||||
const prefix = (await fse.pathExists('./src')) ? '../src' : '../stories';
|
||||
@ -44,7 +54,7 @@ export async function configureMain({
|
||||
// .replaceAll(/"(path\.dirname\(require\.resolve\(path\.join\('.*\))"/g, (_, a) => a)}`;
|
||||
|
||||
await fse.writeFile(
|
||||
`./.storybook/main.${commonJs ? 'cjs' : 'js'}`,
|
||||
`./${storybookConfigFolder}/main.${commonJs ? 'cjs' : 'js'}`,
|
||||
dedent`
|
||||
const path = require('path');
|
||||
${stringified}
|
||||
@ -53,20 +63,9 @@ export async function configureMain({
|
||||
);
|
||||
}
|
||||
|
||||
const frameworkToPreviewParts: Partial<Record<SupportedFrameworks | SupportedRenderers, any>> = {
|
||||
angular: {
|
||||
prefix: dedent`
|
||||
import { setCompodocJson } from "@storybook/addon-docs/angular";
|
||||
import docJson from "../documentation.json";
|
||||
setCompodocJson(docJson);
|
||||
|
||||
`.trimStart(),
|
||||
},
|
||||
};
|
||||
|
||||
export async function configurePreview(framework: SupportedFrameworks | SupportedRenderers) {
|
||||
const { prefix = '', extraParameters = '' } = frameworkToPreviewParts[framework] || {};
|
||||
const previewPath = `./.storybook/preview.js`;
|
||||
export async function configurePreview(options: ConfigurePreviewOptions) {
|
||||
const { prefix = '' } = options?.frameworkPreviewParts || {};
|
||||
const previewPath = `./${options.storybookConfigFolder}/preview.js`;
|
||||
|
||||
// If the framework template included a preview then we have nothing to do
|
||||
if (await fse.pathExists(previewPath)) {
|
||||
@ -83,7 +82,6 @@ export async function configurePreview(framework: SupportedFrameworks | Supporte
|
||||
date: /Date$/,
|
||||
},
|
||||
},
|
||||
${extraParameters}
|
||||
}`
|
||||
.replace(' \n', '')
|
||||
.trim();
|
||||
|
@ -2,6 +2,7 @@ import type { NpmOptions } from '../NpmOptions';
|
||||
import type { SupportedLanguage, Builder, ProjectType } from '../project_types';
|
||||
import type { JsPackageManager } from '../js-package-manager/JsPackageManager';
|
||||
import { type PackageManagerName } from '../js-package-manager/JsPackageManager';
|
||||
import type { FrameworkPreviewParts } from './configure';
|
||||
|
||||
export type GeneratorOptions = {
|
||||
language: SupportedLanguage;
|
||||
@ -9,6 +10,8 @@ export type GeneratorOptions = {
|
||||
linkable: boolean;
|
||||
pnp: boolean;
|
||||
commonJs: boolean;
|
||||
storiesRoots: string[];
|
||||
frameworkPreviewParts?: FrameworkPreviewParts;
|
||||
};
|
||||
|
||||
export interface FrameworkOptions {
|
||||
@ -16,6 +19,7 @@ export interface FrameworkOptions {
|
||||
extraAddons?: string[];
|
||||
staticDir?: string;
|
||||
addScripts?: boolean;
|
||||
addMainFile?: boolean;
|
||||
addComponents?: boolean;
|
||||
addBabel?: boolean;
|
||||
addESLint?: boolean;
|
||||
@ -23,13 +27,16 @@ export interface FrameworkOptions {
|
||||
extensions?: string[];
|
||||
framework?: Record<string, any>;
|
||||
commonJs?: boolean;
|
||||
storybookConfigFolder?: string;
|
||||
componentsDestinationPath?: string;
|
||||
}
|
||||
|
||||
export type Generator = (
|
||||
export type Generator<T = void> = (
|
||||
packageManagerInstance: JsPackageManager,
|
||||
npmOptions: NpmOptions,
|
||||
generatorOptions: GeneratorOptions
|
||||
) => Promise<void>;
|
||||
generatorOptions: GeneratorOptions,
|
||||
commandOptions?: CommandOptions
|
||||
) => Promise<T>;
|
||||
|
||||
export type CommandOptions = {
|
||||
packageManager: PackageManagerName;
|
||||
@ -40,6 +47,7 @@ export type CommandOptions = {
|
||||
html?: boolean;
|
||||
skipInstall?: boolean;
|
||||
parser?: string;
|
||||
// Automatically answer yes to prompts
|
||||
yes?: boolean;
|
||||
builder?: Builder;
|
||||
linkable?: boolean;
|
||||
|
@ -176,19 +176,20 @@ export function addToDevDependenciesIfNotPresent(
|
||||
}
|
||||
}
|
||||
|
||||
export function copyTemplate(templateRoot: string) {
|
||||
export function copyTemplate(templateRoot: string, destination = '.') {
|
||||
const templateDir = path.resolve(templateRoot, `template-csf/`);
|
||||
|
||||
if (!fs.existsSync(templateDir)) {
|
||||
throw new Error(`Couldn't find template dir`);
|
||||
}
|
||||
|
||||
fse.copySync(templateDir, '.', { overwrite: true });
|
||||
fse.copySync(templateDir, destination, { overwrite: true });
|
||||
}
|
||||
|
||||
export async function copyComponents(
|
||||
renderer: SupportedFrameworks | SupportedRenderers,
|
||||
language: SupportedLanguage
|
||||
language: SupportedLanguage,
|
||||
destination?: string
|
||||
) {
|
||||
const languageFolderMapping: Record<SupportedLanguage, string> = {
|
||||
[SupportedLanguage.JAVASCRIPT]: 'js',
|
||||
@ -232,7 +233,7 @@ export async function copyComponents(
|
||||
return './stories';
|
||||
};
|
||||
|
||||
const destinationPath = await targetPath();
|
||||
const destinationPath = destination ?? (await targetPath());
|
||||
await fse.copy(join(getCliDir(), 'rendererAssets/common'), destinationPath, {
|
||||
overwrite: true,
|
||||
});
|
||||
|
1
code/lib/cli/src/index.ts
Normal file
1
code/lib/cli/src/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './js-package-manager';
|
@ -37,11 +37,11 @@ import type { CommandOptions } from './generators/types';
|
||||
|
||||
const logger = console;
|
||||
|
||||
const installStorybook = (
|
||||
projectType: ProjectType,
|
||||
const installStorybook = <Project extends ProjectType>(
|
||||
projectType: Project,
|
||||
packageManager: JsPackageManager,
|
||||
options: CommandOptions
|
||||
): Promise<void> => {
|
||||
): Promise<any> => {
|
||||
const npmOptions: NpmOptions = {
|
||||
installAsDevDependencies: true,
|
||||
skipInstall: options.skipInstall,
|
||||
@ -64,18 +64,8 @@ const installStorybook = (
|
||||
pnp: options.usePnp,
|
||||
};
|
||||
|
||||
const runGenerator: () => Promise<void> = async () => {
|
||||
const runGenerator: () => Promise<any> = async () => {
|
||||
switch (projectType) {
|
||||
case ProjectType.ALREADY_HAS_STORYBOOK:
|
||||
logger.log();
|
||||
paddedLog('There seems to be a Storybook already available in this project.');
|
||||
paddedLog('Apply following command to force:\n');
|
||||
codeLog(['sb init [options] -f']);
|
||||
|
||||
// Add a new line for the clear visibility.
|
||||
logger.log();
|
||||
return Promise.resolve();
|
||||
|
||||
case ProjectType.REACT_SCRIPTS:
|
||||
return reactScriptsGenerator(packageManager, npmOptions, generatorOptions).then(
|
||||
commandLog('Adding Storybook support to your "Create React App" based project')
|
||||
@ -135,9 +125,8 @@ const installStorybook = (
|
||||
);
|
||||
|
||||
case ProjectType.ANGULAR:
|
||||
return angularGenerator(packageManager, npmOptions, generatorOptions).then(
|
||||
commandLog('Adding Storybook support to your "Angular" app\n')
|
||||
);
|
||||
commandLog('Adding Storybook support to your "Angular" app\n');
|
||||
return angularGenerator(packageManager, npmOptions, generatorOptions, options);
|
||||
|
||||
case ProjectType.EMBER:
|
||||
return emberGenerator(packageManager, npmOptions, generatorOptions).then(
|
||||
@ -204,6 +193,13 @@ const installStorybook = (
|
||||
commandLog('Adding Storybook support to your "Server" app\n')
|
||||
);
|
||||
|
||||
case ProjectType.NX /* NX */:
|
||||
paddedLog(
|
||||
'We have detected Nx in your project. Please use `nx g @nrwl/storybook:configuration` to add Storybook to your project.'
|
||||
);
|
||||
paddedLog('For more information, please see https://nx.dev/packages/storybook');
|
||||
return Promise.reject();
|
||||
|
||||
case ProjectType.UNSUPPORTED:
|
||||
paddedLog(`We detected a project type that we don't support yet.`);
|
||||
paddedLog(
|
||||
@ -296,10 +292,7 @@ async function doInitiate(options: CommandOptions, pkg: PackageJson): Promise<vo
|
||||
try {
|
||||
if (projectTypeProvided) {
|
||||
if (installableProjectTypes.includes(projectTypeProvided)) {
|
||||
const storybookInstalled = isStorybookInstalled(packageJson, options.force);
|
||||
projectType = storybookInstalled
|
||||
? ProjectType.ALREADY_HAS_STORYBOOK
|
||||
: projectTypeProvided.toUpperCase();
|
||||
projectType = projectTypeProvided.toUpperCase();
|
||||
} else {
|
||||
done(`The provided project type was not recognized by Storybook: ${projectTypeProvided}`);
|
||||
logger.log(`\nThe project types currently supported by Storybook are:\n`);
|
||||
@ -316,12 +309,27 @@ async function doInitiate(options: CommandOptions, pkg: PackageJson): Promise<vo
|
||||
}
|
||||
done();
|
||||
|
||||
await installStorybook(projectType as ProjectType, packageManager, {
|
||||
const storybookInstalled = isStorybookInstalled(packageJson, options.force);
|
||||
|
||||
if (storybookInstalled && projectType !== ProjectType.ANGULAR) {
|
||||
logger.log();
|
||||
paddedLog('There seems to be a Storybook already available in this project.');
|
||||
paddedLog('Apply following command to force:\n');
|
||||
codeLog(['sb init [options] -f']);
|
||||
|
||||
// Add a new line for the clear visibility.
|
||||
logger.log();
|
||||
return;
|
||||
}
|
||||
|
||||
const installResult = await installStorybook(projectType as ProjectType, packageManager, {
|
||||
...options,
|
||||
...(isEsm ? { commonJs: true } : undefined),
|
||||
}).catch((e) => {
|
||||
process.exit();
|
||||
});
|
||||
|
||||
if (!options.skipInstall) {
|
||||
if (!options.skipInstall && !storybookInstalled) {
|
||||
packageManager.installDependencies();
|
||||
}
|
||||
|
||||
@ -332,7 +340,13 @@ async function doInitiate(options: CommandOptions, pkg: PackageJson): Promise<vo
|
||||
await automigrate({ yes: options.yes || process.env.CI === 'true', packageManager: pkgMgr });
|
||||
|
||||
logger.log('\nTo run your Storybook, type:\n');
|
||||
codeLog([packageManager.getRunStorybookCommand()]);
|
||||
|
||||
if (projectType === ProjectType.ANGULAR) {
|
||||
codeLog([`ng run ${installResult.projectName}:storybook`]);
|
||||
} else {
|
||||
codeLog([packageManager.getRunStorybookCommand()]);
|
||||
}
|
||||
|
||||
logger.log('\nFor more information visit:', chalk.cyan('https://storybook.js.org'));
|
||||
|
||||
if (projectType === ProjectType.REACT_NATIVE) {
|
||||
|
@ -376,9 +376,16 @@ export abstract class JsPackageManager {
|
||||
): // Use generic and conditional type to force `string[]` if fetchAllVersions is true and `string` if false
|
||||
Promise<T extends true ? string[] : string>;
|
||||
|
||||
public executeCommand(command: string, args: string[], stdio?: 'pipe' | 'inherit'): string {
|
||||
public abstract runScript(script: string, args: string[], cwd?: string): string;
|
||||
|
||||
public executeCommand(
|
||||
command: string,
|
||||
args: string[],
|
||||
stdio?: 'pipe' | 'inherit',
|
||||
cwd?: string
|
||||
): string {
|
||||
const commandResult = spawnSync(command, args, {
|
||||
cwd: this.cwd,
|
||||
cwd: cwd ?? this.cwd,
|
||||
stdio: stdio ?? 'pipe',
|
||||
encoding: 'utf-8',
|
||||
shell: true,
|
||||
|
@ -57,6 +57,37 @@ describe('NPM Proxy', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('runScript', () => {
|
||||
describe('npm6', () => {
|
||||
it('should execute script `npm run compodoc -- -e json -d .`', () => {
|
||||
const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockReturnValue('6.0.0');
|
||||
|
||||
npmProxy.runScript('compodoc', ['-e', 'json', '-d', '.']);
|
||||
|
||||
expect(executeCommandSpy).toHaveBeenLastCalledWith(
|
||||
'npm',
|
||||
['run', 'compodoc', '--', '-e', 'json', '-d', '.'],
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('npm7', () => {
|
||||
it('should execute script `npm run compodoc -- -e json -d .`', () => {
|
||||
const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockReturnValue('7.1.0');
|
||||
|
||||
npmProxy.runScript('compodoc', ['-e', 'json', '-d', '.']);
|
||||
|
||||
expect(executeCommandSpy).toHaveBeenLastCalledWith(
|
||||
'npm',
|
||||
['run', 'compodoc', '--', '-e', 'json', '-d', '.'],
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('addDependencies', () => {
|
||||
describe('npm6', () => {
|
||||
it('with devDep it should run `npm install -D @storybook/preview-api`', () => {
|
||||
|
@ -38,6 +38,10 @@ export class NPMProxy extends JsPackageManager {
|
||||
return this.uninstallArgs;
|
||||
}
|
||||
|
||||
public runScript(command: string, args: string[], cwd?: string): string {
|
||||
return this.executeCommand(`npm`, ['run', command, '--', ...args], undefined, cwd);
|
||||
}
|
||||
|
||||
protected getResolutions(packageJson: PackageJson, versions: Record<string, string>) {
|
||||
return {
|
||||
overrides: {
|
||||
|
@ -46,6 +46,21 @@ describe('NPM Proxy', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('runScript', () => {
|
||||
it('should execute script `yarn compodoc -- -e json -d .`', () => {
|
||||
const executeCommandSpy = jest.spyOn(pnpmProxy, 'executeCommand').mockReturnValue('7.1.0');
|
||||
|
||||
pnpmProxy.runScript('compodoc', ['-e', 'json', '-d', '.']);
|
||||
|
||||
expect(executeCommandSpy).toHaveBeenLastCalledWith(
|
||||
'pnpm',
|
||||
['run', 'compodoc', '-e', 'json', '-d', '.'],
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addDependencies', () => {
|
||||
it('with devDep it should run `pnpm add -D @storybook/preview-api`', () => {
|
||||
const executeCommandSpy = jest.spyOn(pnpmProxy, 'executeCommand').mockReturnValue('6.0.0');
|
||||
|
@ -24,6 +24,10 @@ export class PNPMProxy extends JsPackageManager {
|
||||
return this.executeCommand('pnpm', ['--version']);
|
||||
}
|
||||
|
||||
runScript(command: string, args: string[], cwd?: string): string {
|
||||
return this.executeCommand(`pnpm`, ['run', command, ...args], undefined, cwd);
|
||||
}
|
||||
|
||||
protected getResolutions(packageJson: PackageJson, versions: Record<string, string>) {
|
||||
return {
|
||||
overrides: {
|
||||
|
@ -46,6 +46,21 @@ describe('Yarn 1 Proxy', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('runScript', () => {
|
||||
it('should execute script `yarn compodoc -- -e json -d .`', () => {
|
||||
const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockReturnValue('7.1.0');
|
||||
|
||||
yarn1Proxy.runScript('compodoc', ['-e', 'json', '-d', '.']);
|
||||
|
||||
expect(executeCommandSpy).toHaveBeenLastCalledWith(
|
||||
'yarn',
|
||||
['compodoc', '-e', 'json', '-d', '.'],
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addDependencies', () => {
|
||||
it('with devDep it should run `yarn install -D --ignore-workspace-root-check @storybook/preview-api`', () => {
|
||||
const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockReturnValue('');
|
||||
|
@ -16,6 +16,10 @@ export class Yarn1Proxy extends JsPackageManager {
|
||||
return `yarn ${command}`;
|
||||
}
|
||||
|
||||
runScript(command: string, args: string[], cwd?: string): string {
|
||||
return this.executeCommand(`yarn`, [command, ...args], undefined, cwd);
|
||||
}
|
||||
|
||||
protected getResolutions(packageJson: PackageJson, versions: Record<string, string>) {
|
||||
return {
|
||||
resolutions: {
|
||||
|
@ -31,6 +31,21 @@ describe('Yarn 2 Proxy', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('runScript', () => {
|
||||
it('should execute script `yarn compodoc -- -e json -d .`', () => {
|
||||
const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockReturnValue('7.1.0');
|
||||
|
||||
yarn2Proxy.runScript('compodoc', ['-e', 'json', '-d', '.']);
|
||||
|
||||
expect(executeCommandSpy).toHaveBeenLastCalledWith(
|
||||
'yarn',
|
||||
['compodoc', '-e', 'json', '-d', '.'],
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setRegistryUrl', () => {
|
||||
it('should run `yarn config set npmRegistryServer https://foo.bar`', () => {
|
||||
const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockReturnValue('');
|
||||
|
@ -17,6 +17,10 @@ export class Yarn2Proxy extends JsPackageManager {
|
||||
return `yarn ${command}`;
|
||||
}
|
||||
|
||||
runScript(command: string, args: string[], cwd?: string): string {
|
||||
return this.executeCommand(`yarn`, [command, ...args], undefined, cwd);
|
||||
}
|
||||
|
||||
protected getResolutions(packageJson: PackageJson, versions: Record<string, string>) {
|
||||
return {
|
||||
resolutions: {
|
||||
|
@ -69,7 +69,6 @@ export enum ProjectType {
|
||||
SFC_VUE = 'SFC_VUE',
|
||||
ANGULAR = 'ANGULAR',
|
||||
EMBER = 'EMBER',
|
||||
ALREADY_HAS_STORYBOOK = 'ALREADY_HAS_STORYBOOK',
|
||||
WEB_COMPONENTS = 'WEB_COMPONENTS',
|
||||
MITHRIL = 'MITHRIL',
|
||||
MARIONETTE = 'MARIONETTE',
|
||||
@ -82,6 +81,7 @@ export enum ProjectType {
|
||||
RAX = 'RAX',
|
||||
AURELIA = 'AURELIA',
|
||||
SERVER = 'SERVER',
|
||||
NX = 'NX',
|
||||
}
|
||||
|
||||
export enum CoreBuilder {
|
||||
@ -192,20 +192,6 @@ export const supportedTemplates: TemplateConfiguration[] = [
|
||||
return dependencies.every(Boolean) || files.every(Boolean);
|
||||
},
|
||||
},
|
||||
{
|
||||
preset: ProjectType.WEBPACK_REACT,
|
||||
dependencies: ['react', 'webpack'],
|
||||
matcherFunction: ({ dependencies }) => {
|
||||
return dependencies.every(Boolean);
|
||||
},
|
||||
},
|
||||
{
|
||||
preset: ProjectType.REACT,
|
||||
dependencies: ['react'],
|
||||
matcherFunction: ({ dependencies }) => {
|
||||
return dependencies.every(Boolean);
|
||||
},
|
||||
},
|
||||
{
|
||||
preset: ProjectType.ANGULAR,
|
||||
dependencies: ['@angular/core'],
|
||||
@ -284,6 +270,22 @@ export const supportedTemplates: TemplateConfiguration[] = [
|
||||
return dependencies.every(Boolean);
|
||||
},
|
||||
},
|
||||
// DO NOT MOVE ANY TEMPLATES BELOW THIS LINE
|
||||
// React is part of every Template, after Storybook is initialized once
|
||||
{
|
||||
preset: ProjectType.WEBPACK_REACT,
|
||||
dependencies: ['react', 'webpack'],
|
||||
matcherFunction: ({ dependencies }) => {
|
||||
return dependencies.every(Boolean);
|
||||
},
|
||||
},
|
||||
{
|
||||
preset: ProjectType.REACT,
|
||||
dependencies: ['react'],
|
||||
matcherFunction: ({ dependencies }) => {
|
||||
return dependencies.every(Boolean);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// A TemplateConfiguration that matches unsupported frameworks
|
||||
@ -300,11 +302,7 @@ export const unsupportedTemplate: TemplateConfiguration = {
|
||||
},
|
||||
};
|
||||
|
||||
const notInstallableProjectTypes: ProjectType[] = [
|
||||
ProjectType.UNDETECTED,
|
||||
ProjectType.UNSUPPORTED,
|
||||
ProjectType.ALREADY_HAS_STORYBOOK,
|
||||
];
|
||||
const notInstallableProjectTypes: ProjectType[] = [ProjectType.UNDETECTED, ProjectType.UNSUPPORTED];
|
||||
|
||||
export const installableProjectTypes = Object.values(ProjectType)
|
||||
.filter((type) => !notInstallableProjectTypes.includes(type))
|
||||
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"extends": "%SET_DURING_SB_INIT%",
|
||||
"extends": "../tsconfig.app.json",
|
||||
"compilerOptions": {
|
||||
"types": ["node"],
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"exclude": ["../src/test.ts", "../src/**/*.spec.ts", "../projects/**/*.spec.ts"],
|
||||
"include": ["../src/**/*", "../projects/**/*"],
|
||||
"exclude": ["../src/test.ts", "../src/**/*.spec.ts"],
|
||||
"include": ["../src/**/*"],
|
||||
"files": ["./typings.d.ts"]
|
||||
}
|
||||
|
178
code/yarn.lock
178
code/yarn.lock
@ -22,7 +22,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@angular-devkit/architect@npm:0.1500.5, @angular-devkit/architect@npm:^0.1500.4":
|
||||
"@angular-devkit/architect@npm:0.1500.4":
|
||||
version: 0.1500.4
|
||||
resolution: "@angular-devkit/architect@npm:0.1500.4"
|
||||
dependencies:
|
||||
"@angular-devkit/core": 15.0.4
|
||||
rxjs: 6.6.7
|
||||
checksum: b6be2ddc3b656cdb86e147238501e6cc00254d9ee711f0dd9c3ae384c1faea84774dcc0b1c11dea489828307e04e081beb0045f12d4d0a879aecabb39d492584
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@angular-devkit/architect@npm:^0.1500.4":
|
||||
version: 0.1500.5
|
||||
resolution: "@angular-devkit/architect@npm:0.1500.5"
|
||||
dependencies:
|
||||
@ -33,13 +43,13 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"@angular-devkit/build-angular@npm:^15.0.4":
|
||||
version: 15.0.5
|
||||
resolution: "@angular-devkit/build-angular@npm:15.0.5"
|
||||
version: 15.0.4
|
||||
resolution: "@angular-devkit/build-angular@npm:15.0.4"
|
||||
dependencies:
|
||||
"@ampproject/remapping": 2.2.0
|
||||
"@angular-devkit/architect": 0.1500.5
|
||||
"@angular-devkit/build-webpack": 0.1500.5
|
||||
"@angular-devkit/core": 15.0.5
|
||||
"@angular-devkit/architect": 0.1500.4
|
||||
"@angular-devkit/build-webpack": 0.1500.4
|
||||
"@angular-devkit/core": 15.0.4
|
||||
"@babel/core": 7.20.2
|
||||
"@babel/generator": 7.20.4
|
||||
"@babel/helper-annotate-as-pure": 7.18.6
|
||||
@ -50,7 +60,7 @@ __metadata:
|
||||
"@babel/runtime": 7.20.1
|
||||
"@babel/template": 7.18.10
|
||||
"@discoveryjs/json-ext": 0.5.7
|
||||
"@ngtools/webpack": 15.0.5
|
||||
"@ngtools/webpack": 15.0.4
|
||||
ansi-colors: 4.1.3
|
||||
autoprefixer: 10.4.13
|
||||
babel-loader: 9.1.0
|
||||
@ -124,20 +134,38 @@ __metadata:
|
||||
optional: true
|
||||
tailwindcss:
|
||||
optional: true
|
||||
checksum: 067685257b42f89ba6407846b3cac2ed28aad91541cb6cefdd55e29e6d0bc844321013bb2b47cbfe0b06495cd54e568f355ebf56ef7635301a8379be5bd68771
|
||||
checksum: 2c3e835bbac7715d1cf1cb1e27af6f09ad1e8eeb389e18282e0991751e4902c05d017c9d5d836ef2e0f38cfc6540a7ef72d8ed12962d1138c8ebc7f7fee8ac20
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@angular-devkit/build-webpack@npm:0.1500.5":
|
||||
version: 0.1500.5
|
||||
resolution: "@angular-devkit/build-webpack@npm:0.1500.5"
|
||||
"@angular-devkit/build-webpack@npm:0.1500.4":
|
||||
version: 0.1500.4
|
||||
resolution: "@angular-devkit/build-webpack@npm:0.1500.4"
|
||||
dependencies:
|
||||
"@angular-devkit/architect": 0.1500.5
|
||||
"@angular-devkit/architect": 0.1500.4
|
||||
rxjs: 6.6.7
|
||||
peerDependencies:
|
||||
webpack: ^5.30.0
|
||||
webpack-dev-server: ^4.0.0
|
||||
checksum: 06438ae79c1fcebbb170a5ec27c3946dfa4f4cd8ed80588deeefc54ab4550b2d779119eb7949e1477c44c3e29e8ca85369cb430c2833295b4823495a4c725052
|
||||
checksum: 5aeb788acbed900c9fa2985d178ba1248e842fd175a5f1e2f4ef5a833e812e7cb0ddc7344fe2b208e0f58ad15c9db4fc8ff6fc9408973df992478cbd84df2250
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@angular-devkit/core@npm:15.0.4":
|
||||
version: 15.0.4
|
||||
resolution: "@angular-devkit/core@npm:15.0.4"
|
||||
dependencies:
|
||||
ajv: 8.11.0
|
||||
ajv-formats: 2.1.1
|
||||
jsonc-parser: 3.2.0
|
||||
rxjs: 6.6.7
|
||||
source-map: 0.7.4
|
||||
peerDependencies:
|
||||
chokidar: ^3.5.2
|
||||
peerDependenciesMeta:
|
||||
chokidar:
|
||||
optional: true
|
||||
checksum: 428a20d96e237d24a62ae3d5284e3140f906e212883e094cc64ec622a5065234f001bd21f9608ad2478088c1cc40aadf48bd53c399ad02be0c98b61d27d3ba11
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -159,27 +187,27 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@angular-devkit/schematics@npm:15.0.5":
|
||||
version: 15.0.5
|
||||
resolution: "@angular-devkit/schematics@npm:15.0.5"
|
||||
"@angular-devkit/schematics@npm:15.0.4":
|
||||
version: 15.0.4
|
||||
resolution: "@angular-devkit/schematics@npm:15.0.4"
|
||||
dependencies:
|
||||
"@angular-devkit/core": 15.0.5
|
||||
"@angular-devkit/core": 15.0.4
|
||||
jsonc-parser: 3.2.0
|
||||
magic-string: 0.26.7
|
||||
ora: 5.4.1
|
||||
rxjs: 6.6.7
|
||||
checksum: c008f7dcb0c722b7a7f7a2a4b69c45cf75ac0a7c0c8fbdb44453bd930ddca9692965a7d6de276201d78d10c5e1c6a04fe494f7cdfbdcd51b13186543e159e8c0
|
||||
checksum: b53397b5770987bc98f697bcde56cef23b0958e4ebcdf7713c7ba8c56295869a069259fdbb480495e9ee79dae342ce88b27b64f518eeb974a38c981c4602f726
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@angular/cli@npm:^15.0.4":
|
||||
version: 15.0.5
|
||||
resolution: "@angular/cli@npm:15.0.5"
|
||||
version: 15.0.4
|
||||
resolution: "@angular/cli@npm:15.0.4"
|
||||
dependencies:
|
||||
"@angular-devkit/architect": 0.1500.5
|
||||
"@angular-devkit/core": 15.0.5
|
||||
"@angular-devkit/schematics": 15.0.5
|
||||
"@schematics/angular": 15.0.5
|
||||
"@angular-devkit/architect": 0.1500.4
|
||||
"@angular-devkit/core": 15.0.4
|
||||
"@angular-devkit/schematics": 15.0.4
|
||||
"@schematics/angular": 15.0.4
|
||||
"@yarnpkg/lockfile": 1.1.0
|
||||
ansi-colors: 4.1.3
|
||||
ini: 3.0.1
|
||||
@ -196,7 +224,7 @@ __metadata:
|
||||
yargs: 17.6.2
|
||||
bin:
|
||||
ng: bin/ng.js
|
||||
checksum: 7cb92b2f0ed2f1dea4b3c44e6cefe4ebb6e04cfb98c622daf4815888645c00bdd0d5acf1e4a12ee9a122ccc2b55864aedeabe88aeedcd83d2a33d39a27be86a2
|
||||
checksum: 1443a089fd99b47ddfe53a9ebcbd10a56357a43bdb25597f0dd6e540508bea9fd74e3b640969b2c5d1eba346fd189426bc355109e2a1fedffa76702f4b8aabb5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -1275,13 +1303,13 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"@babel/plugin-transform-block-scoping@npm:^7.20.2, @babel/plugin-transform-block-scoping@npm:^7.8.3":
|
||||
version: 7.20.11
|
||||
resolution: "@babel/plugin-transform-block-scoping@npm:7.20.11"
|
||||
version: 7.20.8
|
||||
resolution: "@babel/plugin-transform-block-scoping@npm:7.20.8"
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils": ^7.20.2
|
||||
peerDependencies:
|
||||
"@babel/core": ^7.0.0-0
|
||||
checksum: 3840c342c5ef6c53c750bf3801c30b3770b016516b4589d164e227688ed2dd0aa86496ac340b0735b9fa0cee30ff5338f1e291b2a91df5cce17e585298674e8b
|
||||
checksum: 6c324f45b889e1de02f1f60b748d2de3b71dc90b9b2075e38f008e7363825fad1a4894bda8bd2eb632f68e351e11451ed86b5e97b081ed90a30390585675b27f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -1421,33 +1449,33 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"@babel/plugin-transform-modules-amd@npm:^7.13.0, @babel/plugin-transform-modules-amd@npm:^7.19.6":
|
||||
version: 7.20.11
|
||||
resolution: "@babel/plugin-transform-modules-amd@npm:7.20.11"
|
||||
version: 7.20.7
|
||||
resolution: "@babel/plugin-transform-modules-amd@npm:7.20.7"
|
||||
dependencies:
|
||||
"@babel/helper-module-transforms": ^7.20.11
|
||||
"@babel/helper-plugin-utils": ^7.20.2
|
||||
peerDependencies:
|
||||
"@babel/core": ^7.0.0-0
|
||||
checksum: 327077cc746d2ef14d0792a970058d9b7170ff480c1d1d7acf874ef7cfeae0c680e86a45896ea27066e9ebdd82dc2be09d321385eef1e0b4255659d75ea2e008
|
||||
checksum: 85973356d2183711ebe3338899d726070ea4f06c9fccdd2808d80337a791935b409605e4c610660a159bb4d495332d2e33b387c0384c165f898fe0107c1ddb88
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/plugin-transform-modules-commonjs@npm:^7.13.8, @babel/plugin-transform-modules-commonjs@npm:^7.19.6, @babel/plugin-transform-modules-commonjs@npm:^7.2.0":
|
||||
version: 7.20.11
|
||||
resolution: "@babel/plugin-transform-modules-commonjs@npm:7.20.11"
|
||||
version: 7.20.7
|
||||
resolution: "@babel/plugin-transform-modules-commonjs@npm:7.20.7"
|
||||
dependencies:
|
||||
"@babel/helper-module-transforms": ^7.20.11
|
||||
"@babel/helper-plugin-utils": ^7.20.2
|
||||
"@babel/helper-simple-access": ^7.20.2
|
||||
peerDependencies:
|
||||
"@babel/core": ^7.0.0-0
|
||||
checksum: f3a3281c252a978255076ff7274e4ac1ec252e0db4b3d73122c278ce9fd8318179fc804638ce726870146fa0845e2559711453ce7a391dc2a792d96dc0f6b04c
|
||||
checksum: 57024919a30796a4b087e78a9ac14d31a6ba43c6fdd38f55e1fce25a932e660f4b898037480f9b4dc73faae2f2846b0faa73697a0819e0382f58759ff6b3f732
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/plugin-transform-modules-systemjs@npm:^7.19.6":
|
||||
version: 7.20.11
|
||||
resolution: "@babel/plugin-transform-modules-systemjs@npm:7.20.11"
|
||||
version: 7.19.6
|
||||
resolution: "@babel/plugin-transform-modules-systemjs@npm:7.19.6"
|
||||
dependencies:
|
||||
"@babel/helper-hoist-variables": ^7.18.6
|
||||
"@babel/helper-module-transforms": ^7.20.11
|
||||
@ -1455,7 +1483,7 @@ __metadata:
|
||||
"@babel/helper-validator-identifier": ^7.19.1
|
||||
peerDependencies:
|
||||
"@babel/core": ^7.0.0-0
|
||||
checksum: 1843b2044b711765581d6130ea7901afde6e6f5af4e4219ab675033a090f4dacb6656bfada8f211a2cd9bbae256c7f4bd0b8613b750e56674feee5252de1ad76
|
||||
checksum: 0f05058170f1d2027bda95ae8d57b021698f4d7f33df859c95db072ae80941079c5049ac12bde3bc87311436e9451e5edca8205754e9a4e5b54bd6e4f3ecf2ed
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -1996,7 +2024,25 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.20.1, @babel/traverse@npm:^7.20.10, @babel/traverse@npm:^7.20.12, @babel/traverse@npm:^7.20.5, @babel/traverse@npm:^7.20.7, @babel/traverse@npm:^7.4.5, @babel/traverse@npm:^7.7.0, @babel/traverse@npm:^7.7.2, @babel/traverse@npm:^7.8.6":
|
||||
"@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.20.1, @babel/traverse@npm:^7.20.5, @babel/traverse@npm:^7.4.5, @babel/traverse@npm:^7.7.0, @babel/traverse@npm:^7.7.2, @babel/traverse@npm:^7.8.6":
|
||||
version: 7.20.8
|
||||
resolution: "@babel/traverse@npm:7.20.8"
|
||||
dependencies:
|
||||
"@babel/code-frame": ^7.18.6
|
||||
"@babel/generator": ^7.20.7
|
||||
"@babel/helper-environment-visitor": ^7.18.9
|
||||
"@babel/helper-function-name": ^7.19.0
|
||||
"@babel/helper-hoist-variables": ^7.18.6
|
||||
"@babel/helper-split-export-declaration": ^7.18.6
|
||||
"@babel/parser": ^7.20.7
|
||||
"@babel/types": ^7.20.7
|
||||
debug: ^4.1.0
|
||||
globals: ^11.1.0
|
||||
checksum: aef74e2b334b5c92a224dbe68357ba2383d43804fb7a5c6e76ca477d6640ddd3f428280687fdd413d6729a00d3f61f6ba86acd91a18d75126e107d9db91f008c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/traverse@npm:^7.20.10, @babel/traverse@npm:^7.20.12":
|
||||
version: 7.20.12
|
||||
resolution: "@babel/traverse@npm:7.20.12"
|
||||
dependencies:
|
||||
@ -2014,6 +2060,24 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/traverse@npm:^7.20.7":
|
||||
version: 7.20.10
|
||||
resolution: "@babel/traverse@npm:7.20.10"
|
||||
dependencies:
|
||||
"@babel/code-frame": ^7.18.6
|
||||
"@babel/generator": ^7.20.7
|
||||
"@babel/helper-environment-visitor": ^7.18.9
|
||||
"@babel/helper-function-name": ^7.19.0
|
||||
"@babel/helper-hoist-variables": ^7.18.6
|
||||
"@babel/helper-split-export-declaration": ^7.18.6
|
||||
"@babel/parser": ^7.20.7
|
||||
"@babel/types": ^7.20.7
|
||||
debug: ^4.1.0
|
||||
globals: ^11.1.0
|
||||
checksum: a712402374c2e1cdd7e7880deda0f0051123c09abc9a110e4594bf90c858211e678185b927dffe8780de981ff87ac98bcffdc3fbf46c262bd21b6d64cd1d3b58
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/types@npm:^7.0.0, @babel/types@npm:^7.11.5, @babel/types@npm:^7.18.10, @babel/types@npm:^7.18.6, @babel/types@npm:^7.18.8, @babel/types@npm:^7.18.9, @babel/types@npm:^7.19.0, @babel/types@npm:^7.2.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.2, @babel/types@npm:^7.20.5, @babel/types@npm:^7.20.7, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.6.1, @babel/types@npm:^7.7.0, @babel/types@npm:^7.7.2, @babel/types@npm:^7.8.3, @babel/types@npm:^7.8.6, @babel/types@npm:^7.8.7, @babel/types@npm:^7.9.6":
|
||||
version: 7.20.7
|
||||
resolution: "@babel/types@npm:7.20.7"
|
||||
@ -4022,14 +4086,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@ngtools/webpack@npm:15.0.5":
|
||||
version: 15.0.5
|
||||
resolution: "@ngtools/webpack@npm:15.0.5"
|
||||
"@ngtools/webpack@npm:15.0.4":
|
||||
version: 15.0.4
|
||||
resolution: "@ngtools/webpack@npm:15.0.4"
|
||||
peerDependencies:
|
||||
"@angular/compiler-cli": ^15.0.0
|
||||
typescript: ~4.8.2
|
||||
webpack: ^5.54.0
|
||||
checksum: 8314dbba50bdbbc396baad9408c99aa56230de833e32398821f4b7c03f9db87d03fafbc1c098780172b42e92f71c0b86a6e25b0c1acba79037d14872108f125d
|
||||
checksum: 978fa56a13a86974d678c57344a5e4390cddf29fadb4adb1e1012210b77c4c91a581af9d2488f164258ce6a03918b60585c3c559523bf6c6a2bf415c11990c07
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -4961,14 +5025,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@schematics/angular@npm:15.0.5":
|
||||
version: 15.0.5
|
||||
resolution: "@schematics/angular@npm:15.0.5"
|
||||
"@schematics/angular@npm:15.0.4":
|
||||
version: 15.0.4
|
||||
resolution: "@schematics/angular@npm:15.0.4"
|
||||
dependencies:
|
||||
"@angular-devkit/core": 15.0.5
|
||||
"@angular-devkit/schematics": 15.0.5
|
||||
"@angular-devkit/core": 15.0.4
|
||||
"@angular-devkit/schematics": 15.0.4
|
||||
jsonc-parser: 3.2.0
|
||||
checksum: 1c978e1fde5b4028be4e5a2a632f32c8b1330bb85d27b1bf80cb62515905a77bf36bce224691c9a9b1d002c7bbf2352993181dd0c7f3eee6348ea933ec9cf991
|
||||
checksum: 4b5475acaeddb31d424e3911014d12e85bf75caff267c2d9038e967ce7f3cff2d172fef63a88e3f40bbb9cf4f071d7a1fcbc2745f9ec432c5e5b96128924b576
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -11474,9 +11538,9 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"caniuse-lite@npm:^1.0.30001400, caniuse-lite@npm:^1.0.30001406, caniuse-lite@npm:^1.0.30001426":
|
||||
version: 1.0.30001442
|
||||
resolution: "caniuse-lite@npm:1.0.30001442"
|
||||
checksum: 02d10a1d6a83cc88771a42ea5aa0c98f5768180c69badeec2bf40d269bbcbd0239a3c197af5e5dce51d0bd5d04e069394cbe611f489082c8244ab95f597e1842
|
||||
version: 1.0.30001441
|
||||
resolution: "caniuse-lite@npm:1.0.30001441"
|
||||
checksum: 4b91bfc03cdbb9cf54225bbc36c2c568879d05ff8f2a34bdafbd7e5acc578d913b2d169bab4bf8a0992678e308779cd5603be0928d6552acefebfc52ded73aa1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -12419,11 +12483,11 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"core-js-compat@npm:^3.25.1":
|
||||
version: 3.27.1
|
||||
resolution: "core-js-compat@npm:3.27.1"
|
||||
version: 3.26.1
|
||||
resolution: "core-js-compat@npm:3.26.1"
|
||||
dependencies:
|
||||
browserslist: ^4.21.4
|
||||
checksum: 635ffcc3f40ca4cb45b10ea805ebf57bbba69873014c89bec96ae09f15cbd3012bd5102bdf87551ef2f1c629e279837632200c4888428035cf822f6e40dc383b
|
||||
checksum: 2d798049758900a7fd83958e02d1d46d35157dbaa6f916c358f735bfe3095cdf5b54dc999363e654445a94417005eb548b9acc47e1d18eda3d1a43cf05b350a5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -20376,11 +20440,11 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"memfs@npm:^3.4.1, memfs@npm:^3.4.3":
|
||||
version: 3.4.13
|
||||
resolution: "memfs@npm:3.4.13"
|
||||
version: 3.4.12
|
||||
resolution: "memfs@npm:3.4.12"
|
||||
dependencies:
|
||||
fs-monkey: ^1.0.3
|
||||
checksum: f14ab3ff938eacf688577d1b0f7bf77ca3a05d4df9c335b024ed6790e6b224b569cc4b61c1de604c0420a0fac6b3fbf3f283c72fd2be9ce395534539599ac63b
|
||||
checksum: 60c44a3887fb02fc2f625dca0f801db5174cd9990ebb6aa5871b6800c442f2b5d1d900168db3a717c380dda76e3c891afc4623ac3a1568a2978bf05bbf727f23
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -5,24 +5,4 @@
|
||||
npx storybook init
|
||||
```
|
||||
|
||||
- Update your `angular.json` file to include Storybook's custom builder:
|
||||
|
||||
```json
|
||||
{
|
||||
"storybook": {
|
||||
"builder": "@storybook/angular:start-storybook",
|
||||
"options": {
|
||||
"browserTarget": "angular-cli:build",
|
||||
"port": 6006
|
||||
}
|
||||
},
|
||||
"build-storybook": {
|
||||
"builder": "@storybook/angular:build-storybook",
|
||||
"options": {
|
||||
"browserTarget": "angular-cli:build"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you run into issues with the installation, check the [Troubleshooting section](#troubleshooting) below for guidance on how to solve it.
|
@ -1,20 +1,15 @@
|
||||
import { readJSON, writeJSON } from 'fs-extra';
|
||||
import { join } from 'path';
|
||||
|
||||
const logger = console;
|
||||
|
||||
export async function updatePackageScripts({ cwd, prefix }: { cwd: string; prefix: string }) {
|
||||
logger.info(`🔢 Adding package scripts:`);
|
||||
const packageJsonPath = join(cwd, 'package.json');
|
||||
const packageJson = await readJSON(packageJsonPath);
|
||||
packageJson.scripts = {
|
||||
...packageJson.scripts,
|
||||
storybook: packageJson.scripts.storybook.replace(/(npx )?storybook/, `${prefix} storybook`),
|
||||
'build-storybook': packageJson.scripts['build-storybook'].replace(
|
||||
/(npx )?storybook/,
|
||||
`${prefix} storybook`
|
||||
),
|
||||
|
||||
...(packageJson.scripts.storybook && {
|
||||
storybook: `${prefix} ${packageJson.scripts.storybook}`,
|
||||
'build-storybook': `${prefix} ${packageJson.scripts['build-storybook']}`,
|
||||
}),
|
||||
// See comment in combine-compodoc as to why this is necessary
|
||||
...(packageJson.scripts['docs:json'] && {
|
||||
'docs:json': 'DIR=$PWD; cd ../../scripts; yarn ts-node combine-compodoc $DIR',
|
||||
|
Loading…
x
Reference in New Issue
Block a user