Anyone successfully integrated Svelte into Phoenix 1.6.x + esbuild?

In the case of the esbuild error, just install the dependency, cd assets npm i esbuild, must be above 0.9.6 which is the version that svelte-esbuild needs, in this case it tells you that it cannot find that module because it has not been installed

In the case of elixir I use version 1.12.1, erlang otp 23 and it compiles well for windows 10 and for linux with the ubuntu 18.04 distro

Try to install that stack, delete the dependencies and rebuild it, it should work for telemetry case

Well, I did npm install upfront. Was kind-of expecting that things needed for the example to work would already be present in package.json so the initial impression was that it might be something deeper. After adding it there the error is in fact gone. Checking further.

Mine are:

$ elixir --version
Erlang/OTP 24 [erts-12.1.5] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Elixir 1.13.0 (compiled with Erlang/OTP 24)

and I need these due to some dependencies breaking on earlier versions. It does not complain on the “linux” branch though.

In this case I already fixed that error, I added it to the package.json and it was uploaded to github

For now it was only an educational exercise, with the idea of helping people who wanted to see how to make the integration of the different tools possible.

However, the objective is met because the telemetry error is on the backend side and does not hinder the integration of svelte with phoenix 1.6. If you want to see it running, you could install the aforementioned stack using the asdf plugin that allows you to install different versions without damaging other projects.

Thank you for that. The integration part is exactly what I am/was looking for. Still need to do more thorough checking but on the surface the linux-tailwind works as expected and recompiles Svelte stuff on the fly. And faaast too! :wink:

1 Like

Excellent, very happy to help, happy new year 2022 for you and all the community!!

2 Likes

@silverdr, I just finished switching Svonix over to ESBuild - maybe you’d find the way the plugin is declared useful?

Granted in my case components are not all bundled into the same file but rather imported on demand upon declaration in a phx template.

2 Likes

@nikokozak Yes – thank you – every little bit counts! I still haven’t migrated the project in question to 1.6, but this surely will be of help. Thanks for taking time to post information here.

P. S. I noticed you “loosely” based it on Sveltex, which I found not to be up to snuff for some use cases, but that’s another, only “loosely” related story :wink:

1 Like

@silverdr I’d love to hear about that, whenever you have time - at the moment I haven’t really tried stretching Svelte too much, so I haven’t encountered the edge cases I’m sure exist.

Now that I am now mostly done with migration to 1.6.x. I’ll have to return to this so I’ll get back to you too :wink:

Close to successful migration to 1.6.x. What I am also very happy about is that I found:

which allows the project to be both webpack and node.js cancer-free :wink:

But… now it’s time to get back to Svelte components, which are used in some places, and that most probably means that “Revenge Of Node_Modules” is coming…

Or maybe somebody thought out a way to get Svelte into Phoenix w/o node?

I understand it might be more tricky than Tailwind, but maybe?

1 Like

I wrote a short blog post about it:

1 Like

@yendrisrogelio I managed to get basic functionality working now. The issue, which your example repository does not tackle is Svelte components’ internal CSS styles. CSS for component’s markup works only as long as you put tailwind classes directly. IOW words this works:

<script>
  console.log("test");
</script>

<h1 class="text-red-500 text-5xl font-bold text-center">Tailwind CSS 4444</h1>

but this does not:

<script>
  console.log("test");
</script>

<style>
	h1 {
		@apply text-blue-700;
	}
</style>

<h1 class="text-5xl font-bold text-center">Tailwind CSS 4444</h1>

Even though it worked with the old build system.

Any chances for you to have a look at it and maybe come up with a solution?

Sorry for the late reply but I’ve been busy with work. The problem you have is the following, you are trying to apply postcss directives inside the styles of svelte. So that svelte can understand it you need to install svelte-preprocess to your dependencies cd assets && npm i svelte-preprocess, then you must modify your build.js file finally being like this…

const esbuild = require("esbuild")
const sveltePlugin = require("esbuild-svelte")
const sveltePreprocess = require("svelte-preprocess");

const args = process.argv.slice(2)
const watch = args.includes('--watch')
const deploy = args.includes('--deploy')

let opts = {
  entryPoints: ['js/app.js'],
  bundle: true,
  target: 'es2016',
  outdir: '../priv/static/assets',
  logLevel: 'info',
  plugins: [
    sveltePlugin({
        preprocess: sveltePreprocess({
			postcss: {
				plugins: [
					require("tailwindcss"), 
					require("autoprefixer"),
				],
			},
		}),
      })
  ]
}

if (watch) {
  opts = {
    ...opts,
    watch,
    sourcemap: 'inline'
  }
}

if (deploy) {
  opts = {
    ...opts,
    minify: true
  }
}

const promise = esbuild.build(opts)

if (watch) {
  promise.then(_result => {
    process.stdin.on('close', () => {
      process.exit(0)
    })

    process.stdin.resume()
  })
}

So your svelte component works perfectly with tailwindcss

<script>
  console.log("test");
</script>

<style>
	h1 {
		@apply text-blue-700;
	}
</style>

<h1 class="text-5xl font-bold text-center">Tailwind CSS 4444</h1>

Thank you very much for finding time to have a look and respond.

I see. And you are certainly right for this particular case. Yet I should have given a bit more context rather than simply use your demo for the example. What I have in the project is:

a) I already have everything needed to “compile” tailwind stuff, including all @apply directives (PostCSS). This comes from phoenixframework / tailwind,

b) esbuild-svelte buildscript build.js properly processes and extracts Svelte specific stylesheet files.

Therefore in the perfect world phoenixframework / tailwind should be able to compile them and bundle the results in one go, along with everything else it already does. Still I don’t seem to get it to work, at least in a non-smelly way. Any clues?

The problem is that Svelte module’s specific classes don’t make it to the final bundle at all. And that’s understandable because in default configuration both output to the same destination w/o knowing about each other. I can make tailwind output to a different file so that it doesn’t overwrite the one that comes from Svelte but I am having hard time getting the Svelte one processed. I can’t @import that into app.css because “@apply is not supported within nested at-rules like @import”. I can’t pass it as another input to tailwind because

and adding another watcher or so feels smelly.

Since it gets a bit of a different topic I started another thread for this

Right now I don’t have much time to try a solution, but maybe you could try another way, I don’t know if it’s good for you, but maybe it could work

It’s best to inject all of the above into a high-level component so they’re accessible on every page. You can inject them in the App.svelte file:

<script>
  console.log("test");
</script>

<style global lang="postcss">
  @tailwind base;
  @tailwind components;
  @tailwind utilities;
  
  h1 {
		@apply text-blue-700;
	}
</style>

<h1 class="text-5xl font-bold text-center">Tailwind CSS 4444</h1>

Then you would already have tailwind on all the nested components of the svelte to be used
and maybe this way you avoid svelte class conflicts. I don’t know but maybe that’s how it works for you


It works

1 Like