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 module contents not being inlined #813

Closed
dowrow opened this issue Mar 1, 2021 · 10 comments
Closed

CSS module contents not being inlined #813

dowrow opened this issue Mar 1, 2021 · 10 comments

Comments

@dowrow
Copy link

dowrow commented Mar 1, 2021

Hello, I'm using microbundle to build a library mono-repo.
I'm using lerna and yarn workspaces.
Also, my components use React (.js only no TS) and CSS modules.

The package.json of a sample package looks like this:

{
  "name": "@myprivatescope/accordion",
  "version": "1.0.7",
  "repository": "https://github.com/myprivatescope/web-components",
  "description": "Display a collapsed resume that expands on click",
  "source": "Accordion.js",
  "main": "dist/main/index.js",
  "module": "dist/module/index.js",
  "license": "MIT",
  "dependencies": {
    "react": "^17.0.1",
    "react-dom": "^17.0.1"
  }
}

And my root package.json:


{
  "name": "web-components",
  "private": true,
  "workspaces": { 
    "packages": [ 
      "packages/*" 
    ] 
  },
  "devDependencies": {
    "@storybook/addon-contexts": "^5.3.21",
    "@storybook/addon-controls": "^6.1.11",
    "@storybook/addon-essentials": "^6.1.11",
    "@storybook/addon-links": "^6.1.11",
    "@storybook/addon-storysource": "^6.1.11",
    "@storybook/react": "^6.1.11",
    "autoprefixer": "^10.2.4",
    "case-sensitive-paths-webpack-plugin": "^2.4.0",
    "lerna": "^3.22.1",
    "microbundle": "^0.13.0",
    "postcss": "^8.2.6",
    "postcss-modules": "^3.0.0",
    "storybook-addon-smart-knobs": "^6.0.2",
    "storybook-css-modules-preset": "^1.0.5"
  },
  "scripts": {
    "clean": "lerna exec rm -- -rf node_modules dist .cache package-lock.json yarn.lock && lerna clean && rm -rf node_modules package-lock.json yarn-lock.json",
    "version": "lerna version",
    "bootstrap": "lerna bootstrap --force-local",
    "link": "lerna link",
    "build": "lerna exec --parallel -- microbundle --css inline --css-modules true --jsx React.createElement --jsxFragment React.Fragment",
    "publish": "lerna publish from-package",
    "storybook": "start-storybook -s ./static -p 3000"
  }
}

yarn build works and bundles with no error, but for some reason the styles defined in the Accordion.module.css (which are imported straight from the Accordion.js) are not being copied into the dist files.

Am I missing something?

@dowrow dowrow changed the title CSS module contents not being inlined in mono-repo packages CSS module contents not being inlined Mar 2, 2021
@dowrow
Copy link
Author

dowrow commented Mar 5, 2021

Do I need to add more context/info here? I see more recent issues being addressed and I'm still stuck here with no replies.

@rschristian
Copy link
Collaborator

@dowrow

The --css inline option is to inline a CSS file as a string. Not really compatible with CSS modules.

To illustrate:

style.css

.heading {
  color: blue;
}

index.js

import css from './style.css'
console.log(css);

With --css inline, you'd end up with just

index.js

console.log(".heading{color: blue;}");

CSS Modules you generate hashed class names, but keep the CSS files around. You then use the hashes in the class attribute in your markup. Really different uses.

People respond to issues when they can, it's not necessarily anything wrong with your issue if no one responds. There's a lot of repositories and only so many hours in the day.

@dowrow
Copy link
Author

dowrow commented Mar 8, 2021

Thank you very much for the answer, @rschristian
I'm new to Open Source so thank you for the understanding and sorry for being pushy.

I'll try and remove the inline flag. On the other hand, when I try to consume this components on NextJS I get an error that the bundle should contain the CSS inside the same file as the JS. Is there any way to concat it?

@rschristian
Copy link
Collaborator

@dowrow Nothing to apologize for, you weren't being pushy. Just an honest question.

What do you mean by "the bundle should contain the CSS inside the same file as the JS"? I can't imagine they're actually advocating for nothing but inline styles, but I've never used Next. Can you show this error?

Is there a way to concat what? CSS Modules need to either have the styles in a .css file or within a <style /> tag in some HTML. That's the way they work, by creating scoped class names. Class names then need to match up against a resource.

If you just want to use inline styles you certainly can do that, something like <div style="color: blue" /> will get the job done, though I wouldn't recommend it, as it means users of your component cannot change any of the styling (I assume you're using Microbundle to make a component).

@rschristian
Copy link
Collaborator

If you did end up wanting to not require your users import a style sheet, react-colorful is a great example of how to do it and where the inline CSS option was requested from. The CSS is manually scoped with react-color__ prefixes, which gets you the scoping you lose from dropping CSS modules, and then the inlined style sheet is injected straight into the head of the doument so users don't need to mess with the style sheet themselves.

