Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any way to deploy source maps to Sentry, and not package them in the serverless ZIP files? #145

Open
ffxsam opened this issue Jun 15, 2021 · 25 comments

Comments

@ffxsam
Copy link
Contributor

ffxsam commented Jun 15, 2021

Hi, I just started using this plugin today, and I'm super impressed! With serverless-webpack, my API (37 Lambda functions) took 12 minutes to build & deploy. Now, with serverless-esbuild, it takes about 2 minutes. 馃槒

The only thing missing for me, is that I was relying on the Sentry Webpack plugin to automatically push my source maps to Sentry. With esbuild, is there some way I can have it dump my .map files to a folder, separately from the CloudFormation deployment, and then upload those to Sentry? Even if I have to use their CLI tool to upload the source maps, that's fine. I just need some way to hook into the build process and execute a process to do this.

Thanks!

@olup
Copy link
Contributor

olup commented Jun 15, 2021

Maybe more of a esbuild plugin to build ?

@ffxsam
Copy link
Contributor Author

ffxsam commented Jun 15, 2021

@olup I was just looking into this, but since plugins are experimental, I couldn't find any documentation.

I looked through the source code a bit, and I didn't see any way for a plugin to see which files were saved as a result of the build process.

Correction: looks like if I set the write option to false, then my plugin gets a full array of files with their contents as Uint8Array objects. So, I'm thinking I might be able to filter this list and save the .map files in a separate folder, then spawn a sentry-cli process to upload the source maps. This could work!

Now I just need to figure out where to save the .js files so Serverless can find them & deploy them to AWS, and how/where to save the .map files.

@olup
Copy link
Contributor

olup commented Jun 15, 2021

Thing is, packaging the js file is a bit involved and is partly the reason this lib exists. The code has been refined to cover many edge case. I wonder if there is a way to have an esbuild plugin that can work alongside normal operations of this lib.

@olup
Copy link
Contributor

olup commented Jun 15, 2021

Maybe something around https://esbuild.github.io/plugins/#resolve-callbacks ? There is quite a bit of doc to fiddle around.

@ffxsam
Copy link
Contributor Author

ffxsam commented Jun 15, 2021

I've been working on it, and making good progress. So far, this will save out source maps to their own folder. The last part is to just have this execute sentry-cli to upload them.

const fs = require('fs');
const path = require('path');

const envPlugin = {
  name: 'upload-sourcemaps',
  setup(build) {
    build.onEnd(args => {
      for (const file of args.outputFiles) {
        const { base, dir } = path.parse(file.path);

        if (/\.map$/.test(file.path)) {
          const funcDir = dir.replace(/.*\.build\//, '')

          fs.mkdirSync(`./.sourcemaps/${funcDir}`, { recursive: true });
          fs.writeFileSync(`./.sourcemaps/${funcDir}/${base}`, file.contents);

          continue;
        }


        fs.mkdirSync(dir, { recursive: true });
        fs.writeFileSync(file.path, file.contents);
      }
    });
  },
};

module.exports = [envPlugin];

@olup
Copy link
Contributor

olup commented Jun 15, 2021

Or you could leave the source map where they are and feed the path to sentry cli. In any case, you should open a repo. I am sure many teams would be happy to have such a plugin for esbuild (in a serverless-esbuild project or other). Should we close this issue as it is not specifically linked to serverless-esbuild ?

@ffxsam
Copy link
Contributor Author

ffxsam commented Jun 15, 2021

Leaving the source maps where they're placed by esbuild would include them in the ZIP file that goes up to AWS, and that's not necessary.

I'll absolutely create a public repo for this once it's done!

@olup
Copy link
Contributor

olup commented Jun 28, 2021

Hi there, can we close this as it will be handles by some esbuild plugin ?

@ffxsam
Copy link
Contributor Author

ffxsam commented Jun 28, 2021

Sure!

@olup olup closed this as completed Jun 28, 2021
@Steakeye
Copy link

Steakeye commented Sep 6, 2021

I'm converting a webpack build over to ESBuild and I've come across this exact requirement; does anyone know if a plugin has been released to handle this?

@floydspace
Copy link
Owner

hi @Steakeye, I don't this the plugin exists as npm package, you can try using the code snipped suggested by @ffxsam

@floydspace floydspace reopened this Sep 6, 2021
@simonc
Copy link

simonc commented Sep 28, 2021

For anyone new to esbuild and finding this page, @ffxsam's code works but you need to specify write: false in the options for args.outputFiles to be present.

# serverless.yml
custom:
  esbuild:
    plugins: plugins.js # file that contains the sourcemap-upload code
    sourcemap: external # using 'external' here as we only need the map files
    write: false

@kopertop
Copy link

@ffxsam did you ever make a public plugin for this? this is still the top google search result for this issue so I think it would be helpful if there was a final resolution here.

@ffxsam
Copy link
Contributor Author

ffxsam commented Jan 12, 2022

@kopertop I didn't post it officially anywhere, no. I've since moved to Serverless Stack, so I had to modify my plugin code a bit.

@henriquecarv
Copy link

When combining this solution with typescript, has anybody experienced your stack trace referring to the minified/bundled .js file instead of its .ts file?

@atwoodjw
Copy link

@henriquecarv Yes. Did you ever figure this out?

@henriquecarv
Copy link

henriquecarv commented Mar 22, 2022

@atwoodjw I did not figure it out back then, so I stopped trying after a while. Might get back to it again sometime later :)

