Skip to content
This repository has been archived by the owner on Sep 7, 2020. It is now read-only.

Commit

Permalink
✨ Added: support for Glamor and styled-components out of the …
Browse files Browse the repository at this point in the history
…box.

Now if you use [Glamor](https://github.com/threepointone/glamor/) to
write your style, static rendering will take that into account and will
prerender styles for you. Nothing to setup. It’s even injecting glamor
ids if you want to rehydrate on startup. See [glamor server
documentation](https://github.com/threepointone/glamor/blob/master/docs/
server.md) to setup hydratation (you will need to handle this yourself
in your ``scripts/phenomic.browser.js``.
Since [styled-components](https://styled-components.com/) [use Glamor
under the
hood](styled-components/styled-components#124)
, this will work for this library as well.

Ref #864
  • Loading branch information
MoOx committed Nov 16, 2016
1 parent 0c0fae4 commit 15f55f8
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 28 deletions.
4 changes: 4 additions & 0 deletions src/builder/webpack/config.node.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ const defaultExternals = [
// to not bundle all deps in the static build (for perf)
// the problem is that if people rely on node_modules for stuff
// like css, this breaks their build.
//
// Glamor integration
"glamor",
"glamor/server",
]

const sourceMapSupport = require.resolve("source-map-support/register")
Expand Down
68 changes: 64 additions & 4 deletions src/components/Html/__tests__/__snapshots__/index.js.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
exports[`test should render Html componnent 1`] = `
exports[`test should render Html component 1`] = `
<html
lang="en">
<head>
Expand All @@ -21,11 +21,71 @@ exports[`test should render Html componnent 1`] = `
rel="stylesheet" />
</head>
<body>
<div />
<script />
<div
dangerouslySetInnerHTML={
Object {
"__html": "<div />",
}
}
id="phenomic" />
<script
phenomicStuff={true} />
<script
data-react-helmet={true}
src="test.js" />
</body>
</html>
`;

exports[`test should render Html component when glamor available 1`] = `
<html
lang="en">
<head>
<title
data-react-helmet={true} />
<meta
charSet="utf-8"
data-react-helmet={true} />
<meta
content="IE=edge"
data-react-helmet={true}
httpEquiv="X-UA-Compatible" />
<meta
content="width=device-width, initial-scale=1"
data-react-helmet={true}
name="viewport" />
<style
dangerouslySetInnerHTML={
Object {
"__html": ".stuff {}",
}
}
data-react-helmet={true} />
<link
data-react-helmet={true}
href="test.css"
rel="stylesheet" />
</head>
<body>
<div
dangerouslySetInnerHTML={
Object {
"__html": "<div />",
}
}
id="phenomic" />
<script
phenomicStuff={true} />
<script
dangerouslySetInnerHTML={
Object {
"__html": "window._glam = [{\"id\":\"s\"}]",
}
}
data-react-helmet={true} />
<script
data-react-helmet={true}
src="test.css" />
src="test.js" />
</body>
</html>
`;
34 changes: 30 additions & 4 deletions src/components/Html/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,42 @@ import { createRenderer } from "react-addons-test-utils"

import Html from "../index.js"

test("should render Html componnent", () => {
test("should render Html component", () => {
const renderer = createRenderer()
renderer.render(
/* eslint-disable react/jsx-no-bind */
<Html
css={ [ "test.css" ] }
js={ [ "test.css" ] }
renderBody={ () => <div /> }
renderScript={ () => <script /> }
js={ [ "test.js" ] }
renderBody={ () => "<div />" }
renderScript={ () => <script phenomicStuff /> }
/>
)
expect(renderer.getRenderOutput()).toMatchSnapshot()
})

test("should render Html component when glamor available", () => {
jest.mock(
"glamor/server",
() => ({
renderStatic: (render) => ({
html: render(),
css: ".stuff {}",
ids: [ { id: "s" } ],
}),
}),
{ virtual: true }
)
const renderer = createRenderer()
renderer.render(
/* eslint-disable react/jsx-no-bind */
<Html
css={ [ "test.css" ] }
js={ [ "test.js" ] }
renderBody={ () => "<div />" }
renderScript={ () => <script phenomicStuff /> }
/>
)
expect(renderer.getRenderOutput()).toMatchSnapshot()
jest.unmock("glamor/server", { virtual: true })
})
45 changes: 42 additions & 3 deletions src/components/Html/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,52 @@ const defaultMeta = [
]

const Html = (props: Props) => {

// Inject default html metas before
// Those need to be rendered somehow otherwise Helmet won't consider those
renderToString(
<Helmet
htmlAttributes={ defaultHtmlAttributes }
meta={ defaultMeta }
/>
)

// Glamor integration
// https://github.com/threepointone/glamor/blob/master/docs/server.md
let glamorRenderStatic
try {
// $FlowFixMe just ignore glamor as we don't have it as a dep
glamorRenderStatic = require("glamor/server").renderStatic
}
catch (e) {
// skip glamor if not working
}

// render body
let body
if (glamorRenderStatic) {
const glamorResult = glamorRenderStatic(() => props.renderBody())

console.log({ glamorResult })
renderToString(
<Helmet
style={ [
{ "cssText": glamorResult.css },
] }
script={ [
{ "innerHTML": `window._glam = ${
JSON.stringify(glamorResult.ids)
}` },
] }
/>
)
body = glamorResult.html
}

body = body || props.renderBody()

renderToString(
<Helmet
link={ [
...props.css.map((file) => ({ rel: "stylesheet", href: file })),
] }
Expand All @@ -39,8 +79,6 @@ const Html = (props: Props) => {
/>
)

// render body
const body = props.renderBody()
// rewind html metas
const head = Helmet.rewind()

Expand All @@ -51,10 +89,11 @@ const Html = (props: Props) => {
{ head.base.toComponent() }
{ head.title.toComponent() }
{ head.meta.toComponent() }
{ head.style.toComponent() }
{ head.link.toComponent() }
</head>
<body>
{ body }
<div id="phenomic" dangerouslySetInnerHTML={{ __html: body }} />
{ props.renderScript() }
{ head.script.toComponent() }
</body>
Expand Down
2 changes: 1 addition & 1 deletion src/static/__tests__/url-as-html.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,8 @@ test("custom script tags", async (t) => {
}
}
</script>
<script data-react-helmet="true" src="/test.js"></script>
<script data-react-helmet="true" src="http://foo.bar/baz.js"></script>
<script data-react-helmet="true" src="/test.js"></script>
</body>
</html>`)
Expand Down
26 changes: 10 additions & 16 deletions src/static/url-as-html.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,22 +64,16 @@ export default function(

/* eslint-disable react/no-multi-comp */

const renderBody = () => {
const body = render(
<PhenomicContextProvider
collection={ collectionMin }
metadata={ metadata }
>
<ReduxContextProvider store={ store }>
<RouterContextProvider { ...renderProps } />
</ReduxContextProvider>
</PhenomicContextProvider>
)

return (
<div id="phenomic" dangerouslySetInnerHTML={{ __html: body }} />
)
}
const renderBody = () => render(
<PhenomicContextProvider
collection={ collectionMin }
metadata={ metadata }
>
<ReduxContextProvider store={ store }>
<RouterContextProvider { ...renderProps } />
</ReduxContextProvider>
</PhenomicContextProvider>
)

const renderScript = () => {
if (options.clientScripts) {
Expand Down

0 comments on commit 15f55f8

Please sign in to comment.