Search code examples
typescriptwebpacknext.jssentry

Next.js source maps with typescript on Sentry


I have a simple setup for a project that imitates the Next JS sentry (simple) example

The problem is without sentry Enable JavaScript source fetching feature on, I cannot get the source maps to report correctly to sentry example: enter image description here

with the Enable JavaScript source fetching it shows correctly example (of the same error): enter image description here

Here is the configuration files used:

// next.config.js
const { parsed: localEnv } = require("dotenv").config();
const webpack = require("webpack");
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");

// Package.json => "@zeit/next-source-maps": "^0.0.4-canary.1",
const withSourceMaps = require("@zeit/next-source-maps")({ devtool: "source-map" });

module.exports = withSourceMaps({
  target: "serverless",
  env: {
    // Will be available on both server and client
    // Sentry DNS configurations
    SENTRY_DNS: process.env.SENTRY_DNS,
  },
  poweredByHeader: false,

  webpack(config, options) {
    config.plugins.push(new webpack.EnvironmentPlugin(localEnv));
    config.resolve.plugins.push(new TsconfigPathsPlugin());
    config.node = {
      // Fixes node packages that depend on `fs` module
      fs: "empty",
    };

    if (!options.isServer) {
      config.resolve.alias["@sentry/node"] = "@sentry/browser";
    }

    return config;
  },
});

The src/pages/_app.tsx and src/pages/_error.tsx follow the example mentioned in the repo.

// tsconfig.json
{
  "compilerOptions": {
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "baseUrl": ".",
    "declaration": false,
    "emitDecoratorMetadata": true,
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "isolatedModules": true,
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "module": "esnext",
    "moduleResolution": "node",
    "noEmit": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "paths": {
      "@src/*": ["./src/*"],
      "@components/*": ["./src/components/*"],
      "@services/*": ["./src/services/*"],
      "@utils/*": ["./src/utils/*"]
    },
    "removeComments": false,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "sourceRoot": "/",
    "strict": true,
    "target": "es6",
    "jsx": "preserve"
  },
  "exclude": [
    "node_modules",
    "cypress",
    "test",
    "public",
    "out"
  ],
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "compileOnSave": false
}

The source maps are uploaded to sentry during CI build process Using this script (after next build and next export)

configure-sentry-release.sh
#!/bin/bash
set -eo pipefail

# Install Sentry-CLI
curl -sL https://sentry.io/get-cli/ | bash

export SENTRY_ENVIRONMENT="production"
export SENTRY_RELEASE=$(sentry-cli releases propose-version)

# Configure the release and upload source maps
echo "=> Configure Release: $SENTRY_RELEASE :: $SENTRY_ENVIRONMENT"
sentry-cli releases new $SENTRY_RELEASE --project $SENTRY_PROJECT
sentry-cli releases set-commits --auto $SENTRY_RELEASE
sentry-cli releases files $SENTRY_RELEASE upload-sourcemaps ".next" --url-prefix "~/_next" 
sentry-cli releases deploys $SENTRY_RELEASE new -e $SENTRY_ENVIRONMENT
sentry-cli releases finalize $SENTRY_RELEASE

Is there anyway to get the source maps to work with sentry (without the Enable JavaScript source fetching and without leaving the source map publicly available on the server)?


Solution

  • This can be solved by abandoning the configure-sentry-release.sh script to upload the source maps manually but instead using sentry webpack plugin

    yarn add @sentry/webpack-plugin
    

    and use the plugin with next.config.js (webpack) to upload the source maps during the build step

    // next.config.js
      ...
      webpack(config, options) {
        ...
        // Sentry Webpack configurations for when all the env variables are configured
        // Can be used to build source maps on CI services
        if (SENTRY_DNS && SENTRY_ORG && SENTRY_PROJECT) {
          config.plugins.push(
            new SentryWebpackPlugin({
              include: ".next",
              ignore: ["node_modules", "cypress", "test"],
              urlPrefix: "~/_next",
            }),
          );
        }
        ...
    

    More on the issue can be found here: