Vue 3 × TypeScript の開発環境の構築 & バンドルには Vue CLI や Vite を用いれば良いが、諸事情でそれらを使わずに素の Webpack で構築したい場合があるかもしれない・・・。2021/9/26 現在で Webpack × Vue × TypeScript の記事はググれば出てくるものの、バージョンの違いか、スムーズに進まないことが多々あった。そこで今回、快適に構築するため手順のメモを作成したので公開。
各ツール・パッケージのバージョン
筆者が動作確認した際には、下記バージョンのものを使用した。
yarn: 1.22.10
-
ts-loader: 9.2.6
typescript: 4.4.3
vue: 3.2.19
vue-loader: 16.8.1
webpack: 5.54.0
webpack-cli: 4.8.0
webpack-dev-server: 4.3.0
プロジェクト構成
webpack_vue_ts
├── dist
│ └── main.js
├── node_modules
│ └── ...
├── package.json
├── public
│ └── index.html
├── src
│ ├── App.vue
│ ├── main.ts
│ └── shims-vue.d.ts
├── tsconfig.json
├── webpack.config.js
└── yarn.lock
プロジェクトの初期化
yarn init
時には -y
オプションでマニュアルの初期設定をスキップし、 --private
オプションで "private": true
を設定している。
$ mkdir webpack_vue_ts && cd $_
$ yarn init -y --private
必要なパッケージの追加
必要な場合は適宜バージョン指定する。
$ yarn add -D ts-loader typescript vue@next vue-loader@next \
webpack webpack-cli webpack-dev-server
html ファイルの作成
Vue インスタンスをマウントする開発環境用の public/index.html
を作成する。 <div id="app"></div>
にマウントする想定。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="http://localhost:8080/main.js"></script>
</body>
</html>
TypeScript 設定ファイルの作成
tsconfig.json
を作成する。 Vue.js 公式 などを参照。
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"noImplicitThis": true,
"jsx": "preserve",
"moduleResolution": "node",
},
"include": ["./src/"]
}
src/shims-vue.d.ts
を作成する。 Vue CLI 使用時に作成されるものを参照。
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
エントリポイントと App コンポーネントの作成
メインのコンポーネントとなる src/App.vue
ファイルを作成し、エントリポイントとなる src/main.ts
でマウントするための記述をする。
とりあえず defineComponent
を用いて src/App.vue
のサンプルコードを記述してみる。
<template>
<h1>Hello</h1>
<div>{{ message }}</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
type DataType = {
message: string
}
export default defineComponent({
data(): DataType {
return {
message: "",
}
},
created() {
this.initMessage()
},
methods: {
initMessage(): void {
this.message = "World"
}
}
})
</script>
例えばここで this.message
に number 型の値を代入しようとすると、VSCode で Vetur などの拡張機能を入れている場合、エラーメッセージを表示して教えてくれるはず。
src/main.ts
で App
をマウントするための記述をする。
import { createApp } from "vue"
import App from './App.vue'
createApp(App).mount('#app')
Webpack 設定ファイルの作成
webpack.config.js
を作成する。
const { VueLoaderPlugin } = require('vue-loader')
const webpack = require('webpack')
module.exports = {
mode: 'development',
entry: './src/main.ts',
output: {
path: `${__dirname}/dist`,
filename: "main.js",
},
devServer: {
static: [
{
directory: `${__dirname}/public`,
},
{
directory: `${__dirname}/dist`,
}
],
headers: {
"Access-Control-Allow-Origin": "*"
},
},
module: {
rules: [
{
test: /\.(tsx|ts)?$/,
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/],
},
exclude: /node_modules/,
},
{
test: /\.vue$/,
loader: 'vue-loader',
}
]
},
resolve: {
modules: ['node_modules'],
extensions: ['.ts', '.js', '.vue'],
},
plugins: [
new webpack.DefinePlugin({
"__VUE_OPTIONS_API__": true,
"__VUE_PROD_DEVTOOLS__": false
}),
new VueLoaderPlugin()
],
target: ["web", "es5"]
}
上記ファイルに関する参考記事は下記
- Webpack
- Vue × TypeScript
- Feature Flags
script の追加
package.json
に、開発サーバー起動スクリプトとバンドルファイル出力スクリプトを追加する。
{
...
"scripts": {
"dev": "webpack-dev-server --open",
"build": "webpack"
},
...
}
以上で開発環境の構築が完了。
開発サーバーの起動
スクリプトを追加したため、プロジェクトルートで下記コマンドにより開発サーバーが起動し、デフォルトのブラウザで localhost:8080
が開かれる。
$ yarn dev
バンドルファイルの出力
下記コマンドにより、バンドルファイル dist/main.js
が出力される。
$ yarn build
以上です。閲覧ありがとうございました!