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

webpack.configをtypescriptで書く話

More than 1 year has passed since last update.

webpack.configをtypescriptで書く話

Webpack.config.jsがつらい

というか.jsがつらい
ようやくtypescriptにも慣れてきた所でジワジワとwebpack.config.jsの中身が膨れ上がり始めた
このままでは精神的によろしくないので、全部typescriptに落とし込んでしまおうという流れになった

環境

packages.json
{
  "devDependencies":{
    "@types/webpack": "^4.39.1",
    "typescript": "^3.2.2",
    "ts-node": "6.0.4", // 大事なやつ
    "webpack": "^4.36.1",
    "webpack-cli": "^3.3.6"
  }
}

前回に引き続き登場のts-node
このモジュールによって、.tsなコンフィグファイルを読ませることが可能となっている

手順

何も考えずに
npm i --save-dev @types/webpack typescript ts-node webpack webpack-cli
を実行

webpack.config.jsと同じディレクトリにwebpack.config.tsを作り、以下のようにする

webpack.config.ts
import * as WebPack from "webpack";

const options: WebPack.Configuration[] = [
{
  // ここに内容記述
}];

export default options;

これで準備OK
試しに記述してみる

const entry: WebPack.Entry = {
  main: "./src/Main.ts",
  option: "./src/Option.ts"
};
const output: WebPack.Output = {
  filename: "[name].js",
  path: `${__dirname}/dist/js`
}

const options: WebPack.Configuration[] = [
{
  name: "debug_local"
  entry: entry,
  output: output,
  //...
}];

このようになる
WebpPack.以下の型は、プロパティ名と一致しているので特に型を探す手間もなく簡単に記述できる

型定義のないプラグイン

webpackのLoaderは文字列一致でnode_modulesから呼び出してくれるが、Pluginの方はインスタンスが必要になる
型定義のあるプラグインは

import * as PluginName "PluginModule";

const options: WebPack.Configuration[] = [
  {
    plugins: [new PluginName()],
  },

と呼んでやればいいが、自分の使いたいプラグインの型定義ファイルが公開されていない場合は

const PluginType = require('ModuleName');
const plugin = new PluginType();

const options: WebPack.Configuration[] = [
  {
    plugins: [plugin],
  }
];

自分で作るプラグイン

今回は、.scssから.d.tsを生成するtyped-css-modulesをWebpack.Pluginに落とし込んでみる
これにより、ビルド時に勝手にd.tsの生成をしてくれるようになる

import * as TCS from "typed-css-modules";

class SCSSTypeGenerator implements WebPack.Plugin {
  apply(compiler: WebPack.Compiler){
    console.log("[SCSSTypeGenerator]start scss -> d.ts");
    const baseDirectory = Path.join(__dirname, "/src");
    TCS.run(baseDirectory, {
      camelCase: true,
      dropExtension: true,
      pattern: "**/*.scss"
    });
  }
}

インターフェースは
apply(compiler: Compiler): void
だけ実装すれば動作してくれるのでとてもお手軽
プラグインの実行タイミングをずらしたい場合は、引数の
compiler.hooks.以下にあるイベントにフックすることで実現できる
イベントごとに微妙に型が違うので注意すること(SyncHook<T>,AsyncSeriesHook<T>等)

Egliss
drecom-inc
Drecom with entertainment として発明を産み続け、人々の期待を超えるサービスを提供することを目的とした会社です。
https://www.drecom.co.jp/
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
ユーザーは見つかりませんでした