Skip to content
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

Update transformer-elm to use swc instead of terser #8134

Closed

Conversation

balazs-lengyel
Copy link

↪️ Pull Request

The elm transformer is broken for at least some bigger elm applications (see for example #7585). The reason is that terser doesn't really like the JS output by the elm compiler (see for example https://discourse.elm-lang.org/t/ot-webpack-terser-build-issue/7606)

In the discussion for #7585 @rjdellecese wrote about using swc instead of terser to solve the issue without turning of optimization, but there was no code shared. So I tried to recreate the work from the description.

The only issue have with this PR is that my practical JS knowledge is limited and I couldn't get the plugin to work locally for testing. It should be a trivial change though. Any feedback/pointer on how to get a local version of transformer-elm working on a nix-based system are appreciated!

💻 Examples

No publicly shareable codebase, but the issue seems to happen whenever terser is used to optimize elm applications above a certain size/complexity.

🚨 Test instructions

✔️ PR Todo

  • Added/updated unit tests for this change
  • Filled out test instructions (In case there aren't any unit tests)
  • Included links to related issues/PRs

@mischnic
Copy link
Member

There's a paragraph in https://github.com/parcel-bundler/parcel/blob/v2/CONTRIBUTING.md#getting-started-with-bug-fixing:

If you want to test out your change outside the monorepo, you can run /path/to/monorepo/packages/core/parcel/src/bin.js build src/index.html (provided that you don't have any @parcel/* plugins installed in this project).

@mischnic
Copy link
Member

Looks like swc expects the options to have a different format.

  1) elm
       should remove debugger in production:
     Failed to deserialize swc::config::JsMinifyOptions from json string (`{"minify":true,"jsc":{"minify":{"compress":{"keep\_fargs":false,"passes":2,"pure\_funcs":["F2","F3","F4","F5","F6","F7","F8","F9","A2","A3","A4","A5","A6","A7","A8","A9"],"pure\_getters":true,"unsafe":true,"unsafe\_comps":true},"mangle":{"reserved":["F2","F3","F4","F5","F6","F7","F8","F9","A2","A3","A4","A5","A6","A7","A8","A9"]}}}}`)

Caused by:
    unknown field `minify`, expected one of `compress`, `mangle`, `format`, `ecma`, `keepClassnames`, `keepFnames`, `module`, `safari10`, `toplevel`, `sourceMap`, `outputPath`, `inlineSourcesContent` at line 1 column 9
  Error: Failed to deserialize swc::config::JsMinifyOptions from json string (`{"minify":true,"jsc":{"minify":{"compress":{"keep_fargs":false,"passes":2,"pure_funcs":["F2","F3","F4","F5","F6","F7","F8","F9","A2","A3","A4","A5","A6","A7","A8","A9"],"pure_getters":true,"unsafe":true,"unsafe_comps":true},"mangle":{"reserved":["F2","F3","F4","F5","F6","F7","F8","F9","A2","A3","A4","A5","A6","A7","A8","A9"]}}}}`)

@rjdellecese
Copy link

Hi @balazs-lengyel, thanks for following up on this!

Here are the options I'm providing to the swc minify function in my forked plugin:

  {
    compress: {
      keep_fargs: false,
      passes: 2,
      pure_funcs: elmPureFuncs,
      pure_getters: true,
      unsafe_arrows: true,
      unsafe_comps: true,
      unsafe_Function: true,
      unsafe_math: true,
      unsafe_symbols: true,
      unsafe_methods: true,
      unsafe_proto: true,
      unsafe_regexp: true,
      unsafe_undefined: true,
    },
    mangle: false,
  }

It diverges more from the Terser options currently used by the Parcel Elm transformer because I based it off of the Terser configuration that I was previously using with Webpack.

@balazs-lengyel
Copy link
Author

Thanks @mischnic! It seems that I have gone full circle until I understood the error messages and what I needed to do. Now I've rebased and force pushed

Thanks @rjdellecese for sharing, did you need any of the additional settings for elm specific reasons or was it just for your project specific needs?

@rjdellecese
Copy link

Thanks @rjdellecese for sharing, did you need any of the additional settings for elm specific reasons or was it just for your project specific needs?

My project began its life using Webpack via https://github.com/halfzebra/create-elm-app, so it was pretty much just a translation of what had been configured there—that is, I have no particular reason to believe that just using the previously-specified options in Parcel's existing Elm transformer wouldn't work just fine (unless I'm forgetting something).

@balazs-lengyel
Copy link
Author

@mischnic: Updated - can you restart CI?

@balazs-lengyel
Copy link
Author

I don't see how to fix further tests (failed HMR/css) - can you give me a hint on how to approach that?

@mischnic
Copy link
Member

You can ignore them, these tests are flakey

@balazs-lengyel
Copy link
Author

You can ignore them, these tests are flakey

If there is nothing else to do, I'd say this is done!

@mischnic
Copy link
Member

So what exactly is the motivation here? That for some inputs, Terser is very slow/doesn't terminate at all in a reasonable time?
Also, the reason Parcel itself still uses Terser and not swc for minification is that swc's output is sometimes bigger (and occasionally also broken)

@balazs-lengyel
Copy link
Author

So what exactly is the motivation here? That for some inputs, Terser is very slow/doesn't terminate at all in a reasonable time? Also, the reason Parcel itself still uses Terser and not swc for minification is that swc's output is sometimes bigger (and occasionally also broken)

Yes, terser doesn't terminate for elm programs after they reach (some unknown) size/complexity or use a pattern where the elm compiler puts too much stress on terser.

While testing on a private project and waiting for this bug to occur, I found that the swc minified version was in the same ballpark as the terser one (usually much less then 1kB difference on the up to ~50kB results)

This has hit:

  • me while migrating from webpack in two codebases at work
  • me once in the private project a few weeks later
  • @rjdellecese as well
  • at least one elm/webpack user as well. Probably some more who haven't reported this.

This PR fixed the build issue I had, with the only caveat that i couldn't test the full application as I needed to comment out some parts of the js/css while doing the /path/to/monorepo/packages/core/parcel/src/bin.js build-style build.

@balazs-lengyel balazs-lengyel force-pushed the elm_optimize branch 2 times, most recently from 56d801c to 516f0b8 Compare August 1, 2022 09:33
@balazs-lengyel
Copy link
Author

@mischnic just updated to rebase onto v2 with #8076 merged - can we merge this?

@balazs-lengyel
Copy link
Author

never mind! I just realized that this seems to be fixed in terser!

@rjdellecese
Copy link

In terser/terser#1212, it seems?

Thank you @ChristophP for reporting the issue!

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.

None yet

3 participants