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

Create multiple sourcemaps from a single build #6813

Open
Xotic750 opened this issue Mar 21, 2018 · 21 comments
Open

Create multiple sourcemaps from a single build #6813

Xotic750 opened this issue Mar 21, 2018 · 21 comments

Comments

@Xotic750
Copy link

Do you want to request a feature or report a bug?

feature

What is the current behavior?

Set devtool;. NODE_ENV === PRODUCTION ? 'nosources-source-map' : 'eval-source-map';

Sourcemap type is built.

If the current behavior is a bug, please provide the steps to reproduce.

What is the expected behavior?

If this is a feature request, what is motivation or use case for changing the behavior?

What we'd like is to be able to create multiple sourcemaps for production as a single run.

Set devtool: NODE_ENV === PRODUCTION ? ['nosources-source-map', 'source-map'] : 'eval-source-map';

The first sourcemap will be used client side and included in the the js e.g. //# sourceMappingURL=index.js.map

The second sourcemap would be used for our monitoring system, and would have a filename for example index.js.map2 or anything sensible.

All this would be performed in a single build run.

Perhaps this is already possible and we just haven't discovered how.

Please mention other relevant information such as the browser version, Node.js version, webpack version, and Operating System.

@ooflorent
Copy link
Member

You could use a multi-config build to achieve this:

if (process.env.NODE_ENV === "production") {
  module.exports = [
    createConfig({name: "prod1", devtool: "nosources-source-map"}),
    createConfig({name: "prod2", devtool: "source-map"}),
  ]
} else {
  module.exports = createConfig({name: "dev", devtool: "eval-source-map"})
}

@Xotic750
Copy link
Author

Xotic750 commented Mar 21, 2018

Thanks, we have tried a multi-config. There have been concerns as to whether each config definitely creates the same final bundle (all my tests indicate that they are, but that is a limited set). Though each build does produce a different hash which is included in the sourcemap), hence a preference to have the sourcemaps created in a single run. There is also the consideration of the time that it takes to bundle our application, twice if we are using multi-config to generate the 2 types of sourcemap that we require.

Just to add that this is for medical solutions, so there is a great deal of red-tape around what is and what isn't allowed, and the high level of concern.

Thanks for any time and consideration.

@sokra
Copy link
Member

sokra commented Mar 21, 2018

That's possible. Just use this configuration, or similar:

devtool: "hidden-source-map",
plugins: [
  new SourceMapDevtoolPlugin({
    filename: "[file].secondary.map",
    noSources: true
  })
]

@Xotic750
Copy link
Author

That's great, thanks! I will be sure to try that first thing in the morning.

@Xotic750
Copy link
Author

Xotic750 commented Mar 22, 2018

It looked very promising, I set

devTool: NODE_ENV === PRODUCTION ? 'hidden-source-map' : 'eval-source-map';
plugins: [
    new webpack.SourceMapDevToolPlugin({
      filename: '[file].map',
      noSources: true,
    }),
],
output: {
    filename: FILENAME,
    path: BUILD_DIR,
    sourceMapFilename: '[file].monitor.map',
},

2 files were created, the index.js.map was spot on with no source in the map file and only this link was appended to the bundle. The other file index.js.monitor.map was created but the content was:

