使用Angular来使用Storybook

首先

我打算在Angular中实践Atomic Design,所以尝试使用Storybook。
由于遇到了一些问题,所以我想记录下来。
在引入过程中,官方文档和这篇文章对我很有参考价值。
https://qiita.com/Quramy/items/463ed80f0d6fcd9e3939

环境

這是我們所測試的環境。

    • Angular: 6.0.3

 

    storybook: 3.4.8

引入

执行以下命令即可。
在项目中应该生成了用于storybook的文件。

npm i -g @storybook/cli
cd {対象プロジェクトのディレクトリ}
getstorybook

在 getstorybook 上进行的活动如下所述。
https://storybook.js.org/basics/guide-angular/#docs-content

请注意,如果没有将storybook相关的文件添加到src/tsconfig.app.json的exclude中,将会在angular构建时出现错误。

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "module": "es2015",
    "types": []
  },
  "exclude": [
    "src/test.ts",
    "**/*.spec.ts",
    "stories",            // 追加
    "**/**.stories.ts"    // 追加
  ]
}

打开故事书应用。

可以通过以下命令之一启动 Storybook。在浏览器中访问 localhost:6006 可以进行确认。

yarn storybook
# or
npm run storybook

如果发生无法读取未定义的属性’compilation’的情况

听说要使用Angular6,似乎必须使用StoryBook 4.0-alpha。

如果出现了“Module build failed: Error: Cannot find module ‘babel-core’”这个错误。

安装babel-core能解决这个问题。

yarn add babel-core --dev

解决组件的依赖关系 de

举个例子,如果在故事板中使用了名为”item”的组件,同时使用了名为”price”的组件,就必须解决它们之间的依赖关系。
由于storybook不查看angular的模块文件,所以如果仅在故事板中添加了”item”组件而没有添加”price”元素,它会生气地告诉你,它不知道”price”是什么。
解决依赖关系的方法如下所示。它与模块文件类似,所以我想应该能轻松写出来。

const itemStories = storiesOf('{story名}', module);
itemStories.addDecorator(
  moduleMetadata({
    declarations: [
       PriceComponent
    ],
    imports: [],
    providers: []
  })
);

读取为全局样式的方法

我认为有时候你可能会想要引用各个组件中全局定义的样式。
在Angular中,只需要将样式添加到angular.json中即可,但是在Storybook中,与angular.json无关,因此你需要自己实现全局的引用。

在scss的情况下,您可以在story文件(src/stories/*.stories.ts)中通过以下方式导入目标文件。

import '!style-loader!css-loader!sass-loader!../styles.scss';

在 CSS 的情况下,只需要 sass-loader 而不需要 scss。

import '!style-loader!css-loader!../styles.css';

使用旋钮

knobs是一个可以在storybook上动态更改component的输入值的插件。由于默认情况下没有包含在内,所以需要手动添加。

yarn add @storybook/addon-knobs --dev

将其添加到storybook/addons.js中。


import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';
import '@storybook/addon-notes/register';
import '@storybook/addon-knobs/register';  // 追加

这个故事中会给组件添加knobs。如果是用Angular,则需要导入适用于Angular的knobs。


import { withKnobs, text, number, color, object } from '@storybook/addon-knobs/angular';

const itemStories = storiesOf('{story名}', module);
txtContainerStories.addDecorator(withKnobs);

在导入时,以src为起点使用路径进行导入。

在使用angular时,如果要在scss或ts文件中导入其他文件,可以从任何文件中使用以下方式以src为起点编写路径(取决于tsconfig的配置)。


// e.g.
import { ButtonComponent } from 'src/app/shared/button/button.component.ts';

// e.g.
@import 'src/variables/colors.scss';

然而,在storybook中,它无法解决路径,导致出现错误。
这也需要自己解决。
方法是通过扩展storybook的webpack配置来实现。

    1. 在storybook的根目录下创建webpack.config.js文件。

webpack.config.js

const genDefaultConfig = require(‘@storybook/angular/dist/server/config/defaults/webpack.config.js’);
const path = require(‘path’);

module.exports = (baseConfig, env) => {
const config = genDefaultConfig(baseConfig, env);

return config;
};

添加设置以解决src路径的别名。这样,在导入时即使从src指定,storybook也不会抱怨。

webpack.config.js

const genDefaultConfig = require(‘@storybook/angular/dist/server/config/defaults/webpack.config.js’);
const path = require(‘path’);

module.exports = (baseConfig, env) => {
const config = genDefaultConfig(baseConfig, env);

// 追加
config.resolve = {
…config.resolve,
alias: {
src: path.resolve(__dirname, ‘../src’)
}
};

return config;
};

我觉得未来还会有其他情况需要自己扩展webpack的配置,所以最好一开始就准备好webpack.config.js。

静态文件的引用

我认为经常会有在组件等中引用assets下的图像或图标的情况,但要在storybook中加载assets文件,需要在启动或构建时添加选项。
打开package.json并修改scripts。


{
  "name": "test-project",
  "version": "0.0.0",
  "scripts": {
    // 省略...
    "storybook": "start-storybook -p 6006 -s ./src",  // 修正
    "build-storybook": "build-storybook -s ./src"    // 修正
  },
  // 省略...
}

我正在做的是添加一个名为static-dir的选项。这样,在构建时,生成的目录中将包含一个名为assets的目录,从storybook上也可以引用该目录。为什么指定的值不是assets而是src呢?因为只有指定目录中的文件和子目录会被展开,而指定的目录本身不会被展开。在angular中引用图像等时,通常会使用assets/image/item.png这样的路径,但如果在static-dir选项中指定了assets,那么只能通过image/item.png引用。但是,如果指定src,将会生成很多不必要的文件,如果您知道更好的方法,请务必告诉我!

最后

虽然遇到了一些问题,但是能够将组件列出并关联起来,非常方便!而且根据atomic design的理念构建,使得组件的可重用性增强,代码维护也更容易,简直是一大福利。虽然一开始可能会花费一些时间,但是我希望从现在开始都能意识到atomic design并进行开发。

bannerAds