Failed to parse source map エラーの解決方法
問題の概要
Rollupで作成したnpmライブラリをReactプロジェクトで使用した際に、以下の警告が表示されることがあります:
Failed to parse source map from 'C:\Users\XXXX\Desktop\example\node_modules\@AAA\BBB\src\components\Button\Button.tsx' file:
Error: ENOENT: no such file or directory, open
'C:\Users\XXXX\Desktop\example\node_modules\@AAA\BBB\src\components\Button\Button.tsx'
このエラーはソースマップの解析に失敗したことを示していますが、実際にはボタンなどのコンポーネントは正常に動作し、Webpackも「No issues found.」と報告します。
根本原因
この問題は、Create React App (CRA) とWebpack 5.xの組み合わせで発生することが多いです。ライブラリのビルド設定とアプリケーションのソースマップ処理の間での不整合が原因で、実際には存在しないソースファイルへの参照を解決しようとします。
ソースマップとは
ソースマップは、変換・圧縮されたコードと元のソースコードを対応付けるためのファイルです。デバッグ時に元のソースコードを表示できるようにします。
解決方法
方法1: 環境変数でソースマップ生成を無効化(簡易的)
最も簡単な解決方法は、環境変数でソースマップの生成を無効にすることです。
.envファイル
GENERATE_SOURCEMAP=false
あるいは、package.jsonのスクリプトで直接指定:
{
"scripts": {
"start": "GENERATE_SOURCEMAP=false react-scripts start"
}
}
注意点
この方法ではローカル開発時のデバッグが難しくなるため、本番環境以外での使用をおすすめします。
方法2: Webpackの設定で特定パッケージを除外
source-map-loaderを使用している場合、特定のパッケージを除外することで警告を防げます。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(js|mjs|jsx|ts|tsx|css)$/,
enforce: 'pre',
use: [
{
loader: require.resolve('source-map-loader'),
options: {
filterSourceMappingUrl: (url, resourcePath) => {
// 特定のパッケージを除外
if (resourcePath.includes('@AAA/BBB')) {
return false;
}
return true;
},
},
},
],
exclude: [/@babel(?:\/|\\{1,2})runtime/],
},
],
},
};
方法3: Rollup設定の最適化(ライブラリ開発者向け)
ライブラリを開発している場合、Rollupの設定を見直すことで根本的に解決できます。
rollup.config.mjs
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import postcss from 'rollup-plugin-postcss';
import { dts } from 'rollup-plugin-dts';
export default [
{
input: 'src/index.ts',
external: ['react', 'react-dom'],
output: [
{
file: 'dist/cjs/index.js',
format: 'cjs',
sourcemap: true,
},
{
file: 'dist/esm/index.js',
format: 'esm',
sourcemap: true,
},
],
plugins: [
resolve(),
commonjs(),
typescript({
tsconfig: './tsconfig.json',
sourceMap: true // TypeScriptソースマップを有効に
}),
postcss(),
],
},
{
input: 'dist/esm/types/index.d.ts',
output: [{ file: 'dist/index.d.ts', format: 'esm' }],
plugins: [dts()],
external: [/\.(css|less|scss)$/],
},
];
方法4: ソースファイルをパッケージに含める
パッケージにソースファイルを含めることで、ソースマップの参照を解決できます。
package.json
{
"files": ["dist", "src"]
}
これにより、node_modulesにソースファイルが含まれるようになり、ソースマップの参照が正しく解決されます。
推奨される解決策
状況に応じた最適な解決方法を選択してください:
- ライブラリ使用者の場合: 方法1または方法2で警告を抑制
- ライブラリ開発者の場合: 方法3で正しいソースマップ生成を確保
- 相互互換性を重視する場合: 方法4でソースファイルを含める
パフォーマンス考慮
ソースマップを完全に無効にするとデバッグが困难になります。可能な限り、正しいソースマップ生成と適切な除外設定の組み合わせをおすすめします。
まとめ
「Failed to parse source map」エラーは、ソースマップの参照不一致によって発生する警告です。本番環境ではパフォーマンス向上のためソースマップを無効にし、開発環境では適切な設定でデバッグ機能を維持することをおすすめします。
ライブラリ開発者は、正しいソースマップ生成設定を心がけ、使用者が遭遇する問題を未然に防ぎましょう。