@epiphone
Copy link

Sentry now provides an esbuild plugin for uploading source maps: https://docs.sentry.io/platforms/javascript/sourcemaps/uploading/esbuild.

@walterholohan
Copy link

@epiphone thank you for this, I will give it a go

@simonc
Copy link

simonc commented Dec 24, 2022

@walterholohan if you get it to work with serverless I'd be very interested in your config 馃槄

Merry xmas everyone 馃巵馃巹

@walterholohan
Copy link

Hopefully @epiphone can provide his magic sauce on how he got it working

@atwoodjw
Copy link

The esbuild plugin automatically creates releases and upload source maps when bundling the app, but serverless-esbuild bundles in response to multiple serverless lifecycle hooks (e.g. package, deploy, invoke local, offline, etc.) While appropriate for package and deploy, I don't think we want the plugin creating releases and uploading source maps when invoking a function locally or running offline.

To be useful in the context of serverless-esbuild, I think we need a way to conditionally use the plugin based on serverless lifecycle hooks.

@ghost
Copy link

ghost commented Jul 13, 2023

did anyone try out using Sentry with serverless-esbuild and sentry esbuild plugin

@rafael-lua
Copy link

@amitUpscale

I did, and it seems to have worked well for now.

For esbuild-serverless configuration, we have:

  esbuild:
    bundle: true
    minify: false
    sourcemap: external # we had to set this to external
    sourcesContent: true
    exclude: ['aws-sdk']
    target: 'node18'
    platform: 'node'
    plugins: esbuildPlugins.js # we declare an external plugin

And for the plugin file, we have:

const { sentryEsbuildPlugin } = require('@sentry/esbuild-plugin')

module.exports = [
  sentryEsbuildPlugin({
    org: 'my-org',
    project: 'the-sentry-project',
    authToken: process.env.SENTRY_AUTH_TOKEN,
    release: {
      name: process.env.APP_VERSION, // would be your release version
      finalize: process.env.SENTRY_RELEASE_FINALIZE === 'true', // we have CI for beta and prod. We only finalize on prod.
      dist: 'server',
    },
  }),
]

With that, just by running the serverless deploy command, sentry will take care of uploading the source files. We did it remix, and this is the way for us to send the server side source-maps.

@cpcwood
Copy link

cpcwood commented Nov 14, 2023

Following @rafael-lua's comment 馃檶馃徎 I also managed to upload sourcemaps and remove them from the zip by specifying them in the sourcemaps.filesToDeleteAfterUpload option, e.g.

const { sentryEsbuildPlugin } = require('@sentry/esbuild-plugin')

module.exports = [
  sentryEsbuildPlugin({
    org: 'my-org',
    project: 'the-sentry-project',
    authToken: process.env.SENTRY_AUTH_TOKEN,
    sourcemaps: {
      assets: ['./.esbuild/.build/**/*'],
      filesToDeleteAfterUpload: ['./.esbuild/.build/**/*.js.map']
    }
  })
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests