Skip to content

style is not affective on vue demo #1152

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
eminoda opened this issue Aug 1, 2020 · 22 comments
Closed

style is not affective on vue demo #1152

eminoda opened this issue Aug 1, 2020 · 22 comments

Comments

@eminoda
Copy link

eminoda commented Aug 1, 2020

  • Operating System: window10
  • Node Version: v10.15.3
  • NPM Version: 6.4.1
  • webpack Version: 4.44.1
  • css-loader Version: 4.2.0

Expected Behavior

I use wepback make a simple vue demo, try to use scss-loader parse scss style, expect below picture

搜狗截图20年08月01日1631_2

Actual Behavior

but,now is this picture. You can css style is not become effective, because <style> attribute is not appear to html.
搜狗截图20年08月01日1630_1

Code

{
        test: /\.scss$/,
        use: [
          {
            loader: 'vue-style-loader',
            options: {
              // sourceMap: false,
              // shadowMode: false,
            },
          },
          {
            loader: 'css-loader',
            options: {
              // sourceMap: false,
              // importLoaders: 2,
              // modules: {
              //   localIdentName: '[name]_[local]_[hash:base64:5]',
              // },
            },
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: false,
            },
          },
        ],
      }
// additional code, HEY YO remove this block if you don't need it

Solution

I try to downgrade css-loader to 3.5.3,webpack builded ok,I dont know why is it.

@birdofpreyru
Copy link
Contributor

birdofpreyru commented Aug 1, 2020

I believe, I know why it happens: in their update from v3.6.0 to v4.0.0 they bumped loader-utils dependency from v1.2.3 to v2.0.0. That altered generated hashes in class names, and right away breaks any web app setups with server-side rendering, as hashes generated at server-side (usually with alternative tools) mismatch hashes generated by webpack-bundled JS. Very bad, css-loader guys did not noticed this change, and have not mentioned it explicitly as a huge breaking change in the release notes.

Also, I am still struggling to figure out how to achieve old hash values with the latest css-loader. I figured out, the loader-utils changed the default hashing algo from md5 to md4, but so far it seems that just specifying md5 explicitly still does not result in the old values. Should be some extra changes affecting hashes (or might be I am doing something stupid).

UPDATED: And I found the second reason of changed hashes:
https://github.com/webpack-contrib/css-loader/blob/master/src/utils.js#L60
It used to join the path and class name by + in v3.6.0, now it joins them by \u0000. As it is hard-coded, there is no way to keep hash values with v3.6.0 > v4.2.0 upgrade 😭

@alexander-akait
Copy link
Member

alexander-akait commented Aug 1, 2020

It is expected, because we have some rare cases where generated classes can be potential same for difference classes, so we fix it, you can use getlocalIdent() if you want to return previous behavior

@alexander-akait
Copy link
Member

alexander-akait commented Aug 1, 2020

Also, I am still struggling to figure out how to achieve old hash values with the latest css-loader. I figured out, the loader-utils changed the default hashing algo from md5 to md4, but so far it seems that just specifying md5 explicitly still does not result in the old values. Should be some extra changes affecting hashes (or might be I am doing something stupid).

You should not use old algorithm, because it has collisions as I described above

Just regenerate classnames

@alexander-akait
Copy link
Member

changed the default hashing algo from md5 to md4

Because md4 is faster for hashing, it is the perf improvement

@alexander-akait
Copy link
Member

Why you need old classes? We have exportOnlyLocals for SSR, you should never use hardcoded classnames

@birdofpreyru
Copy link
Contributor

birdofpreyru commented Aug 1, 2020

@evilebottnawi well, I wouldn't care much about the algo you prefer, but...

There is https://www.npmjs.com/package/babel-plugin-react-css-modules (125k weekly downloads)
and there is https://www.npmjs.com/package/babel-plugin-css-modules-transform (51k weekly downloads),
both relying on matching classnames with css-loader.

I guess, I'm now to fork & update them sometime soon :)

And I am not sure what Vue is using, but I guess in the nutshell it bumps into a similar problem ¯_(ツ)_/¯

@alexander-akait
Copy link
Member

babel-plugin-react-css-modules need to update and has incompatibility with current implementation 😞 Why do you use this? There are a lot of alternative solutions

@birdofpreyru
Copy link
Contributor

birdofpreyru commented Aug 1, 2020

I use it in my React setup since 2018. It looked like a great choice back then, and it did not caused me any issue since. If something is not broken I don't fix it :)

I'll appreciate if you suggest a better alternative, or warn me about any incompatibility issues beside the classname difference discussed above. With what I know currently, the option to just fork / update / package my own version of babel-plugin-react-css-modules seems like the easiest and fastest to me :)

@alexander-akait
Copy link
Member

alexander-akait commented Aug 1, 2020

You can use exportOnlyLocals to implement SSR, is it what you search?

@birdofpreyru
Copy link
Contributor

I guess, it would work if I pass server-side code through Webpack, but that's not how I do stuff. I only use Webpack to bundle the client-side code, and the server-side code I just compile with Babel only.

@alexander-akait
Copy link
Member

hm, make sense, in your case I recommend to migrate on the getLocalIdent option, it is allow to control it, also will be great to implement it on babel-plugin-react-css-modules side

@ThiefMaster
Copy link

ThiefMaster commented Aug 1, 2020

Could you provide an example on what to specify as getLocalIdent to restore compatibility with babel-plugin-react-css-modules?

After looking at the implementation this looks like a huge pain in the ass to fix. getLocalIdent calls multiple functions coming from other libraries, so it looks like I'd have to add those as dependencies to my application just to keep using the old implementation...

@alexander-akait
Copy link
Member

alexander-akait commented Aug 3, 2020

You can find example in README, if you need help with implementation, please provide repo with example and I will help

@birdofpreyru
Copy link
Contributor

Here is my fork of babel-plugin-react-css-modules with fixed compatibility to css-loader:
https://www.npmjs.com/package/@dr.pogodin/babel-plugin-react-css-modules

@evilebottnawi it would be very handy if you export defaultGetLocalIdent(..) function as a named export of css-loader. I found a way to get it anyway, but it is kind of goofy :)

@alexander-akait
Copy link
Member

@birdofpreyru Sorry we can't export defaultGetLocalIdent, because we change it very often, so we have to do constantly breaking change when we change something, it is not good, why do not copy/paste code?

@birdofpreyru
Copy link
Contributor

@evilebottnawi

why do not copy/paste code?

For the reason you told: to not have to update dependent code each time you change something inside defaultGetLocalIdent (assuming the dependent code just wants to generate matching classnames). I don't get your point about breaking changes: if you change the default classname generation it might be a breaking change for users no matter whether you export the default classname generator function directly, or just use it behind the scene. Also, if you export it, you can just put a disclaimer in the docs that the exact generated classname may change between releases and won't be anounced as a breaking change.

@alexander-akait
Copy link
Member

Changes are not critical in all cases, but it can be breaking change for developers who rely on this, it was discussed already, for example we can change first characters if class starts number on other ._1234 to .x1234, it was breaking change who uses this function, but it is not breaking change for us

@ThiefMaster
Copy link

ThiefMaster commented Aug 10, 2020

But by exporting it, tools like babel-plugin-react-css-modules can (peer-)depend on an exact version of this package (or ~ version if you promise to not change the logic in patch releases) and use the same logic you have, to avoid breakage due to different hashing logic.

This is clearly better than them having to re-implement your logic, and then having to make a fixed release ASAP whenever something changes here (or preventing people from upgrading if they don't)...

@alexander-akait
Copy link
Member

It will violate semver, I don't want to do it without no real good reason, because many developer starts to use it, we will get a lot of issue after new release, what is a problem with copy/paste, code is very small

@ThiefMaster
Copy link

It uses code from other libraries (normalize-path, cssesc, loader-utils). So by copying the code, those libraries now have to be dependencies of my own code/library, because I am the one using them (and thus need to care about updating them).

@ThiefMaster
Copy link

Anyway, would it really be a problem to use semver-major releases for changes to that logic? I guess you don't change it that often...

@alexander-akait
Copy link
Member

Anyway, would it really be a problem to use semver-major releases for changes to that logic? I guess you don't change it that often...

It used to happen often, now less often, ok, i am ready to consider exporting this, but it will still be internal and can't change in any version, so if want to rely on this, use pinned version of css-loader in your app, but my recommendation is avoid it

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

4 participants