我想知道是否可以在 create-react-app 的生产版本中使用 javascript 源映射
我在 create-react-app 频谱上问过这个问题,但没有回复 https://spectrum.chat/create-react-app/general/sourcemaps-not-working-in-product~2995d466-e080-4d35- 8151-坏3e7f8fb98
示例程序
npx create-react-app test
cd test
**modify src/App.js to console.error in the App function and nothing else really, see below**
yarn build
cd build
python -m SimpleHTTPServer //or some static web server for current folder
visit http://localhost:8000, see that all the names are mangled in the stack trace for the console.error
App.js 修改示例
import React from 'react';
import logo from './logo.svg';
import './App.css';
function MyFunction() {
console.error('hello world')
}
function App() {
MyFunction()
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
这是此控制台的堆栈跟踪。开发工具中出现错误
App.js:6 hello world
i @ main.34a6654b.chunk.js:1
Ki @ 2.d53d57ba.chunk.js:2
vo @ 2.d53d57ba.chunk.js:2
cu @ 2.d53d57ba.chunk.js:2
ou @ 2.d53d57ba.chunk.js:2
Zo @ 2.d53d57ba.chunk.js:2
qo @ 2.d53d57ba.chunk.js:2
Du @ 2.d53d57ba.chunk.js:2
这是不可读的。如果用户最终导致我们的应用程序崩溃,我们如何从他们那里获得正确的堆栈跟踪?
我在生产版本的开发工具控制台中看到它确实显示“检测到源映射”,因此存在源映射。但它就是不起作用?
当前使用create-react-app 3.4.1
这可以通过搜索使用源映射进行生产构建的答案来解决
我发现这个答案效果很好,特别是“编辑:”中的答案并使用 source-map-js (source-map 需要 nodejs 和 fs 模块)使用源映射时以字符串形式获取堆栈跟踪?
使用时的代码
import {RawSourceMap, SourceMapConsumer} from 'source-map-js';
const sourceMaps: {[key: string] : RawSourceMap} = {};
async function getSourceMapFromUri(uri: string) {
if (sourceMaps[uri] != undefined) {
return sourceMaps[uri];
}
const uriQuery = new URL(uri).search;
const currentScriptContent = await (await fetch(uri)).text();
let mapUri = RegExp(/\/\/# sourceMappingURL=(.*)/).exec(currentScriptContent)[1];
mapUri = new URL(mapUri, uri).href + uriQuery;
const map = await (await fetch(mapUri)).json();
sourceMaps[uri] = map;
return map;
}
async function mapStackTrace(stack: string) {
const stackLines = stack.split('\n');
const mappedStack = [];
for (const line of stackLines) {
const match = RegExp(/(.*)(http:\/\/.*):(\d+):(\d+)/).exec(line);
if (match == null) {
mappedStack.push(line);
continue;
}
const uri = match[2];
const consumer = new SourceMapConsumer(await getSourceMapFromUri(uri));
const originalPosition = consumer.originalPositionFor({
line: parseInt(match[3]),
column: parseInt(match[4]),
});
if (originalPosition.source == null || originalPosition.line == null || originalPosition.column == null) {
mappedStack.push(line);
continue;
}
mappedStack.push(`${originalPosition.source}:${originalPosition.line}:${originalPosition.column + 1}`);
}
return mappedStack.join('\n');
}