webpack + ts-loader + node.js なプログラムで、スタックトレースに index.ts の何行目と出したいだけなんだが(出た)
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 した成果物でもやりたい。
node のバージョンは v18.17.1
ソースマップを有効にして 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.js
と index.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)
期待通りの出力が出た。
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.js
と dist/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)
あ、出たわ。期待通りの出力が。
期待通りの結果が出るソースを一旦セーブしておく。
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'),
},
};
プロダクションで稼動している node プログラムがエラーを通知するとき、ソースマップ有効になってない?為にスタックトレースを見ても原因が特定しづらい状態になっている
どうやら実行環境(AWS Lambda)で --enable-source-maps
が指定されていないだけな可能性が浮上。ってかたぶんそう。
webpack.config.js
には devtool: 'inline-source-map',
が指定されており、成果物の bundle.js
は、inline-source-map を指定しないときと比べてそれなりにファイルサイズが増しているので、ソースマップ情報は含まれている模様。そしてローカルで --enable-source-maps
付きで実行したら index.ts の情報が出た。
AWS Lambda で --enable-source-maps
を有効にすると Cold Start が遅くなる、という情報が散見されて、確かにそうだろうなあと思いつつ、inline-source-map なら変わらない(元々遅かった)んじゃね?とも思う。