Next.js: Add sourcemap support for Node.js in development

Created on 27 Sep 2018  路  17Comments  路  Source: vercel/next.js

Bug report

Describe the bug

I get errors like:

TypeError: Cannot read property 'i18n' of undefined
at new MyApp (/Users/sheerun/Source/Project/search/.next/server/static/development/pages/_app.js:85530:22)

When error happens on server side, with newest next.js 7

Honestly it's hard to debug such errors when I need to dig into compiled file.

story 5 feature request

Most helpful comment

This is pretty inconvenient for debugging SSR and API route errors. Any way we could get the priority bumped on this?

Also, this solution doesn't seem to work with typescript sources?

All 17 comments

Please provide a reproduction, SSR errors should be hydrated on the client side using react-error-overlay too.

I'm seeing the same. Errors thrown during SSR request print stack trace from compiled js without sourcemap.

Steps to Reproduce:

package.json:

{
  "dependencies": {
    "next": "^7.0.2",
    "react": "^16.6.3",
    "react-dom": "^16.6.3"
  }
}

pages/index.js:

import React from 'react'

const Page = () => {
  return (
    <div>
      <h1>Hello</h1>
    </div>
  )
}

Page.getInitialProps = async () => {
  throw new Error('SSR Error')
  return {
    foo: 123
  }
}

export default Page

Stack trace:

Error: SSR Error
    at Function._callee$ (/Users/pretzel/code/nextjs-example/.next/server/static/development/pages/index.js:143:17)
    at tryCatch (/Users/pretzel/code/nextjs-example/node_modules/regenerator-runtime/runtime.js:62:40)
    at Generator.invoke [as _invoke] (/Users/pretzel/code/nextjs-example/node_modules/regenerator-runtime/runtime.js:288:22)
    at Generator.prototype.(anonymous function) [as next] (/Users/pretzel/code/nextjs-example/node_modules/regenerator-runtime/runtime.js:114:21)
    at asyncGeneratorStep (/Users/pretzel/code/nextjs-example/.next/server/static/development/pages/index.js:112:103)
    at _next (/Users/pretzel/code/nextjs-example/.next/server/static/development/pages/index.js:114:194)
    at /Users/pretzel/code/nextjs-example/.next/server/static/development/pages/index.js:114:364
    at new Promise (<anonymous>)
    at Function.getInitialProps (/Users/pretzel/code/nextjs-example/.next/server/static/development/pages/index.js:114:97)
    at _callee$ (/Users/pretzel/code/nextjs-example/node_modules/next/dist/lib/utils.js:86:30)
    at tryCatch (/Users/pretzel/code/nextjs-example/node_modules/regenerator-runtime/runtime.js:62:40)
    at Generator.invoke [as _invoke] (/Users/pretzel/code/nextjs-example/node_modules/regenerator-runtime/runtime.js:288:22)
    at Generator.prototype.(anonymous function) [as next] (/Users/pretzel/code/nextjs-example/node_modules/regenerator-runtime/runtime.js:114:21)
    at asyncGeneratorStep (/Users/pretzel/code/nextjs-example/node_modules/@babel/runtime-corejs2/helpers/asyncToGenerator.js:5:24)
    at _next (/Users/pretzel/code/nextjs-example/node_modules/@babel/runtime-corejs2/helpers/asyncToGenerator.js:27:9)
    at /Users/pretzel/code/nextjs-example/node_modules/@babel/runtime-corejs2/helpers/asyncToGenerator.js:34:7

https://github.com/zeit/next.js/issues/2285 from 2017 appears related, perhaps some architecture changed in 7.0.0

I'm going to look into extending the webpack config

implementing the following worked in my setup, at least to get the correct line numbers in the stack :)

  require('source-map-support').install({
    retrieveSourceMap: function(source) {
      if (source.indexOf('.next') > -1) {
        const rel = relative(process.cwd(), source)
        const mapPath = `${rel}.map`
        return {
          url: basename(rel),
          map: fs.readFileSync(mapPath, 'utf8')
        }
      }
    }
  })

@bhurlow Where do I put it?

@abs-zero, I'm putting this in the index.js file of my next.js, which is configured programmatically. I'm still fiddling with the best way to resolve the source maps, I'll reply with more info

Based on the reproduction case, this seems to fall under https://github.com/zeit/next.js/issues/5400.

Are you seeing the plain-text "Internal Server Error" response in any other cases besides errors within _app.js getInitialProps?

(edit) Sorry, I'm realizing this is specifically about server-side error logging, and yes... definitely an issue for production code.

Added the solution by @bhurlow to next.config.js, but there's a caveat, the browser gets it too. Any ideas on how to limit this to console only?

// next.config.js

const { PHASE_DEVELOPMENT_SERVER } = require('next/constants');

module.exports = phase => {
  if (phase === PHASE_DEVELOPMENT_SERVER) {
    const { relative, basename } = require('path');
    const { readFileSync } = require('fs');

    require('source-map-support').install({
      retrieveSourceMap: function(source) {
        if (source.indexOf('.next') > -1) {
          const rel = relative(process.cwd(), source);
          const mapPath = `${rel}.map`;
          return {
            url: basename(rel),
            map: readFileSync(mapPath, 'utf8')
          };
        } else {
          return null;
        }
      }
    });
  }

  return {};
};

This is pretty inconvenient for debugging SSR and API route errors. Any way we could get the priority bumped on this?

Also, this solution doesn't seem to work with typescript sources?

@aequasi I was able to get this all working w/o explicitly requiring the source-maps. In your next config, set config.devtool to 'eval-source-map', and make sure that you have the tsconfig setup with sourcemaps.

next.config.js

module.exports = { 
  webpack(config, _) {
    config.devtool = 'eval-source-map';
    return config;
  };
};

tsconfig.json

{
  "compilerOptions": {
     ...
     "sourceMap": true
  },
  ...
}

I don' think anyone has explicitly mentioned whether this is for development only, but I'm personally trying to do this in production.

@kyle-mccarthy so that method may be great in dev but I don' think for my situation it would work :man_shrugging:

@kyle-mccarthy unfortunately those settings didn't work for me. Server side breakpoints don't break on my ts files at all, opting always to go to a wildly off js file.

just to keep this alive... this is one of the reasons the dev experience for next.js is kinda bad right now. it's almost impossible to debug server-side code ATM, which... is super important given that next.js is an SSR react framework. also seems like feature request is missing the point. Not being able to debug server-side code in an SSR react framework is a bug, IMO.

FWIW, @kyle-mccarthy's method also does not work anymore because of this. apparently the next.js build now reverts any changes you make to devtool.

@andycmaj, I have almost no problems debugging next in development with both vscode and chrome debuggers, client or node. It was not easy and intuitive to setup for vscode though. Nevertheless all the source maps work just fine with 9.5.x (9.4.x didn't work for vscode->node debugging only.). The only one - sometimes when code recompiles debuggers don't see updated sources. It's annoying, but not happening that often.

I'm not sure though which problem you have.

I'm on 9.3.x and my issue was SSR debugging. are you saying this issue is now fixed in 9.5? should this bug be closed or associated with a PR then?

I'm on 9.3.x and my issue was SSR debugging. are you saying this issue is now fixed in 9.5? should this bug be closed or associated with a PR then?

This issue is not about the debugger but about the errors logged in the console which are currently not resolved

Server side break points not hitting is most likely related to this issue https://github.com/vercel/next.js/issues/15823

Was this page helpful?
0 / 5 - 0 ratings