Electron用のwebpack configを完全にTypeScriptに移行した


ElectronアプリをTypeScriptで書くようにしたのに、Webpackが.jsだと、なんかダサいなと思ったので、Webpack関係もTypeScriptに移行した。

Electron用と言いつつ、大抵のプロジェクトで使えると思う。

環境

  • TypeScript : 3.7.5
  • webpack : 4.41.5
  • webpack-merge : 4.2.2

ベース移行

基本的なことは、公式に書いてある。

パッケージインストール

$ yarn add --dev typescript ts-node @types/node @types/webpack

設定ファイル

webpack.config.ts

import * as path from 'path';
import * as webpack from 'webpack';

const config: webpack.Configuration = {
  mode: 'production',
  entry: './foo.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'foo.bundle.js'
  }
};

export default config;

modulecommonjsに変更するのをお忘れなく

tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    ...
  }
}

Develop & Production Build設定

Build modedevelopmentproductionで分けたかったのでファイルを下記のように分ける。

・ webpack.common.ts    //共通設定
 ・ webpack.dev.ts      //Prodction Build設定
 ・ webpack.prod.ts     //Development Build設定

Webpack commmon

modeは、webpack.dev.tswebpack.prod.ts内で設定するからwebpack.common.tsからは削除

webpack.common.ts
import * as path from "path";
import { Configuration } from "webpack";

export const main: Configuration = {
- mode: 'production',
  target: "electron-main",
  node: {
    __dirname: false,
    __filename: false
  },
  entry: path.resolve(__dirname, "src", "main", "main.ts"),
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: "ts-loader",
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: [".ts", ".js"]
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "main.js"
  }
};

export const renderer: Configuration = {
- mode: 'production',
  target: "electron-renderer",
  entry: path.resolve(__dirname, "src", "renderer", "renderer.ts"),
  resolve: {
    extensions: [".ts", ".js"]
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "renderer.js"
  }
};

Webpack merge

ここからは、Webpack.common.tsConfigurationをマージするためWebpack mergeを使用する。

パッケージインストール

$ yarn add --dev webpack-merge @types/webpack-merge

Webpack production

webpack.prod.ts
import { Configuration } from "webpack";
import webpackMerge from "webpack-merge";
import { main, renderer } from "./webpack.common";

const prod: Configuration = {
+  mode: "production"
};

const mainConfig = webpackMerge(main, prod);
const rendererConfig = webpackMerge(renderer, prod);

export default [mainConfig, rendererConfig];

Webpack development

webpack.dev.ts
import { Configuration } from "webpack";
import webpackMerge from "webpack-merge";
import { main, renderer } from "./webpack.common";

const dev: Configuration = {
+  mode: "development",
  devtool: "inline-source-map"
};

const mainConfig = webpackMerge(main, dev);
const rendererConfig = webpackMerge(renderer, dev);

export default [mainConfig, rendererConfig];

npm scripts

最後にnpm scriptsでconfigファイルの呼び出し部分をちょちょいと直せばOK

package.json
"scripts": {
-    "dev": "webpack --watch --config webpack.dev.js",
+    "dev": "webpack --watch --config webpack.dev.ts",    
-    "build": "webpack --config webpack.prod.js",
+    "build": "webpack --config webpack.prod.ts",
    "start": "electron ./dist/main.js"
  },

成果物

まとめ

次は、esbuildに以降したいな

参考サイト