@@ -20,7 +20,7 @@ defmodule Volt.Tailwind do
2020
2121 use GenServer
2222
23- defp bundle_path , do: Application . app_dir ( :volt , "priv/tailwind.js" )
23+ @ tailwind_version "^4.2.2"
2424
2525 def start_link ( opts \\ [ ] ) do
2626 GenServer . start_link ( __MODULE__ , opts , name: __MODULE__ )
@@ -69,7 +69,7 @@ defmodule Volt.Tailwind do
6969 defp ensure_runtime ( % { runtime: nil } = state ) do
7070 { :ok , rt } = QuickBEAM . start ( )
7171 { :ok , _ } = QuickBEAM . eval ( rt , "globalThis.process = {env: {NODE_ENV: 'production'}};" )
72- { :ok , _ } = QuickBEAM . eval ( rt , read_bundle! ( ) )
72+ { :ok , _ } = QuickBEAM . eval ( rt , runtime_source ( ) )
7373
7474 scanner =
7575 if state . sources != [ ] do
@@ -149,6 +149,7 @@ defmodule Volt.Tailwind do
149149
150150 @ impl true
151151 def terminate ( _reason , % { runtime: nil } ) , do: :ok
152+
152153 def terminate ( _reason , % { runtime: rt } ) do
153154 QuickBEAM . stop ( rt )
154155 :ok
@@ -192,25 +193,74 @@ defmodule Volt.Tailwind do
192193 }
193194 end
194195
195- defp read_bundle! do
196- path = bundle_path ( )
197-
198- case File . read ( path ) do
199- { :ok , contents } ->
200- contents
201-
202- { :error , :enoent } ->
203- raise """
204- Missing generated Tailwind runtime at #{ path } .
196+ defp runtime_source do
197+ NPM . install ( % { "tailwindcss" => @ tailwind_version } , __skip_project_check__: true )
205198
206- Regenerate it with:
199+ nm_dir = NPM . node_modules_dir! ( )
200+ tw_dir = Path . join ( nm_dir , "tailwindcss" )
201+ source = File . read! ( Path . join ( [ tw_dir , "dist" , "lib.js" ] ) )
202+ theme = File . read! ( Path . join ( tw_dir , "theme.css" ) )
203+ preflight = File . read! ( Path . join ( tw_dir , "preflight.css" ) )
204+ utilities = File . read! ( Path . join ( tw_dir , "utilities.css" ) )
207205
208- mix volt.npm
209- mix volt.vendor.tailwind
210- """
206+ wrap_runtime ( source , theme , preflight , utilities )
207+ end
211208
212- { :error , reason } ->
213- raise File.Error , reason: reason , action: "read file" , path: path
214- end
209+ defp wrap_runtime ( source , theme , preflight , utilities ) do
210+ """
211+ var TW = (() => {
212+ var module = { exports: {} };
213+ var exports = module.exports;
214+ #{ source }
215+ return {
216+ compileCss: async function(inputCss, candidates) {
217+ var css = inputCss == null ? '@import "tailwindcss";' : inputCss;
218+ var compiler = await module.exports.compile(css, {
219+ from: 'app.css',
220+ loadStylesheet: async function(id) {
221+ if (id === 'tailwindcss') {
222+ return {
223+ base: '.',
224+ content: '@import "tailwindcss/theme.css" layer(theme);\\ n@import "tailwindcss/preflight.css" layer(base);\\ n@import "tailwindcss/utilities.css" layer(utilities);'
225+ };
226+ }
227+
228+ if (id === 'tailwindcss/theme.css') {
229+ return { base: '.', content: module.exports.Features ? requireAsset('theme') : '' };
230+ }
231+
232+ if (id === 'tailwindcss/preflight.css') {
233+ return { base: '.', content: requireAsset('preflight') };
234+ }
235+
236+ if (id === 'tailwindcss/utilities.css') {
237+ return { base: '.', content: requireAsset('utilities') };
238+ }
239+
240+ throw new Error('Unsupported stylesheet: ' + id);
241+ }
242+ });
243+
244+ return compiler.build(candidates || []);
245+ }
246+ };
247+
248+ function requireAsset(kind) {
249+ if (kind === 'theme') {
250+ return #{ Jason . encode! ( theme ) } ;
251+ }
252+
253+ if (kind === 'preflight') {
254+ return #{ Jason . encode! ( preflight ) } ;
255+ }
256+
257+ if (kind === 'utilities') {
258+ return #{ Jason . encode! ( utilities ) } ;
259+ }
260+
261+ return '';
262+ }
263+ })();
264+ """
215265 end
216266end
0 commit comments