@dowrow
Copy link
Author

dowrow commented Mar 8, 2021

What do you mean by "the bundle should contain the CSS inside the same file as the JS"? I can't imagine they're actually advocating for nothing but inline styles, but I've never used Next. Can you show this error?

Sure, this is the output I get when building the Next webapp:

info  - Creating an optimized production build  
Failed to compile.

./node_modules/@myscope/accordion/dist/module/index.css
Global CSS cannot be imported from within node_modules.
Read more: https://err.sh/next.js/css-npm
Location: node_modules/@myscope/accordion/dist/module/index.js

Following that link, you can read:

Compiled dependencies do not have references to CSS files, or any other files that require bundler-specific integrations.

So yes, I guess they are advocating for inlining styles or requiring the users to import the stylesheets separately.

I see how react-colorful worked around this restriction.
I guess I could just stop using CSS modules, scope the styles manually using BEM and build the components using the --css inline flag again.

I was just looking for an easy solution that somehow transformed my 37 components (all of which use CSS modules) into components with inlined styles, but looks like I had no luck!

Thank you a lot anyway, @rschristian

@rschristian
Copy link
Collaborator

rschristian commented Mar 8, 2021

Sure, this is the output I get when building the Next webapp:

info  - Creating an optimized production build  
Failed to compile.

./node_modules/@myscope/accordion/dist/module/index.css
Global CSS cannot be imported from within node_modules.
Read more: https://err.sh/next.js/css-npm
Location: node_modules/@myscope/accordion/dist/module/index.js

Are you importing this from _app.js? Apparently that's the only place you're allowed to do this: vercel/next.js#10059 (comment)

Edit: Misread. How does your lib have any reference to a CSS file? Microbundle strips those? Are you adding a CSS import (i.e., import './style.css') in your bundle output? Yeah, can't do that. That's not actually allowed with JS.

I was just looking for an easy solution that somehow transformed my 37 components (all of which use CSS modules) into components with inlined styles, but looks like I had no luck!

Yeah, --css inline inlines the CSS file (as a string), it doesn't inline the styles. The distinction ends up being pretty big. If you really wanted to you probably could write your own pipeline to deal with that, but I certainly wouldn't recommend it. Probably easier ways.

@dowrow
Copy link
Author

dowrow commented Mar 8, 2021

Edit: Misread. How does your lib have any reference to a CSS file? Microbundle strips those? Are you adding a CSS import (i.e., import './style.css') in your bundle output? Yeah, can't do that. That's not actually allowed with JS.

Good question, I guess had some old dist files from an earlier build with Parcel that required the css files.
However, stripping those references as Microbundle does won't help either.

Yeah, --css inline inlines the CSS file (as a string), it doesn't inline the styles. The distinction ends up being pretty big. If you really wanted to you probably could write your own pipeline to deal with that, but I certainly wouldn't recommend it. Probably easier ways.

I see.

Problem is Next doesn't allow me to import any .css except for CSS modules outside the _app. So, basically I have no way to create self-contained components for Next using Microbundle :s

@rschristian
Copy link
Collaborator

The error message is that you're importing a CSS file in built JS. It might not resolve all the problems but does need to be fixed, then other errors will appear, if any, and you can fix those.

Next doesn't seem to allow any CSS imports from node_modules outside of _app.js, it doesn't matter your CSS method. So you can either use standard style sheets and import into your _app.js, do something like react-colorful, maybe just write inline styles, or pick up CSS-in-JS. You still have some options.

Still, is there any reason why you can't import your style sheets into _app.js? CSS module scoping means it won't conflict with anything.

Not really a Microbundle limitation/issue but a NextJS one (as seen by the amount of people begging for that functionality).

@dowrow
Copy link
Author

dowrow commented Mar 8, 2021

The error message is that you're importing a CSS file in built JS. It might not resolve all the problems but does need to be fixed, then other errors will appear, if any, and you can fix those.

Yes, I meant I can't just stripe the CSS imports if there's no any other way to import the styles later on.

Next doesn't seem to allow any CSS imports from node_modules outside of _app.js, it doesn't matter your CSS method. So you can either use standard style sheets and import into your _app.js, do something like react-colorful, maybe just write inline styles, or pick up CSS-in-JS. You still have some options.

Sure, for anyone else interested there's this thread about the topic: vercel/next.js#13282

CSS-in-JS styles (aka <style jsx>{``}</style>) would result on styles being defined inside the dist/index.js, right? This might be my best bet for what I want to accomplish. I wonder if there's any other way to transform the styles defined on the CSS modules to CSS-in-JS.

Still, is there any reason why you can't import your style sheets into _app.js? CSS module scoping means it won't conflict with anything.

I guess I could import the generated dist/index.css of each component on the _app.js and it should work, but feels hacky and polluted to include 37 global stylesheets.

Again, thank you for your time, @rschristian

@dowrow dowrow closed this as completed Mar 9, 2021
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

2 participants