webpackでTypeScript+Vueをcompileする設定

なんとも大変なwebpackとtsの設定ファイル

今回初めて、TypeScriptVueを一緒に使ってみようと思い立ち、設定をしてみたのですが、まぁこれが大変でした。
自分自身がフロントエンド周りに疎いということもありますが、色々出てくる情報を参考にしても、versionが合ってないことが多々あり、エラーで引っかかるということが多くありました。

今回の自分の環境

node 12.0.0
npm 6.9.0
webpack 5.24.2
webpack-cli 4.5.0
typescript 4.2.2
vue 2.6.12
node 12.0.0 npm 6.9.0 webpack 5.24.2 webpack-cli 4.5.0 typescript 4.2.2 vue 2.6.12
node 12.0.0
npm 6.9.0
webpack 5.24.2
webpack-cli 4.5.0
typescript 4.2.2
vue 2.6.12

package.jsonの設定

まずはnpm installする際のpackage.jsonを設定します。とりあえず、最低限だけ記載しておきます。

{
"name": "",
"version": "1.0.0",
"scripts": {
"build": "webpack",
"watch": "webpack -w"
},
"browser": {
"vue": "vue/dist/vue.common.js"
},
"type": "module",
"license": "ISC",
"dependencies": {
"vue": "^2.6.12"
},
"devDependencies": {
"typescript": "^4.2.2",
"ts-loader": "^8.0.17",
"webpack": "^5.24.2",
"webpack-cli": "^4.5.0"
}
}
{ "name": "", "version": "1.0.0", "scripts": { "build": "webpack", "watch": "webpack -w" }, "browser": { "vue": "vue/dist/vue.common.js" }, "type": "module", "license": "ISC", "dependencies": { "vue": "^2.6.12" }, "devDependencies": { "typescript": "^4.2.2", "ts-loader": "^8.0.17", "webpack": "^5.24.2", "webpack-cli": "^4.5.0" } }
{
  "name": "",
  "version": "1.0.0",
  "scripts": {
    "build": "webpack",
    "watch": "webpack -w"
  },
  "browser": {
    "vue": "vue/dist/vue.common.js"
  },
  "type": "module",
  "license": "ISC",
  "dependencies": {
    "vue": "^2.6.12"
  },
  "devDependencies": {
    "typescript": "^4.2.2",
    "ts-loader": "^8.0.17",
    "webpack": "^5.24.2",
    "webpack-cli": "^4.5.0"
  }
}

webpack.config.jsの設定

続いて、webpack.config.jsの中身。webpackを使用するのに必要です。

const path = require('path');
const glob = require("glob");
const dir = path.resolve(__dirname, "proj/assets/ts")
const entries = glob
.sync("**/*.ts", {
cwd: dir
})
.map(function (key) {
return [key.replace(/\.(ts|tsx)/g, ''), path.resolve(dir, key)];
});
module.exports = {
mode: "development",
entry: Object.fromEntries(entries),
output: {
filename: '[name].bundle.js',
path: `${__dirname}/proj/static/js/dist`
},
module: {
rules: [
{
test: /\.ts$/,
use: "ts-loader"
}
]
},
resolve: {
extensions: ['.js', '.vue', '.json', '.ts'],
alias: {
vue: "vue/dist/vue.common.js"
}
},
target: ["web", "es5"],
};
const path = require('path'); const glob = require("glob"); const dir = path.resolve(__dirname, "proj/assets/ts") const entries = glob .sync("**/*.ts", { cwd: dir }) .map(function (key) { return [key.replace(/\.(ts|tsx)/g, ''), path.resolve(dir, key)]; }); module.exports = { mode: "development", entry: Object.fromEntries(entries), output: { filename: '[name].bundle.js', path: `${__dirname}/proj/static/js/dist` }, module: { rules: [ { test: /\.ts$/, use: "ts-loader" } ] }, resolve: { extensions: ['.js', '.vue', '.json', '.ts'], alias: { vue: "vue/dist/vue.common.js" } }, target: ["web", "es5"], };
const path = require('path');
const glob = require("glob");

const dir = path.resolve(__dirname, "proj/assets/ts")
const entries = glob
  .sync("**/*.ts", {
      cwd: dir
  })
  .map(function (key) {
      return [key.replace(/\.(ts|tsx)/g, ''), path.resolve(dir, key)];
  });

module.exports = {
    mode: "development",
    entry: Object.fromEntries(entries),
    output: {
        filename: '[name].bundle.js',
        path: `${__dirname}/proj/static/js/dist`
    },
    module: {
        rules: [
            {
                test: /\.ts$/,
                use: "ts-loader"
            }
        ]
    },
    resolve: {
        extensions: ['.js', '.vue', '.json', '.ts'],
        alias: {
            vue: "vue/dist/vue.common.js"
        }
    },
    target: ["web", "es5"],
};

ポイント1. entryを各ファイル毎に分ける

entryにコンパイルしたいtsファイルへのパスを通すのですが、割と多かったのが以下のような書き方で、ファイルを一つに纏めてしまうというやり方でした。

const entries = glob.sync(path.resolve(__dirname, "proj/assets/ts/**/*.ts"));
const entries = glob.sync(path.resolve(__dirname, "proj/assets/ts/**/*.ts"));
const entries = glob.sync(path.resolve(__dirname, "proj/assets/ts/**/*.ts"));

もちろん、このやり方でも良いのですが、自分は出力ファイルを分けたかったので、上記のような設定にしたのですが、この書き方が分からずに大分ハマりました。

ポイント2. resolveのaliasにvueのパスを通す

こちら、色々な例が出ていまして、vue$: とするだとか、node_modules/vue/dist/vue.common.js とするだとか、色々あり、どれで試しても特にエラーなどが出ない為に、非常に混乱しました。。

結果として、vue: “vue/dist/vue.common.js” に落ち着きました。

tsconfig.jsonの設定

最後に、tsconfig.jsonの中身。TypeScriptをコンパイルする際のオプション。

そもそも、元々、自分はこのファイルが必要なのか分からなかったです。。最初gulpを使って、そちらにオプションを書いていたというのもあったのですが、ずっとこのファイルがなくても、コンパイルエラーにもならないし、何が問題なのか分からずで、このファイルを後から追加してみたという感じでした。

{
"compilerOptions": {
"sourceMap": true,
"target": "es5",
"module": "es2015",
"lib": [
"dom",
"es2020"
],
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
{ "compilerOptions": { "sourceMap": true, "target": "es5", "module": "es2015", "lib": [ "dom", "es2020" ], "moduleResolution": "node", "allowSyntheticDefaultImports": true, "experimentalDecorators": true, "emitDecoratorMetadata": true } }
{
  "compilerOptions": {
    "sourceMap": true,
    "target": "es5",
    "module": "es2015",
    "lib": [
      "dom",
      "es2020"
    ],
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

ポイント. moduleResolutionの設定

自分の中でのポイントはmoduleResolutionにnodeを設定するということです。意外とこれが書かれている参考ページがなくて、node_modulesの中身が読めていないようでした。

以上で、とりあえずTypeScriptとVueのファイルをコンパイルすることに成功し、動かすことが出来ました!
上記のファイルに加えて、nodeのversionもかなり重要だと思います。他versionでは通らないかもしれないので、十分注意してください。

最後に

node周りはversionが合ってないと全然通らないということが結構あって、かなり大変ですね。。

自分自身でもちゃんと使っているもののversionを記していこうと思いました。

コメントを残す