Nuxt v2.4で公式にTypescriptがサポートされた。
この記事はそれ以前のNuxtでTypescriptを使うための方法について記述している。
これから始めるならNuxt(v2.4以降) + Typescriptセットアップを参照いただきたい。
最近、Nuxtについてよく見かけるので、やってみようとちょっと触ってみた。
どうせなら、Typescriptでやりたい。PugやSassを使えたほうがいいだろうとセットアップしてみた。
このエントリの結果できあがる構成の
2018/10/06 時点での主なモジュールのバージョンは次の通り。
- nuxt: 2.1.0
- typescript: 3.1.1
- pug: 2.0.3
- node-sass: 4.9.3
セットアップ
最初に vue-cli をインストールする。vue init
を使うには@vue/cli-init
のインストールも必要らしい。
$ npm i @vue/cli @vue/cli-init
続いて、typescript のセットアップされたテンプレートを利用してプロジェクトを作成する。
最初にプロジェクト名等を聞いてくる。適当に入力して進む。
$ vue init nuxt-community/typescript-template my-project
? Project name my-project
? Project description Nuxt.js TypeScript project
? Author HeRo <hero@example.com>
vue-cli · Generated "my-project".
To get started:
cd my-project
npm install # Or yarn
npm run dev
vue init
の実行出力の最後に次に実行すべきコマンドが示されるのでそれに従う。
まずはディレクトリを移動して、モジュールのインストール
$ cd my-project
$ yarn
yarn install v1.3.2
info No lockfile found.
[1/4] 🔍 Resolving packages...
warning nuxt > postcss-cssnext@3.1.0: 'postcss-cssnext' has been deprecated in favor of 'postcss-preset-env'. Read more at https://moox.io/blog/deprecating-cssnext/
warning nuxt > autoprefixer > browserslist@2.11.3: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
warning nuxt > css-loader > cssnano > autoprefixer > browserslist@1.7.7: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
warning nuxt > postcss-cssnext > caniuse-api > browserslist@2.11.3: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
warning nuxt > webpack-bundle-analyzer > bfj-node4@5.3.1: Switch to the `bfj` package for fixes and new features!
warning nuxt > css-loader > cssnano > postcss-merge-rules > browserslist@1.7.7: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
warning nuxt > css-loader > cssnano > postcss-merge-rules > caniuse-api > browserslist@1.7.7: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
warning " > vuex-class@0.3.1" has unmet peer dependency "vue@^2.5.0".
warning " > vuex-class@0.3.1" has unmet peer dependency "vuex@^3.0.0".
warning " > vuex-class@0.3.1" has unmet peer dependency "vue-class-component@^6.0.0".
[4/4] 📃 Building fresh packages...
success Saved lockfile.
warning Your current version of Yarn is out of date. The latest version is "1.10.1" while you're on "1.3.2".
info To upgrade, run the following command:
$ curl -o- -L https://yarnpkg.com/install.sh | bash
✨ Done in 35.84s.
続いて npm run dev
を実行。
$ npm run dev
> my-project@1.0.0 dev /Users/hoge/nuxt-lesson/my-project
> nuxt
… debug nuxt › axios › baseURL: http://localhost:3000/
… debug nuxt › axios › browserBaseURL: http://localhost:3000/
nuxt:build App root: /Users/hoge/nuxt-lesson/my-project +0ms
nuxt:build Generating /Users/hoge/nuxt-lesson/my-project/.nuxt files... +0ms
nuxt:build Generating files... +30ms
nuxt:build Generating routes... +13ms
nuxt:build Building files... +33ms
nuxt:build Adding webpack middleware... +1s
████████████████████ 100%
Build completed in 6.942s
DONE Compiled successfully in -4054ms
OPEN http://localhost:3000
最後にURLが示されるので、それをブラウザで開いてみる。
次のページが表示される。
もろもろアップグレード
とりあえず、動く状態になったものの、2018/10/06 時点ではこんな感じ。
$ yarn outdated
yarn outdated v1.3.2
info Color legend :
"<red>" : Major Update backward-incompatible updates
"<yellow>" : Minor Update backward-compatible features
"<green>" : Patch Update backward-compatible bug fixes
Package Current Wanted Latest Package Type URL
@types/node 9.6.34 9.6.34 10.11.4 devDependencies https://github.com/DefinitelyTyped/DefinitelyTyped.git
nuxt 1.4.2 1.4.2 2.1.0 dependencies https://github.com/nuxt/nuxt.js#readme
ts-loader 3.5.0 3.5.0 5.2.1 devDependencies https://github.com/TypeStrong/ts-loader
typescript 2.9.2 2.9.2 3.1.1 devDependencies http://typescriptlang.org/
✨ Done in 0.44s.
いろいろ古い。
まずは差し障り少なそうなところからアップグレード。
$ yarn upgrade @types/node@^10.11.4
$ yarn upgrade typescript@^3.1.1
この時点で、npm run dev
を試しても動作に問題はない。
yarn upgrade nuxt@^2.1.0
この時点で、npm run dev
を試すと次のようなエラーが発生する。
$ npm run dev
> my-project@1.0.0 dev /Users/hero/Develop/typescritp/my-project
> nuxt
INFO Building project
✔ success Builder initialized
✔ success Nuxt files generated
✖ error TypeError: Cannot set property 'ts' of undefined
at Builder.extendBuild.config (/Users/hero/nuxt-lesson/my-project/modules/typescript.js:24:33)
at Builder.<anonymous> (/Users/hero/nuxt-lesson/node_modules/nuxt/dist/nuxt.js:158:17)
at WebpackClientConfig.extendConfig (/Users/hero/nuxt-lesson/my-project/node_modules/nuxt/dist/nuxt.js:3144:56)
at WebpackClientConfig.extendConfig (/Users/hero/nuxt-lesson/my-project/node_modules/nuxt/dist/nuxt.js:3286:26)
at WebpackClientConfig.config (/Users/hero/nuxt-lesson/my-project/node_modules/nuxt/dist/nuxt.js:3182:33)
at WebpackClientConfig.config (/Users/hero/nuxt-lesson/my-project/node_modules/nuxt/dist/nuxt.js:3325:26)
at Builder.webpackBuild (/Users/hero/nuxt-lesson/my-project/node_modules/nuxt/dist/nuxt.js:3922:56)
at Builder.build (/Users/hero/nuxt-lesson/my-project/node_modules/nuxt/dist/nuxt.js:3632:16)
modules/typescript.jsが悪そうなので、次のように1行足してみる。
// Add TypeScript loader for vue files
for (let rule of config.module.rules) {
if (rule.loader === "vue-loader") {
rule.options.loaders = rule.options.loaders || {}; // <=この行を追加
rule.options.loaders.ts = tsLoader
}
}
再度npm run dev
を実行すると今度は次のようなエラー。
$ npm run dev
> my-project@1.0.0 dev /Users/hero/Develop/typescritp/my-project
> nuxt
INFO Building project
✔ success Builder initialized
✔ success Nuxt files generated
ERROR Failed to compile with 2 errors 12:23:10 PM
error in (webpack)-hot-middleware/client.js?name=client&reload=true&timeout=30000&path=/__webpack_hmr
Module build failed (from ./node_modules/ts-loader/index.js):
TypeError: Cannot read property 'ts' of undefined
at getLoaderOptions (/Users/hero/Develop/typescritp/my-project/node_modules/ts-loader/dist/index.js:70:44)
at Object.loader (/Users/hero/Develop/typescritp/my-project/node_modules/ts-loader/dist/index.js:23:19)
@ multi webpack-hot-middleware/client?name=client&reload=true&timeout=30000&path=/__webpack_hmr ./.nuxt/client.js
error in ./.nuxt/client.js
Module build failed (from ./node_modules/ts-loader/index.js):
TypeError: Cannot read property 'ts' of undefined
at getLoaderOptions (/Users/hero/Develop/typescritp/my-project/node_modules/ts-loader/dist/index.js:70:44)
at Object.loader (/Users/hero/Develop/typescritp/my-project/node_modules/ts-loader/dist/index.js:23:19)
@ multi webpack-hot-middleware/client?name=client&reload=true&timeout=30000&path=/__webpack_hmr ./.nuxt/client.js
READY Listening on http://localhost:3000
ERROR Failed to compile with 2 errors 12:23:10 PM
error in (webpack)-hot-middleware/client.js?name=client&reload=true&timeout=30000&path=/__webpack_hmr
Module build failed (from ./node_modules/ts-loader/index.js):
TypeError: Cannot read property 'ts' of undefined
at getLoaderOptions (/Users/hero/Develop/typescritp/my-project/node_modules/ts-loader/dist/index.js:70:44)
at Object.loader (/Users/hero/Develop/typescritp/my-project/node_modules/ts-loader/dist/index.js:23:19)
@ multi webpack-hot-middleware/client?name=client&reload=true&timeout=30000&path=/__webpack_hmr ./.nuxt/client.js
error in ./.nuxt/client.js
Module build failed (from ./node_modules/ts-loader/index.js):
TypeError: Cannot read property 'ts' of undefined
at getLoaderOptions (/Users/hero/Develop/typescritp/my-project/node_modules/ts-loader/dist/index.js:70:44)
at Object.loader (/Users/hero/Develop/typescritp/my-project/node_modules/ts-loader/dist/index.js:23:19)
@ multi webpack-hot-middleware/client?name=client&reload=true&timeout=30000&path=/__webpack_hmr ./.nuxt/client.js
ts-loaderが悪そう。どうせ古いし、アップグレードしてしまおう。
$ yarn ts-loader@^5.2.1
そして、npm run dev
を実行すると、エラーがなくなった。アップグレード成功!
Pugの導入
まずは必要なモジュールのインストール
$ yarn add -D pug pug-plain-loader
で、nuxt-community/typescript-template には次の3つの*.vue
モジュールがある。
- components/Card.vue
- layouts/default.vue
- pages/index.vue
この中の<template>
タグの中を HTMLから Pugに変更していく。
html2pug - convert your html code to jadeなどオンラインの変換サイトを利用すれば簡単だ。
components/Card.vue
最初のファイル。
<template>
<div class="card">
<h2> </h2>
<img :src="'https://robohash.org/' + person.first_name + '_' + person.last_name" />
</div>
</template>
pugに書き換えると次のようになる。
<template lang="pug">
.card
h2
img(:src="'https://robohash.org/' + person.first_name + '_' + person.last_name")
</template>
layouts/default.vue
次のファイル。
<template>
<div>
<nuxt/>
</div>
</template>
これをPugに書き換えると次の通り。
<template lang="pug">
div
nuxt
</template>
pages/index.vue
最後のファイル。
<template>
<section>
<h1 class="header">Nuxt TypeScript Starter</h1>
<div class="cards">
<Card v-for="person in people" :key="person.id" :person="person"></Card>
</div>
</section>
</template>
これも Pugに書き換えるとこの通り。
<template lang="pug">
section
h1.header Nuxt TypeScript Starter
.cards
card(v-for="person in people" :key="person.id" :person="person")
</template>
で、再度、npm run dev
を実行すると、何も変わらず表示できる。
SASSの導入
とりあえず、必要なモジュールのインストール
$ yarn add -D node-sass sass-loader
で、Pugの場合と同じように3ファイルを書き換えればよいわけだが、layouts/default.vueには<style>
はないので次の2ファイルを変換する。
- components/Card.vue
- pages/index.vue
これも、css2sass | Convert CSS Snippets to Syntactically Awesome StyleSheets codeなどを使うと簡単。
components/Card.vue
<style scoped>
.card {
font-family: "Segoe UI", Tahoma, Geneva, Verdana,
sans-serif;
padding: 1rem;
margin: 0.25rem;
border: 0.25rem solid gainsboro;
}
</style>
これをSASSに変換すると次の通り。
<style scoped lang="sass">
.card
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif
padding: 1rem
margin: 0.25rem
border: 0.25rem solid gainsboro
</style>
pages/index.vue
<style scoped>
.header {
font-family: "Segoe UI", Tahoma, Geneva, Verdana,
sans-serif;
}
.cards {
display: flex;
flex-wrap: wrap;
}
</style>
<style scoped lang="sass">
.header
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif
.cards
display: flex
flex-wrap: wrap
</style>
以上、 Nuxt + Typescript with Pug & SASS の出来上がり。