Search code examples
reactjsnpmwebpackwebpack-dev-serversource-maps

Webpack 4 devtool option does not work with webpack-dev-server


Before I decided to post this issue, I did quite a few things as a background check. So, my problem is:

- I use webpack v4.6.0 and webpack-dev-server v3.1.3 - they work fine together, but now I am trying to set up source maps for my application, it seems that devtool option does not work.

At least for me, I have tried and tested every option from the list:

  • Webpack 4 - Sourcemaps : this issue suggests that devtool: 'source-map' should work out of the box, but this is not the case for me
  • how to make webpack sourcemap to original files : adding devtoolModuleFilenameTemplate: info =>'file://' + path.resolve(info.absoluteResourcePath).replace(/\\/g, '/') to my output config did not help much, instead of client.js it shows index.js for me thoughenter image description hereenter image description here
  • https://github.com/webpack/webpack/issues/6400 : this one is not an accurate description of my issue, by trying the methods here did not seem to help me either
  • I tried to use webpack.SourceMapDevToolPluginbut it doesn't work with my setup either, even when I delete devtools or set them to false
  • I do not use UglifyJS plugin here
  • I know that webpack-dev-server is in maintenance now, so I tried webpack-serve, but it seems like source maps do not work with it either
  • I have tried source-map-support package as well, but no luck either, have a similar situation as here: enter image description here

Do you know if that issue is going to be fixed by some PR or have you tried to solve it yourself? Any tips or help is appreciated!

I would like to get output as described here, in blogpost with direct links to my files and the original files code.

My webpack.js

// webpack v4.6.0
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const stylish = require('eslint/lib/formatters/stylish');
const webpack = require('webpack');

module.exports = {
  entry: { main: './src/index.js' },
  output: {
    devtoolModuleFilenameTemplate: info =>
      'file://' + path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[hash].js'
  },
  devtool: 'source-map',
  devServer: {
    contentBase: './dist',
    hot: true
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'eslint-loader',
        options: {
          formatter: stylish
        }
      }
    ]
  },
  plugins: [
    // new webpack.SourceMapDevToolPlugin({
    //   filename: '[file].map',
    //   moduleFilenameTemplate: undefined,
    //   fallbackModuleFilenameTemplate: undefined,
    //   append: null,
    //   module: true,
    //   columns: true,
    //   lineToLine: false,
    //   noSources: false,
    //   namespace: ''
    // }),
    new CleanWebpackPlugin('dist', {}),
    new HtmlWebpackPlugin({
      inject: false,
      hash: true,
      template: './src/index.html',
      filename: 'index.html'
    }),
    new WebpackMd5Hash(),
    new webpack.NamedModulesPlugin(),
    new webpack.HotModuleReplacementPlugin()
  ]
};

my package.json

{
  "name": "post",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "storybook": "start-storybook -p 9001 -c .storybook",
    "dev": "webpack-dev-server --mode development --open",
    "build": "webpack --mode production"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@storybook/addon-actions": "^3.4.3",
    "@storybook/react": "v4.0.0-alpha.4",
    "babel-cli": "^6.26.0",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "babel-runtime": "^6.26.0",
    "clean-webpack-plugin": "^0.1.19",
    "eslint": "^4.19.1",
    "eslint-config-prettier": "^2.9.0",
    "eslint-loader": "^2.0.0",
    "eslint-plugin-prettier": "^2.6.0",
    "eslint-plugin-react": "^7.7.0",
    "html-webpack-plugin": "^3.2.0",
    "prettier": "^1.12.1",
    "react": "^16.3.2",
    "react-dom": "^16.3.2",
    "webpack": "v4.6.0",
    "webpack-cli": "^2.0.13",
    "webpack-dev-server": "v3.1.3",
    "webpack-md5-hash": "0.0.6",
    "webpack-serve": "^0.3.1"
  },
  "dependencies": {
    "source-map-support": "^0.5.5"
  }
}

my output in console is: enter image description here

