White Box技術部

WEB開発のあれこれ(と何か)

久しぶりにやったらTypeScriptのWebpackビルドで詰まった

今日は雑記なのでとりとめもないです。

WebpackでTSをビルドしたらWARNINGとERRORがめっちゃ出る

ちょっと話題に上がったので、なんとなく昔作ったプログラムをリファクタリングしていたのですが、 JSからTSに変えたついでにWebpackも導入したところ、ビルドしたらこんな感じのエラーがずらーっと出て、参ってしまったわけです。

WARNING in ./node_modules/config/lib/config.js 544:15-36
Critical dependency: the request of a dependency is an expression
 @ ./src/app.ts

WARNING in ./node_modules/config/parser.js 39:10-26
Critical dependency: the request of a dependency is an expression
 @ ./node_modules/config/lib/config.js
 @ ./src/app.ts

〜〜省略〜〜

ERROR in ./node_modules/when/lib/env.js
Module not found: Error: Can't resolve 'vertx' in '/reviewet/node_modules/when/lib'
 @ ./node_modules/when/lib/env.js 32:14-35
 @ ./node_modules/when/lib/decorators/timed.js
 @ ./node_modules/when/when.js
 @ ./node_modules/requestretry/index.js
 @ ./node_modules/slack-node/lib/lib/slack.seed.js
 @ ./node_modules/slack-node/lib/index.js
 @ ./src/lib/slack.ts
 @ ./src/domains/Notification.ts
 @ ./src/domains/Android.ts
 @ ./src/app.ts

とはいえ、node_modules配下のファイルをチェックしてしまってエラーになっているような感じなのはすぐに読み取れたので、 「exclude設定がなんかおかしいんだろうな」ぐらいの軽い気持ちではいました。

案の定、ドハマリしてしまったわけですが。

対処方法

運良く、対策が見つかったのでその方法を記載します。

webpack-node-externalsを利用する

以下の記事でwebpack-node-externalsを利用する方法が提案されており、このやり方でエラーを消すことができました。

ちなみにloaderの設定にexcludeを追加したり、babel-loaderを消してみたり、resolveを書いてみたり、tsconfig.jsonにexcludeを書いたりしましたが、全て効果はありませんでした。

webpack.jsサンプル

自分のwebpack.js(実際にはwebpack-mergeを使っているので、webpack.common.jsという名前ですが)に反映したコードは以下になります。

import path from 'path';
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
import nodeExternals from 'webpack-node-externals';

const src = path.resolve(__dirname, 'src');
const dist = path.resolve(__dirname, 'dist');

export default {
  target: 'node',
  externals: [nodeExternals()],

  entry: {
    app: src + '/app.ts'
  },

  plugins: [new CleanWebpackPlugin()],

  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      {
        test: /\.tsx?$/,
        loader: 'ts-loader'
      }
    ]
  },

  resolve: {
    extensions: ['.js', '.ts', '.json']
  },

  output: {
    filename: '[name].js',
    publicPath: dist,
    path: dist
  }
};

tsconfig.jsonはこんな感じです。

{
  "compilerOptions": {
    "target": "es2017",
    "module": "esnext",
    "lib": [
      "esnext",
      "dom"
    ],
    "allowJs": true,
    "sourceMap": true,
    "isolatedModules": true,

    "strict": true,

    "moduleResolution": "node",
    "typeRoots": ["src/@types"],
    "esModuleInterop": true
  }
}

ちなみに・・・

これがそのコード修正の全量なのですが、大体やりたかったリファクタリングが終わったので実行してみたところ、iOS側のアプリデータもまともに解析できなくなっていました。。。

調べてみると、RSSで配信されている内容が変わっていたからなのですが、そもそもアプリ自体の情報が配信されなくなっていたため、軽い修正で直るわけでもないので、せっかくやったけどもういいかな・・・っていう気分になっていたりはします。

やっぱり今アプリ開発していないのがモチベーションを下げているんですかね。自分で使っていれば意地でもなんとかしていたと思うので。