Search code examples
webpacksource-mapsuglifyjswebpack-2extract-text-plugin

Webpack 2 ExtractTextPlugin CSS sourcemaps overwriting babel 6 JS sourcemaps


EDIT: found a solution shortly after posting this question. See My Answer below.


I have a webpack 2 based project that uses ExtractTextPlugin to pull out SCSS/CSS into a separate file.

Additionally, I have two entry points defined in webpack (vendor and app), which build out to my JS bundles.

For some reason, ExtractTextPlugin seems to break the sourcemap generated for the app bundle, app.js.map. If I look at the sourcemap, it points to random lines in the extracted CSS file, instead of the JS.

Looking inside the sourcemap file itself, I only see CSS and SCSS files listed under "sources" (shortene sample below):

{"version":3,"sources":["webpack:///webpack:///~/icon-font/package/styles/ficon.css","webpack:///webpack:///~/styles/package/styles/_imports.scss","webpack:///webpack:///~/styles/package/styles/includes/_variables.scss","webpack:///webpack:///~/styles/package/styles/includes/_mixins-utilities.scss", .....

however, if I comment out the ExtractTextPlugin in the webpack config, I get JS files listed in sources:

{"version":3,"sources":["webpack:///app-552b3935c142f5001484.js","webpack:///./src/lib/Globals.js","webpack:///./src/actions/AdActions.js", ....

So not really sure what is going on here... It seems like something about ExtractTextPlugin is breaking or overwriting the sourcemap for the app bundle?

Here is how I have all relevant plugins defined in my webpack config:

{
  entry: {
    vendors: [
      'react',
      'react-dom',
      'react-redux',
    ],
    app: path.resolve(__dirname, './../src/client.js'),
  },
  output: {
    path: path.resolve(__dirname, './../dist/assets/'),
    filename: '[name]-[chunkhash].js',
    sourceMapFilename: '[name]-[chunkhash].js.map',
  },
  cache: false,
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.(scss|sass|css)$/,
        loader: ExtractTextPlugin.extract({
          loader: [
            'css?sourceMap',
            'postcss-loader',
            'sass?sourceMap'
          ],
        }),
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [path.join(__dirname, '../src')],
        exclude: [NODE_MODULES_DIR],
      },
    ],
  },
  plugins: [
    new webpack.LoaderOptionsPlugin({
      debug: false,
      postcss: () => ([autoprefixer]),
      eslint: {
        emitWarning: true,
      },
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendors',
      minChunks: Infinity,
    }),
    new webpack.optimize.AggressiveMergingPlugin(),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false,
        drop_console: true,
        collapse_vars: true,
        reduce_vars: true,
      },
      output: {
        comments: false,
        ascii_only: true,
      },
    }),
    new ExtractTextPlugin({ filename: '_all.[chunkhash].css', allChunks: true }),
  ],
}

Any ideas what may be causing this? Could it be some sort of conflict with UglifyJS and the ExtractTextPlugin? a config issue on my part?


Solution

  • Found the solution shortly after posting this question! Just wanted to answer it incase anyone else encounters this same issue.

    I managed to find this helpful github issue. The issue lies with the sourceMapFileName set in webpack output. Mine was:

    sourceMapFilename: '[name]-[chunkhash].js.map',
    

    which, coincidentally, would match both the CSS from extractTextPlugin as well as the app bundle. So one was overwriting the other.

    Changing that line to:

    sourceMapFilename: '[file].map',
    

    allows a unique CSS map and JS map to be generated!

    Hope this helps someone. :)