Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sourcemap doesn't work with devtool option contain "eval" #529

Closed
genshinw opened this issue May 8, 2020 · 5 comments · Fixed by #827
Closed

Sourcemap doesn't work with devtool option contain "eval" #529

genshinw opened this issue May 8, 2020 · 5 comments · Fixed by #827

Comments

@genshinw
Copy link

genshinw commented May 8, 2020

  • Operating System:
  • Node Version: 10.15.2
  • NPM Version: 6.4.1
  • webpack Version: 4.41.6
  • mini-css-extract-plugin Version: 0.9.0

Expected Behavior

Use the devtool options with "eval" such as "cheap-module-eval-source-map", the extract css file can map to the really css or sass file.
image

Actual Behavior

My entry file 'main.js' which import 'testSass.scss', with the devtool options "cheap-module-eval-source-map" to get the fast rebuild . But it'can not map the body style to the real sass file.
image
If I change devtool to "cheap-module-source-map" without 'eval', It works.

Code

// webpack.config.js
module.exports = {
  mode: 'development', // 'production'
  devtool: 'cheap-module-source-map',
  entry: {
    'learn': './src/main.js',
  },
  module: {
    rules: [ // 添加对模块处理特定规则
      {
        test: /\.s[ac]ss$/i,
        use: [{
          loader: MiniCssExtractPlugin.loader,
          options: {hmr: true}
          },
          {loader: 'css-loader', options: {sourceMap: true}},
          {loader: 'sass-loader', options: {sourceMap: true}},]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css'
    }),
    new HtmlWebpackPlugin(),
  ],
  devServer: {
    port: 9000,
    hot: true
  }
}

How Do We Reproduce?

You can use the config above . If cannot reproduce , I will give a repo later.

Addition

I found an hack with add the sourcemapPlugin with devtools in #29 (comment)

new webpack.SourceMapDevToolPlugin({ 
      filename: "[file].map",
      exclude: ["/vendor/"]
    }),
```js
@genshinw
Copy link
Author

Hi @sokra , has any solution?

@alexander-akait
Copy link
Member

alexander-akait commented Aug 10, 2020

Yes, it is limitation, eval doesn't work with CSS, you need to use source-map, we need documented it

@andy0130tw
Copy link

andy0130tw commented Jan 24, 2022

After hacking around a while, I have found that it is actually possible to have CSS source maps inlined when devtool option contains "eval". To be precise, this plugin currently only supports source maps that are emitted in separate files. In our case, this is not possible since our devtool option expects no .map files emitted. We can still include an inline source map, though. What I have done is to replace this line of src/index.js...

return new ConcatSource(externalsSource, source);

... with:

const result = new ConcatSource(externalsSource, source);
const m = result.map();
// if the source map information is available...
if (m != null) {
  const encoded = Buffer.from(JSON.stringify(m)).toString('base64');
  const footer = `/*# sourceMappingURL=data:application/json;charset=utf-8;base64,${encoded} */`;
  result.add(new RawSource(footer));
}
return result;

And we have embedded the source map. Now the devtool can detect it properly.

@andy0130tw
Copy link

andy0130tw commented Jan 25, 2022

Follow-up: After reading webpack's source code a little bit more, I manage to adjust the configuration accordingly so it produces the inline source map instead, without touching the source code of mini-css-extract-plugin:

{
  /* ... */
  plugins: [
    new MiniCssExtractPlugin(),
    new webpack.SourceMapDevToolPlugin({
      test: /\.css$/i,
      filename: null,
      append: '/*# sourceMappingURL=[url] */',
    })
  ]
}

Normally we would turn off the devtool option, but if we are using an "eval-*-source-map" as its value, it is applying a different plugin EvalSourceMapDevToolPlugin. As long as the plugin we add is NOT touching JS files, we won't interfere that option: https://github.com/webpack/webpack/blob/v5.67.0/lib/WebpackOptionsApply.js#L225-L246

This also solves issue #29 and seems more elegant than both the original and my previous solution.

@lazyunderscore
Copy link

After hacking around a while, I have found that it is actually possible to have CSS source maps inlined when devtool option contains "eval". To be precise, this plugin currently only supports source maps that are emitted in separate files. In our case, this is not possible since our devtool option expects no .map files emitted. We can still include an inline source map, though. What I have done is to replace this line of src/index.js...

return new ConcatSource(externalsSource, source);

... with:

const result = new ConcatSource(externalsSource, source);
const m = result.map();
// if the source map information is available...
if (m != null) {
  const encoded = Buffer.from(JSON.stringify(m)).toString('base64');
  const footer = `/*# sourceMappingURL=data:application/json;charset=utf-8;base64,${encoded} */`;
  result.add(new RawSource(footer));
}
return result;

And we have embedded the source map. Now the devtool can detect it properly.

It really works! Nice solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants