source-map 定位源码错误位置
- 需要安装source-map库
 - webpack配置需要配上devtool: “hidden-source-map”,devtool详细配置看这里devtool配置
 - 配置完webpack打包后,可以看到打包出来的.js.map文件

 - 将生产包产生错误的栈赋值给stack即可,即设置stack = error.stack,格式见下面例子,可以这样获取,注意是error.stack
 
window.addEventListener("error", (event) => {
  console.log("%c [ event.error.stack ]-13", "font-size:13px; background:pink; color:#bf2c9f;", event.error.stack)
})
 
- 注意这里说的是生产包产生的错误,不是测试环境,测试环境一般是设置为自动加载source map,也就是直接在浏览器可以点击定位到源码(为防止别人发现我代码写得太烂,线上不建议这样使用)
 - 主要流程:通过将.js.map读出来,然后通过source-map库的处理该文件,再根据错误栈error.stack做位置匹配,具体匹配流程可以到这里膜拜一下大佬操作source-map
 - 这里只是一个简单的demo,需要手动复制错误,手动执行文件
 
/** 通过source-map 定位源码错误位置 */
const fs = require("fs")
const path = require("path")
const { SourceMapConsumer } = require("source-map")
const stack = `
  Error: 手动抛出错误
  at onClick (http://localhost:3000/static/js/main.08fa76b6.js:2:12177)
  at te (http://localhost:3000/static/js/vendor.30784604.js:2:131903)
  at Object.Ie (http://localhost:3000/static/js/vendor.30784604.js:2:596135)
  at De (http://localhost:3000/static/js/vendor.30784604.js:2:596289)
  at http://localhost:3000/static/js/vendor.30784604.js:2:616171
  at Zr (http://localhost:3000/static/js/vendor.30784604.js:2:616265)
  at zr (http://localhost:3000/static/js/vendor.30784604.js:2:616679)
  at http://localhost:3000/static/js/vendor.30784604.js:2:622117
  at cu (http://localhost:3000/static/js/vendor.30784604.js:2:685488)
  at Ae (http://localhost:3000/static/js/vendor.30784604.js:2:595268)
`
function processShowErrorLocation() {
  const dirName = path.resolve(__dirname, "../../dist/static/js")
  const isExit = fs.existsSync(dirName)
  if (!isExit) {
    console.log(
      "%c [ 文件夹路径不存在,是不是没有打包,可执行命令yarn build:prod ]-26",
      "font-size:13px; background:pink; color:#bf2c9f;",
    )
    return
  }
  const files = fs.readdirSync(dirName)
  const regex = /^(?!vendor).*\.js.map$/
  files.forEach((item) => {
    if (!regex.test(item)) {
      return
    }
    const filePath = path.join(dirName, item)
    getSourceCodeLocation(filePath)
  })
}
async function getSourceMapConsumer(filePath) {
  const mapFile = path.resolve(filePath)
  const sourceMapContent = fs.readFileSync(mapFile).toString()
  return await new SourceMapConsumer(sourceMapContent)
}
async function getSourceCodeLocation(filePath) {
  const match = /(\w+\.js):(\d+):(\d+)/.exec(stack)
  const line = parseInt(match[2], 10)
  const column = parseInt(match[3], 10)
  const consumer = await getSourceMapConsumer(filePath)
  const originalPosition = consumer.originalPositionFor({
    line,
    column,
    bias: SourceMapConsumer.GREATEST_LOWER_BOUND,
  })
  originalPosition.mapFilePath = filePath
  if (!originalPosition.source) {
    return
  }
  console.log(originalPosition) // { source: 'test.js', line: 2, column: 0, name: 'sum' }
}
processShowErrorLocation()
 

 


















