-
Notifications
You must be signed in to change notification settings - Fork 5
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
Add foreign JS integration article #14
Conversation
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.
Great post, I learned a lot.
I noticed some stuff to change, but fortunately nothing major!
|
||
## Using JavaScript backend with existing JavaScript tools | ||
|
||
Any, even the most complex and technically beautiful undertaking is worthless if its fruits are not usable. |
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.
Any, even the most complex and technically beautiful undertaking is worthless if its fruits are not usable. | |
Yet, even the most complex and technically beautiful undertaking is worthless if its fruits are not usable. |
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.
Done
|
||
### Optimizing and bundling | ||
|
||
Currently, `google-closure-compiler` is supported for minification of the bundle (see [previous blog](https://blog.haskell.org/report-of-js-code-minification/)). Let's try it. |
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.
Currently, `google-closure-compiler` is supported for minification of the bundle (see [previous blog](https://blog.haskell.org/report-of-js-code-minification/)). Let's try it. | |
Currently, `google-closure-compiler` is supported for minification of the bundle (see the blog post on [JS code minification](https://blog.haskell.org/report-of-js-code-minification/)). Let's try it. |
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.
Done
``` | ||
|
||
Notice we have to call `google-closure-compiler` with two input files: first is the `all.js` package generated by the compiler after bundling our library with all dependencies, | ||
GHC rts and emscripten rts files; second, is the `all.externs.js` file that declares external variables for the minifier. Its purpose is twofold - first it instructs the compiler those are declared elsewhere and it should not fail with undeclared variable; second, it prohibits mangling those identifiers during minification. |
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.
GHC rts and emscripten rts files; second, is the `all.externs.js` file that declares external variables for the minifier. Its purpose is twofold - first it instructs the compiler those are declared elsewhere and it should not fail with undeclared variable; second, it prohibits mangling those identifiers during minification. | |
GHC's RTS and emscripten RTS files; second, is the `all.externs.js` file that declares external variables for the minifier. Its purpose is twofold - It informs the compiler that those variables are declared elsewhere, as not to fail with an "undeclared variable" error, and it prevents the mangling of those identifiers during minification. |
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.
Done
import Data.Text qualified as T | ||
``` | ||
|
||
We are going to use foreign import for initializing and destroying a button ripple effect. We will include this code in `js-sources` pragma of the cabalfile: |
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.
We are going to use foreign import for initializing and destroying a button ripple effect. We will include this code in `js-sources` pragma of the cabalfile: | |
We are going to use foreign import for initializing and destroying a button ripple effect. We will include this code in `js-sources` field of the package's cabal file: |
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.
Done
``` | ||
|
||
We are going to use foreign import for initializing and destroying a button ripple effect. We will include this code in `js-sources` pragma of the cabalfile: | ||
```yaml |
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.
```yaml | |
```cabal |
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.
Done
|
||
Callbacks fully enable probably the most fascinating purpose of JavaScript backend, which is web programming. GHCJS has been around for quite some time now, | ||
however it is both outdated (being a GHC fork requiring separate maintenance; currently stuck on 8.10) and cumbersome to use (often necessitating a separate setup, typically through Nix). In one of my previous companies, while evaluating potential options for rewriting the frontend, I decided to use PureScript. It was close enough to Haskell and very easy to set up - it can be installed directly through `npm`, has its own `stack`-like package manager `spago` with a suite of existing bundler plugins, and a blazing fast language server. | ||
During this journey I was using [purescript-halogen](https://github.com/purescript-halogen/purescript-halogen) library - a typesafe, declarative VDOM framework based on the Elm Architecture. |
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.
Maybe a link to the Elm Architecture could be useful for the reader?
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.
Added a link to https://guide.elm-lang.org/architecture/
} | ||
``` | ||
|
||
And voila! It all works as before. The uncompressed bundle size is slightly bigger (844 KiB vs 803 KiB with `google-closure-compiler`) however we don't need any more workarounds, |
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.
And voila! It all works as before. The uncompressed bundle size is slightly bigger (844 KiB vs 803 KiB with `google-closure-compiler`) however we don't need any more workarounds, | |
And voilà! It all works as before. The uncompressed bundle size is slightly bigger (844 KiB vs 803 KiB with `google-closure-compiler`) however we don't need any more workarounds, |
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.
Fixed (sorry I never know whether it's acute or grave)
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.
*problemu (it's genitive) ;)
|
||
## Thanks! | ||
|
||
Many thanks to [Serge S. Gulin](https://github.com/GulinSS) for his help and discussions on Matrix channel, and to [Hécate Kleidukos](https://gitlab.haskell.org/Kleidukos) for inviting me to write this blog. I want also to thank [Sylvain Henry](https://gitlab.haskell.org/hsyl20) and [Luite Stegeman](https://gitlab.haskell.org/luite) for our mail and PR discussions, and whole IOG GHC Engineering team for the joint effort of releasing the JS backend. Awesome work! |
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.
Many thanks to [Serge S. Gulin](https://github.com/GulinSS) for his help and discussions on Matrix channel, and to [Hécate Kleidukos](https://gitlab.haskell.org/Kleidukos) for inviting me to write this blog. I want also to thank [Sylvain Henry](https://gitlab.haskell.org/hsyl20) and [Luite Stegeman](https://gitlab.haskell.org/luite) for our mail and PR discussions, and whole IOG GHC Engineering team for the joint effort of releasing the JS backend. Awesome work! | |
Many thanks to [Serge S. Gulin](https://github.com/GulinSS) for his help and discussions on Matrix channel, and to [Hécate Kleidukos](https://gitlab.haskell.org/Kleidukos) for inviting me to write this blog post. I want also to thank [Sylvain Henry](https://gitlab.haskell.org/hsyl20) and [Luite Stegeman](https://gitlab.haskell.org/luite) for our mail and PR discussions, and whole IOG GHC Engineering team for the joint effort of releasing the JS backend. Awesome work! |
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.
Done
|
||
What's next? There is still a lot to do in terms of code size & performance, as well as integration with other tools: | ||
|
||
- This cabal [PR](https://github.com/haskell/cabal/pull/10722) adds a new pragma `js-options` that allows to pass custom flags to `js-sources` preprocessor. |
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.
- This cabal [PR](https://github.com/haskell/cabal/pull/10722) adds a new pragma `js-options` that allows to pass custom flags to `js-sources` preprocessor. | |
- This cabal [PR](https://github.com/haskell/cabal/pull/10722) adds a new field, `js-options`, that allows to pass custom flags to `js-sources` preprocessor. |
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.
Fixed
@GulinSS Could I ask you to take a look? |
```sh | ||
mateusz@m12844:~/personal/halogen-blog$ ./run_example 1 | ||
(...) | ||
+ npx google-closure-compiler --language_in UNSTABLE --compilation_level ADVANCED_OPTIMIZATIONS --warning_level QUIET --isolation_mode IIFE --assume_function_wrapper --emit_use_strict --js /home/mateusz/personal/halogen-blog/dist-newstyle/build/javascript-ghcjs/ghc-9.12.1/example1-0.1.0.0/x/example1/build/example1/example1.jsexe/all.js --js /home/mateusz/personal/halogen-blog/dist-newstyle/build/javascript-ghcjs/ghc-9.12.1/example1-0.1.0.0/x/example1/build/example1/example1.jsexe/all.externs.js --js_output_file ../dev/index.js |
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.
May be add a small description why UNSTABLE
with a link?
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.
Sure. Added.
```sh | ||
mateusz@m12844:~/personal/halogen-blog$ brotli -Z -o dev/index.js.br dev/index.js | ||
mateusz@m12844:~/personal/halogen-blog$ du -h dev/index.js.br | ||
76K dev/index.js.br |
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.
wow wow
May be it would be nice to add few figures which demonstrate what you see in browser? |
It's in the videos. Not sure how that renders on the page but in github it works fine |
Ah! Finally found it, nice! |
@Kleidukos @GulinSS is it good to go? |
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.
If @GulinSS is happy, I am!
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.
Me too!
|
Indeed I can reproduce |
Strange works on my phone
…On Thu, 9 Jan 2025 at 11:21, Hécate ***@***.***> wrote:
Indeed I can reproduce
—
Reply to this email directly, view it on GitHub
<#14 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AGKZAGJM3FWTXHW5NQ5MYZT2JZESNAVCNFSM6AAAAABU2HFZKWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNZZG4YTQOBRGU>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Made a PR:
#15
On Thu, 9 Jan 2025 at 11:24, Mateusz Goślinowski <
***@***.***> wrote:
… Strange works on my phone
On Thu, 9 Jan 2025 at 11:21, Hécate ***@***.***> wrote:
> Indeed I can reproduce
>
> —
> Reply to this email directly, view it on GitHub
> <#14 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AGKZAGJM3FWTXHW5NQ5MYZT2JZESNAVCNFSM6AAAAABU2HFZKWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNZZG4YTQOBRGU>
> .
> You are receiving this because you authored the thread.Message ID:
> ***@***.***>
>
|
No description provided.