-
Notifications
You must be signed in to change notification settings - Fork 114
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
Replace Webpacker with jsbundling-rails + Webpack #5746
Conversation
app/javascript/packages/rails-i18n-webpack-plugin/extract-keys-webpack-plugin.js
Show resolved
Hide resolved
Looked like CI was upset that |
Couple more thoughts:
|
I like that the final assets have fingerprints in them, because then it works well when we eventually deploy to a CDN and don't have to deal with asset breakages across deploys, would removing that remove some intermediate step? Or remove fingerprinting entirely? |
Ah, sorry, I should have clarified: I would still aim to keep the fingerprint, but generate those in Webpack instead, using the One thing I noticed in perusing Webpacker source is that they include the digest only in production environments, following some Webpack build performance recommendations. |
I feel like with any of these projects, it's hard to tell what will stay up to date and what will drift and get stale over time. If it looks like |
Yeah, I also forgot it handles the |
Restored the first of these in 72e1058. I'm thinking the second could be possible as well, by one of either:
|
app/javascript/packages/document-capture/components/button-to.jsx
Outdated
Show resolved
Hide resolved
One data point: The Before: https://app.circleci.com/pipelines/github/18F/identity-idp/64363/workflows/796fe5bb-ffdc-4adb-9a38-1dc55f270cef/jobs/100173 Edit: Also worth reiterating that this opens up the opportunity to switch from Babel to |
Solid lead from logging:
|
Actually... this may just work automatically, at least in these sense that:
So even if compilation is in-progress while making the request, there would never be a case where the user would see behavior from the "old" code after refreshing. One edge-case is if the manifest doesn't yet exist, such as when starting up the server for the first time. In my experience, the build takes less time to become ready than the Rails server. Alternatively, we could omit the manifest file from the Generally, it'd still be a good idea to have some safeguards hereabouts for if the file doesn't exist: identity-idp/app/helpers/script_helper.rb Lines 45 to 47 in 54495cc
|
Note to self: Do a pass on interoperability with devops workflows, specifically assumptions around Webpacker, Currently, this branch flattens |
Similar assumptions exist in CircleCI/GitLab CI: |
**Why**: To simplify ongoing work in #5746, to avoid double-processing of SASS files, and to consolidate in preparation for future CSS bundling refactoring (cssbundling-rails).
* Standardize SASS processing to Sprockets **Why**: To simplify ongoing work in #5746, to avoid double-processing of SASS files, and to consolidate in preparation for future CSS bundling refactoring (cssbundling-rails). * Alphabetize
df1a527
to
43179cf
Compare
**Why**: As discovered in #5746 (e40b020), if forgery prevention is disabled (e.g. test environment), then there is no CSRF token meta tag on the page. Thus, our assumptions that this would always be present are mistaken. To avoid appending an invalid null token to relevant requests in an environment where forgery protection is disabled, we should properly handle the possibility of its absence.
Couple interop improvements here:
Also confirming that CloudFront/S3 assets are being uploaded correctly during build:
|
* Change document capture CSRF handling to optional **Why**: As discovered in #5746 (e40b020), if forgery prevention is disabled (e.g. test environment), then there is no CSRF token meta tag on the page. Thus, our assumptions that this would always be present are mistaken. To avoid appending an invalid null token to relevant requests in an environment where forgery protection is disabled, we should properly handle the possibility of its absence. * specs
89303b3
to
761f6d9
Compare
More interop with legacy Webpacker. Also, we may be building CSS in the future.
**Why**: Webpacker fell back automatically to RAILS_ENV, which is assigned in Circle configuration. Use an explicit NODE_ENV instead, and restore Webpack missing key handling behavior.
Mode can only be "production" or "development", not an arbitrary NODE_ENV value (e.g. "test")
Needed in build environments
Now outputting to nested js/ directory
By default, Webpack output uses arrow function syntax, obviously not supported in IE. Thanks es5-safe!
This is the default for jsbundling-rails, but we're outputting to public instead
Lots of places we set RAILS_ENV, leading to inconsistencies if we don't also set NODE_ENV (e.g. bin/migrate for devops build)
Would have thought this would be automatic by "mode"!
8af5bb5
to
5160075
Compare
Another quality-of-life regression with this is that running feature specs locally will assume that the latest-built JavaScript already exists, whereas previously Webpacker would integrate into the request stack to kick off a compilation if needed. I don't think this is strictly a blocker since it's a matter of running |
It would be nice if |
Yeah, that seems like a reasonable compromise for now 👍 I'll add it. Edit: See 08bfc38. |
**Why**: One of the other advantages / hopes with #5746 was a more direct path to incrementally adopting native TypeScript if we choose.
* Try: TypeScript **Why**: One of the other advantages / hopes with #5746 was a more direct path to incrementally adopting native TypeScript if we choose. * Move babel/preset-typescript to dependencies Required for production build * wip: ESLint, Mocha * Move TypeScript ESLint rules to shared configuration * Revert extends to main Simplify diff * Add test case for additional resolved Webpack extensions
After the fact, I notice that https://github.com/rails/jsbundling-rails/blob/98780f2/lib/tasks/jsbundling/build.rake#L14-L15 I assume that's not automatically invoked, but that someone could run |
Hi @aduth @mitchellhenke @zachmargolis, @tomdracz, and I have been putting a lot of effort into https://github.com/shakacode/shakapacker, the successor to webpacker. V6 addressed many of the issues of v5 and prior. In fact, upon a closer look at the PR description, #5746 (comment), I think shakapacker v6 addresses every one of your concerns. Since you guys seem to like features like HMR and code-splitting, I'm curious why the transition away from webpacker is helpful? I took a look at the code and the comments, including this follow-up PR https://github.com/18F/identity-idp/pull/5805/files It seems that you're reinventing a lot of what is already in webpacker v6, and you'd be a lot better off with shakapacker. We could work together to solve these issues that you're seeing. And we can be progressive. For example, we've even got SWC.rs support started, added in shakacode/shakapacker#29. FWIW, I've been working on webpack integration since this article I published in 2014, and I'm the creator of React on Rails. Anyway, I'm reaching out to see if you'd be interested in working with us on Shakapacker. |
Hi @justin808, thanks for reaching out. You're absolutely right to point out that a lot of what we've implemented here is reinventing the wheel. As mentioned in the original comment, we were beginning to feel held back by Webpacker v5 (Webpack v4) and, absent any alternative known to us at the time, this felt like the most viable path forward. That being said, our requirements are such that we were already hitting the limits of what we could do within Webpacker. In particular, the code that you reference here has largely existed already from when we were previously using Webpacker, originally introduced in #5223 as a way to allow us a sort of "language pack script" functionality that was only possible by reimplementing parts of the Webpacker manifest script lookup behavior. I'm glad to see Webpacker continue to live on through Shakapacker. However, speaking for myself, I'm quite happy with the result of the work here and the direct control it allows us over the build configuration. If we start to run into problems with our current approach, we’ll definitely take another look at Shakapacker. |
@aduth wrote
Anyway, I'd love to know what Webpacker limits suggest that the extra code you all added to your project is better than Shakapacker v6+. I think what you wrote applies to older versions of webpacker. The new v6+ gem:
(@tomdracz, did I miss anything?) I think you can delete a lot of the boilerplate you added and have a small webpack.config.js that uses webpack-merge and does a few simple customizations of the default and then 💥 you got what you have now and more! Now that we can quickly iterate on Shakapacker, I think it will be super-amazing super-quickly 🚀 ! |
Related: #5725
Why: To improve performance of JavaScript builds, to adopt modern defaults for Rails, and to migrate away from the now >1 year out-of-date Webpack 4 tied to the latest stable version of Webpacker (and in so doing, eliminate such version tying altogether).
Observations:
Good:
Still need to measureEdit: Replace Webpacker with jsbundling-rails + Webpack #5746 (comment)babel-loader
toswc-loader
could be a good move to further improve build performanceNot-so-good:
The Webpack build itself is reasonably fast, but the Rails side of it can be rather slow, at least on initial boot-upEdit: This was addressed by bypassing Sprockets and outputting Webpack bundles directly topublic
.Webpacker was better integrated into Rails requests and had some nice quality-of-life features we'd lose:Edit: This was addressed by runningwebpack-dev-server
in parallel to the Rails process, and loading scripts as served from this dev server.rails s
will no longer include JavaScript compilation. You'd also need to runyarn build --watch
in the backgroundNext:
A few of the included changes are things we could probably consider doing sooner than later, regardless of
jsbundling-rails
:Stop compiling SASS with WebpackEdit: This was done separately in Standardize SASS processing to Sprockets #5793@18f/identity-i18n-webpack-plugin
for Webpack 5Set
in many places where they are arrays in Webpack v4. This causes deprecation warnings. In most cases, we could cast those values to arrays ([...val]
) which would work for either a set or an array.