Guide on Styling and CSS options
This question comes up a lot. A guide listing the options would be helpful, and I don't think that would break scope as long at it's mostly links and summaries.
I'd like to aggregate material from:
- https://discourse.purescript.org/t/css-strategies-for-purescript-apps/374
- https://github.com/thomashoneyman/purescript-halogen-realworld/issues/46#issuecomment-537170339
- https://discourse.purescript.org/t/typed-css-with-tailwind/1422
The steps to include CSS in a webpack project are also not intuitive for beginners. Instructions should be documented somewhere. Posting here in the meantime.
A failed attempt (click to expand)
For example, this was my initial flawed interpretation of one suggestion:
I think you’d need to import the css in your js files. Like in an FFI module.
So, if I have a directory structure like this:
dev
├── index.html
├── index.js
└── tailwind.css
src
├── Main.purs
├── Main.js
└── Tailwind.purs
Do I put this in Main.js:
"use strict";
import '../dev/tailwind.css';
This compiles, but the js contents do not get incorporated into the final bundle. I seems to be skipped when the compiler determines it's an unnecessary FFI module.
So then if I add this line:
exports.dummy = 5;
I get a FFI parsing error on import. Is this related to the ES modules todo?
The actual solutions are to either:
1.
Delete src/Main.js and create ./dev/tailwind.js with this content:
"use strict";
import './tailwind.css';
Then add this file as an entry point in webpack.config.js:
entry: {
"index.js": [
"./dev/tailwind.js",
"./dev/index.js",
],
Edit: Improved technique described in next post.
2.
Use an html template with HtmlWebpackPlugin, and link to the css file from within this template index.html.
webpack.config.js:
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "./dev/index.html"
}),
],
dev/index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Title</title>
<link rel="stylesheet" href="/dev/tailwind.css">
</head>
<body></body>
</html>
Your first solution can be simplified a bit by dropping the JavaScript file and referring to ./dev/tailwind.css directly in the entry:
"index.js": [
- "./dev/tailwind.js",
+ "./dev/tailwind.css",
"./dev/index.js",
],
Also your initial attempt can be fixed by importing the stylesheet with the CommonJS require function instead of an ES import, exporting it from the foreign module and then importing it in PureScript (beware, the path is relative to the output directory):
"use strict";
-import '../dev/tailwind.css';
+exports.stylesheet = require('../../dev/tailwind.css');
+foreign import stylesheet :: Unit
This is quite useful for CSS modules, because then you can type the stylesheet with forall classes. Record classes and refer to the generated class names by record field lookup with the classes you wrote on the stylesheet.
Great tips! Working example with your suggestion applied here: https://github.com/milesfrain/tps-save-gist/tree/simple-webpack-fixed