alephjs / aleph.js

The Full-stack Framework in Deno.
https://aleph.deno.dev/
MIT License
5.27k stars 166 forks source link

Support for Tailwind CSS #42

Open yiss opened 3 years ago

yiss commented 3 years ago

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

shadowtime2000 commented 3 years ago

@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.

ije commented 3 years ago

@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 commented 3 years ago

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"]
}
shadowtime2000 commented 3 years ago

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).

ije commented 3 years ago

@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.

yiss commented 3 years ago

@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 ?

ije commented 3 years ago

@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": {}}]
}
yiss commented 3 years ago

@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?

ije commented 3 years ago

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"]
};
mojtabakaviani commented 3 years ago

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

shadowtime2000 commented 3 years ago

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.

JLarky commented 3 years ago

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

ije commented 3 years ago

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

jcayzac commented 3 years ago

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/-/twind@v0.15.4-FGDVNAhKzGSxolMsJRTE/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.

JLarky commented 3 years ago

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

aadamsx commented 3 years ago

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?

ije commented 3 years ago

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!

shadowtime2000 commented 3 years ago

@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

aadamsx commented 3 years ago

@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?

shadowtime2000 commented 3 years ago

@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

Zequez commented 3 years ago

@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/twind@0.16.13/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

ije commented 3 years ago

@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

algoflows commented 3 years ago

is it possible to use tailwind yet?

ije commented 3 years ago

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

aadamsx commented 3 years ago

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

ije commented 3 years ago

@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

aadamsx commented 3 years ago

@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!

ije commented 3 years ago

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

Xeevis commented 2 years ago

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.

osilkin98 commented 2 years ago

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