Background
Preact is a really cool alternative to React. It's designed to be a fast, small (a mere 3kB) alternative to React with almost the same API. All your favorite buzz word things are there - hooks, functional components, server-side rendering out of the box, you name it. It's a great choice for more performance-oriented projects.
Styled Components are a great way of building scoped and reusable components quickly in the React world. You are essentially writing SASS-like styles in JavaScript. I know, it sounds sacrilegious, but I promise you it's actually pretty cool. Styled is a great choice for when you want a more atomic design structure to your app/component library.
You might've noticed that I said Styled is a part of the "React world", not the "Preact World". That's because it's a companion library to React, but, with a few tweaks - it'll work with our Preact app just as well.
Creating our Preact app with Preact CLI
Much like any cool framework/library worth its salt these days - Preact, too, has its own CLI package. Execute this in your terminal to install it:
npm i -g preact-cli
After installing the CLI, we can use it to create our fancy Preact app:
preact create default my-project
For a TypeScript Preact project, execute this command instead:
preact create typescript my-project
After the CLI is done creating your new app, you can navigate to it:
cd my-project
Installing Styled components
Now we need to install Styled Components, and (optionally) its helper Babel plugins:
npm i styled-components
npm i --save-dev babel-plugin-styled-components @quickbaseoss/babel-plugin-styled-components-css-namespace
or
yarn add styled-components
yarn add -D babel-plugin-styled-components @quickbaseoss/babel-plugin-styled-components-css-namespace
Aliasing React to Preact and setting up Babel
We need to do some "magic" called aliasing, so that when Styled looks for React it gets Preact compatibility instead.
Create a new file called preact.config.js
in the root folder of your project (if you've used the TypeScript CLI template, it should already be created, in which case just add the code below to the pre-existing method there) and populate it with the following code:
export default {
webpack(config) {
config.resolve.alias['react'] = 'preact/compat';
config.resolve.alias['react-dom/test-utils'] = 'preact/test-utils';
config.resolve.alias['react-dom'] = 'preact/compat';
}
};
Next, open .babelrc
and add the following code to the preexisting object:
{
"presets": [
"preact-cli/babel"
],
"plugins": [
"@quickbaseoss/babel-plugin-styled-components-css-namespace",
"babel-plugin-styled-components"
]
}
Setting up for use with TypeScript
Disregard this section if you've not used the TypeScript template.
Getting our Styled components to behave under TS is fairly easy. First, we need to install the types for Styled:
npm i --save-dev @types/styled-components
or
yarn add -D @types/styled-components
Then we need to modify our tsconfig.json
and add the following to the compilerOptions
object:
{
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"react": ["node_modules/preact/compat/"],
"react-dom": ["node_modules/preact/compat/"]
}
}
Now we can safely import/export Styled components into Preact components without getting TS errors.
Creating our first Styled component in JavaScript
Let's create a sample styled component to test with. In src/routes/home
create test.component.js
:
import styled from 'styled-components';
const Test = styled.div`
background: red;
`;
export default Test;
And then import and use it in src/routes/home/index.js
:
import { h } from 'preact';
import style from './style.css';
import Test from './test.component';
const Home = () => (
<div class={style.home}>
<Test>
<h1>Home</h1>
<p>This is the Home component.</p>
</Test>
</div>
);
export default Home;
Creating our first Styled component in TypeScript
In src/routes/home
create test.component.ts
:
import styled from 'styled-components';
const Test = styled.div`
background: red;
`;
export default Test;
And then import and use it in src/routes/home/index.tsx
:
import { h } from 'preact';
import style from './style.css';
import Test from './test.component';
const Home = () => (
<div class={style.home}>
<Test>
<h1>Home</h1>
<p>This is the Home component.</p>
</Test>
</div>
);
export default Home;
Inspecting the fruits of our labor
To check out our super-dooper Styled component, run:
npm run dev
or
yarn dev
And navigate to http://localhost:8080/:
That was it! You now have Styled Components inside of your Preact app.