Skip to content

Instantly share code, notes, and snippets.

@developit
Last active August 29, 2020 04:18
Show Gist options
  • Save developit/23fc4995c3b2c07bd8ff3f916565bb03 to your computer and use it in GitHub Desktop.
Save developit/23fc4995c3b2c07bd8ff3f916565bb03 to your computer and use it in GitHub Desktop.
asdf

Preact CLI with styled-components

This shows how to use styled-components with preact-cli.

Styles are collected and inlined during pre-rendering, with no extra build or configuration step required.

The only configuration change required is to add a constant, just to prevent SSR-specific styled-components code from being loaded on the client.

{
"presets": [
"preact-cli/babel"
],
"plugins": [
"babel-plugin-styled-components"
]
}
build
node_modules
package-lock.json
size-plugin.json
import styled, { ThemeProvider } from "styled-components";
const Button = styled.button`
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border-radius: 3px;
color: ${props => props.theme.main};
border: 2px solid ${props => props.theme.main};
`;
const theme = {
main: "mediumseagreen"
};
export function App() {
return (
<div>
<Button theme={{ main: "royalblue" }}>Ad hoc theme</Button>
<ThemeProvider theme={theme}>
<div>
<Button>Themed</Button>
<Button theme={{ main: "darkorange" }}>Overidden</Button>
</div>
</ThemeProvider>
</div>
);
}
import { App } from "./App";
import wrap from './styled-components-ssr';
export default wrap(App);
{
"name": "preact-cli-styled-components",
"version": "1.0.0",
"scripts": {
"dev": "preact watch",
"build": "preact build",
"serve": "serve build -s -n",
"start": "npm run -s build && npm run -s serve"
},
"eslintConfig": {
"extends": "preact"
},
"dependencies": {
"preact": "^10.3.4",
"preact-render-to-string": "^5.1.4",
"styled-components": "^5.0.1"
},
"devDependencies": {
"babel-plugin-styled-components": "^1.10.7",
"eslint": "^6.8.0",
"eslint-config-preact": "^1.1.1",
"preact-cli": "^3.0.0-rc.10",
"serve": "^11.3.0"
}
}
module.exports = (config, env, helpers) => {
// Define a `process.env.SSR` boolean constant:
const DefinePlugin = helpers.getPluginsByName(config, "DefinePlugin")[0];
DefinePlugin.plugin.definitions['process.env.SSR'] = String(env.ssr);
};
let wrap;
// For SSR only: wrap the app to collect and append styles
if (process.env.SSR) {
wrap = (App) => {
const { ServerStyleSheet, StyleSheetManager } = require("styled-components");
const sheet = new ServerStyleSheet();
const StyleTags = () => sheet.getStyleElement();
return (props) => [
<StyleSheetManager sheet={sheet.instance}>
<App {...props} />
</StyleSheetManager>,
<StyleTags />
]
};
}
else {
wrap = x => x;
}
export default wrap;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment