css-loader icon indicating copy to clipboard operation
css-loader copied to clipboard

Css class got duplicated if @import sytnax is used

Open fa93hws opened this issue 5 years ago • 4 comments

  • Operating System: OSX 10.15.2
  • Node Version: v10.17.0
  • NPM Version: 6.11.3
  • webpack Version: 4.41.5
  • css-loader Version: 3.4.2

Expected Behavior

"preload_fonts" which imports "font_a" which composes "font_base" and; "preload_fonts" which imports "font_b" which composes "font_base". On this case, the "baseFont" appears only once.

Actual Behavior

the "baseFont" module appears twice.

image

How Do We Reproduce?

https://github.com/fa93hws/duplicate-import npm run start, open console and switch to style Editor tab.

fa93hws avatar Jan 23 '20 01:01 fa93hws

Do not use css modules and pure @import together, your output is expected (I will documented that limitation). You can override some styles for .baseFont in font_b.css and with dedupe i will got invalid result. composes works like require in JS, @import has other logic, CSS is not module based so each next @import can potential override previously styles and we can't dedupe that

alexander-akait avatar Jan 23 '20 10:01 alexander-akait

I want to documented that

alexander-akait avatar Jan 31 '20 10:01 alexander-akait

You can override some styles for .baseFont in font_b.css and with dedupe i will got invalid result

I'm interested in understanding this as well. I've been under the impression that it is okay to "throw away future identical @import or composes"

For example:

/* preload_fonts */
@import './font_a.css';
@import './font_b.css';

/* font_a */
:global(.globalFontA) {
  font-size: 20px;
  font-weight: 1000;
}

.fontA {
  composes: baseFont from './font_base.css';
  color: blue;
}

/* font_b */
:global(.globalFontB) {
  font-size: 20px;
}

.fontB {
  composes: baseFont from './font_base.css';
  color: green;
}

/* font_base */
.baseFont {
  color: red;
  font-weight: 600;
  font-size: 22;
}

should result in:

/* preload_fonts */
/* imported font_a */
/* -> start composed font_base */
.baseFont-HASH {
  color: red;
  font-weight: 600;
  font-size: 22;
}
/* -> end composed font_base */

.globalFontA {
  font-size: 20px;
  font-weight: 1000;
}

.fontA-HASH {
  color: blue;
}

/* imported font_b */
/* -> start composed font_base */
/* duplicate, it is now empty somehow */
/* -> end composed font_base */

.globalFontB {
  font-size: 20px;
}

.fontB-HASH {
  color: green;
}

juanca avatar Nov 10 '20 02:11 juanca

it's cause import over hundred times css library in my case😰,in JS it solved with namespace and the library is singled declared well place, in commonjs it's isolated,so it can't override by other module,but in esmoule definition this behavior is allowed.

eg:

a.js

const A = {
    a:123
}
export default A
setTimeout(()=>{
  console.log(A.a);
})

b.js

import A from './a'
A.a = 456

c.js

import A from './a'
import './b'
console.log(A.a) >>> 456
>>> 456 // from a.js

re-declare class still contain vitiums :

lib.css

.color{
       color:red;
}

.title{
       font-size:20px;
}

lib2.css

.color{
       color:blue;
}

output.css

// from user context
.title{
   font-size:16px;
}

// import from lib.css
.color{
       color:red;
}

.title{
       font-size:20px;
}

// import from lib2.css
.color{
       color:blue;
}

// after a title always 20px

i think css import's behavior should like ESmodule , just find a solution about css naming or css scope to avoid override

joebnb avatar Dec 05 '20 05:12 joebnb