Nuxt.js x Class API x Storybook (x SCSS)
前提・環境
$ node -v v14.17.3 $ npm -v 7.19.1 $ yarn -v 1.22.10 $ nuxt -v @nuxt/cli v2.15.8
- Nuxt.js x TypeScript x Class API のプロジェクトが用意されていること
Class API の Nuxt.js で Storybook を使ってみる
まずはデフォルトで動作確認
1. まずは https://storybook.js.org/docs/react/get-started/install に従って Storybook をインストール
$ npx sb init
2. デフォルト状態で動作確認
$ yarn storybook
3. 問題ないことを確認
まぁ。。。Options API の例だし、できるよね。
続いて、↑ で生成された Vue ファイルを Class API 向けに編集する
1. 編集作業
// ./stories/Button.vue <template> <button type="button" :class="classes" @click="onClick" :style="style">{{ label }}</button> </template> - <script> - import './button.css'; + <script lang="ts"> + import { Vue, Component, Prop } from 'vue-property-decorator' - export default { - name: 'my-button', + @Component + export default class Input extends Vue { - props: { - label: { - type: String, - required: true, - }, - primary: { - type: Boolean, - default: false, - }, - size: { - type: String, - default: 'medium', - validator: function (value) { - return ['small', 'medium', 'large'].indexOf(value) !== -1; - }, - }, - backgroundColor: { - type: String, - }, - }, + @Prop({ type: String, required: true }) + private readonly label!: string + @Prop({ type: Boolean, default: false }) + private readonly primary!: boolean + @Prop({ + type: String, + default: 'medium', + validator: (value) => { + return ['small', 'medium', 'large'].indexOf(value) !== -1 + }, + }) + private readonly size!: string + @Prop({ type: String }) + private readonly backgroundColor!: string - computed: { - classes() { - return { - 'storybook-button': true, - 'storybook-button--primary': this.primary, - 'storybook-button--secondary': !this.primary, - [`storybook-button--${this.size}`]: true, - }; - }, - style() { - return { - backgroundColor: this.backgroundColor, - }; - }, - }, + private get classes() { + return { + 'storybook-button': true, + 'storybook-button--primary': this.primary, + 'storybook-button--secondary': !this.primary, + [`storybook-button--${this.size}`]: true, + } + } + private get style() { + return { + backgroundColor: this.backgroundColor, + } + } - methods: { - onClick() { - this.$emit('onClick'); - }, - }, + private onClick() { + this.$emit('onClick') + } - }; + } </script> + <style scoped> + .storybook-button { + font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: 700; + border: 0; + border-radius: 3em; + cursor: pointer; + display: inline-block; + line-height: 1; + } + .storybook-button--primary { + color: white; + background-color: #1ea7fd; + } + .storybook-button--secondary { + color: #333; + background-color: transparent; + box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset; + } + .storybook-button--small { + font-size: 12px; + padding: 10px 16px; + } + .storybook-button--medium { + font-size: 14px; + padding: 11px 20px; + } + .storybook-button--large { + font-size: 16px; + padding: 12px 24px; + } + </style>
2. そして動作確認!
$ yarn storybook
問題なく行ける!!
この調子で SCSS もやってしまえ!
Style を SCSS にする
1. 編集作業
// ./stories/Button.vue - <style scoped> + <style lang="scss" scoped>
2. 動作確認
$ yarn storybook ERROR in ./stories/Button.vue?vue&type=style&index=0&id=43fc969c&lang=scss&scoped=true& (./node_modules/vue-docgen-loader/lib??ref--12!./node_modules/vue-loader/lib??vue-loader-options!./stories/Button.vue?vue&type=style&index=0&id=43fc969c&lang=scss&scoped=true&) 49:0 Module parse failed: Unexpected token (49:0) File was processed with these loaders: * ./node_modules/vue-docgen-loader/lib/index.js * ./node_modules/vue-docgen-loader/lib/index.js * ./node_modules/vue-loader/lib/index.js You may need an additional loader to handle the result of these loaders.
- ここに来て、エラー!
3. ということでググる
- https://storybook.js.org/docs/react/configure/webpack#extending-storybooks-webpack-config
- どうやら、SCSS を使うときは Webpack Config をいじってね。とのことらしい。
ということでいじる
// ./.storybook/main.jsmain.js + const path = require('path'); module.exports = { "stories": [ "../stories/**/*.stories.mdx", "../stories/**/*.stories.@(js|jsx|ts|tsx)" ], "addons": [ "@storybook/addon-links", "@storybook/addon-essentials" - ] + ], + webpackFinal: async (config, { configType }) => { + // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION' + // You can change the configuration based on that. + // 'PRODUCTION' is used when building the static version of storybook. + + // Make whatever fine-grained changes you need + config.module.rules.push({ + test: /\.scss$/, + use: ['style-loader', 'css-loader', 'sass-loader'], + include: path.resolve(__dirname, '../'), + }); + + // Return the altered config + return config; + }, }
4. 動作確認
$ yarn storybook
いけた!
assets/scss/styles.scss に定義してある変数を使ってみる
1. Vue ファイルの編集作業
// ./stories/Button.vue .storybook-button--primary { - color: white; - background-color: #1ea7fd; + color: $color_light; + background-color: $color_primary; }
2. 動作確認
$ yarn storybook ERROR in ./stories/Button.vue?vue&type=style&index=0&id=43fc969c&lang=scss&scoped=true& (./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/sass-loader/dist/cjs.js!./node_modules/vue-loader/lib??vue-loader-options!./stories/Button.vue?vue&type=style&index=0&id=43fc969c&lang=scss&scoped=true&) Module build failed (from ./node_modules/sass-loader/dist/cjs.js): SassError: Undefined variable. ╷ 59 │ color: $color_light; │ ^^^^^^^^^^^^
3. Storybook の設定周り編集作業
// ./.storybook/main.js config.module.rules.push({ test: /\.scss$/, - use: ['style-loader', 'css-loader', 'sass-loader'], + use: [ + 'style-loader', + 'css-loader', + 'sass-loader', + { + loader: 'sass-resources-loader', + options: { + resources: ['assets/scss/styles.scss'], + }, + }, + ], include: path.resolve(__dirname, '../'), })
4. 動作確認
$ yarn storybook
最後に
- Storybook をインストールしたことで、
yarn dev
実行時に CSS-Loader 周りにエラーが出る yarn add -D css-loader@4.2.0
とバージョン指定することで解決できる
yarn dev
と yarn storybook
別々のビルドになるので、両方確認しなきゃいけないことがわかった。