Closed7

webpack + ts-loader + node.js なプログラムで、スタックトレースに index.ts の何行目と出したいだけなんだが(出た)

amay077amay077

sourceMap のお話なんだけど。
プロダクションで稼動している node プログラムがエラーを通知するとき、ソースマップが有効になってない?為にスタックトレースを見ても原因が特定しづらい状態になっているので、基本的なところから動作確認していく。

まず普通に ts-node で実行。

index.ts

console.log('Hello index.ts');
throw new Error('This is an error');
console.log('Bye index.ts');

実行

npx ts-node index.ts

スタックトレース

Error: This is an error
    at Object.<anonymous> (/xxx/index.ts:2:7)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)

これを webpack した成果物でもやりたい。

amay077amay077

ソースマップを有効にして js ファイルにトランスパイルしてみる。

package.json

{
  "name": "githubnode",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "ts-node index.ts",
    "tsc_run": "tsc && node build/index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ts-node": "^10.9.2",
    "typescript": "^5.5.4"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "sourceMap": true,
    "outDir": "build"
  }
}

トランスパイル

tsc

build/index.jsindex.js.map が生成される。

node で実行1

node build/index.js

スタックトレース1

Error: This is an error
    at Object.<anonymous> (/xxxx/build/index.js:3:7)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)

ts の情報出てない...

node で実行2

--enable-source-maps が必要だった。

node --enable-source-maps build/index.js

スタックトレース2

Error: This is an error
    at Object.<anonymous> (/xxxx/index.ts:2:7)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)

期待通りの出力が出た。

amay077amay077

webpack を導入。

npm install --save-dev webpack webpack-cli ts-loader

webpack.config.js

const path = require('path');

module.exports = {
  mode: 'development',
  entry: './index.ts',
  devtool: 'source-map',
  module: {
    rules: [{
      test: /\.tsx?$/,
      use: [{
        loader: 'ts-loader',
      }],
      exclude: /node_modules/,
    }],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

webpack を実行すると、dist/bundle.jsdist/bundle.js.map が作成されている。

node で実行

node --enable-source-maps dist/bundle.js

スタックトレース

Error: This is an error
    at <anonymous> (webpack://xxxx/index.ts:2:7)
    at Object.<anonymous> (webpack://xxxx/index.ts:3:29)

あ、出たわ。期待通りの出力が。

amay077amay077

期待通りの結果が出るソースを一旦セーブしておく。

index.ts

console.log('Hello index.ts');
throw new Error('This is an error');
console.log('Bye index.ts');

tsconfog.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "sourceMap": true,
    "outDir": "build"
  }
}

package.json

{
  "name": "githubnode",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "ts-node index.ts",
    "tsc_run": "tsc && node --enable-source-maps build/index.js",
    "webpack_run": "webpack && node --enable-source-maps dist/bundle.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "ts-node": "^10.9.2",
    "typescript": "^5.5.4",
    "ts-loader": "^9.5.1",
    "webpack": "^5.93.0",
    "webpack-cli": "^5.1.4"
  }
}

webpack.config.js

const path = require('path');

module.exports = {
  mode: 'development',
  entry: './index.ts',
  devtool: 'source-map',
  module: {
    rules: [{
      test: /\.tsx?$/,
      use: [{
        loader: 'ts-loader',
      }],
      exclude: /node_modules/,
    }],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
};
amay077amay077

プロダクションで稼動している node プログラムがエラーを通知するとき、ソースマップ有効になってない?為にスタックトレースを見ても原因が特定しづらい状態になっている

どうやら実行環境(AWS Lambda)で --enable-source-maps が指定されていないだけな可能性が浮上。ってかたぶんそう。

webpack.config.js には devtool: 'inline-source-map', が指定されており、成果物の bundle.js は、inline-source-map を指定しないときと比べてそれなりにファイルサイズが増しているので、ソースマップ情報は含まれている模様。そしてローカルで --enable-source-maps 付きで実行したら index.ts の情報が出た。

amay077amay077

AWS Lambda で --enable-source-maps を有効にすると Cold Start が遅くなる、という情報が散見されて、確かにそうだろうなあと思いつつ、inline-source-map なら変わらない(元々遅かった)んじゃね?とも思う。

このスクラップは4ヶ月前にクローズされました