lustre-labs / lustre

An Elm-inspired framework for building HTML templates, single page applications, and server-rendered components in Gleam!
https://hexdocs.pm/lustre
MIT License
738 stars 52 forks source link

Remove the CLI from main package to publish it separately #69

Closed ghivert closed 3 months ago

ghivert commented 3 months ago

Hi and first thanks for the package!

I tried to setup a Lustre application by using Vite to leverage on existing tooling (live reload, etc.). Unfortunately, Vite refuses to build when internal node modules (like child_process) are required. Because of the imports chain, the CLI is imported in the Lustre package, and Vite refuses to build because of the presence of node modules.

Because of the nature of Lustre to be 100% browser compatible, I think it could gains to separate the CLI from the package, to avoid requiring node modules in browser.

Right now, to make it work, I had to do something like this:

// vite.config.js
import * as path from 'path'
import gleam from 'vite-gleam'

const childProcess = path.resolve(process.cwd(), './src/polyfills/child_process.js')
const fs = path.resolve(process.cwd(), './src/polyfills/fs.js')

export default {
  resolve: {
    alias: [
      { find: 'node:child_process', replacement: childProcess },
      { find: 'node:fs', replacement: fs },
    ],
  },
  plugins: [gleam()],
}
// src/polyfills/child_process.js
export const spawnSync = () => {}
// src/polyfills/fs.js
export const statSync = () => {}
export default {}

It's working, and the main function will never be used in the frontend, so it's not a big deal, but it would greatly improve as a quality-of-life to kickstart a project.

It could easily be separated by having a lustre-cli package, no? Unless it's not compatible with gleam -m lustre? In this case, isn't it possible to not bundle the CLI parts in browser?

hayleigh-dot-dev commented 3 months ago

Hey, thanks for opening this! I'd really like to avoid moving the CLI into a separate package. Most people coming to Lustre will not be super experienced with frontend/js tooling and it's very high on my priorities to make the experience for those people as painless as possible: it feels like a bit of a bummer to add an extra step before they can get building.

That said it's also super important that Lustre plays nice with proper production-ready tooling! I will investigate and see if we can come up with a solution. I think some part of the problem is that gleam generates imports for unused modules so even if we mark the main function as Erlang-only it will still generate unused imports for modules like glint and simplifile, and that can upset tree-shaking because imports can have side effects. If you go poking in the cli source you'll see some awful hack I had to introduce to get esbuild to work – similar to your resolve alias trick above.

We'll work it out! 💪

ghivert commented 3 months ago

Thanks for your quick answer!

I think we can also properly let the CLI in the package as long as production-ready folks used to use specific tools (Webpack, Vite, etc.) are aware of what's happening and can integrate the package easily. I spent a couple of hours trying to understand what's happening, but I really wanted Gleam and Lustre to work on my frontend. I can clearly think that someone who don't want it really much won't take so much time in a setup while others languages have things like Vite and others CLI.

In a first time, having a proper, complete setup guide with current build tool used in modern JS stack could greatly help the adoption of the framework, mainly because we need to use the existing tooling almost every time when pushing to production and having to fight against the habits acquired in JS ecosystem (and if you need that or this specific library, it's so much easier to use Vite to manage node_modules and all).

hayleigh-dot-dev commented 3 months ago

@ghivert we decided to bite the bullet and move the CLI stuff out of lustre and into a separate package users will have to add. It's a little bit of friction but it's worth it to avoid hacks with other tooling.

It also means apps using lustre in production erlang settings don't have to include deps like simplifile, which may present an issue for auditing purposes etc. Thanks for prompting us to do this.