Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get correct source map file for a single chunk with CommonsChunkPlugin, UglifyJsPlugin and SourceMapDevToolPlugin?

I'm trying to get webpack to output correct sourcemaps for a React project that's split into app and vendor chunks using CommonsChunkPlugin and minified using UglifyJsPlugin. This is for production environment, so I:

  • don't want a huge sourcemap for vendor bundle generated.
  • don't want the webpack:// sources in map file
  • don't want map files for css
  • need actual map file output and linked to from the js file so that error monitoring tools can load it

All this seems to be a bit too much for the devtool config option so I'm trying to use SourceMapDevToolPlugin directly with devtool: false.

The relevant parts of webpack config look like this:

entry: production ? {
    app: './src/index.jsx',
    vendor: Object.keys(packageDotJson.dependencies)
} : './src/index.jsx',

output: {
    path: production ? './dist' : './assets',
    publicPath: production ? '' : '/',
    filename: production ? 'app.[hash].js' : 'app.js'
},

plugins: production ? [
    new webpack.optimize.CommonsChunkPlugin(/* chunkName= */"vendor", /* filename= */"vendor.bundle.[hash].js"),
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin({
        compress: {
            warnings: false
        }
    }),
    new ExtractTextPlugin("app.[hash].css"),
    new webpack.SourceMapDevToolPlugin({
        test: [/\.js$/, /\.jsx$/],
        filename: "app.[hash].js.map",
        append: "//# sourceMappingURL=[url]",
        moduleFilenameTemplate: "[absolute-resource-path]",
        fallbackModuleFilenameTemplate: "[absolute-resource-path]",
        columns: false
    }),
    new HtmlWebpackPlugin({...})
] : [
    new HtmlWebpackPlugin({...})
]

Sadly, what I'm getting with this is a map file named correctly after my app js file, but containing:

{"version":3,"file":"vendor.bundle.05d4e19a02044f47a73a.js","sources":["vendor.bundle.05d4e19a02044f47a73a.js","*"]...}

Changing test to test: /^app\.(.*)\.js$/, creates a similar map file that maps app.05d4e19a02044f47a73a.js to itself. I can't seem to get the original js and jsx source files in sources.

I've tried playing with the plugin order but that didn't change anything.

What am I doing wrong?

I also find it unclear whether test/include/exclude should point to original sources or the minified js files. With other loaders and plugins it's kinda obvious but not with SourceMapDevToolPlugin.

like image 425
Miloš Rašić Avatar asked Jul 08 '16 16:07

Miloš Rašić


People also ask

How do source map files work?

A source map is a file that maps from the transformed source to the original source, enabling the browser to reconstruct the original source and present the reconstructed original in the debugger.

What is source map in Webpack?

Source maps connect the bundle file with corresponding source files. Source maps are not a Webpack only concept. It is a common debugging technique which is respected by all modern browsers. Webpack has the ability to generate source maps. Let us try generating a source map.

What are jQuery map files?

What is jQuery Source Map? As the name suggests, it consists of a whole bunch of information that can be used to map the code within a compressed file back to it's original source . It is used by browser's debugger to help developers debug the minified version of script file.


1 Answers

Ok, figured out a solution on my own. My SourceMapDevToolPlugin options actually weren't filtering out the vendor bundle, but the filename was set to "app.[hash].js.map", which cause the vendor chunk map to be generated and to overwrite the app chunk map with the same filename.

The correct options are:

    new webpack.SourceMapDevToolPlugin({
        test: [/\.js$/, /\.jsx$/],
        exclude: 'vendor',
        filename: "app.[hash].js.map",
        append: "//# sourceMappingURL=[url]",
        moduleFilenameTemplate: '[resource-path]',
        fallbackModuleFilenameTemplate: '[resource-path]',
    })

The minified app.[hash].js is included in the sources but this doesn't seem to cause any problems for the browsers.

columns: false is what caused the plugin to only map the minified file to itself for some reason.

like image 134
Miloš Rašić Avatar answered Oct 06 '22 00:10

Miloš Rašić