6

If I use devtool: 'source-map' it works great with CSS:

I'm getting the file, row and everything is awesome

But, my JavaScript variable names are no fun:

Mangeled JavaScript vars

So, if I use devtool: eval-source-maps. Life is great - debugging JS. But my CSS then points to the big bundle-css instead of the separate files:

Great times debugging JS!

This is no fun...

How do I have my cake and eat it too?! I would like to use eval-source-map for JS and source-map for CSS during the same build.

This is my webpack config (using the latest of everything as of this writing):

/* eslint no-console:"off" */
const {resolve} = require('path');
const webpack = require('webpack');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const InlineManifestWebpackPlugin = require('inline-manifest-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const {getIfUtils, removeEmpty} = require('webpack-config-utils');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
// const OfflinePlugin = require('offline-plugin/runtime').install();

module.exports = (env) => {
    const {ifProd, ifNotProd} = getIfUtils(env);
    const config = {
        context: resolve('src'),
        entry: './js/index/index.js',
        output: {
            filename: 'bundle.[name].[hash].js',
            path: resolve('dist'),
            pathinfo: ifNotProd()
        },
        // devtool: 'source-map' //This works for CSS but not JS,
        devtool: 'eval-source-map' //This works for JS but not css
        module: {
            rules: [
                {
                    test: /\.js$/,
                    loader: 'babel-loader',
                    exclude: /(node_modules)/
                },
                {
                    test: /\.js$/,
                    loader: 'eslint-loader',
                    exclude: /(node_modules)/
                },
                {
                    test: /\.css$/,
                    use: ExtractTextPlugin.extract({
                        fallback: 'style-loader',
                        use: [
                            {
                                loader: 'css-loader',
                                options: {importLoaders: 1, minimize: false, sourceMap: true}
                            }
                        ]
                    })
                },
                {
                    test: /\.html$/,
                    use: {
                        loader: 'html-loader'
                    }
                },
                {
                    test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                    loader: 'url-loader?limit=10000&mimetype=application/font-woff',
                    query: {
                        name: 'static/media/files/[name].[hash:8].[ext]'
                    }
                }, {
                    test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                    loader: 'file-loader',
                    query: {
                        name: 'static/media/fonts/[name].[hash:8].[ext]'
                    }
                },
                {
                    test: /\.(gif|jpe?g|png)$/,
                    loader: 'url-loader?limit=25000',
                    query: {
                        limit: 10000,
                        name: 'static/media/images/[name].[hash:8].[ext]'
                    }
                }
            ]
        },
        plugins: removeEmpty([
            // ifProd(new InlineManifestWebpackPlugin()),
            // ifProd(new webpack.optimize.CommonsChunkPlugin({
            //     names: ['manifest']
            // })),
            new HtmlWebpackPlugin({
                template: './index.html'
                // inject: 'head'
            }),
            // new OfflinePlugin(),
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: ifProd('"production"', '"development"')
                }
            }),
            new UglifyJSPlugin({
                    parallel: {
                        cache: true
                    },
                    sourceMap: true
                }
            ),
            new OptimizeCssAssetsPlugin({
                cssProcessorOptions: {
                    preset: 'default',
                    map: {inline: false}
                }
            }),
            new ExtractTextPlugin('styles.[name].[hash].css'),
            new BundleAnalyzerPlugin(),
            new ProgressBarPlugin(),
        ])
    };
    if (env.debug) {
        console.log(config);
        debugger // eslint-disable-line
    }
    return config;
};

1 Answer 1

6

This seems to work:

{
  ...webpackConfig,
  devtool: false,
  plugins: [
    new webpack.SourceMapDevToolPlugin({
      test: /\.s?[ac]ss$/
    }),
    new webpack.EvalSourceMapDevToolPlugin({
      test: /\.(vue|[jt]sx?)$/
    }),
  ]
}

This will give you inline-source-map for css, scss and sass and eval-source-map for vue, js, jsx, ts and tsx

Sign up to request clarification or add additional context in comments.

4 Comments

This sadly does not seem to work for CSS files that are imported within a .js file. Any ideas on how to adjust for that? Still gets handled with eval-sourcemap instead of sourcemap.
Update, turns out nothing to do with imports from a JS file. Got it working by adding columns: true to the first plugin (CSS). In addition I also had to modify the regex as CSS filenames seem to have the version has in there too. Result: new webpack.SourceMapDevToolPlugin({ test: /\.s?[ac]ss(\?hash=[A-z0-9]*)?$/, columns: true })
But @redfox05 it looks like columns defaults to true according to webpack.js.org/plugins/eval-source-map-dev-tool-plugin and webpack.js.org/plugins/source-map-dev-tool-plugin unless I'm missing something.
@god_is_love Can't really remember now, but it was the only thing I changed, so....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.