概要
前回はOpenAPIを公開したので、今回はStoryBookを公開してみる。
Next.jsをWebpack5で使用しているため、StoryBookも同様にWebpack5で利用したかった。
いろいろハマったので備忘録。
できたもの。
ハマリ1 StoryBookでWebpack5が使えない。
2021/03/03時点でbetaの6.2.0から対応の模様。
npmインストールについて
FROM node:14.16.0
WORKDIR /app/internals/component-catalog
RUN npm install -g npm@7.6.0
COPY package.json /app/internals/component-catalog/package.json
COPY package-lock.json /app/internals/component-catalog/package-lock.json
RUN npm ci
# Story Book
RUN npm i -D @storybook/cli@next
RUN npx --force sb init --type react --builder webpack5
RUN npm i --no-optional -D babel-preset-react-app
RUN npm i --no-optional -D @storybook/addon-knobs@next
RUN npm i --no-optional -D @storybook/addon-storysource@next
RUN npm i --no-optional -D @storybook/addon-viewport@next
RUN npm i --no-optional -D @storybook/addon-backgrounds@next
RUN npm i --no-optional -D @storybook/builder-webpack5@next
RUN npm i --no-optional -D @storybook/addon-console
# storybookのwebpackでローダーを使えるようにする
RUN npm i --no-optional -D css-loader style-loader
RUN npm i --no-optional -D precss autoprefixer postcss
RUN npm i --no-optional -D sass-loader
RUN npm i --no-optional -D fibers
RUN npm i --no-optional -D postcss-loader@5
RUN npm i --no-optional -D html-webpack-plugin@5 --force
WORKDIR /app
RUN npm i --no-optional -D bootstrap@next
jsonはnext.jsのプロジェクトのものをそのまま。
{
"name": "app",
"version": "0.0.1",
"description": "",
"main": "index.js",
"scripts": {
"start": "next start",
"build": "next build",
"dev": "next dev",
"lint": "eslint --ext .ts,.tsx --ignore-path .gitignore .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "hibohiboo <hibohiboo66+github@gmail.com>",
"license": "MIT",
"dependencies": {
"date-fns": "^2.18.0",
"date-fns-tz": "^1.1.3",
"firebase": "^8.2.9",
"isomorphic-unfetch": "^3.1.0",
"next": "^10.0.7",
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
"devDependencies": {
"@types/node": "^14.14.31",
"@types/react": "^17.0.2",
"@types/react-dom": "^17.0.1",
"@typescript-eslint/eslint-plugin": "^4.16.1",
"@typescript-eslint/parser": "^4.16.1",
"bootstrap": "^5.0.0-beta2",
"classnames": "^2.2.6",
"encoding": "^0.1.13",
"eslint": "^7.21.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-react": "^7.22.0",
"eslint-plugin-react-hooks": "^4.2.0",
"next-pwa": "^4.0.0-beta.0",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-preset-env": "^6.7.0",
"prettier": "^2.2.1",
"sanitize.css": "^12.0.1",
"sass": "^1.32.8",
"sharp": "^0.26.3",
"styled-components": "^5.2.1",
"styled-media-query": "^2.1.2",
"stylelint": "^13.11.0",
"stylelint-config-prettier": "^8.0.2",
"stylelint-config-recess-order": "^2.3.0",
"stylelint-config-recommended-scss": "^4.2.0",
"stylelint-config-standard": "^20.0.0",
"stylelint-declaration-block-no-ignored-properties": "^2.3.0",
"stylelint-declaration-use-variable": "^1.7.2",
"stylelint-no-unsupported-browser-features": "^4.1.4",
"stylelint-prettier": "^1.2.0",
"stylelint-scss": "^3.19.0",
"typescript": "^4.2.2",
"webpack": "^5.24.2"
}
}
webpack5をインストールするだけではダメ。設定に、builder:'webpack5'
と明示してやる必要がある。
const { resolve } = require('path')
module.exports = {
core: {
builder: 'webpack5',
},
stories: ['../stories/**/*.stories.tsx'],
}
ハマリ2 React is not defined
これはNext.jsでReactはimportしなくても使えるのが原因だった。
1行追加してやることで解決。
StorybookのFAQにあったのでハマる人は多い模様。
+ import React from 'react'
import styles from '../styles/Count.module.scss'
const Count: React.FC<{ num: string }> = ({ num }) => {
return <span className={styles.kotaFrame}>{num}</span>
}
export default Count
ハマリ3 @import '~bootstrap/scss/functions';
が解決できない
sass-loaderでは~でnode_modulesを示すのだが、
今回storybookをsrcとは別の深い階層にインストールしていたのが問題だったもよう。
- internal
- component-catalog
- .storybook
- node_modules <- ここにbootstrapを入れても`で解釈されない
- bootstrap
- node_modules <- ここのnode_modulesが~で解釈される
- bootstrap
- src
- styles
- mybootstrap.scss <- ここで~bootstrapをインポートしている
なので、それに合わせて.github/workflows/gh-pages.ymlも更新
name: github pages
on:
push:
branches:
- docs # Set a branch name to trigger deployment
jobs:
deploy:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: '14'
- name: StoryBook Setup
run: npm ci
working-directory: ./internals/component-catalog
+ - name: StoryBook Setup for ~bootstrap.scss
+ run: npm i bootstrap@next
- name: StoryBook Make
run: npx build-storybook -c ./.storybook -o ./component-catalog --no-dll
working-directory: ./internals/component-catalog
- name: StoryBook Move files
run: |
mkdir -p ./docs/publish/component-catalog
mv ./internals/component-catalog/component-catalog ./docs/publish/
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
ハマリ4 Error from chokidar
これは、公開ではなく手元で動かそうとしたときに発生したエラー。
エラーは出るが、手元でStoryBookのページは問題なく見ることができた。謎。
以下のように、chokidarがnode_modules配下のファイルを監視しようとして、監視対象がlinuxの設定上限を超えるため発生するエラーの模様。
Error from chokidar (/app/internals/component-catalog/node_modules/@storybook/components/node_modules/core-js/modules): Error: ENOSPC: System limit for number of file watchers reached, watch '/app/internals/component-catalog/node_modules/@storybook/components/node_modules/core-js/modules/esnext.iterator.reduce.js'
addonsを指定するとエラーが発生する挙動であった。
module.exports = {
core: {
builder: 'webpack5',
},
stories: ['../stories/**/*.stories.tsx'],
+ addons: ['@storybook/addon-knobs/register',],
}
なお、見るフォルダを指定するオプションがあるaddonだと、このエラーは起きなかった。
const { resolve } = require('path')
module.exports = {
core: {
builder: 'webpack5',
},
// ディレクトリと拡張子の変更
stories: ['../stories/**/*.stories.tsx'],
addons: [
+ {
+ name: '@storybook/addon-storysource',
+ options: {
+ rule: {
+ test: [/\.stories\.tsx?$/],
+ include: [resolve(__dirname, '../stories')], // You can specify directories
+ },
+ },
},
],
}
node_modules
の監視をignoreできるオプションがないか探したけれど見つからず。
https://yatta47.hateblo.jp/entry/2020/11/21/213106 を参考に、sudo sysctl fs.inotify.max_user_watches=24288
を行って設定上限をあげたところ発生はなくなった。