PaimaStudios / paima-game-templates

Paima Engine Game Templates for developers.
https://paimastudios.com
MIT License
11 stars 8 forks source link

Think about de-duplicating modules when frontend is also a JS project #46

Open SebastienGllmt opened 1 year ago

SebastienGllmt commented 1 year ago

Current standard build steup

If you look at the template system, you'll notice a lot of templates have 3 build steps:

  1. Building the code for Paima Engine to use (api & state machine). This powers the state machine run as part of the Paima Engine executable, as well as the light client endpoints it exposes: https://github.com/PaimaStudios/paima-engine/blob/2168ed678e2687f014320809a609f377302ba740/packages/paima-sdk/paima-build-utils/src/standalone-esbuildconfig.template.cts#L17-L20
  2. Building the middleware, which exposes all the Paima functions your frontend will need (https://github.com/PaimaStudios/paima-engine/blob/master/packages/paima-sdk/paima-build-utils/src/middleware-esbuildconfig.template.cts)
  3. Building the frontend

This is a very logical separation of concerns when the frontend is written with Unity, Game Maker or any other non-Javascript environment

What is the problem?

If the frontend is also written in Javascript, this can cause unexpected duplication of global variables.

To see an example of this, think of the @perawallet/connect library. It is included as part of Paima Engine for the Algorand wallet functionality, but might also be used by the frontend as part of milkomeda-wsc.

That means that when you generate middleware.js from step (2), you get a fully compiled JS file (it doesn't refer to NPM packages - it packs their entire source code into a single JS file).

image

Since middleware.js contains a full copy of @perawallet/connect, Javascript does not de-duplicate this copy of the library from the copy referenced in the frontend repository through milkomeda-wsc

Now, this is not an issue in a lot of cases. However, some JS libraries might not be written with the expectation that they run on the same page under different contexts, leading to errors such as this: https://github.com/perawallet/connect/issues/156

How can we fix it?

Well, there isn't really anything wrong with the current setup per se. As long as we submit fixes to libraries like we did for Pera, then everything should work out.

Another way we can tackle this is to change the templates where the frontend is also in JS to simply consume the middleware as a standard package part of the workspace instead (aka merge steps 2 & 3 into a single build step). This is more complicated than it sounds because it means the build process for the frontend has to be compatible with the build process for Paima itself. Since that means we need to align ESM versions and properly mock out nodejs modules (fs, etc.) and ENV variables in the same way, this would probably involve writing some kind of Paima build-util for the most common JS compilation tools like Webpack (not fun).