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

CSS is injected multiple times without ExtractTextPlugin #853

Closed
sqal opened this issue Jun 21, 2017 · 5 comments
Closed

CSS is injected multiple times without ExtractTextPlugin #853

sqal opened this issue Jun 21, 2017 · 5 comments

Comments

@sqal
Copy link

sqal commented Jun 21, 2017

Version

12.2.0

Reproduction link

https://github.com/sqal/vue-loader-duplicate-css-repo

Steps to reproduce

  • Clone repo
  • npm install && npm run build && npm run serve
  • Open devtools and check injected stylesheets in the head tag

What is actually happening?

As you can see there are two components used in my app - A and B which both includes 2 other components. All three components includes the same stylesheet file. The difference between A and B is that, component A imports css using SFC <style> tag and component B imports css in the script tag. Now when open devtools and look at the head tag you can see that 4 stylesheets have been injected into the DOM. There is only one stylesheet file with B.css and 3 the same stylesheets with A.css.

So my question is - is this a bug? or what exactly is happening here? Why there is a different behavior between importing css in the <style> tag and <script>` tag. And if i don't use ExtractTextPlugin in my project, how can I prevent duplicate css injection into the DOM? I would appreciate if someone could clarify this issue. Thank you

@sqal
Copy link
Author

sqal commented Jul 20, 2017

Any thoughts on this?

@drwpow
Copy link

drwpow commented Jul 25, 2017

webpack introduced tree shaking in 2.x, which gave it the ability to remove duplicate modules via ES6 import. So you can always expect webpack to intelligently only include things once through JS.

I’m not sure what’s going on here, but your use of <script src=""> isn’t documented in the Vue Loader docs. If I had to take a stab at it, I’d guess that this is somehow using postcss-import to include CSS files within other CSS files. I should note that postcss-import does NOT tree shake, and will include a file as many times as it’s imported.

@sqal
Copy link
Author

sqal commented Jul 25, 2017

@DangoDev Thanks for taking a look at my issue, however i don't that postcss is wrongdoer here, simply because after disabling postcss, the result is the same :/ And I don't use postcss-import plugin in my project plugin Also <script src=""> usage is documented, here https://vue-loader.vuejs.org/en/start/spec.html (Src Imports section)

@drwpow
Copy link

drwpow commented Jul 25, 2017

Ah! I missed that. Vue Loader does require PostCSS as its own dependency, whether or not you’re using it in your project. But you’re right—that documentation seems to suggest it’s loading the file via CommonJS require(). There is a likelihood it’s not using ES6’s import function to allow for tree shaking.

@Jinjiang
Copy link
Member

@DangoDev as my understanding, the tree-shaking is about removing the code which won't be required, not the code duplicated. Any version of webpack or rollup will remove duplicated module. So don't worry too much about itself.

@sqal I have a look deep into it. A explanation is that the finally generated code for <style src="./A.css"> is like:

// in A.vue
require("!!vue-style-loader!css-loader?{\"minimize\":true,\"sourceMap\":true}!../../../node_modules/vue-loader/lib/style-compiler/index?{\"vue\":true,\"id\":\"data-v-6fc77723\",\"scoped\":false,\"hasInlineConfig\":false}!./A.css")

// in A1.vue
require("!!vue-style-loader!css-loader?{\"minimize\":true,\"sourceMap\":true}!../../../node_modules/vue-loader/lib/style-compiler/index?{\"vue\":true,\"id\":\"data-v-ed81d2c2\",\"scoped\":false,\"hasInlineConfig\":false}!./A.css")

// in A2.vue
require("!!vue-style-loader!css-loader?{\"minimize\":true,\"sourceMap\":true}!../../../node_modules/vue-loader/lib/style-compiler/index?{\"vue\":true,\"id\":\"data-v-ed9e01c4\",\"scoped\":false,\"hasInlineConfig\":false}!./A.css")

They have three different scope id even though the component style is not scoped. So webpack will consider them as three different modules. That could explain why there are 3 duplicated <style> in DOM.

I don't think that is a bug, but obviously it could be improved. I will have a try for this.

Thanks.

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

No branches or pull requests

3 participants