Nuxt.js＋StorybookでJSX記法がトランスパイルできないときはbabel.config.jsを用意する

Nuxtでjsx記法を使ったコンポーネントが、Storybookでトランスパイルに失敗するという問題に遭遇しました。

##再現手順

まずnuxtのプロジェクトを作成して、Storybookを導入します。

```shell
npx crete-nuxt-app storybooksample
cd storybooksample
npx sb init
```

続いて、Jsxを使ったコンポーネントを作成し、storiesを用意します。

```vue:stories/HelloJsx.vue
<script>
export default {
  render(h) {
    return <div>Hello</div>
  },
}
</script>
```

```javascript:stories/HelloJsx.stories.js
import Hello from './HelloJsx.vue'

export default {
  title: 'Example/Hello',
  component: Hello,
  argTypes: {},
}

const Template = (args, { argTypes }) => ({
  props: Object.keys(argTypes),
  components: { Hello },
  template: '<hello />',
})

export const MyHello = Template.bind({})
```

この状態で`yarn storybook`を実行すると下のようなエラーが出ます。

```shell
ERROR in ./stories/HelloJsx.vue?vue&type=script&lang=js& (./node_modules/vue-docgen-loader/lib??ref--12!./node_modules/babel-loader/lib??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./stories/HelloJsx.vue?vue&type=script&lang=js&) 3:11
Module parse failed: Unexpected token (3:11)
File was processed with these loaders:
 * ./node_modules/vue-docgen-loader/lib/index.js
 * ./node_modules/vue-docgen-loader/lib/index.js
 * ./node_modules/babel-loader/lib/index.js
 * ./node_modules/vue-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| export default {
|   render: function render(h) {
>     return <div>Hello</div>;
|   }
| };
 @ ./stories/HelloJsx.vue?vue&type=script&lang=js& 1:0-228 1:244-247 1:249-474 1:249-474
 @ ./stories/HelloJsx.vue
 @ ./stories/HelloJsx.stories.js
 @ ./stories sync ^\.(?:(?:^|[\\\/]|(?:(?:(?!(?:^|[\\\/])\.).)*?)[\\\/])(?!\.)(?=.)[^\\\/]*?\.stories\.(js|jsx|ts|tsx))$
 @ ./.storybook/generated-stories-entry.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/vue/config.js-generated-other-entry.js ./node_modules/@storybook/addon-links/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/addParameter.js-generated-other-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined
```

## 解決

下記のファイルをプロジェクト直下に作成します。これは@vue/cliで`vue create storybooktest`としてプロジェクトを作成したときに作られるものと同じ内容です。
 

```javascript:babel.config.js
module.exports = {
  presets: ['@vue/cli-plugin-babel/preset'],
}
```

このモジュールをプロジェクトに追加しましょう。

```shell
yarn add -D @vue/cli-plugin-babel
```

これでOKです。Storybookを見てみましょう。

```shell
yarn storybook
```
![スクリーンショット 2021-02-03 201247.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110629/6f03eb4e-bd9e-3dfa-cd9a-574f385aed49.png)

うまく行きました。