documentation icon indicating copy to clipboard operation
documentation copied to clipboard

Guide on Styling and CSS options

Open milesfrain opened this issue 5 years ago • 3 comments

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

milesfrain avatar Jul 18 '20 18:07 milesfrain

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>

milesfrain avatar Jul 21 '20 18:07 milesfrain

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.

kl0tl avatar Jul 21 '20 19:07 kl0tl

Great tips! Working example with your suggestion applied here: https://github.com/milesfrain/tps-save-gist/tree/simple-webpack-fixed

milesfrain avatar Jul 21 '20 19:07 milesfrain