webpack.configをtypescriptで書く話
Webpack.config.jsがつらい
というか.jsがつらい
ようやくtypescriptにも慣れてきた所でジワジワとwebpack.config.jsの中身が膨れ上がり始めた
このままでは精神的によろしくないので、全部typescriptに落とし込んでしまおうという流れになった
環境
{
"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を作り、以下のようにする
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>
等)