dennisreimann / uiengine

Workbench for UI-driven development
https://dennisreimann.github.io/uiengine/
MIT License
368 stars 25 forks source link

styled-components: CSS not being applied #29

Closed MrAvantiC closed 5 years ago

MrAvantiC commented 6 years ago

Hi Dennis! :)

Describe the bug

I tried to take UIEngine for a spin with a project from scratch using the jsx-adapter and styled-components.

While the definition of the components works as expected and the styled-components library applies its generated classes to the elements, the actual css seems to get lost somewhere along the way.

To Reproduce

I setup a minimalistic project to reproduce the described behaviour if you take a look at the Heading-component here: https://github.com/MrAvantiC/uiengine-test

Expected behavior

The code

const Heading = styled.h1`
  color: red;
`

should result in a red font-color.

dennisreimann commented 6 years ago

Hi René :)

It seems the project is missing a build process (i.e. Webpack) that builds the actual assets, in this case transforms the styled-components code to CSS. The JSX adapter renders your components server-side and outputs the resulting HTML. I haven‘t used styled-components yet, but it looks like you need at least some kind of babel plugin like this one to get the CSS https://github.com/styled-components/babel-plugin-styled-components

Depending on how the plugin works it might add the CSS inline to the page or extracts it into a separate file. In the latter case you would have to reference the file in the src/templates/uiengine.html file.

Let me know if you still have trouble getting this to work :)

Cheers Dennis

MrAvantiC commented 6 years ago

Hey,

I was confused because I have a pretty minimalistic setup somewhere else with just browserify+babelify+browsersync where styled-components "just worked" without any additional plugins or such.

But it makes sense that if the JSX-Adapter renders server-side it is missing the part to "collect the styles". Guess I'll have to take a look at the adapter then.

Thanks for the hint. :)

MrAvantiC commented 5 years ago

Hey Dennis!

For completeness sake I wanted to share the solution to have Styled-Components work in the UIEngine: I modified the JSX-Adapter like this to ensure that the css is collected:

const ReactAdapter = require('@uiengine/adapter-react')
const { renderToString } = require('react-dom/server')
const {
  FileUtil: { invalidateRequireCache },
} = require('@uiengine/util')

const { ServerStyleSheet } = require('styled-components')

ReactAdapter.render = (options, filePath, data = {}) => {
  invalidateRequireCache(filePath)

  let Element = require(filePath)
  if (Element.default) Element = Element.default
  const vdom = Element(data)

  const sheet = new ServerStyleSheet()
  const html = renderToString(sheet.collectStyles(vdom))
  const styleTags = sheet.getStyleTags()

  return styleTags + html
}

module.exports = ReactAdapter

Thanks for your help!

dennisreimann commented 5 years ago

Hey René, thanks for sharing this 👍🏻