-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
front: upgrade NGE to v2.7.0 #8309
Conversation
Codecov ReportAttention: Patch coverage is
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## dev #8309 +/- ##
============================================
- Coverage 27.48% 27.47% -0.02%
Complexity 2155 2155
============================================
Files 1316 1316
Lines 158162 158163 +1
Branches 3262 3262
============================================
- Hits 43469 43451 -18
- Misses 112710 112729 +19
Partials 1983 1983
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
5e9bf49
to
510f415
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the update and the fix, which i guess was not easy to find 😮
510f415
to
151a70d
Compare
Unfortunately this turned out to be more involved than expected. Let's get the easy stuff out of the way first: - We're now using the official NGE package from NPM, so we can drop the @osrd-project namespace! 🎉 - Thanks to Louis we now have translations and don't need to become fluent in German anymore! - Upstream no longer creates one subdirectory per language, so we can drop "en/" from our import paths. - Upstream has added a proper fix for dark themes, so we can drop our sbb-light class that we applied on the iframe's <html> element. - For reasons detailed below, we need to use vite-plugin-static-copy, and this plugin requires ESM instead of CJS, so we need to add "type": "module" in our package.json [1]. Hopefully this Doesn't Break Stuff™. Edit: oh, of course this caused havoc everywhere, so let's just turn on ESM specifically for vite.config.ts instead of the whole project for now. This is done by renaming it to vite.config.mts. Now onto the real fun. The source of the issue is that NGE now dynamically loads i18n files on startup (e.g. the JSON file containing English translations). Unfortunately this doesn't play well with our bundler, vite. vite doesn't include the NGE translation files in the final build. vite looks at all of the imports, then flattens them inside a single directory with a modified filename. Since NGE source files are immutable assets one does not simply import the i18n files from the React NGE component to make them available to NGE: we need the i18n files to be placed in a well-known directory at build time with a predictable filename. The nicest way to resolve this would be some kind of directory URL import: import ngeBase from 'netzgrafik-frontend/dist/netzgrafik-frontend?url'; However vite doesn't support importing directories like so and it doesn't seem like a plugin exists for this. We can instead instruct vite to copy over the NGE i18n files via a third-party plugin named vite-plugin-static-copy. We need to grab the root directory of the netzgrafik-frontend package somehow, we could hardcode the "mode_modules/" path but that would be quite fragile. Instead, we can leverage require.resolve() but we need to pass the full path to a nested file then compute its dirname because that function doesn't like directories. Now that our i18n files are copied to a directory, we need to convince NGE to pick them up at the correct location. As-is, NGE tries to load them relative to the URL, which results in hilarious paths such as: /operational-studies/projects/2/studies/1/scenarios/1/src_assets_i18n_en_json.js Append a <base> tag to the <iframe> so that anything NGE tries to load is looked up in the special NGE directory we've copied the i18n files into. The cherry on top is: TypeError: __require.resolve is not a function which happens because require.resolve() is only available in CJS, and we just switched to ESM for the sake of the new vite-plugin-static-copy dependency. This can be resolved with a bit of juggling with createRequire from 'node:module'. [1]: https://vitejs.dev/guide/troubleshooting.html#this-package-is-esm-only
151a70d
to
1f77b3f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for all these solutions, LGTM (tested) !!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM & tested ✅
Thanks for the explanations !
Unfortunately this turned out to be a tad more involved than expected.
Let's get the easy stuff out of the way first:
<html>
element."type": "module"
in our package.json 1. Hopefully this Doesn't Break Stuff™. Edit: oh, of course this caused havoc everywhere, so let's just turn on ESM specifically for vite.config.ts instead of the whole project for now. This is done by renaming it to vite.config.mts.Now onto the real fun. The source of the issue is that NGE now dynamically loads i18n files on startup (e.g. the JSON file containing English translations). Unfortunately this doesn't play well with our bundler, vite. vite doesn't include the NGE translation files in the final build. vite looks at all of the imports, then flattens them inside a single directory with a modified filename. Since NGE source files are immutable assets one does not simply import the i18n files from the React NGE component to make them available to NGE: we need the i18n files to be placed in a well-known directory at build time with a predictable filename.
The nicest way to resolve this would be some kind of directory URL import:
However vite doesn't support importing directories like so and it doesn't seem like a plugin exists for this.
We can instead instruct vite to copy over the NGE i18n files via a third-party plugin named vite-plugin-static-copy. We need to grab the root directory of the netzgrafik-frontend package somehow, we could hardcode the "mode_modules/" path but that would be quite fragile. Instead, we can leverage require.resolve() but we need to pass the full path to a nested file then compute its dirname because that function doesn't like directories.
Now that our i18n files are copied to a directory, we need to convince NGE to pick them up at the correct location. As-is, NGE tries to load them relative to the URL, which results in hilarious paths such as:
Append a
<base>
tag to the<iframe>
so that anything NGE tries to load is looked up in the special NGE directory we've copied the i18n files into.The cherry on top is:
which happens because require.resolve() is only available in CJS, and we just switched to ESM for the sake of the new vite-plugin-static-copy dependency. This can be resolved with a bit of juggling with createRequire from 'node:module'.
Ideas welcome if you find a better way to fix this!