opral / inlang-paraglide-js

Tree-shakable i18n library build on the inlang ecosystem.
https://inlang.com/m/gerre34r/library-inlang-paraglideJs
42 stars 0 forks source link

Evaluating language splitting with copying files #9

Closed linear[bot] closed 6 months ago

linear[bot] commented 6 months ago

TLDR: Seems to be the right approach for file-based routers, but will need adaptation for each framework.

Overview

The idea behind this approach is to copy the routes/ folder (or framework equivalent) for each language during build.

|- routes/
   |- de/
   |- en/

We then replace any imports for messages.js with the appropriate messages/lang.js

Prototype findings

  1. Might not possible to make generic. File-Based routers include both pages and server logic. We only want to apply the transform to client-code. We will need to differentiate between the two on a framework by framework basis. In server code, we allow stuff like { languageTag: "de" } on a message by message basis. It may be possible to spot this & not do the transform, but that's more complexity.
  2. Not 100% efficient. Since we are only doing the magic-transform for route files, component files aren't re-bundled for each language. This is leaving a lot of savings on the table. Should we copy lib/ folders too? But then, where do we stop?
  3. Difficult to make work in non-file-based routing. Frameworks like remix use a routeId based routing solution. There we would need to greatly adapt this approach, although it's still useable.

None of these are a dealbreaker IMO. I'm fairly confident that this is the best we can do without first-party support from frameworks.

Suggested API

In the prototype, the best API I could come up with is a paraglide-js build command. It works similarly to doppler, in that you pass it the build command you want to run.

paraglide-js build --route-dir ./src/app -- vite build

//or
paraglide-js-adaper-[framework] build

This allows us to run setup code before the build, and to clean up afterwards.

Technical Challenges

This approach does result in a lot of duplication, since you need entirely separate language-detection & routing logic during build and production. We will need to deal with a lot of bugs stemming from this duplication, but I don't really see a better way right now.

I do have a version that mostly works, but still suffers from a lot of these edge-cases

linear[bot] commented 6 months ago

PARJS-21 Evaluating language splitting with copying files

samuelstroschein commented 6 months ago

Is it not possible to create virtual modules in vite instead of paraglide-js-next build ?

LorisSigrist commented 6 months ago

No. (almost?) All frameworks using file-based routing read directly from FS. They also don't always do it in the same process, so we can't just shim fs with our own thing. We unfortunately need to shuffle around real files.

samuelstroschein commented 6 months ago

uhh tough one. if it's the right approach, i guess we have to do it :/

LorisSigrist commented 6 months ago

The only alternative here would be the postprocessor that I proposed, but that would also have it's own suite of challenges:

IMO the file-copy one is the better approach. All the challenges at least have a clear path to fixing them. I suggest we move forward with this

samuelstroschein commented 6 months ago

@loris.sigrist we can release this as experimental. the most convincing thing is the fact that only the build script needs to be adjusted, not dev mode.