phoenixframework / tailwind Goto Github PK
View Code? Open in Web Editor NEWAn installer for tailwind
License: MIT License
An installer for tailwind
License: MIT License
Running a mix tailwind.install
as part of my normal build process on my development environment automatically creates a file at /assets/css/app.css
. My project uses DartSass and has an app.scss
file instead, so the net effect is that if I run my build from a clean working copy, I end up with an untracked file in git for app.css
.
I propose adding a --skip-prepare
option to the tailwind install task that will skip the modifications it makes to app.css
and app.js
if the user desires and have prepared a Pull Request for this functionality.
Hi there, I've been using Tailwind for a while now and I think it's fantastic. It's great to see Tailwind adopted in an "official" package ^^
However, I noticed that, after installing it, I end up with a lot of files (.gz
especially) versioned in my repo. Since these digested files are put in the same dir, and since only priv/static/
is ignored, there are about 200 files popping when I do git status
.
Is there a way to change the directory for digested assets, or maybe have git ignore the hashed files somehow?
Hello.
We have a custom tailwind.config.js
which is overwritten by mix tailwind.install
. As far as I understand, this command is invoked during fetching the dependencies and first set up of the dependency.
The problem, however, comes when we're running the compilation (we're using distillery releases) in CI, because it will rewrite all customizations and breaks the build.
Could you please clarify a bit the way the problem should be addressed? I believe the simplest solution is check whether file exists there: https://github.com/phoenixframework/tailwind/blob/master/lib/tailwind.ex#L225 and not rewrite it.
This is a duplicate of #5 (was a bit late for me, haven't noticed), so probably it will be better to close it and address it within the main issue.
mix tailwind default --minify
works ok locally but seems to fail in GCP Cloud Build where the reason doesn't seem to be obvious.
deploy.yml
- name: 'gcr.io/something/docker-base-images/alpine-elixir-builder'
id: 'run tailwind'
entrypoint: mix
args: [ 'tailwind', 'default', '--minify' ]
output
17:08:26.506 [debug] Downloading tailwind from https://github.com/tailwindlabs/tailwindcss/releases/download/v3.0.3/tailwindcss-linux-x64
** (Mix) `mix tailwind default --minify` exited with 2
TL;DR we should either remove or make prep_css and prep_js optional somehow. Also they should be documented.
I have a phoenix project setup where I need to combine a variety of css and js libraries for specific pages/uses, as well as tailwind for my general site styling. For example, using something like SurveyJS means I need to import both it's js and css. I use npm just to install and track these other js/css libraries with dependabot.
So my current setup is:
This works great, except that this package goes into my app.css and manually adds the tailwind directives, and also removes importing app.css from app.js (which I don't need because esbuild can just bundle app.css with separate profile, but still).
This seems heavy handed, I should be able to ultimately decide what ends up in my app.js and app.css, particularly because those get version controlled.
As far as I can see, this isn't actually documented somewhere and it only happens on install, so I was really confused why those files kept being modified when I didn't modify them. It breaks what is otherwise a really nice workflow where I combine the two standalones esbuild and tailwind (or dart_saas for that matter).
When running tailwind in this docker image hexpm/elixir:1.15.0-erlang-26.0.1-alpine-3.18.2
I get the following error:
** (UndefinedFunctionError) function :http_util.timestamp/0 is undefined (module :http_util is not available)
(inets 9.0.1) :http_util.timestamp()
(inets 9.0.1) httpc.erl:750: :httpc.handle_request/9
(tailwind 0.2.0) lib/tailwind.ex:289: Tailwind.fetch_body!/1
(tailwind 0.2.0) lib/tailwind.ex:215: Tailwind.install/1
(tailwind 0.2.0) lib/tailwind.ex:196: Tailwind.install_and_run/2
(tailwind 0.2.0) lib/mix/tasks/tailwind.ex:51: Mix.Tasks.Tailwind.install_and_run/1
(mix 1.15.0) lib/mix/task.ex:447: anonymous fn/3 in Mix.Task.run_task/5
(mix 1.15.0) lib/mix/task.ex:506: Mix.Task.run_alias/6
when I switch to hexpm/elixir:1.14.5-erlang-26.0.1-alpine-3.18.2
it runs correctly as expected.
Following the setup instructions, when I try to run docker build
, it fails at the mix assets.deploy
step with the following message:
** (RuntimeError) tailwind is not available for architecture: aarch64-unknown-linux-gnu
Not sure if this is a problem in this library or with the standalone Tailwind releases.
I've got a 2021 Macbook Pro, running MacOS 12.1, using the docker build pipeline generated by the newest version of Phoenix. Elixir 1.13.1, Erlang 24.1.6.
Currently the installation process always replaces the tailwind config. So in CI for example since tailwind isn't there in _build
the config gets replaced. I made a change on my own branch to only replace when the file does not exist: rowofpixels@5c1ca1d
The alternative in CI would be to:
mix tailwind.install
mix assets.deploy
Wondering which approach would be best.
Hello, love this project and excited to see it continue <3
In assets/js/app.js
line 3 is removed but not lines 1 and 2 which pertain to it:
// We import the CSS which is extracted to its own file by esbuild.
// Remove this line if you add a your own CSS build pipeline (e.g postcss).
import "../css/app.css"
I'm suggesting removing lines 1 & 2 as well because it would be confusing in the future to come across those comments having forgotten you already did "remove this line". This file augmentation code is already being tested, so a PR could add those as well.
Alternatively, you could comment out line 3 instead of deleting it. In that case, there is a grammatical error on line 2 which could be PR'd as well.
I'm happy to submit a PR for any of this when I get a chance, but also happy to have someone else do the work π if it's deemed a worthy change. Thanks! :D
Error:
** (RuntimeError) tailwind is not available for architecture: aarch64-apple-darwin20.6.0
Hey everyone. I was running into this issue where I create a new phoenix project and I start it up, and it leaves me with a non-formatted screen. I looked at the console and the phoenix logs, which says app.css cannot be found. Well, the reason is, is because it's still downloading the 44MB Tailwind binary.
Now I know that we have a blue info line saying that it's downloading tailwind, but I thought because it moved to the next line, it was done. Turns out that's not the case. Also, there's no notifier on when it is downloaded.
While I know this now, this can be a problem for newbies needing clarification, and others not used to this situation.
So I wanted to fix it but not sure of the best approach. 2 ideas:
Anyways, would love the feedback on this and hope to contribute!
Quickly looking through the source code, I couldn't find a way to access Tailwindcss theme values (e.g., retrieve a color's hex code saved in tailwind.config.js
) in Elixir code.
Did I miss something? Is the feature planned for the future, or is it technically impossible?
Thanks for your work!
my config
# Configure esbuild (the version is required)
config :esbuild,
version: "0.13.5",
default: [
args:
~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
cd: Path.expand("../assets", __DIR__),
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
]
# Configures Elixir's Logger
config :logger, :console,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id]
# Use Jason for JSON parsing in Phoenix
config :phoenix, :json_library, Jason
config :tailwind,
version: "3.0.24",
default: [
args: ~w(
--config=tailwind.config.js
--input=css/app.css
--output=../priv/static/assets/app.css
),
cd: Path.expand("../assets", __DIR__)
]
my mix.exs
defp aliases do
[
setup: ["deps.get", "ecto.setup", "assets.deploy"],
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"],
"assets.deploy": [
"cmd --cd assets npm i",
"tailwind default --minify",
"esbuild default --minify",
"phx.digest"
]
]
end
the error
** (RuntimeError) couldn't fetch https://github.com/tailwindlabs/tailwindcss/releases/download/v3.0.24/tailwindcss-linux-x64: {:error, {:failed_connect, [{:to_address, {'objects.githubusercontent.com', 443}}, {:inet, [:inet], {:tls_alert, {:unexpected_message, 'TLS client: In state hello_middlebox_assert at ssl_gen_statem.erl:736 generated CLIENT ALERT: Fatal - Unexpected Message\n {unexpected_msg,{internal,{encrypted_extensions,\#{sni => {sni,[]}}}}}'}}}]}}
(tailwind 0.1.8) lib/tailwind.ex:328: Tailwind.fetch_body!/1
Warning: (tailwind 0.1.8) lib/tailwind.ex:230: Tailwind.install/0
(tailwind 0.1.8) lib/tailwind.ex:215: Tailwind.install_and_run/2
Warning: (tailwind 0.1.8) lib/mix/tasks/tailwind.ex:51: Mix.Tasks.Tailwind.install_and_run/1
(mix 1.13.4) lib/mix/task.ex:397: anonymous fn/3 in Mix.Task.run_task/3
Warning: (mix 1.13.4) lib/mix/task.ex:455: Mix.Task.run_alias/5
(mix 1.13.4) lib/mix/cli.ex:84: Mix.CLI.run_task/2
Warning: [os_mon] cpu supervisor port (cpu_sup): Erlang has closed
[os_mon] memory supervisor port (memsup): Erlang has closed
Error: Process completed with exit code 1.
Version 1.7.0-rc.2 of phoenix won't start on a raspberry pi host (debian 9.13). After running mix phx.server
I am greeted with the following:
** (Mix) Could not start application tailwind: exited in: Tailwind.start(:normal, [])
** (EXIT) an exception was raised:
** (RuntimeError) tailwind is not available for architecture: armv7l-unknown-linux-gnueabihf
(tailwind 0.1.9) lib/tailwind.ex:284: Tailwind.target/0
(tailwind 0.1.9) lib/tailwind.ex:157: Tailwind.bin_path/0
(tailwind 0.1.9) lib/tailwind.ex:174: Tailwind.bin_version/0
(tailwind 0.1.9) lib/tailwind.ex:100: Tailwind.start/2
(kernel 8.4) application_master.erl:293: :application_master.start_it_old/4
I was wondering if this could be supported? Version 1.6.15 ran without issues.
From #33 (comment), we still see this issue constantly.
In umbrella projects tailwind generate sassets files in root when installing. It's very easy to reproduce. Just remove the tailwind bin file and Tailwind library will create assets files in root. This would also be an issue if you are using non-standard path for assets for whatever reason.
I opened a PR half a year ago to not auto generate files when watching the assets: #53
But maybe it's better to just deal with it using the :cd
config: #78
This is more a question, but we can implement this as a PR if there is an appetite for it.
Our home-grown CMS has a lot of blocks that have tailwind classes in them, and the content for these blocks is all in the database. But when doing analysis to purge classes, since those classes are only defined in content in the database, these CSS classes still get purged.
Our solution has to been to dump out to a git-ignored /priv/static/prerendered/blocks.html
file that just concatenates all those blocks' contents, and adding that html file to the tailwind PurgeCSS content path.
However, this doesn't feel elegant. We have to remember to run the module that generates the additional dynamic content and dumps it in a file.
What if we had a config option that allows for us to define MFAs for various events (main one being "before purge") where we could either generate this file and return {:files, [list_of_generated_files]}, or "string content" that is used in the purge analysis?
something like:
config :tailwind, :events,
before_purge: {MyModuleThatGeneratesTheStaticFile}
Thoughts? We can't be the only ones facing this :-) I didn't necessarily look at the tailwind side for a solution because we would like to ideally run elixir code to be able to generate that additional content.
Is it possible to support the download for custom binaries?
My use case is downloading a custom tailwind binary that supports third-party plugin's ex. Daisy UI.
We can use the Tailwind config to override the default binary URL to get the custom.
It shouldn't be a critical change.
Command:
mix tailwind default
Output:
** (Mix) mix tailwind default exited with 137
Platform:
Mac OS X (13-inch, M1, 2020)
Memory 16GB
Mix Tailwind Version:
{:tailwind, "~> 0.1.5", runtime: Mix.env() == :dev}
Mix Config Setup:
config :tailwind,
version: "3.0.10",
default: [
args: ~w(
--config=tailwind.config.js
--input=css/app.css
--output=../priv/static/assets/app.css
),
cd: Path.expand("../assets", __DIR__)
]
It's hardcoded to create assets/tailwind.config.js
and assets/css/app.css
, despite using profiles that use other directories.
Edit: tailwind.install
is being invoked from my watcher config like this:
tailwind: {Tailwind, :install_and_run, [:engineering, ~w(--watch)]}
I think run
uses the profile, but install
doesn't.
Related to #44.
Esbuild watcher process esbuild-darwin-arm64
will be terminated normally after mix phx.server
stopped. While tailwind watcher process tailwind-macos-arm64
survived, and its parent process became null. I thought it is kind of unexpected.
Erlang/OTP 25 [erts-13.0.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]
Elixir 1.13.4 (compiled with Erlang/OTP 24)
{:phoenix, "~> 1.6.10"}
Hello all,
I am trying to use phoenix 1.7 with tailwind without the npm dependencies.
I dont know why but the tailwind is not compiling and generating the css file even with a simple example project.
Seems that the JS generation works ok.
I am using VSCode on windows with WSL1:
Please take a look at the following commands:
$ elixir -v
Erlang/OTP 24 [erts-12.2.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]
Elixir 1.15.0-dev (1c41021) (compiled with Erlang/OTP 24)
$ mix tailwind.install
16:28:05.615 [debug] Downloading tailwind from https://github.com/tailwindlabs/tailwindcss/releases/download/v3.1.8/tailwindcss-linux-x64
$ mix archive.install hex phx_new 1.7.0-rc.0
$ mix phx.new counter --live
$ cd counter/
$ mix ecto.create
$ mix phx.server
[info] Running CounterWeb.Endpoint with cowboy 2.9.0 at 127.0.0.1:4000 (http)
[info] Access CounterWeb.Endpoint at http://localhost:4000
[watch] build finished, watching for changes...
[info] GET /
[debug] Processing with CounterWeb.PageController.home/2
Parameters: %{}
Pipelines: [:browser]
[info] Sent 200 in 147ms
[info] GET /assets/app.css
**[debug] ** (Phoenix.Router.NoRouteError) no route found for GET /assets/app.css (CounterWeb.Router)**
(counter 0.1.0) lib/phoenix/router.ex:482: CounterWeb.Router.call/2
(counter 0.1.0) lib/counter_web/endpoint.ex:1: CounterWeb.Endpoint.plug_builder_call/2
(counter 0.1.0) lib/plug/debugger.ex:136: CounterWeb.Endpoint."call (overridable 3)"/2
(counter 0.1.0) lib/counter_web/endpoint.ex:1: CounterWeb.Endpoint.call/2
(phoenix 1.7.0-rc.2) lib/phoenix/endpoint/sync_code_reload_plug.ex:22: Phoenix.Endpoint.SyncCodeReloadPlug.do_call/4
(plug_cowboy 2.6.0) lib/plug/cowboy/handler.ex:11: Plug.Cowboy.Handler.init/2
(cowboy 2.9.0) /home/nuno/phoenix_projects/counter/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
(cowboy 2.9.0) /home/nuno/phoenix_projects/counter/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
(cowboy 2.9.0) /home/nuno/phoenix_projects/counter/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
(stdlib 3.17) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
[watch] build started (change: "js/app.js")
[watch] build finished
[debug] Live reload: priv/static/assets/app.js
[debug] Live reload: priv/static/assets/app.js
Now the website loads but has no css.
I then tried to force it:
$ mix assets.deploy
** (Mix) `mix tailwind default --minify` exited with 8
The code is here:
github proj
Does anyone have an idea of the reason?
May it be some issue with tailwind CLI and WSL1?
Thank you very much, any help is appreciated.
Thank you for your work, this stack is quite awesome.
Intellisense doesn't work for me in VS Code, because the https://github.com/tailwindlabs/tailwindcss-intellisense plugin can't find the tailwindcss executable.
A workaround is to install a second executable locally, just for intellisense, via npm:
cd assets
npm install [email protected]
npm install @tailwindcss/forms
rm package-lock.json
The team behind Tailwind CSS, launched a Prettier plugin for Tailwind CSS v3.0+ that automatically sorts classes based on their recommended class order.
I was thinking it would be really cool to be able to do the same by creating a Mix Format Plugin similar to what have been done to HEEX in Phoenix LiveView.
I am willing to work on this. Do you guys think it could be part of this package?
Problem
Builds run in WoodpeckerCI fail due to it setting HTTPS_PROXY to some value by default that does not match what this library expects.
+ cd .. && MIX_ENV=prod mix assets.deploy
01:10:30.698 [debug] Downloading tailwind from https://github.com/tailwindlabs/tailwindcss/releases/download/v3.2.7/tailwindcss-linux-x64
01:10:30.701 [debug] Using HTTPS_PROXY:
** (FunctionClauseError) no function clause matching in String.to_charlist/1
The following arguments were given to String.to_charlist/1:
# 1
nil
Attempted function clauses (showing 1 out of 1):
def to_charlist(+string+) when -is_binary(string)-
(elixir 1.14.4) lib/string.ex:2530: String.to_charlist/1
(tailwind 0.2.1) lib/tailwind.ex:276: Tailwind.fetch_body!/1
(tailwind 0.2.1) lib/tailwind.ex:224: Tailwind.install/1
(tailwind 0.2.1) lib/tailwind.ex:205: Tailwind.install_and_run/2
(tailwind 0.2.1) lib/mix/tasks/tailwind.ex:57: Mix.Tasks.Tailwind.install_and_run/1
(mix 1.14.4) lib/mix/task.ex:421: anonymous fn/3 in Mix.Task.run_task/4
(mix 1.14.4) lib/mix/task.ex:479: Mix.Task.run_alias/6
(mix 1.14.4) lib/mix/cli.ex:84: Mix.CLI.run_task/2
Solution
Should the library silently (or with a log message, but still continue running) continue without setting a proxy when URI.parse cant parse the environment variable? If so, id be happy to get a PR up this weekend for that.
Wondering if there's a way to specify more than one input file for bundling. Adding more than one --input=β¦
doesn't seem to do the trick.
Steps to reproduce:
mix phx.new foobar --no-ecto --no-gettext --no-dashboard --no-live --no-mailer
config :tailwind, version: "3.2.1", default: [ ......]
mix phx.server
and open your app in browser.app.css
, add the following (below the generated @tailwind
directives:a {
@apply text-green-500;
}
Notice that the live reloading works and your changes are reflected in the browser. You can change this css and live reload will continue to work.
5. BUT: if you make an error in your app.css:
a {
@apply not-a-real-class;
}
You will see the following printed in the console:
Rebuilding...
/snapshot/tailwindcss/node_modules/postcss/lib/input.js:148
result = new CssSyntaxError(
^
CssSyntaxError: tailwindcss: /home/simon/workspace/den_dash/assets/css/app.css:6:2: The `not-a-real-class` class does not exist. If `not-a-real-class` is a custom class, make sure it is defined within a `@layer` directive.
at Input.error (/snapshot/tailwindcss/node_modules/postcss/lib/input.js:148:16)
at AtRule.error (/snapshot/tailwindcss/node_modules/postcss/lib/node.js:60:32)
at processApply (/snapshot/tailwindcss/lib/lib/expandApplyAtRules.js:357:29)
at /snapshot/tailwindcss/lib/lib/expandApplyAtRules.js:505:9
at /snapshot/tailwindcss/lib/processTailwindFeatures.js:55:50
at Object.Once (/snapshot/tailwindcss/lib/cli/build/plugin.js:251:19)
at LazyResult.runOnRoot (/snapshot/tailwindcss/node_modules/postcss/lib/lazy-result.js:337:23)
at LazyResult.runAsync (/snapshot/tailwindcss/node_modules/postcss/lib/lazy-result.js:393:26) {
reason: 'The `not-a-real-class` class does not exist. If `not-a-real-class` is a custom class, make sure it is defined within a `@layer` directive.',
file: '/home/simon/workspace/den_dash/assets/css/app.css',
source: '@import "tailwindcss/base";\n' +
'@import "tailwindcss/components";\n' +
'@import "tailwindcss/utilities";\n' +
'\n' +
'a {\n' +
'\t@apply not-a-real-class;\n' +
'}\n',
line: 6,
column: 2,
endLine: 6,
endColumn: 26,
input: {
line: 6,
column: 2,
endLine: 6,
endColumn: 26,
source: '@import "tailwindcss/base";\n' +
'@import "tailwindcss/components";\n' +
'@import "tailwindcss/utilities";\n' +
'\n' +
'a {\n' +
'\t@apply not-a-real-class;\n' +
'}\n',
url: 'file:///home/simon/workspace/den_dash/assets/css/app.css',
file: '/home/simon/workspace/den_dash/assets/css/app.css'
},
plugin: 'tailwindcss'
}
Now, if you fix the error in app.css:
a {
@apply text-red-500;
}
your changes will not be reflected in the browser until you kill mix phx.server
and restart it.
If you instead use version 3.1.6: config :tailwind, version: "3.1.6", default: [ ......]
and repeat the same process, you will see a different error message printed in console:
Rebuilding...
CssSyntaxError: tailwindcss: /home/simon/workspace/foobar/assets/css/app.css:6:2: The `not-a-real-class` class does not exist. If `not-a-
real-class` is a custom class, make sure it is defined within a `@layer` directive.
4 |
5 | a {
> 6 | @apply not-a-real-class;
| ^
7 | }
8 |
and things will continue to work once you fix the error (no need to restart phx.server).
Hi all,
I posted this discussion in the tailwind repo: tailwindlabs/tailwindcss#7826
There is currently no binary for freebsd and I relay like to use phoenixframework/tailwind
as well as I love my FreeBSD servers.
I tried to compile the source with vercel/pkg
but did not succeed. Is there anyone else out there who needs a FreeBSD binary and more knowledge about how to compile that?
kind regards!
I previously had a version of tailwind installed in my app that did not support container queries:
config :tailwind,
version: "3.1.8"
I want to use container queries so I updated it 3.2.
I also updated my tailwind.config.js:
plugins: [
..
require("@tailwindcss/container-queries"),
..
]
I deleted my app.css and then ran mix tailwind.install and then mix tailwind default. Then I try to run the app and see this error in the terminal:
Error: Cannot find module '@tailwindcss/container-queries'
Require stack:
- /Users/app/assets/tailwind.config.js
- /snapshot/tailwindcss/lib/cli/build/plugin.js
- /snapshot/tailwindcss/lib/cli/build/index.js
- /snapshot/tailwindcss/lib/cli.js
- /snapshot/tailwindcss/standalone-cli/standalone.js
1) If you want to compile the package/file into executable, please pay attention to compilation warnings and specify a literal in 'require' call. 2) If you don't want to compile the package/file into executable and want to 'require' it from filesystem (likely plugin), specify an absolute path in 'require' call using process.cwd() or process.execPath.
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function._resolveFilename (pkg/prelude/bootstrap.js:1955:46)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at Module.require (pkg/prelude/bootstrap.js:1855:31)
at Module.require (/snapshot/tailwindcss/standalone-cli/standalone.js:25:22)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/Users/app/assets/tailwind.config.js:22:5)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Module._compile (pkg/prelude/bootstrap.js:1894:32) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/Users/app/assets/tailwind.config.js',
'/snapshot/tailwindcss/lib/cli/build/plugin.js',
'/snapshot/tailwindcss/lib/cli/build/index.js',
'/snapshot/tailwindcss/lib/cli.js',
'/snapshot/tailwindcss/standalone-cli/standalone.js'
],
pkg: true
Any idea on how I can add this plugin?
Hey,
I've followed the Readme to install tailwind in a phoenix project.
In dev it works great, but when I'm trying to run mix assets.deploy
to run it for production but I have the following error:
mix assets.deploy
Done in 238ms.
> css/app.css:1:8: error: Could not resolve "tailwindcss/base" (mark it as external to exclude it from the bundle)
1 β @import "tailwindcss/base";
β΅ ~~~~~~~~~~~~~~~~~~
> css/app.css:2:8: error: Could not resolve "tailwindcss/components" (mark it as external to exclude it from the bundle)
2 β @import "tailwindcss/components";
β΅ ~~~~~~~~~~~~~~~~~~~~~~~~
> css/app.css:3:8: error: Could not resolve "tailwindcss/utilities" (mark it as external to exclude it from the bundle)
3 β @import "tailwindcss/utilities";
β΅ ~~~~~~~~~~~~~~~~~~~~~~~
3 errors
** (Mix) `mix esbuild default --minify` exited with 1
my config.exs file:
config :tailwind,
version: "3.0.12",
default: [
args: ~w(
--config=tailwind.config.js
--input=css/app.css
--output=../priv/static/assets/app.css
),
cd: Path.expand("../assets", __DIR__)
]
# Configure esbuild (the version is required)
config :esbuild,
version: "0.14.0",
default: [
args:
~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
cd: Path.expand("../assets", __DIR__),
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
]
in the mix.exs file:
"assets.deploy": ["esbuild default --minify", "tailwind default --minify", "phx.digest"]
elixir: 1.13.1-otp24
erlang: 24.2
Any idea?
I apologize upfront for stupid question. I come from systems & backend engineering world, the world of frontend is new and frightening to me. I am trying to get started with Phoenix on FreeBSD.
I am aware of #49 , however this option has big drawback: there are are no official tailwind cli packages for FreeBSD and current package is outdated, maintained by a single person and relies on a complicated series of dirty hacks to get it working. (All thanks to convoluted build process of the tailwindcss CLI)
As I gather from the readme it is possible to use tailwindcss with nodejs:
For third-party Tailwind plugin support (e.g. DaisyUI), the node package must be used. See the Tailwind Node.js installation instructions if you require third-party plugin support.
However official tailwind documentation gives very generic guidance how to install it. Following those steps verbatim does not produce working result.
Can you please provide more detailed and tailored to phoenix steps?
I do have node
and tailwind installed. npx tailwindcss
works. As I understand tailwind
mix dependency should not be needed, or at least should be reconfigured. I want to re-use auto-generated tailwind.config.js
.
This snippet from config/config.ex
hints on what input/output paths should be but I would appreciate official step-by-step getting started instruction for a web monkey like me.
# Configure tailwind (the version is required)
config :tailwind,
version: "3.2.7",
default: [
args: ~w(
--config=tailwind.config.js
--input=css/app.css
--output=../priv/static/assets/app.css
),
cd: Path.expand("../assets", __DIR__)
]
P.S. It seems that this bit has to be adjusted to run npx tailwind
instead...
defp aliases do
[
setup: ["deps.get", "assets.setup", "assets.build"],
"assets.setup": ["tailwind.install --if-missing", "esbuild.install --if-missing"],
"assets.build": ["tailwind default", "esbuild default"],
"assets.deploy": ["tailwind default --minify", "esbuild default --minify", "phx.digest"]
]
end
I don't know why I get this error?
=> ERROR [builder 15/19] RUN mix assets.deploy 16.5s
------
> [builder 15/19] RUN mix assets.deploy:
#24 1.717
#24 1.717 23:43:45.075 [debug] Downloading tailwind from https://github.com/tailwindlabs/tailwindcss/releases/download/v3.0.24/tailwindcss-linux-x64
#24 16.31 node:internal/modules/cjs/loader:933
#24 16.31 const err = new Error(message);
#24 16.31 ^
#24 16.31
#24 16.31 Error: Cannot find module 'tailwindcss-textshadow'
#24 16.31 Require stack:
#24 16.31 - /app/assets/tailwind.config.js
#24 16.31 - /snapshot/tailwindcss/lib/cli.js
#24 16.31 - /snapshot/tailwindcss/standalone-cli/standalone.js
#24 16.31 1) If you want to compile the package/file into executable, please pay attention to compilation warnings and specify a literal in 'require' call. 2) If you don't want to compile the package/file into executable and want to 'require' it from filesystem (likely plugin), specify an absolute path in 'require' call using process.cwd() or process.execPath.
#24 16.31 at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
#24 16.31 at Function._resolveFilename (pkg/prelude/bootstrap.js:1819:46)
#24 16.31 at Function.Module._load (node:internal/modules/cjs/loader:778:27)
#24 16.31 at Module.require (node:internal/modules/cjs/loader:1005:19)
#24 16.31 at Module.require (pkg/prelude/bootstrap.js:1719:31)
#24 16.31 at Module.require (/snapshot/tailwindcss/standalone-cli/standalone.js:21:22)
#24 16.31 at require (node:internal/modules/cjs/helpers:94:18)
#24 16.31 at Object.<anonymous> (/app/assets/tailwind.config.js:25:5)
#24 16.31 at Module._compile (node:internal/modules/cjs/loader:1101:14)
#24 16.31 at Module._compile (pkg/prelude/bootstrap.js:1758:32) {
#24 16.31 code: 'MODULE_NOT_FOUND',
#24 16.31 requireStack: [
#24 16.31 '/app/assets/tailwind.config.js',
#24 16.31 '/snapshot/tailwindcss/lib/cli.js',
#24 16.31 '/snapshot/tailwindcss/standalone-cli/standalone.js'
#24 16.31 ],
#24 16.31 pkg: true
#24 16.31 }
#24 16.33 ** (Mix) `mix tailwind default --minify` exited with 1
------
Error failed to fetch an image or build from source: error building: executor failed running [/bin/sh -c mix assets.deploy]: exit code: 1
I read in README
here that if I needed to use 3rd party plugin for Tailwind
then I need to install node, and I did that.
Here is my package.json
file:
{
"devDependencies": {
"postcss": "^8.4.12",
"tailwindcss": "^3.0.24",
"tailwindcss-rtl": "^0.9.0",
"tailwindcss-textshadow": "^2.1.3"
},
"dependencies": {
"@fontsource/inter": "^4.5.7",
"@fontsource/noto-kufi-arabic": "^4.5.6"
}
}
I also thought to install tailwindcss
itself as node package thinking this would help, that's why you will find it above in the package.json
file, but I also tried at first without installing it and just installed the only 2 3rd party plugins I needed tailwindcss-rtl
& tailwindcss-text-shadow
!
But it seems my tailwind.config.js
doesn't feel these 3rd party plugins!!
I get this error when I deploy to Fly.io
, and this is my Dockerfile
#EASA ATPL Theory Distance Learning + Refresh Cours Find eligible builder and runner images on Docker Hub. We use Ubuntu/Debian instead of
# Alpine to avoid DNS resolution issues in production.
#
# https://hub.docker.com/r/hexpm/elixir/tags?page=1&name=ubuntu
# https://hub.docker.com/_/ubuntu?tab=tags
#
#
# This file is based on these images:
#
# - https://hub.docker.com/r/hexpm/elixir/tags - for the build image
# - https://hub.docker.com/_/debian?tab=tags&page=1&name=bullseye-20210902-slim - for the release image
# - https://pkgs.org/ - resource for finding needed packages
# - Ex: hexpm/elixir:1.13.4-erlang-24.3.3-debian-bullseye-20210902-slim
#
ARG ELIXIR_VERSION=1.13.4
ARG OTP_VERSION=24.3.3
ARG DEBIAN_VERSION=bullseye-20210902-slim
ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}"
FROM ${BUILDER_IMAGE} as builder
# install build dependencies
RUN apt-get update -y && apt-get install -y build-essential git curl \
software-properties-common \
npm
RUN npm install npm@latest -g && \
npm install n -g && \
n lts
# prepare build dir
WORKDIR /app
# install hex + rebar
RUN mix local.hex --force && \
mix local.rebar --force
# set build ENV
ENV MIX_ENV="prod"
ENV NODE_ENV="production"
# install mix dependencies
COPY mix.exs mix.lock ./
RUN mix deps.get --only $MIX_ENV
RUN mkdir config
# copy compile-time config files before we compile dependencies
# to ensure any relevant config change will trigger the dependencies
# to be re-compiled.
COPY config/config.exs config/${MIX_ENV}.exs config/
RUN mix deps.compile
COPY priv priv
COPY lib lib
COPY assets assets
RUN NODE_ENV=$NODE_ENV npm install --prefix assets
# compile assets
RUN mix assets.deploy
# Compile the release
RUN mix compile
# Changes to config/runtime.exs don't require recompiling the code
COPY config/runtime.exs config/
COPY rel rel
RUN mix release
# start a new build stage so that the final image will only contain
# the compiled release and other runtime necessities
FROM ${RUNNER_IMAGE}
RUN apt-get update -y && apt-get install -y libstdc++6 openssl libncurses5 locales \
&& apt-get clean && rm -f /var/lib/apt/lists/*_*
# Set the locale
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
WORKDIR "/app"
RUN chown nobody /app
# set runner ENV
ENV MIX_ENV="prod"
# Only copy the final release from the build stage
COPY --from=builder --chown=nobody:root /app/_build/${MIX_ENV}/rel/gat ./
USER nobody
CMD ["/app/bin/server"]
I don't understand when the Tailwind binary is downloaded and installed in a prod environment.
I got this error during deploy:
Step 15/31 : COPY lib lib
---> cd38882bac8e
Step 16/31 : RUN npm run --prefix ./assets deploy
---> Running in 3abb3c2ba603
> deploy
> NODE_ENV=production tailwindcss --postcss --minify -i css/app.css -o ../priv/static/assets/app.css
sh: tailwindcss: not found
Error failed to fetch an image or build from source: error building: error rendering build status stream: The command '/bin/sh -c npm run --prefix ./assets deploy' returned a non-zero code: 127
And here is my Dockerfile, which comes straight from the Fly.io documentation:
# Using the Hex.pm docker images. You have much better version control for
# Elixir, Erlang and Alpine.
#
# - https://hub.docker.com/r/hexpm/elixir/tags
# - Ex: hexpm/elixir:1.11.2-erlang-23.3.2-alpine-3.13.3
#
# Debugging Notes:
#
# docker run -it --rm hello_elixir /bin/ash
###
### Fist Stage - Building the Release
###
FROM hexpm/elixir:1.12.2-erlang-24.0.3-alpine-3.14.0 AS build
# install build dependencies
RUN apk add --no-cache build-base npm git
# prepare build dir
WORKDIR /app
# extend hex timeout
ENV HEX_HTTP_TIMEOUT=20
# install hex + rebar
RUN mix local.hex --force && \
mix local.rebar --force
# set build ENV as prod
ENV MIX_ENV=prod
ENV SECRET_KEY_BASE=nokey
# Copy over the mix.exs and mix.lock files to load the dependencies. If those
# files don't change, then we don't keep re-fetching and rebuilding the deps.
COPY mix.exs mix.lock ./
COPY config config
RUN mix deps.get --only prod && \
mix deps.compile
# install npm dependencies
COPY assets/package.json assets/package-lock.json ./assets/
RUN npm --prefix ./assets ci --progress=false --no-audit --loglevel=error
COPY priv priv
COPY assets assets
# NOTE: If using TailwindCSS, it uses a special "purge" step and that requires
# the code in `lib` to see what is being used. Uncomment that here before
# running the npm deploy script if that's the case.
COPY lib lib
# build assets
RUN npm run --prefix ./assets deploy
RUN mix phx.digest
# compile and build release
COPY rel rel
RUN mix do compile, release
###
### Second Stage - Setup the Runtime Environment
###
# prepare release docker image
FROM alpine:3.14.2 AS app
RUN apk add --no-cache libstdc++ openssl ncurses-libs imagemagick
RUN apk --no-cache add msttcorefonts-installer fontconfig && \
update-ms-fonts && \
fc-cache -f
WORKDIR /app
RUN chown nobody:nobody /app
USER nobody:nobody
COPY --from=build --chown=nobody:nobody /app/_build/prod/rel/my_app ./
ENV HOME=/app
ENV MIX_ENV=prod
ENV SECRET_KEY_BASE=nokey
ENV PORT=4000
CMD ["bin/my_app", "start"]
What am I missing here? Should I download the Tailwind binary separately?
The current installation instructions assume that users are not working in or starting a new umbrella project, ie mix new my_app --umbrella
.
I ran into a lot of issues trying to get this to work in a new umbrella project, and eventually just gave up and started the project fresh as a default mix
project.
I'm pretty new to Elixir, so it could just be that I'm missing something pretty obvious, but I thought that this would Just Workβ’ and was surprised when it didn't.
Would it be possible to add example usage for --umbrella
projects?
I am building out a simple todo app with LiveView and the Tailwind module. I am injecting a hex color value into my HEEX template and using it with Tailwind's new arbitrary value feature:
<li class="flex-1 border flex items-center border-red-500">
<span class={"h-8 w-8 bg-[#{list.color}] after:content-[' '] before:content-[''] rounded-full"}></span>
<span class="text-xl"><%= list.name %></span>
</li>
In the DOM I can see the value is parsed correctly bg-[#34ba56]
; however there is no color rendered and when looking at the classes applied to the node there is no bg
class being applied. I checked the issues on Tailwind and found nothing and then tested the arbitrary values feature in the online playground with the same version of Tailwind I am currently using in the project 3.0.12
. This does work in that playground, you can see an example here.
When looking at the DOM the class is present as:
.bg-\[\#bab123\] {
--tw-bg-opacity: 1;
background-color: rgb(186 177 35 / var(--tw-bg-opacity));
}
I am thinking that the underlying templating engine is likely escaping the the value but I am not entirely sure π¬. For now I am just going to apply the value to the style
attribute.
<li class="flex-1 border flex items-center border-red-500">
<span class={"h-8 w-8 after:content-[' '] before:content-[''] rounded-full"} style={"background-color: #{list.color}"}></span>
<span class="text-xl"><%= list.name %></span>
</li>
I successfully followed this guide to implement Tailwind CSS.
Now I want to add Inter via inter-ui. I installed the package via npm install inter-ui --prefix assets
and added the following statement to /assets/js/app.js
: import "inter-ui"
. After adding the statement, /priv/static/assets/app.css
now only contain the imported css, instead of complementing it.
To figure out what's happening, I created /assets/css/test.css
body {
font-family: "Inter" !important;
}
Then I added the following lines to /assets/css/app.js
import "../css/test.css"
import "inter-ui"
And the resulting /priv/static/assets/app.css
contains both, the content of /assets/css/test.css
and inter:
/* css/test.css */
body {
font-family: "Inter" !important;
}
/* node_modules/inter-ui/inter.css */
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 100;
font-display: swap;
src: url(./Inter-Thin-3L5KITMZ.woff2?v=3.19) format("woff2"), url(./Inter-Thin-CYZF3GYP.woff?v=3.19) format("woff");
}
// ...
Then I noticed that removing import "inter-ui"
does leave the content of /assets/css/test.css
in /assets/css/app.css
. However, app.css now is one big tailwind file with the content of test.css merged completely (no /* css/test.css */
comments).
When replacing import "inter-ui"
with import "../css/test.css"
, instead of merging the CSS /assets/css/app.css
now solely contains the inter style definitions.
Is this behaviour intended, and if so, how would I import inter-ui when using tailwind?
Hello,
First off I just wanted to start by saying how great this project seems and how grateful I am for your efforts in putting things together. Thank you.
Weirdly, the corporate proxy at work is getting in the way of me using this project because the tailwind settings don't seem to honor the :cacert_path
config key as esbuild does.
In particular, I get the following error when trying to run a mix tailwind.install
on macOS:
16:22:40.417 [notice] TLS :client: In state :wait_cert_cr at ssl_handshake.erl:2098 generated CLIENT ALERT: Fatal - Unknown CA
** (RuntimeError) couldn't fetch https://github.com/tailwindlabs/tailwindcss/releases/download/v3.2.4/tailwindcss-macos-arm64: {:error, {:failed_connect, [{:to_address, {'github.com', 443}}, {:tls, [server_name_indication: 'github.com', verify: :verify_peer, cacertfile: '/path/to/project/_build/dev/lib/castore/priv/cacerts.pem', depth: 2, customize_hostname_check: [match_fun: #Function<6.29392970/2 in :public_key.pkix_verify_hostname_match_fun/1>], versions: [:"tlsv1.2", :"tlsv1.3"]], {:tls_alert, {:unknown_ca, 'TLS client: In state wait_cert_cr at ssl_handshake.erl:2098 generated CLIENT ALERT: Fatal - Unknown CA\n'}}}]}}
lib/tailwind.ex:329: Tailwind.fetch_body!/1
lib/tailwind.ex:230: Tailwind.install/0
(mix 1.13.4) lib/mix/task.ex:397: anonymous fn/3 in Mix.Task.run_task/3
(mix 1.13.4) lib/mix/cli.ex:84: Mix.CLI.run_task/2
Is there any other information we can provide? Happy to provide additional detail and lend a hand to test solutions.
Thanks,
+Jonathan
Is it possible to build several css files?
Example
-> app.css
-> demo.css
to
-> priv/static/assets/app.css
-> priv/static/assets/demo.css
In the readme, it says:
make sure you have a
assets.deploy
alias for deployments, which will also use the--minify
option:"assets.deploy": ["tailwind default --minify", ..., "phx.digest"]
However, it's not entirely clear what it means in the context of an existing Phoenix project that already has an assets.deploy
alias.
Does that mean we replace the existing one:
- "assets.deploy": ["esbuild default --minify", "phx.digest"]
+ "assets.deploy": ["tailwind default --minify", "phx.digest"]
Or that we update it to:
- "assets.deploy": ["esbuild default --minify", "phx.digest"]
+ "assets.deploy": ["tailwind default --minify", "esbuild default --minify", "phx.digest"]
Hello, love this project and looking forward to its future <3
I have setup tailwind successfully using the README instructions but the default phx.new
page CSS is broken. I suspect this is because the CSS from phoenix.css
is missing. This makes sense given the changes being made, but I've spent a few hours now assuming I had done something wrong because the homepage CSS was not what I was expecting.
I can't tell if I have done something wrong.
(A) If I have done something wrong: I can't figure out how to keep the phoenix.css
CSS around within the setup process.
(B) If I have not done something wrong: I suggest there be a note in the README telling me to expect the home page CSS to be messed up, since the phoenix.css
CSS is now missing. And perhaps also recommend me to delete the phoenix.css
file (or something like that).
Hello,
In <myapp>/_build
I have esbuild-openbsd-x64
and tailwind-linux-x64
I think tailwind donβt support OpenBSD (my OS) ?
Attempting to run mix tailwind default
after mix tailwind.install
fails with the following error:
** (Mix) `mix tailwind default` exited with 137
Notably this only occurs for tailwind version 3.0.8. Changing the version back to 3.0.7 results in the default
command running fine.
This was on a fresh project created using mix phx.new my_project
and following the instructions on the readme. I was just seeing how the new tailwind integration works.
I am on macOS.
I'm trying to run a Phoenix project with Tailwind library in a raspberry but it is not working. The project is Dockerized, but when it runs mix assets.deploy
it fails:
Step 16/24 : RUN mix assets.deploy
---> Running in 034ad1ec1be1
added 1 package, and audited 2 packages in 3s
found 0 vulnerabilities
22:38:37.140 [notice] Application tailwind exited: exited in: Tailwind.start(:normal, [])
** (EXIT) an exception was raised:
** (RuntimeError) tailwind is not available for architecture: arm-unknown-linux-musleabihf
(tailwind 0.1.5) lib/tailwind.ex:265: Tailwind.target/0
(tailwind 0.1.5) lib/tailwind.ex:145: Tailwind.bin_path/0
(tailwind 0.1.5) lib/tailwind.ex:162: Tailwind.bin_version/0
(tailwind 0.1.5) lib/tailwind.ex:88: Tailwind.start/2
(kernel 8.2) application_master.erl:293: :application_master.start_it_old/4
I'm using the erlang:24.2.1-alpine
base image which is supports this platform.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.