Skip to content

Configuration options for custom workflows; scalaJsResolverPlugin#34

Open
raquo wants to merge 4 commits into
scala-js:mainfrom
raquo:main
Open

Configuration options for custom workflows; scalaJsResolverPlugin#34
raquo wants to merge 4 commits into
scala-js:mainfrom
raquo:main

Conversation

@raquo
Copy link
Copy Markdown
Contributor

@raquo raquo commented Mar 7, 2026

I've been looking into using Scala.js in Electron, and needed additional functionality from the vite plugin to support Electron's development workflow... or maybe just my flavor of it. Unlike typical frontend development, there's a node.js component that needs to be integrated with fastLinkJS + vite build rather than the vite dev server; the proposed features stem from me trying to wrangle a custom workflow that would work nicely. I think the end result could be broadly useful for custom workflow in general.

I believe everything in this PR is backwards compatible, there should be no breaking changes to users.

New features:

  • Introduced optional task plugin option where you can specify fastLinkJSOutput or fullLinkJSOutput (or a custom command) to decouple this from NODE_ENV (default remains the same).
  • Introduced retries of sbt invocation, to add resilience against "sbt thinks that server is already booting" exceptions.
    • This error can happen if you try to launch multiple sbt sessions at the same time, e.g. concurrently 'vite build this' 'vite build that'. This can be avoided by sleeping, but it's nicer when it just works.
    • To maintain current behaviour, the retries are opt-in by setting maxAttempts option. If you're ok to change behaviour, we could set the default maxAttempts to 3.
  • Introduced a new scalaJsResolverPlugin that is exported separately. All it does is resolve the scalajs: prefix to the scala.js output path that the user needs to provide.
    • This is useful when you know the scala.js output path, and don't want to invoke sbt – for example, if you're calling vite build from within sbt already. Or I guess from another build tool.
    • That resolver plugin is deathly simple, but the new example in the docs shows why it's convenient to have it published together with the scala.js sbt plugin
    • I decided to make it a separate plugin rather than a configuration option to the main plugin to make it more obvious what's happening in the vite config file. If it was all one plugin, most of the configuration options would apply only conditionally depending on the value of one of the configuration option, would be confusing I think. And the two plugins do perform their tasks sufficiently differently, that I think separating them is just clearer, both in the API and in the implementation.
  • More details on the above in the README diff

Technical changes

  • Renamed the main plugin function name from scalaJSPlugin to scalaJsSbtPlugin:
    • Added sbt to differentiate from the other plugin
    • Title-cased JS to Js because it's hard to have good camel case names with uppercase acronyms (scalaJSSbtPlugin, scalaJSSBTPlugin are all less readable). I tend to treat acronyms as if they were words when camelCase-ing, makes naming (and reading) easier.
    • This does not affect existing API as you exported this function as a default export, which comes without a name
    • But if you want to use both scalaJsSbtPlugin and scalaJsResolverPlugin then the new naming becomes relevant and is self-consistent.
    • I kept uppercase JS in the type names of the *Options interfaces to avoid any potential breakage in the public API. Would be nice to convert those to Js for consistency later.
  • Added spaces within braces { shell: true, ...options } to make it consistent with other code. Don't have a preference either way, just wanted to give IDEA a chance to format the file without causing edits.
  • Added .editorConfig file to specify the expected 2-space indent, for same reason.

Hopefully the above decisions are acceptable, these individual features were too small to make PRs individually, so I yolo-d on bundling them. But if something here is not agreeable, let me know of course.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant