aleph.js icon indicating copy to clipboard operation
aleph.js copied to clipboard

Support for Tailwind CSS

Open yiss opened this issue 4 years ago • 30 comments

I discovered AlephJs and I really love it, it just works out of box like magic. I'm trying to add support for TailwindCSS but I have no I idea where to start. The documentation here suggest to use PostCSS but I don't think there is a PostCSS plugin in Deno yet : https://tailwindcss.com/docs/installation


Edit : I checked this pull request #41 and I think we can do something similar for PostCSS

yiss avatar Nov 18 '20 20:11 yiss

@yiss Yeah, there isn't an official way to use PostCSS with Deno but @ije created a CDN which converts NPM packages to Deno compatible packages. I think Aleph already uses that but I don't think it is possible to configure that. Once configuration is allowed, it would probably pretty simple to use Tailwind.

shadowtime2000 avatar Nov 18 '20 21:11 shadowtime2000

@yiss, sorry i'm not user of tailwind, you can try to import tailwind via CDN:

// app.tsx
import 'https://esm.sh/tailwindcss/dist/tailwind.min.css'

but this does not support tailwind's build features, likes tree-shaking, theme, directives, etc.

ije avatar Nov 19 '20 04:11 ije

as @shadowtime2000 mentioned, aleph support postcss with autoprefixer plugin out-of-the-box, but i'm not sure TailwindCSS can be configured in postcss.config.json:

{
  "plugins": ["tailwindcss", "autoprefixer"]
}

ije avatar Nov 19 '20 04:11 ije

We could do a postcss.config.(js|ts) instead:

import autoprefixer from "https://esm.sh/autoprefixer";
import tailwindcss from "https://"

export default {
	plugins: [tailwindcss, autoprefixer]
};

or whatever else is the format for adding plugins to PostCSS (I haven't used it that much).

shadowtime2000 avatar Nov 19 '20 08:11 shadowtime2000

@shadowtime2000 "plugins": ["tailwindcss", "autoprefixer"] means aleph will import those plugins automaticlly from ems.sh where the postcss module is from, autoprefixer plugin can work well but the tailwindcss i'm not sure.

ije avatar Nov 19 '20 09:11 ije

@ije @shadowtime2000 I was thinking of doing something like this : plugins/postcss.ts would be the same as sass-loader plugin. and in the plugins we can do :

import taildwindcss from ' https://'
import autoprefixer from ' https://'

export default {
plugins: [...otherPlugins, postcss([tailwindcss({}), autoprefixer({})]
}

I'm not sure what do you think ?

yiss avatar Nov 19 '20 09:11 yiss

@yiss i want to support postcss out of the box, no extra plugins needed, if you want to configure the postcss plugins you can do like:

{
  "plugins": [{"name": "tailwindcss", "options": {}}, {"name": "autoprefixer", "options": {}}]
}

ije avatar Nov 19 '20 10:11 ije

@ije Seems reasonable since most people would want to use PostCSS and might not want any other plugins. I have a question though, is there a way to specify plugins in the project folder? For example let's say that my app is called my-awesome-aleph if I created a file my-awesome-aleph\plugins.ts with my plugins would that work?

yiss avatar Nov 19 '20 10:11 yiss

postcss.config.(js|ts) could be an option(currently not support):

import plugin from "./your-postcss-plugin.ts"

// import tailwindcss and autoprefixer automaticlly from NPM
export default {
  plugins: [plugin, "tailwindcss", "autoprefixer"]
};

ije avatar Nov 19 '20 11:11 ije

Can add this issue to v0.3.0 roadmap? #5

mojtabakaviani avatar Dec 01 '20 20:12 mojtabakaviani

I think there are already enough things that sill need to be done for v0.3.0, we could try to get it done by then, but I think it would best fit on the roadmap for v0.4.0/future.

shadowtime2000 avatar Dec 20 '20 07:12 shadowtime2000

I tried to set up http://twind.dev/ with aleph, but it requires some stuff for it to work in SSR :)

import 'https://cdn.skypack.dev/twind/shim'

works kind of :) since it's client-only (but causes markup to flicker, official solution to set hidden for html tag

JLarky avatar Jan 07 '21 10:01 JLarky

@JLarky this is vary interesting! i will try it, thanks!

ije avatar Jan 07 '21 11:01 ije

I tried to set up http://twind.dev with aleph, but it requires some stuff for it to work in SSR :)

import 'https://cdn.skypack.dev/twind/shim'

works kind of :) since it's client-only (but causes markup to flicker, official solution to set hidden for html tag

@JLarky how do you use that unnamed import? I tried using twind with aleph but I keep getting an error:

ERROR TypeError: Uncaught SyntaxError: Invalid destructuring assignment target
        w((p = u.forEach(D), true)=>p
                             ~~~~
    at <anonymous> (file:///Users/jcayzac/hello/.aleph/development/-/cdn.skypack.dev/-/[email protected]/dist=es2020,mode=imports/optimized/twind.js:1785:30)

I just modified app.tsx with

 import type { ComponentType } from 'react'
 import React from 'react'
+import { tw } from 'https://cdn.skypack.dev/twind'

 export default function App({ Page, pageProps }: { Page: ComponentType<any>, pageProps: any }) {
   return (
-    <main>
+    <main className={tw`h-screen bg-purple-400 flex items-center justify-center`}>
       <head>
         <title>Hello World - Aleph.js</title>
       </head>
       <Page {...pageProps} />
     </main>
   )
 }

And if I pass ?dts to get the deno typings, so that the import uses https://cdn.skypack.dev/twind?dts, I get this error instead:

ERROR TypeError: Cannot resolve module
"file:///Users/jcayzac/hello/.aleph/development/-/cdn.skypack.dev/twind_dts.js"
 from "file:///Users/jcayzac/hello/.aleph/development/app.c2bd4b3bd.js".

The content of .aleph/development/-/cdn.skypack.dev/ is:

-  twind.js_dts.js  twind.js_dts.js.map  twind.js_dts.meta.json

@ije I think there's some bug in how module URLs are mapped to resources in .aleph. I reported it in #161.

jcayzac avatar Feb 26 '21 03:02 jcayzac

I don't have the project at the moment, but you should check this discussion https://github.com/tw-in-js/twind/issues/70#issuecomment-762184115

JLarky avatar Feb 26 '21 16:02 JLarky

I'm new to Deno/Aleph, come from a node/react background. Is there clear/easy way to add tailwind to a new Aleph project?

aadamsx avatar Mar 24 '21 03:03 aadamsx

i have a radical idea...i want to add a feature for the compiler (not very difficult) to collect the classnames at the compilation pahse, then create the minimum css by usage! no tailwindcss compiler needed or import a huge css!

ije avatar Mar 24 '21 04:03 ije

@ije I think a TailwindCSS implementation called WindiCSS did that and then Tailwind CSS is creating a JIT compiler which does that.

But we could look at generalizing that for just CSS.

Like if we have this in the CSS:

.asdf{color:red;}
.asdf2{color:blue;}

and we had this code:

<div className="asdf">

we would just collect that asdf class name and decide to include it - but it's not that much different from using purgecss so idk what the speed benefits would be

shadowtime2000 avatar Mar 24 '21 04:03 shadowtime2000

@shadowtime2000

Yeah, there isn't an official way to use PostCSS with Deno but @ije created a CDN which converts NPM packages to Deno compatible packages. I think Aleph already uses that but I don't think it is possible to configure that. Once configuration is allowed, it would probably pretty simple to use Tailwind.

I see the aleph.config.ts with postcss and options for adding plugins, will configuration options be allowed so I can just plug in tailwind into the postcss processor?

aadamsx avatar Mar 24 '21 18:03 aadamsx

@aadamsx Correct, you can now configure PostCSS. TailwindCSS doesn't properly convert and we would have to wait until they add Deno support, postui/esm.sh#10

shadowtime2000 avatar Mar 24 '21 18:03 shadowtime2000

@jcayzac

Uncaught SyntaxError: Invalid destructuring assignment target

I've gone on an adventure to hunt down this. I was getting this error too when importing twind. It seems to be an issue with the SWC compiler.

The code where the error is found is:

init((injected = styles.forEach(inject2), true)=>injected

Which indeed has a syntax error; it should be:

init((injected = (styles.forEach(inject2), true))=>injected

And if you make the change on the cache directory it actually does work. The original file where that line comes from at twind has the parenthesis.

And if we go to the source of the file at esm.sh https://cdn.esm.sh/v41/[email protected]/deno/twind.development.js we also find that the parenthesis are there. But then the file gets compiled by SWC when picked by Aleph, and it removes the parenthesis.

It might have to do with this issue reported on SWC https://github.com/swc-project/swc/pull/1566

And that's as far as I could go. In theory SWC in Aleph was updated to the latest version 5 days ago ( https://github.com/alephjs/aleph.js/commit/5d1915e5d47388b33fe1d596d91e25f72af42fe3 ) and that PR should already be in use by Aleph, but my Rust is limited and I couldn't figure it out further. There is another PR that modified that fixer.rs file and removed some of the code added on that PR, maybe the fix was reverted? https://github.com/swc-project/swc/pull/1561

Zequez avatar Apr 29 '21 19:04 Zequez

@Zequez thanks, that is helpful! i will try to upgrade swc again to check out whether it's fixed, or i will make pr to swc project

ije avatar Apr 30 '21 01:04 ije

is it possible to use tailwind yet?

algoflows avatar Jun 30 '21 10:06 algoflows

now we can write plugin for alephjs to support tailwind: https://alephjs.org/docs/api-reference/plugin-api#tailwind-jit-for-jsx

ije avatar Aug 23 '21 19:08 ije

Thanks @ije, but can we get a project repo example of tailwind working with Aleph -- complete with configurations?

aadamsx avatar Aug 23 '21 19:08 aadamsx

@aadamsx will add it later, also need to check out how to compile css for tailwind in deno, currently the compiler records all the static class names in jsx files

ije avatar Aug 23 '21 21:08 ije

@ije great! if you get this all working and complied and provide a tailwind deno demo with configuration, I'll take a look at using Aleph once again!

aadamsx avatar Aug 24 '21 15:08 aadamsx

Just added a tailwindcss example in https://github.com/alephjs/aleph.js/tree/master/examples/tailwindcss, that is using the windicss plugin

ije avatar Sep 01 '21 18:09 ije

With recently published TailwindCSS Standalone CLI it's quite easy to use TailwindCSS with Deno.run with no Node whatsoever. To be able to use PostCSS plugins there are official modules for both PostCSS and for example postcss-import.

PostCSS needs to run first for imports to be inlined, resulting css can then be piped to TailwindCSS CLI.

const twprocess = Deno.run({
  cmd: [
    "cmd", "/C", "./tailwindcss-windows-x64", "-i", "app.pcss", "-o", "app.css", "-c", "tailwind.config.cjs",
  ]
});
await twprocess.status();
twprocess.close();

TailwindCSS Cli includes cssnano (use with --minify) and autoprefixer (enabled by default). But you can pipe stdout from CLI to esbuild or whatever for further processing.

Xeevis avatar Jan 04 '22 07:01 Xeevis

@ije That link is broken when I try to follow it.

osilkin98 avatar Jun 04 '22 17:06 osilkin98