Edit:

I saw a similar question here, but nobody seems to be answering. The error was made on purpose! This does not just apply to linting errors but to every error my my app. Here is a link to my GITHUB repo: https://github.com/marharyta/webpack-fast-development

UPDATE 01.05.2018

I have created another repo with cleaner setup: https://github.com/marharyta/webpack-4.6.0-test And detailed explanation of how I got there here: https://medium.com/p/79fb676417f4/edit Some suggestions were given by the webpack contributors but that still did not work for me: https://github.com/marharyta/webpack-4.6.0-test/issues/1

UPDATE 02.05.2018

After a long investigation, I posted my answer below. The problem was ESLint and probably some mode markings since I had to do it the CLI way. I also an issue in ESLint loader here: https://github.com/webpack-contrib/eslint-loader/issues/227 I also created a post with a more detailed description here: https://medium.com/@riittagirl/how-to-solve-webpack-problems-the-practical-case-79fb676417f4


Solution

  • So, after a long tried and error, I finally got help from one of webpack mainteiners. The main issue was eslint. If you load it as a loader, it creates unexpected behaviour. By deleting the eslint from webpack loaders for js you can fix that.

    The webpack setup before:

    // webpack v4
    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const WebpackMd5Hash = require('webpack-md5-hash');
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    
    const baseConfig = {
      entry: { main: './src/index.js' },
      output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].[hash].js'
      },
      devServer: {
        contentBase: './dist',
        hot: true,
        open: true
      },
      module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            **use: [
              { loader: 'babel-loader' },
              {
                loader: 'eslint-loader',
                options: { formatter: require('eslint/lib/formatters/stylish') }
              }**
            ]
          }
        ]
      },
      plugins: [
        new CleanWebpackPlugin('dist'),
        new HtmlWebpackPlugin({
          inject: false,
          hash: true,
          template: './src/index.html',
          filename: 'index.html'
        }),
        new WebpackMd5Hash()
      ]
    };
    
    if (process.env.NODE_ENV === 'development') {
      baseConfig.devtool = 'inline-source-map';
    }
    
    module.exports = baseConfig

    the webpack that works after:

    // webpack v4
    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const WebpackMd5Hash = require('webpack-md5-hash');
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    module.exports = {
      entry: { main: './src/index.js' },
      output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].[hash].js'
      },
      devtool: 'cheap-module-source-map',
      devServer: {
        contentBase: './dist',
        hot: true,
        open: true
      },
      module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            **use: [{ loader: 'babel-loader' }]**
          }
        ]
      },
      plugins: [
        new CleanWebpackPlugin('dist'),
        new HtmlWebpackPlugin({
          inject: false,
          hash: true,
          template: './src/index.html',
          filename: 'index.html'
        }),
        new WebpackMd5Hash()
      ]
    };

    my packeje.json looks like:

    {
      "name": "post",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "build": "webpack --mode=production",
        "start": "NODE_ENV=development webpack-dev-server --mode=development --hot"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "babel-cli": "^6.26.0",
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.4",
        "babel-preset-env": "^1.6.1",
        "babel-preset-react": "^6.24.1",
        "babel-runtime": "^6.26.0",
        "clean-webpack-plugin": "^0.1.19",
        "eslint": "^4.19.1",
        "eslint-config-prettier": "^2.9.0",
        "eslint-loader": "^2.0.0",
        "eslint-plugin-prettier": "^2.6.0",
        "eslint-plugin-react": "^7.7.0",
        "html-webpack-plugin": "^3.2.0",
        "prettier": "^1.12.1",
        "react": "^16.3.2",
        "react-dom": "^16.3.2",
        "webpack": "^4.6.0",
        "webpack-cli": "^2.0.13",
        "webpack-md5-hash": "0.0.6"
      },
      "dependencies": {
        "webpack-dev-server": "^3.1.3"
      }
    }

    See also the suggestions from the issue that was created on my branch: https://github.com/marharyta/webpack-4.6.0-test