Help us understand the problem. What is going on with this article?

3分でつくる2019年版 Nuxt.js TypeScript 開発環境設定

ほとんど自分のためのメモに近いのですが、3分でNuxt.js+TypeScriptの開発環境を整える覚書です。

--- [2019/08/22 追記] ---
※ Nuxt 2.8での設定方法です!
Nuxt 2.9 から Nuxt TypeScript に変わりました!
公式のマイグレーション方法はこちら https://typescript.nuxtjs.org/migration.html

https://typescript.nuxtjs.org/


--- [2019/09/05 追記] ---
Nuxt 2.9 仕様に記事の内容を変更しました!


Create Nuxt App でベースはセットアップ

create-nuxt-app my-app

prettiereslint を設定する

yarn add -D @nuxt/typescript-build
yarn add @nuxt/typescript-runtime

個人的にNuxtのソースファイルはappディレクトリに入れるのが好きなので、
assets, components, layouts, middleware, pages, plugins, static, store のディレクトリは app に移動。

nuxt.configsrcDir: 'app' を追加。

nuxt.config.jsnuxt.config.ts に変更。

nuxt.config.ts
import { Configuration } from '@nuxt/types'

const config: Configuration = {
  // Config設定の記述
  // ...
  buildModules: [
    // Doc: https://github.com/nuxt-community/eslint-module
    '@nuxtjs/eslint-module',
    '@nuxt/typescript-build' // <- 追加
  ],
  // ...
}

export default config

tsconfig.jsonを作成

tsconfig.json
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "lib": [
      "esnext",
      "esnext.asynciterable",
      "dom"
    ],
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "allowJs": true,
    "sourceMap": true,
    "strict": true,
    "noImplicitAny": false,
    "noEmit": true,
    "baseUrl": "./app",
    "paths": {
      "~/*": ["./*"],
      "@/*": ["./*"]
    },
    "typeRoots": ["/app/@types"],
    "types": [
      "@types/node",
      "@nuxt/types",
      "@nuxtjs/axios"
    ]
  },
  "exclude": [
    "node_modules"
  ]
}

ESLintの設定

yarn add -D @nuxtjs/eslint-config-typescript

.eslintrc.jsをTypeScript用に書き換える
ルールはお好みで

eslintrc.js
module.exports = {
  root: true,
  parser: 'vue-eslint-parser',
  env: {
    browser: true,
    node: true
  },
  parserOptions: {
    // parser: '@typescript-eslint/parser'
  },
  extends: [
    '@nuxtjs',
    '@nuxtjs/eslint-config-typescript', // <= これを追加
    'plugin:nuxt/recommended',
    'plugin:prettier/recommended',
    'prettier',
    'prettier/vue'
  ],
  plugins: [
    'prettier'
  ],
  // add your custom rules here
  rules: {
    'no-unused-vars': 'off',
    '@typescript-eslint/no-unused-vars': 'error',
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    "vue/singleline-html-element-content-newline": "off",
    "vue/no-v-html": "off",
    "vue/html-closing-bracket-spacing": "off",
    "vue/max-attributes-per-line": [2, {
      "singleline": 5,
      "multiline": {
        "max": 1,
        "allowFirstLine": false
      }
    }]
  }
}

nuxt-ts に変更

NPM Scripts の nuxtnuxt-ts に変更する

package.json
{
  "scripts": {
    "dev": "nuxt-ts",
    "build": "nuxt-ts build",
    "generate": "nuxt-ts generate",
    "start": "nuxt-ts start",
    "lint": "eslint --ext .ts,.js,.vue --ignore-path .gitignore ."
  },
  "dependencies": {
    "@nuxt/typescript-runtime",
    "nuxt"
  },
  "devDependencies": {
    "@nuxt/typescript-build"
  }
}

Vue.extend での開発

jsのときとほとんど同じような記述ができる

sample.vue
<script lang="ts">
import Vue, { PropType } from 'vue'
import Hoge from '~/components/Hoge.vue'

// Taskの型定義
type Task = {
  id: number
  name: string
  check: boolean
}

// Dataの型定義
type Data = {
  tasks: Task[]
  name: string
}

export default Vue.extend({
  components: {
    Hoge
  },
  props: {
    dataTask: {
      // ArrayやObjectの場合、詳細な型定義はPropTypeを使う
      type: Array as PropType<Task[]>,
      required: true
    }
  },
  data(): Data {
    return {
      tasks: this.dataTask
      name: 'サンプル'
    }
  }
})
</script>

