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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better support for disabling sourcemaps of node_modules as plugins can't cover all cases. #3310

Open
AshHeskes opened this issue Aug 11, 2023 · 6 comments

Comments

@AshHeskes
Copy link

AshHeskes commented Aug 11, 2023

Referencing this issue which discusses disabling sourcemaps for node_modules. @evanw quite kindly provided a code snippet as a plugin that would filter out sourcemaps for node modules by basically appending an inline sourcemap containing nothing to each file matching the filter.

While this snippet does work in the majority of cases where the imported file is a flavour of JS that supports such comments. It doesn't for example work for require('something.json') which is valid in node > 16 (perhaps earlier). If you append the empty inline sourcemap you get an error during bundling that comments are not supported in JSON. Which is also correct.

As a quick example project:

+ app
  - index.js (`require('some-lib')`)
+ node_modules
  + some-lib
    - index.js (`require('./some-json.json')` - valid)
    - some-json.json (`{ my-prop: 'foo' }` - valid )

With an esbuild config of (using the snippet provided by @evanw):

const esbuild = require('esbuild');
const { readFile } =  require('node:fs/promises');

esbuild.build( {
  entryPoints : [ 'src/index.js' ],
  bundle : true,
  outdir : './dist',
  format : 'cjs',
  platform: 'node',
  plugins: [
    {
      name: 'excludeNodeModulesFromSourceMaps',
      setup(build) {
        build.onLoad({ filter: /node_modules/ }, async (args) => {
          return {
            contents: `${await readFile(
              args.path,
              'utf8'
            )}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIiJdLCJtYXBwaW5ncyI6IkEifQ==`,
            loader: 'default'
          };
        });
      }
    }
  ]
} );

Will error due to the fact you can't have a comment in json. Which means you have to filter out json imports from excludeNodeModulesFromSourceMaps. Which means node_modules importing json will still be included in sourcemaps.

That might not sound like a big deal and normally I would agree. However this method of excluding sourcing maps via a comment doesn't only apply to json it can apply to anything that doesn't use // as a comment. Like a text file, or a binary but it seems insane to handle on a case by case basis. So I think there needs to be a better mechanism to say don't sourcemap dependencies. Than just appending an inline empty sourcemap comment.

An extreme example but very popular one would be require('aws-sdk') which makes heavy use of require('some-json.json'). There's no way to stop esbuild from creating sourcemaps for all that json which bloats the sourcemap file by several MB from what should be just a few hundred KB. Even with all the actual aws-sdk code excluded via the above plugin.

@hyrious
Copy link

hyrious commented Aug 13, 2023

The easiest way to remove the json file's sourcemap is doing a postprocess on the output files and replace those json source contents with null.

On the other hand if you still want to use plugins, you can use a custom onLoad callback that handles those json files by youself, for example:

onLoad({filter: /node_modules.*\.json$/}, args => {
  var json = fs.readFileSync(args.path, 'utf8')
  var js = 'export default ' + json +
    '\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIiJdLCJtYXBwaW5ncyI6IkEifQ=='
  return { contents: js, loader: 'js' }
})

@AshHeskes
Copy link
Author

@hyrious That would solve the current problem for JSON but not for any other import type that a dependency might import. You then have to handle each on a case by case basis. Which seems an unreasonable way to do it. Especially as this will be more and more common as ESM loaders rolls out.

@perpil
Copy link

perpil commented Sep 16, 2023

Another workaround I found is that if you use the copy loader, it leaves the .json content out of the sourcemap.

i.e.
--loader:.json=copy

@aripalo
Copy link

aripalo commented Apr 26, 2024

Also there's other tooling that use esbuild in under the hood such way that plugins aren't an option. An example of this is AWS CDK which uses esbuild CLI command in synchronous manner resulting in a situation where excluding node_modules from sourcemaps is impossible: Which is problematic as having full sourcemap will increase AWS Lambda cold start (due to bigger deployment package size).

The perfect solution to this problem would be native node_modules exclusion from sourcemaps via CLI argument.

@mmarttinen
Copy link

mmarttinen commented Oct 28, 2024

The perfect solution to this problem would be native node_modules exclusion from sourcemaps via CLI argument.

+1 for this.

@evanw
Copy link
Owner

evanw commented Dec 20, 2024

I'd like to enable this along with #3878. Commenting here to link these two issues together.

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

No branches or pull requests

6 participants