Webpack: In production build CSS Sourcemaps in codesplit chunks are "duplicated", contained in both the .map file and the .js file

Created on 24 Nov 2017  路  15Comments  路  Source: vuejs-templates/webpack

Steps to reproduce:

  1. Generate project with vue-router, my exact answers:
? Generate project in current directory? Yes
? Project name vue-app
? Project description A Vue.js project
? Author Jakub Bogucki <[email protected]>
? Vue build runtime
? Install vue-router? Yes
? Use ESLint to lint your code? No
? Setup unit tests No
? Setup e2e tests with Nightwatch? No
  1. Install dependencies
  2. edit src/routes/index.js:

    1. remove import HelloWorld from '@/components/HelloWorld'

    2. replace component: HelloWorld with component: () => import('@/components/HelloWorld')

  3. build project for production
  4. open dist/static/js/0.[hash].js
  5. format it so you can see it well :)
  6. somewhere in the file you should see something like that:
    image
enhancement help wanted

Most helpful comment

Okay, so I've taken a look.

My observations

  1. CSS itself is not "duplicated" - css in a codesplit component only lives in the component, not in the main app.css file.
  2. However, CSS Sourcemaps are "duplicated" - the codesplit chunk (e.g. 0.js) contains the CSS sourcemap for that chunk's CSS, and the map file for the code split chunk (e.g. 0.js.map) contains it as well. Not good.
  3. including the sourcemap in the chunk is bad for file-size, so we should get it out of there somehow.
  4. And finally: this also happens for "normal" .js files that are codesplitted and import a normal .css file - in other words: webpack / style-loader does this, not Vue or vue-loader.

Possible short-term fixes:

  • disabling sourcemaps for production in /config/index.js.
  • Setting allChunks: true in ExtractCSS extracts all css into app.css, even the CSS in codesplit bundles - this also extracts the sourcemap. But that might also be undesirable because I think by default, we do want the CSS to be in the codesplit bundle, but ideally, want the sourcemap for the CSS to be in a separate file.

The end goal:

  • Keep the CSS in the codesplit chunk
  • Get the source-map out of the codesplit chunk

..however, I have no idea if that's actually possible with the current webpack tools we have.

Will investigate further.

Webpack Experts' help welcome

This seems to be a tricky one, so if someone out there has a good trick up their sleeve that they can share, please comment / send PR!

All 15 comments

Thanks for posting this. I have a few questions:

  1. What CSS is duplicated? CSS from code-split .vue files is not added to the main app.css file that gets extracted - at least that's how it's supposed to work. Are you sure it's duplicated?
  2. The production build generates sourcemaps. I'm not sure weither they should be included in the code-split bundle (to put it another way: if webpack simply behaves this way with sourcemaps for codesplit bundles), and if not, we can do anything about this from within this template (read: this would probably have to be fixed in vue-loader

I'll take as soon as I find some time to really dig into this.

Okay, so I've taken a look.

My observations

  1. CSS itself is not "duplicated" - css in a codesplit component only lives in the component, not in the main app.css file.
  2. However, CSS Sourcemaps are "duplicated" - the codesplit chunk (e.g. 0.js) contains the CSS sourcemap for that chunk's CSS, and the map file for the code split chunk (e.g. 0.js.map) contains it as well. Not good.
  3. including the sourcemap in the chunk is bad for file-size, so we should get it out of there somehow.
  4. And finally: this also happens for "normal" .js files that are codesplitted and import a normal .css file - in other words: webpack / style-loader does this, not Vue or vue-loader.

Possible short-term fixes:

  • disabling sourcemaps for production in /config/index.js.
  • Setting allChunks: true in ExtractCSS extracts all css into app.css, even the CSS in codesplit bundles - this also extracts the sourcemap. But that might also be undesirable because I think by default, we do want the CSS to be in the codesplit bundle, but ideally, want the sourcemap for the CSS to be in a separate file.

The end goal:

  • Keep the CSS in the codesplit chunk
  • Get the source-map out of the codesplit chunk

..however, I have no idea if that's actually possible with the current webpack tools we have.

Will investigate further.

Webpack Experts' help welcome

This seems to be a tricky one, so if someone out there has a good trick up their sleeve that they can share, please comment / send PR!

@vuejs-templates/collaborators take a look if you can.

In config/index.js

look into

... build: { ... devtool: '#source-map' ... }

change this devtool value to configure bundle to whether to include sourcemaps or how to include them

see the docs

@CharlesKumar Yes, this option allows to select a sourcemap, and we can also disable it there.

But as I said abov, disabling sourcemaps in production is not a real solution to the problem we are discussing, it's a quick workaround at best.

disabling sourcemaps in production is not a real solution to the problem we are discussing

Agree. We should split the sourcemap into isolation files, only leave the sourcemap file URL. That will save a lot bits.

@LinusBorg Could extract-css-chunks-webpack-plugin provide a possible solution?

@chrisvfritz not on its own. While it extracts css from code split chunks into individual css files (and with them possibly the sourcemaps), it leaves the chunk without runtime code to load that css.

It seems to be meant in SSR scenarios specifically.

I have hit up Sean on Twitter? hoping he has a pointer for us.

setting productionGzip: true may solve the problem

// Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,

a thread from old vue forum

[[Just a [tip](https://varvy.com/pagespeed/enable-compression.html) to newbies who reading this comment]]

Sorry, but that will only compress results, it won't remove the duplicated source maps

Thanks for quick reaction to issues. By "duplicated" I meant that you can see it twice in the js file (for example in the screenshot) not that it's included in both js and css file. Sorry for not being clear enough.

Well it's not really duplicated. One is the "real" css, one is the source css for the source map, so it's not really used as css during runtime. Still it doesn't belong there of course.

After some discusssion with @chrisvfritz I think we should switch to allChunks: true as the default setting for the ExtractTextPlugin.

Opinions?

Just wondering if this issue is still present when setting allChunks to false.

The fix for this issue is to create or edit your vue.config.js file

With

modules.export = { productionSourceMap : false }

Npm run build and all that's the fix

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nicolas-t picture nicolas-t  路  4Comments

brucejcw picture brucejcw  路  4Comments

rkrejcii picture rkrejcii  路  4Comments

SSmale picture SSmale  路  3Comments

ghost picture ghost  路  3Comments