{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourceRoot":""}

We are using Webpack 3.11.0, the production is being uglified "uglifyjs-webpack-plugin": "^1.2.4" and transpiled "babel-core": "^6.26.0" among other things.

Is this a bug or did I configure it incorrectly?

I see a similar report #6133

I created a minimum reproduction of the problem https://github.com/Xotic750/webpack-multi-sourcemap

I also tried with Webpack 4.2.0 (though I am unable to use this in the products at present) with the same result https://github.com/Xotic750/webpack-multi-sourcemap/tree/webpack-4

@Xotic750
Copy link
Author

Xotic750 commented Apr 3, 2018

Is there any more information that I can provide to confirm whether this is our configuration problem or a bug? I'd like to get this working, and would even be willing to try and identify the problem in the source if needed. Thanks.

@alexander-akait
Copy link
Member

@Xotic750 problem still exists?

@Xotic750
Copy link
Author

Xotic750 commented May 15, 2018

@evilebottnawi Updated both branches linked above.
v3.12.0 same result.
v4.8.3 same result

@webpack-bot
Copy link
Contributor

This issue had no activity for at least half a year.

It's subject to automatic issue closing if there is no activity in the next 15 days.

@Xotic750
Copy link
Author

The problem still exists to the best of my knowledge. The test project is still available at https://github.com/Xotic750/webpack-multi-sourcemap but I have not updated it recently. If it is configuration problem on my part then I would love some guidance to show me where I've gone wrong, equally if this is a problem with webpack then I would love to see it fixed.

@webpack-bot
Copy link
Contributor

This issue had no activity for at least half a year.

It's subject to automatic issue closing if there is no activity in the next 15 days.

@Xotic750
Copy link
Author

Xotic750 commented May 16, 2019

https://github.com/Xotic750/webpack-multi-sourcemap
Updated to all the latest dependencies:

  "devDependencies": {
    "@babel/cli": "^7.4.4",
    "@babel/core": "^7.4.4",
    "@babel/plugin-transform-runtime": "^7.4.4",
    "@babel/preset-env": "^7.4.4",
    "@babel/runtime": "^7.4.4",
    "babel-loader": "^8.0.6",
    "terser-webpack-plugin": "^1.2.3",
    "webpack": "^4.31.0",
    "webpack-cli": "^3.3.2"
  },

And the problem still exists (is it my configuration or is this truly a webpack bug?). See the 2 map files produced.
https://github.com/Xotic750/webpack-multi-sourcemap/tree/master/dist

@joshenders
Copy link

Interested in this as well for the exact same use case described in the original post. A nosources-source-map version very public consumption for resolving stacktraces and a source-map version for private internal-only consumption for debugging on the live site.

@Xotic750
Copy link
Author

Xotic750 commented Jul 30, 2019

@joshenders We were never able to get this to work out of the box and so I ended up writing a little plugin to do the job.

/**
 * @file Webpack plugin to build the production sourcemap and add the URL.
 * @copyright Copyright (c) 2018, ProReNata AB
 * @author Graham Fairweather <graham.fairweather@prorenata.se>
 * @version 2.0.0
 * @see {@link https://github.com/webpack/docs/wiki/how-to-write-a-plugin} for further information.
 */

const {ConcatSource, RawSource} = require('webpack-sources');

const PLUGIN_NAME = 'CreateProductionSourcemap';

class CreateProductionSourcemap {
  constructor(options = {}) {
    this.sourceMapFilename = options.sourceMapFilename;
    this.sourceMappingURLComment = options.append;
  }

  apply(compiler) {
    const {filename, sourceMapFilename} = compiler.options.output;

    const onEmit = (compilation, callback) => {
      const {assets} = compilation;

      const outputFileName = this.sourceMapFilename.replace('[file]', filename);
      const sourceMapComment = this.sourceMappingURLComment.replace('[url]', outputFileName);

      utils.stdout.write(`Preparing production sourcemap: "${outputFileName}" `);
      const assetName = sourceMapFilename.replace('[file]', filename);
      const withoutSource = JSON.parse(assets[assetName]._value);

      delete withoutSource.sourcesContent;
      assets[outputFileName] = new RawSource(JSON.stringify(withoutSource));
      assets[filename] = new ConcatSource(new RawSource(assets[filename].source()), sourceMapComment);
      utils.stdout.write('Done.');
      callback();
    };

    if (compiler.hooks) {
      compiler.hooks.emit.tapAsync(PLUGIN_NAME, onEmit);
    } else {
      compiler.plugin('emit', onEmit);
    }
  }
}

module.exports = CreateProductionSourcemap;

and in your webpack config

const CreateProductionSourcemap = require('./DevTools/Build/CreateProductionSourcemap');

{
    devtool:  'source-map',
    output: {
      filename: OUTPUT_FILENAME,
      path: OUTPUT_PATH,
      sourceMapFilename:  '[file].sentry.map' ,
    },
   plugins: [new CreateProductionSourcemap()],
}

That should be it, I don't think I've missed anything.

I would still like to know if we configured webpack incorrectly, or if the fact that we couldn't get it to work is a bug.

@joshenders
Copy link

joshenders commented Jul 30, 2019

Thanks for that! Very helpful. In case anyone wants to do this with jq outside of webpack, here's how:

Removing the sourcesContent key using jq in a build script:

jq  'del(.sourcesContent)' example-source-map.js.map

The nosources-source-map is just a source-map without the sourcesContent key. There are no differences.

diff -u <(jq 'del(.sourcesContent)' example-source-map.js.map) example-nosources-source-map.js.map

You could then gate public/private access to this file using logic in your application load balancer or CDN. e.g

if the source.map request originates from a private network
  serve source-map version
else
  serve nosources-source-map version

This way the sourceMappingURL comment need not change and you have resolved client stack traces for error reporting/RUM as well as debuggability in production without exposing your unminified/obfuscated client source code.

@webpack-bot
Copy link
Contributor

This issue had no activity for at least three months.

It's subject to automatic issue closing if there is no activity in the next 15 days.

@Xotic750
Copy link
Author

Is it worth me updating this example project again?

@alexander-akait
Copy link
Member

@Xotic750 no, all fine, not high priority

@webpack-bot
Copy link
Contributor

Issue was closed because of inactivity.

If you think this is still a valid issue, please file a new issue with additional information.

@joshenders
Copy link

JFYI this issue is currently surfacing on social media as people are seeing sourcemap links to non-routable domains (because the most common way of configuring webpack is still to produce a single build) on Twitter's production site and confusing this with leaking private information from a dev build.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Priority - Low
Development

No branches or pull requests

7 participants