Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

configure SourceMapDevToolPlugin to generate "source-map"

TL;DR

What config options do I need to set in the SourceMapDevToolPlugin to emulate devtool: 'source-map'?

I have to use SourceMapDevToolPlugin to avoid generating a source map for my vendor modules....but I want source-map style maps, not inline-source-map.

Details:

I'm using webpack 4, and don't want to waste time generating a vendor.js.map, so I can't just set devtool and I instead do this:

https://webpack.js.org/plugins/source-map-dev-tool-plugin/#exclude-vendor-maps

but I notice this comment:

You can use the following code to replace the configuration option devtool: inline-source-map with an equivalent custom plugin configuration:

I, for the life of me, can't figure out what options I need to pass in to the plugin to replicate devtool: 'source-map', instead of inline-source-map

my package.json:

"scripts": {
   "build": "webpack -p --config webpack.prod.js",
   "start": "webpack-dev-server --debug --bail --config webpack.dev.js"
},

my (relavent) webpack config:

module.exports = {
   devtool: false, // using SourceMapDevToolPlugin instead
   optimization: {
     splitChunks: {
       cacheGroups: {
         commons: {
           test: /[\\/]node_modules[\\/]/,
           name: 'vendors',
           chunks: 'all'
         },
         styles: {
           test: /\.css$/,
           name: 'styles',
           chunks: 'all'
         }
      }
   },
   plugins: [
     new webpack.SourceMapDevToolPlugin({
       filename: '[name].map',
       exclude: ['vendor.js']
     })
   ]
}

and my dev config:

module.exports = merge(common, {
  mode: 'development',
  devServer: {
    contentBase: './public',
    stats: 'minimal'
  }
});

and my prod config

module.exports = merge(common, {
  mode: 'production',
  stats: 'errors-only'
});
like image 722
Jason Avatar asked Sep 07 '18 19:09

Jason


People also ask

How do I enable source maps?

To enable source maps in Google Chrome, go to Developer Tools, click the little cog icon, and then make sure that “Enable Javascript source maps” is checked. That's it.

How do I enable source map in Webpack?

In a sense, source maps are the decoder ring to your secret (minified) code. Using Webpack, specifying devtool: "source-map" in your Webpack config will enable source maps, and Webpack will output a sourceMappingURL directive in your final, minified file.

How do you find the source map in Webpack?

Enabling source maps in webpackgenerateSourceMaps({ type: "source-map" }), ]); source-map is the slowest and highest quality option of them all, but that's fine for a production build. If you build the project now ( npm run build ), you should see source maps in the project output at the dist directory.


2 Answers

I faced the same question trying to exclude a part of the code from source map. Since I could not get answers to my satisfaction in the Internet, I looked at the source codes of Webpack, and found the following code used by Webpack

https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsApply.js

if (
            options.devtool &&
            (options.devtool.includes("sourcemap") ||
                options.devtool.includes("source-map"))
        ) {
            const hidden = options.devtool.includes("hidden");
            const inline = options.devtool.includes("inline");
            const evalWrapped = options.devtool.includes("eval");
            const cheap = options.devtool.includes("cheap");
            const moduleMaps = options.devtool.includes("module");
            noSources = options.devtool.includes("nosources");
            legacy = options.devtool.includes("@");
            modern = options.devtool.includes("#");
            comment =
                legacy && modern
                    ? "\n/*\n//@ source" +
                      "MappingURL=[url]\n//# source" +
                      "MappingURL=[url]\n*/"
                    : legacy
                    ? "\n/*\n//@ source" + "MappingURL=[url]\n*/"
                    : modern
                    ? "\n//# source" + "MappingURL=[url]"
                    : null;
            const Plugin = evalWrapped
                ? EvalSourceMapDevToolPlugin
                : SourceMapDevToolPlugin;
            new Plugin({
                filename: inline ? null : options.output.sourceMapFilename,
                moduleFilenameTemplate: options.output.devtoolModuleFilenameTemplate,
                fallbackModuleFilenameTemplate:
                    options.output.devtoolFallbackModuleFilenameTemplate,
                append: hidden ? false : comment,
                module: moduleMaps ? true : cheap ? false : true,
                columns: cheap ? false : true,
                lineToLine: options.output.devtoolLineToLine,
                noSources: noSources,
                namespace: options.output.devtoolNamespace
            }).apply(compiler);
        }

So you can see, the options for the SourceMapDevToolPlugin could depend on some of your output webpack configurations (sourceMapFilename, devtoolModuleFilenameTemplate, devtoolFallbackModuleFilenameTemplate, devtoolLineToLine, devtoolNamespace - see https://webpack.js.org/configuration/output).

For my webpack config, the final options that were going in to SourceMapDevToolPlugin when I used devtool: 'source-map' were as follows:

{
    "filename": "[file].map[query]",
    "append": null,
    "module": true,
    "columns": true,
    "lineToLine": false,
    "noSources": false,
    "namespace": ""
}

If you are not using any of the mentioned output options then the above should be fine for you. Otherwise, you will need to take them into consideration. You can modify the node_modules/webpack/lib/WebpackOptionsApply.js to add a console.log with JSON.stringify() to see what exact parameters were used for your Webpack configuration.

Hope this helps.

like image 160
Afzal Avatar answered Oct 13 '22 05:10

Afzal


From the docs, emphasis mine:

filename (string): Defines the output filename of the SourceMap (will be inlined if no value is provided).

which means that if you specify the filename option you have identical behavior to devtool: 'source-map'

devtool: 'inline-source-map' === new webpack.SourceMapDevToolPlugin({})

devtool: 'source-map' === new webpack.SourceMapDevToolPlugin({ filename: '[file].map' })

like image 6
Dave Avatar answered Oct 13 '22 06:10

Dave