Conversation
node-sass 7.0.1 ships native bindings that don't run on current Node (the build failed with "Node Sass does not yet support your current environment" on Node 24), leaving the Sass build stuck on Node 17. Swap it for Dart Sass (sass) and bump sass-loader 6 -> 7 (the last line that supports webpack 3 while accepting an `implementation` option), wired via `implementation: sass` in the webpack config. Also modernize the one deprecated `darken()` call to `color.adjust()`, which produces identical output (#7f7f7f -> #666). Incidental cleanups on the touched files: fix a dead-selector typo (#disscussion-tweets) and drop a spurious executable bit on webpack.config.js, both surfaced by pre-commit hooks. npm regenerated package-lock.json into the current lockfile format as a side effect of touching dependencies on modern npm.
bin/configure-fastly.js was the only consumer of `async` (1.5.2). Rewrite its async.auto / async.forEachOf flow with native async/await and util.promisify over the callback-style fastly-extended helpers, preserving the same dependency ordering and concurrency. Remove the `async` dependency.
Node 17 was never an LTS line and is long past end-of-life; the upcoming build-tooling upgrade needs Node 18+. Point .nvmrc and the GitHub Actions workflow at Node 22 (current LTS). Also remove .travis.yml: CI moved to GitHub Actions, and the file still referenced Travis, the old LLK org, and Node 17, so it was dead and misleading.
Move the build off the end-of-life webpack 3 / Babel 6 toolchain, which was pinned in place because every loader and the Babel packages had to move together. - webpack 3 -> 5 (+ webpack-cli, which webpack 5 needs as a separate dep) - Babel 6 -> 7: @babel/core, @babel/preset-env, @babel/preset-react, babel-loader 10; object-rest-spread now comes from preset-env, so its standalone plugin is gone. babel-eslint 8 -> 10 keeps ESLint 4 working against the Babel 7 parser. - Loaders bumped for webpack 5: css-loader, style-loader, sass-loader (modern Sass API, which clears the legacy-js-api deprecation noise), postcss-loader (plugins move under postcssOptions), html-loader, html-webpack-plugin, copy-webpack-plugin, webpack-dev-middleware. - Drop file-loader and url-loader in favor of built-in asset modules (type: 'asset'), which inline assets under 8 KiB and emit larger ones as cacheable files. Drop json-loader (webpack 5 handles JSON natively) and the unused webpack-dev-server. - autoprefixer's inline `browsers` option was removed upstream; targets now live in .browserslistrc, shared with @babel/preset-env. - css/scss url() and html <img> sources: resolve fragment-relative assets, but leave root-absolute /images/... (served from static) alone. - html-webpack-plugin 5 removed htmlWebpackPlugin.files.chunks; the template now reads files.js[0], with chunks scoped per route. - Build in production mode with a root-absolute publicPath so bundles and emitted assets resolve from any route. Output verified: 13 pages build, per-route script tags resolve, small images inline while larger ones emit to /assets, and root-absolute static references stay literal. Incidental: drop a stray executable bit on dev-server/index.js, surfaced by a pre-commit hook.
The build ran in a single hardcoded production mode. Drive webpack's mode off NODE_ENV instead (defaulting to production, so any build that doesn't opt down stays deploy-safe), which also flips React's dev/prod build to match since webpack derives the bundle's process.env.NODE_ENV from mode. - dev server: defaults NODE_ENV to development for readable, source-mapped local builds. - CI: a small setup job resolves the deploy environment once and derives NODE_ENV from it, so the two travel together. Staging (develop) ships a development build for easier debugging; production (master) ships a production build. Pull-request builds run in development; production mode is still exercised by the master build before the production deploy.
Modernize the build toolchain: Dart Sass, webpack 5/Babel 7, Node 22, drop async
Replace the unmaintained fastly@2.2.0 (thisandagain) client with the official fastly@15 (fastly-js), which is promise-native and covers the full API. fastly-extended.js now wraps the per-resource API classes and keeps promise-returning, upsert-by-name helper signatures, so configure-fastly.js keeps the same behavior: the same conditions, headers, and response objects are created. Also modernized to const/let, arrow functions, and template literals. One behavior change: authenticate() fails fast at startup when the API key is unset, rather than deferring the error to the first API call.
…y-js-client build: migrate Fastly config script to the official fastly-js client
The Makefile was a task runner duplicating what npm scripts already do, with package.json scripts just delegating back to it (npm -> make -> command). Convert the targets to scripts directly and drop the Makefile. - build/clean/lint/start/test become package.json scripts - add a sync-fastly script (was the make sync-fastly target) - drop the stop/watch/dev scripts: they referenced make targets that no longer existed, and the dev server already watches via webpack-dev-middleware - point CI and the README at npm run lint / npm run build
sass-lint ./src/**/*.scss already matches the whole tree, so the separate ./src/*.scss invocation was redundant (and matches nothing, since there are no top-level src/*.scss files).
…ile-with-npm-scripts build: replace Makefile with package.json scripts
configure-fastly.js created a Fastly condition, response object, and header per route. That accumulates objects on every change and spends a synthetic status code per redirect (the live service was already carrying 900-906). Render routes.json into three snippets instead: two lookup tables plus the recv/error logic, overwritten by name on every run, with one reused internal status (700) driving every 301. Redirects and section rewrites become table lookups, so the route config stops accumulating. - routes-to-vcl.js: pure routes.json to snippet-spec generator, with a test wired into npm test / test:unit - fastly-extended.js: add setSnippet (delete-then-create, since fastly-js updateSnippet sends no body) and validateVersion; drop the now-unused condition and response-object helpers - configure-fastly.js: build and write the snippets, validate the version before activating, drop the per-route machinery and unused lodash.defaults
The origin Host header is owned by the backend's Override host setting in the Fastly service config, which cloning a version preserves. Setting it again from configure-fastly duplicated that responsibility and, with a CloudFront-fronted origin, set the wrong value (an S3 bucket name rather than a host CloudFront routes on). Drop setBucketNameHeader and the now-unused header helper; the script manages only the route snippets.
Run the Fastly configuration script as its own job in the deploy workflow, scoped to the resolved GitHub Environment so staging and production each use their own Fastly service and activation setting. Now that route config renders to a few overwritten snippets instead of accumulating per-route objects, running it on every deploy no longer piles up Fastly objects. Activation is gated per environment by the FASTLY_ACTIVATE_CHANGES variable: set it in an environment to activate and purge after configuring, leave it unset to configure and validate only.
The learn section was renamed to explore, but the live config still routed /learn to a now-missing learn page. Redirect /learn and its sub-paths to the matching /explore path (preserving the tail), plus an exact /learn.html redirect, so existing links keep working. Add a "prefix" redirect kind to the generator, rendered as a regex rewrite in recv (a table lookup can only match an exact path).
The configure-fastly job ran in parallel with the S3 upload, so with activation on it could flip Fastly to new routing before the new content was uploaded -- and this PR adds new routes. Depend on the deploy job so content lands first, and so a failed upload skips the Fastly step. FASTLY_ACTIVATE_CHANGES was a presence check, so the string "false" (or any non-empty value) still activated. Require exactly "true".
Prepend a provenance header naming bin/configure-fastly.js to each generated snippet, so it is clear in the Fastly UI that they are generated and how to regenerate them. Use the default snippet priority (100) for app-routes-recv instead of 10. It is the only generated recv snippet, so it needs no special ordering, and keeping it at the default leaves lower numbers free for manually-managed snippets that must sort ahead of it.
…-generated-snippets Configure Fastly during deploy via generated route snippets
…ratchfoundation/scratchjr-website into jessblake-west/devtechupdates
…updates new link to donate page
Merge master to develop
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed Changes
All of the updates since July 2026: