Skip to content

inline import duplication #17

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

Closed
undoZen opened this issue Aug 13, 2014 · 23 comments
Closed

inline import duplication #17

undoZen opened this issue Aug 13, 2014 · 23 comments

Comments

@undoZen
Copy link

undoZen commented Aug 13, 2014

If I require('sub1.css') and require('sub2.css') which both @import url("./base.css") then I'll get rules in bass.css applied twice in my page, which may cause some problem.

Any plan to solve this?

@sokra
Copy link
Member

sokra commented Aug 22, 2014

For this we need to change the exports of the css-loader from a simple string to a description object/array.

Example:

/* style.css */
@import "import.css" medium and (media-query);

body { }
[
  [require.resolve("css!import.css"), "css from import.css", "medium and (media-query)"],
  [require.resolve("css!style.css"), "body {}"]
]

The style-loader need to handle this new format and keep track of which module id is already attached to the DOM ( + HMR + ref-counted style ).

The ExtractTextPlugin need to handle this format, merge duplicate modules and construct a css SourceMap...

Lot of changes required...

@jhnns
Copy link
Member

jhnns commented Aug 22, 2014

Interesting, this could finally enable developers to write truly modular CSS with pre-processors. Currently it's not possible.

@necolas
Copy link

necolas commented Aug 29, 2014

I had this problem too. Having a hard time using webpack to build CSS bundles properly. The dream would be to mirror the ability to generate commons/chunks bundles as with the JS.

@necolas
Copy link

necolas commented Aug 29, 2014

Also consider using the CSS 'module' pattern that is common in npm-land and used in modules like https://github.com/reworkcss/rework-npm. Then this would work with all the existing modules on npm rather than introducing a new syntax.

Using @import "module" is not valid CSS because it lacks the .css extension, so it's appropriate to infer it is a module require.

@jhnns
Copy link
Member

jhnns commented Sep 1, 2014

I'm not sure, but I think the CSS module pattern is already applied.

If you're writing

@import "my-module";

.some-style {}

webpack generates (roughly)

module.exports = require("./my-module.css") + ".some-style {}";

The problem is that pre-processors compile everything down to one big chunk. But with LESS's reference feature it is at least possible to generate a css-file for each module without including the common stuff again.

@necolas
Copy link

necolas commented Sep 1, 2014

That's resolving my-module to ./my-module.css, which is not the same thing as looking up my-module in the moduleDirectories. My suggestion is that since @import "my-module" is not valid CSS, webpack should not treat it as a relative path but as a module name instead (as rework-npm does).

@jhnns
Copy link
Member

jhnns commented Sep 1, 2014

Yes, that would be cool. Currently you need to append ~ to load from modulesDirectories.

Related discussion: webpack-contrib/less-loader#3

@sokra
Copy link
Member

sokra commented Sep 6, 2014

I have a working prototype for this. Just need to do some more testing before release...

It seems like #sourceMappingURL comments are not supported in <style> tags. 😢 So you only get CSS SourceMaps for the extract-text-webpack-plugin...

sokra added a commit to webpack-contrib/style-loader that referenced this issue Sep 7, 2014
This ensures that items with the same id are only added once.
i. e. multiple css file and `@import` the same base css file and it's only added once to the DOM.

webpack-contrib/css-loader#17
@sokra sokra closed this as completed in e928350 Sep 7, 2014
@sokra
Copy link
Member

sokra commented Sep 7, 2014

published...

Now an @imported module is only added once to the DOM. In addition to that the order stays correct for @imported modules.

This also works with the extract-text-webpack-plugin. It includes modules only once. And it can create CSS SourceMaps...

@jhnns
Copy link
Member

jhnns commented Sep 8, 2014

Coool @sokra

@undoZen
Copy link
Author

undoZen commented Sep 8, 2014

great work!

I'm using less now. Wondering does less-loader generate css source map and
does this css-loader keep the source map come with the (maybe less
generated) css file?
On 8 Sep, 2014 11:17 pm, "Johannes Ewald" [email protected] wrote:

Coool @sokra https://github.com/sokra


Reply to this email directly or view it on GitHub
#17 (comment).

@necolas
Copy link

necolas commented Sep 8, 2014

This is great! Thanks Tobias. Only thing that is different from using require now is that combining the common-chunks plugin, css-loader, and extract-text-webpack-plugin doesn't produce a common css bundle. Where's the right place to file a feature request for that?

@nickdima
Copy link

Trying to do the same thing as @necolas
Let's know if you find an alternative

@sokra sokra reopened this Sep 22, 2014
@sokra
Copy link
Member

sokra commented Sep 22, 2014

Working on this, but it requires some refactoring...

@sokra
Copy link
Member

sokra commented Sep 23, 2014

I have a prototype commited (but not published) that should handle this...

The ExtractTextPlugin now build up a mirrowed "extracted" chunk tree with modules. This tree goes to the same optimizing steps as the webpack chunk tree.

@undoZen
Copy link
Author

undoZen commented Sep 26, 2014

0.9.0? I saw it's on npm already.

@sokra
Copy link
Member

sokra commented Sep 26, 2014

The duplication is fixed.
There is just one issue in combination with the CommonsChunkPlugin and ExtractTextPlugin.

@undoZen
Copy link
Author

undoZen commented Sep 26, 2014

fix on this issue not solved in 0.9.0?

@richburdon
Copy link

I'm still seeing duplicates (both with ExtractTextPlugin generated files, and the vanilla less loader which includes multiple style tags)

Is additional configuration required other than the following?

    loader: ExtractTextPlugin.extract('style-loader', 'css-loader!less-loader')

[email protected]
[email protected]

@jhnns
Copy link
Member

jhnns commented May 10, 2016

When you have multiple require() for different Less-files, it's the expected behavior to add multiple style tags.

@mattaningram
Copy link

mattaningram commented Aug 24, 2016

@jhnns But I am importing the same .scss file, just in different React components. So why can't webpack identify that these are the same .scss files and only inject a <style> tag for it once?

Isn't that what it does with the JS imports? If two components import the same dropdown JS plugin, I assume that the plugin code exists only once in the final .js file. But this appears not to be the logic applied when importing styles.

I import the .css or .scss for react-selectize in each instance that react-selectize is used. This creates multiple IDENTICAL <style> injections in the head for some bizarre reason

EDIT: Just read your response here: webpack-contrib/sass-loader#2 and now I understand that this is not webpack's fault and it can't really do anything about it. I guess I'm switching back to doing SASS the traditional way, there just aren't any real benefits to importing per component through JS files and webpack unless you are doing inline styling.

@jhnns
Copy link
Member

jhnns commented Sep 5, 2016

@mattaningram if different components require the same scss file, the compilation for that specific file should happen only once (because it is based on the actual filename). If that's not the case, I would classify this at a webpack bug (could you create a minimal demo for that if that's the case?)

However, whatever happens inside the SCSS file is not transparent to webpack because now SASS is in charge of compiling it to CSS. It just handles all the paths to webpack in order to resolve it.

@phun-ky
Copy link

phun-ky commented Jan 16, 2017

While the original issue here is related to sass/less/stylus, a fix/hack/patch for this is to use the optimize-css-assets-webpack-plugin in conjunction with extract-text-webpack-plugin to produce, like this: https://gist.github.com/phun-ky/766e5ec9f75eac61c945273a951f0c0b.

If you want to use this in dev, you will have to use a plugin like write-file-webpack-plugin to force webpack to write the file to disk in dev.

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

8 participants