クラスコンポーネントでの開発

yarn add nuxt-property-decorator

nuxt-property-decorator には vue-class-component, vue-property-decorator, vuex-class がラップされている

https://github.com/nuxt-community/nuxt-property-decorator#readme

nuxt.configに追加

  build: {
    babel: {
      plugins: [
        ["@babel/plugin-proposal-decorators", { legacy: true }],
        ["@babel/plugin-proposal-class-properties", { loose: true }]
      ]
    }
  }

VSCode

VSCodeの設定で、保存時にエラーをチェックして整形してくれるようにする

/.vscode/settings.json
{
  "javascript.format.insertSpaceBeforeFunctionParenthesis": true,
  "typescript.format.insertSpaceBeforeFunctionParenthesis": true,
  "eslint.enable": true,
  "editor.formatOnSave": false,
  "eslint.autoFixOnSave": true,
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    {
      "language": "typescript",
      "autoFix": true
    },
    {
      "language": "vue",
      "autoFix": true
    },
    {
      "language": "vue-html",
      "autoFix": true
    }
  ],
  "eslint.run": "onType",
  "vetur.format.defaultFormatter.js": "prettier",
  "vetur.format.defaultFormatter.css": "prettier",
  "vetur.format.defaultFormatter.less": "prettier",
  "vetur.format.defaultFormatter.postcss": "prettier",
  "vetur.format.defaultFormatter.scss": "prettier",
  "vetur.format.defaultFormatter.stylus": "stylus-supremacy",
  "vetur.format.defaultFormatter.ts": "prettier",
  "vetur.validation.style": true,
  "vetur.validation.template": true
}

package.jsonに追加

package.json
...
  "browserslist": [
    "last 2 version",
    "android >= 5",
    "IE 11"
  ],
  "_moduleAliases": {
    "~/*": "./app/*",
    "@/*": "./app/*"
  }
...

tsconfig.jsonの編集

tsconfig.json
"baseUrl": "./app"

型定義

@types ディレクトリを作成
*.d.ts の形式のファイルを入れる

例)markdownをimportする際に必要 md.d.ts

md.d.ts
declare module '*.md' {
  const content: string
  export default content
}

assets から 画像ファイルを import する場合、以下のような型定義を読み込んでおく

files.d.ts
declare module '*.png'
declare module '*.jpg'
declare module '*.gif'
declare module '*webp'

Nuxt 2.9から config に router の設定を書くのが非推奨になった

nuxt.config ではなく、/app/router.scrollBehavior.js を作成してそこに設定を記述する。
https://nuxtjs.org/api/configuration-router/#scrollbehavior

srcDirディレクトリ/app/router.scrollBehavior.js
// ページ遷移時にスクロールトップ
export default function(to, from, savedPosition) {
  return { x: 0, y: 0 }
}

おまけ

SassとPugをインストール

yarn add -D node-sass sass-loader pug pug-plain-loader

Stroybook インストール

npx -p @storybook/cli sb init --type vue
yarn add -D path fork-ts-checker-webpack-plugin

TypeScript用にStorybookの webpack.config.js を編集

storybook/webpack.config.js
const path = require('path');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'ts-loader',
            options: {
              appendTsSuffixTo: [/\.vue$/],
              transpileOnly: true
            },
          }
        ]
      },
      {
        test: /\.scss$/,
        use: [
          "style-loader", 
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              importLoaders: 0,
              alias: {
                'assets': path.resolve(__dirname, '../app/assets')
              }
            }
          },
          {
            loader: "sass-resources-loader",
            options: {
              resources: [
                path.resolve(__dirname, '../app/assets/styles/variables/*.scss'),
                path.resolve(__dirname, '../app/assets/styles/common.scss')
              ]
            }
          }
        ]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'file-loader'
      },
      {
        test: /\.pug$/,
        loader: 'pug-plain-loader'
      }
    ]
  },
  plugins: [
    new ForkTsCheckerWebpackPlugin()
  ],
  resolve: {
    extensions: ['.ts', '.js', '.vue', '.json'],
    alias: {
      'static': path.resolve(__dirname, '../app/static'),
      'assets': path.resolve('../app/assets'),
      '@': path.resolve(__dirname, '../app'),
      '~': path.resolve(__dirname, '../app')
    }
  }
};

コピペするとここまでが3分くらいでできるのではないでしょうか。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした