Skip to content

Era-correctness pass: make snippets run on pinned versions - #184

Merged
alpersonalwebsite merged 1 commit into
masterfrom
era-correctness-pass
May 11, 2026
Merged

Era-correctness pass: make snippets run on pinned versions#184
alpersonalwebsite merged 1 commit into
masterfrom
era-correctness-pass

Conversation

@alpersonalwebsite

@alpersonalwebsite alpersonalwebsite commented May 11, 2026

Copy link
Copy Markdown
Owner

Summary

The repo's lessons are intentionally pinned to React 16.6-16.8 / React Router v5 / Enzyme 3 / webpack 4 / Babel 7 / CRA 3 (per examples/*/package.json). This PR keeps that era — no React 18, no RTL, no React Router v6, no Redux Toolkit, no Vite — but fixes the snippets that don't actually run against those pinned versions.

Genuine era bugs (would fail on a fresh install of the pinned versions)

  • clean-webpack-plugin v3 API. Lesson used the v2 positional API (new CleanWebpackPlugin(pathsToClean, cleanOptions)) but examples pin ^3.0.0. v3 dropped positional args and switched to a named import + single options object with cleanOnceBeforeBuildPatterns. As written, the lesson's call silently did nothing.
  • webpack-dev-middleware misconfigured. Both call sites passed config.devServer (contentBase/hot/overlay — those are webpack-dev-server options, not wdm's). wdm v3 expects publicPath/stats/mimeTypes and silently ignored the wrong block. Replaced with the correct options.
  • webpack-hot-middleware was also being passed config.devServer. Same issue; switched to defaults (whm's real options are path/log/heartbeat).
  • css-loader deprecated query: key. All 4 occurrences used query: which css-loader v3 (pinned) accepts only with a deprecation warning. Renamed to options: and updated the modules/localIdentName shape to v3's nested form (modules: { localIdentName: '…' }).
  • Babel package list mismatch. The bulleted list was Babel-6 names (babel-core, babel-preset-env, etc.) while the install command below it used Babel-7 namespaces (@babel/core, @babel/preset-env, etc.). Aligned the list to the actual command and added @babel/plugin-proposal-class-properties.
  • express-static-gzip option mismatch. The lesson used orderPreference: ['br'] but the example pins ^1.1.3, and that option was only added in v2.0.0. v1.x silently ignored it. Removed the explicit ordering and explained v1's default Brotli-preferred fallback chain.
  • 10_unit-tests.md Jest pin. Lesson installed jest-cli@20.0.4 and claimed "react-scripts is locked at 20.0.4". Wrong even at the time — CRA 2 shipped Jest 23, CRA 3 (which the examples pin) shipped Jest 24. Removed the pin and the misleading note; lesson now installs just enzyme + enzyme-adapter-react-16.
  • 08_redux.md redux-thunk transition.
    • The transition section used reduxThunk without ever showing import reduxThunk from 'redux-thunk';.
    • Reducer change was described as "replace return [...state, ...action.payload];" which never matched the current reducer body. Rewrote so it's clear what the prior body was (_.mapKeys(action.payload.data, 'id') under redux-promise) and why the .data hop disappears (the thunk dispatches payload: response.data directly).
    • Removed an obsolete TODO that said "explain Object.assign" by explaining it inline.
  • 09_packages.md Axios snippet. Made it explicit that the snippet's reducer reading action.payload.data only works because redux-promise is applied to the store; without that middleware, payload arrives as an unresolved Promise. Also added a javascript language tag to the previously bare ``` fence (markdownlint MD040).
  • 05_controlled-components.md Debounce snippet. Added the missing import { Debounce } from 'react-throttle';, changed time="400" to the documented numeric time={400}, and clarified that removing value=… makes the input uncontrolled while Debounce manages when onChange fires.

Out of scope (era choice, per the existing pin policy)

  • React 18 / createRoot and React 19
  • Hooks-first rewrite (class components remain primary)
  • React Router v6 (Switch/Route component= left intact)
  • Redux Toolkit / createAsyncThunk / RTK Query
  • React Testing Library replacing Enzyme
  • Vite / Next replacing CRA
  • IE 9/10/11 in browserslist
  • @babel/polyfill deprecated in 7.4 (works in the 7.0-7.2 era pinned)
  • CDN UMD pins to react@16

Test plan

  • Read each modified snippet and confirm the rewritten code matches the pinned versions in examples/*/package.json.
  • Diff 11_webpack.md against itself: clean-webpack-plugin, webpack-dev-middleware, webpack-hot-middleware, css-loader (×4), express-static-gzip, Babel package list.
  • Verify the Redux flow in 08_redux.md still chains correctly end-to-end: action types → action creators → reducer → store wiring → connected App.js. Both the redux-promise and redux-thunk phases.
  • Verify the Axios snippet in 09_packages.md reads with the new "redux-promise required" note.
  • Confirm the react-throttle snippet now includes the Debounce import and numeric time prop.

Summary by CodeRabbit

  • Documentation
    • Updated Controlled Components guidance with clearer debounce configuration examples.
    • Switched Redux async setup documentation from redux-promise to redux-thunk with updated middleware configuration.
    • Clarified package integration patterns for React Router and Axios.
    • Simplified unit testing setup instructions by removing unnecessary Jest CLI steps.
    • Modernized Webpack configuration examples to reflect current package APIs and dependencies.

Review Change Stack

… versions

The repo targets React 16.6-16.8 / RR v5 / Enzyme 3 / webpack 4 / Babel 7 /
CRA 3 (per examples/*/package.json). This pass keeps that era but fixes the
snippets that don't actually work against those pinned versions.

11_webpack.md
- clean-webpack-plugin: lesson used the v2 positional API
  (`new CleanWebpackPlugin(pathsToClean, cleanOptions)`) but examples pin
  ^3.0.0. v3 dropped that signature in favor of a single options object
  with `cleanOnceBeforeBuildPatterns` and made the export named.
  Rewrote to: `const { CleanWebpackPlugin } = require('clean-webpack-plugin')`
  + `new CleanWebpackPlugin({ cleanOnceBeforeBuildPatterns: ['**/*',
    '!template.html', '!manifest.json', '!favicon.ico'], ... })`.
- webpack-dev-middleware: both `require('webpack-dev-middleware')(compiler,
  config.devServer)` calls were passing webpack-dev-server's `devServer`
  block (contentBase/hot/overlay) where wdm v3 expects its own options
  (publicPath/stats/mimeTypes). Silently ignored. Replaced with
  `{ publicPath: config.output.publicPath || '/', stats: 'minimal' }`.
- webpack-hot-middleware: was being passed `config.devServer` too; now
  invoked with default options (whm reads `path`/`log`/`heartbeat`, not
  devServer).
- css-loader: all 4 occurrences used the deprecated `query:` key. css-loader
  v3 (pinned in examples) expects `options:`; `query:` triggers a warning.
  Also updated the `modules`/`localIdentName` shape to css-loader v3's
  nested form (`modules: { localIdentName: ... }`).
- Babel package list: the bulleted list was Babel-6 names
  (`babel-core`/`babel-preset-env`/etc.) while the install command below
  used Babel-7 namespaces (`@babel/core`/`@babel/preset-env`/etc.).
  Aligned the list to match the actual command and added
  `@babel/plugin-proposal-class-properties` which the command installs.
- express-static-gzip: the v1.1.x pin doesn't support `orderPreference`
  (that option was added in v2). Removed the explicit ordering and let
  v1's default behavior serve `.br` when the client accepts it, with a
  short explanation of the fallback chain.

10_unit-tests.md
- Removed the `jest-cli@20.0.4` pin and the misleading "react-scripts is
  locked at 20.0.4" note. CRA 2 shipped Jest 23, CRA 3 ships Jest 24
  (which is what examples/*/package.json pin). The lesson now installs
  only `enzyme` + `enzyme-adapter-react-16`.

08_redux.md
- Reworked the redux-promise → redux-thunk transition section. Added the
  missing `import reduxThunk from 'redux-thunk';` and the install command
  (the lesson was using `reduxThunk` without ever importing it).
- Made the reducer transition explicit: under redux-promise the reducer
  read `action.payload.data`; with the new thunk dispatching
  `payload: response.data` directly, the reducer drops the `.data` hop
  to become `_.mapKeys(action.payload, 'id')`. Replaced the stale
  "replace `return [...state, ...action.payload];`" wording (which never
  matched the current reducer body).
- Removed the obsolete TODO comment about explaining Object.assign by
  actually explaining it inline.

09_packages.md
- Axios action-creator example: clarified that the snippet only works
  with `redux-promise` applied to the store — without it,
  `action.payload.data` would be undefined because payload is still an
  unresolved Promise. Removed the modernization heads-up about Redux
  Toolkit (we're keeping the era).
- Added a `javascript` language tag to the previously bare ```` ``` ````
  fence opening the router example (markdownlint MD040).

05_controlled-components.md
- react-throttle: added the missing `import { Debounce } from 'react-throttle';`,
  changed `time="400"` to `time={400}` to match the documented numeric
  prop, and clarified that the input becomes uncontrolled while Debounce
  manages when onChange fires.
@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Five React tutorial lesson files are updated to modernize package versions and API usage. Debounce setup is clarified, jest-cli is removed from testing deps, Redux async handling switches to thunk, and Webpack examples update Babel scopes, clean-plugin v3, middleware options, and CSS loader configuration.

Changes

Component Input & Testing Modernization

Layer / File(s) Summary
Controlled Components Debounce Setup
05_controlled-components.md
react-throttle setup adds explicit Debounce named-import instruction and clarifies that input becomes uncontrolled while Debounce gates onChange. The time prop changes from string "400" to number {400}.
Jest & Enzyme Testing Configuration
10_unit-tests.md
Unit test installation removes jest-cli pinning. Documentation is updated to state that Create React App includes Jest internally and manual jest-cli installation is unnecessary.

Redux Async Middleware Migration

Layer / File(s) Summary
Redux Thunk Middleware Installation & Wiring
08_redux.md
redux-thunk is installed as a dependency and wired into src/index.js createStore middleware, replacing prior redux-promise configuration.
Redux Thunk Reducer Action Handling
08_redux.md
Reducer normalization is updated to read from action.payload (not action.payload.data) and merge results into existing state via Object.assign, matching thunk dispatch behavior.
Redux Promise & Async Integration Documentation
09_packages.md
React Router example code fence is adjusted for proper formatting. Axios section explanation is rewritten to describe how redux-promise middleware intercepts Promise payloads, waits for resolution, and dispatches a new action with resolved payload.

Webpack & Build Configuration Modernization

Layer / File(s) Summary
Babel Ecosystem Modernization
11_webpack.md
Babel dependencies are updated from legacy babel-* packages to scoped @babel/* equivalents (@babel/core, @babel/preset-react, @babel/plugin-proposal-class-properties).
Clean Webpack Plugin v3 Configuration
11_webpack.md
Plugin configuration is modernized from old root/exclude API to named import and options-based cleanOnceBeforeBuildPatterns that preserves template.html, manifest.json, and favicon.ico.
Dev Middleware Options Configuration
11_webpack.md
Express server middleware for webpack-dev-middleware and webpack-hot-middleware is refactored to accept middleware-specific options objects (with publicPath derived from config.output.publicPath) instead of reusing config.devServer.
CSS Loader Configuration Structure Update
11_webpack.md
CSS loader examples are refactored from query.modules: true to options.modules.localIdentName configuration structure across dev, prod, and shared config snippets.
Express Static Gzip Options Update
11_webpack.md
Express static gzip middleware removes explicit Brotli orderPreference configuration while maintaining enableBrotli: true.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • alpersonalwebsite/react#183: Both PRs modify the same lesson documents with overlapping edits including debounce guidance and redux-promise to redux-thunk migration.

Poem

🐰 Hopping through the docs with bundler cheer,
From babel's old ways to new fronts clear,
Redux thunks now flow where promises stood,
CSS modules dressed in options so good,
Tests run without jest-cli to bind,
Modern React lessons, polished and refined!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Era-correctness pass: make snippets run on pinned versions' accurately reflects the main objective of the PR: updating lesson snippets across multiple files to work correctly with the repository's pinned dependency versions (React 16, webpack 4, Babel 7, etc.).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch era-correctness-pass

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
10_unit-tests.md (1)

30-30: 💤 Low value

Correct guidance! Successfully removes the incorrect jest-cli pin.

The note correctly advises against installing jest-cli and explains that CRA's bundled Jest is sufficient. This aligns with the PR objective to remove incorrect jest-cli@20.0.4 guidance.

Optional precision improvement: Since the repository targets CRA 3 specifically (per PR objectives), you could tighten "currently in the 23/24 series, depending on your CRA version" to "currently Jest 24 in CRA 3" for era-specific accuracy. However, the current phrasing acknowledges variation across CRA versions, which may be intentional.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@10_unit-tests.md` at line 30, Update the guidance in the note about CRA's
bundled Jest to be more specific for this repo: replace the phrase "currently in
the 23/24 series, depending on your CRA version" with "currently Jest 24 in CRA
3" so the note accurately reflects that this repository targets CRA 3 and
therefore ships Jest 24; keep the rest of the sentence about not installing
jest-cli and not pinning jest-cli@20.0.4 intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@08_redux.md`:
- Around line 849-851: The fenced code block containing the npm install command
("npm install --save redux-thunk") lacks a language identifier; update that
fence to include a shell language (e.g., change the opening fence to ```bash or
```shell) so the block becomes ```bash followed by the command and the closing
``` to satisfy MD040 and enable proper syntax highlighting.

In `@11_webpack.md`:
- Around line 427-429: Replace the deprecated presets listed
(`@babel/preset-es2015`, `@babel/preset-stage-2`) with Babel 7-compatible
packages: use `@babel/preset-env` instead of `@babel/preset-es2015`, and remove
`@babel/preset-stage-2` and add the specific proposal plugins you need (for
example `@babel/plugin-proposal-class-properties` for class fields); also update
any install commands to install `@babel/preset-env` and the chosen
`@babel/plugin-proposal-*` plugins instead of the removed presets.

---

Nitpick comments:
In `@10_unit-tests.md`:
- Line 30: Update the guidance in the note about CRA's bundled Jest to be more
specific for this repo: replace the phrase "currently in the 23/24 series,
depending on your CRA version" with "currently Jest 24 in CRA 3" so the note
accurately reflects that this repository targets CRA 3 and therefore ships Jest
24; keep the rest of the sentence about not installing jest-cli and not pinning
jest-cli@20.0.4 intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: deea6dc3-3583-42da-8a3d-81fa672676d1

📥 Commits

Reviewing files that changed from the base of the PR and between 7d0aeae and c56297c.

📒 Files selected for processing (5)
  • 05_controlled-components.md
  • 08_redux.md
  • 09_packages.md
  • 10_unit-tests.md
  • 11_webpack.md

Comment thread 08_redux.md
Comment on lines +849 to +851
```
npm install --save redux-thunk
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add language identifier to code fence.

The npm install command block should specify bash or shell as the language identifier for proper syntax highlighting and to satisfy markdown linters.

📝 Proposed fix
-```
+```bash
 npm install --save redux-thunk
</details>

As per coding guidelines, the static analysis tool flagged: "Fenced code blocks should have a language specified (MD040, fenced-code-language)".

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.22.1)</summary>

[warning] 849-849: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @08_redux.md around lines 849 - 851, The fenced code block containing the npm
install command ("npm install --save redux-thunk") lacks a language identifier;
update that fence to include a shell language (e.g., change the opening fence to
bash or shell) so the block becomes bash followed by the command and the closing to satisfy MD040 and enable proper syntax highlighting.


</details>

<!-- fingerprinting:phantom:triton:puma -->

<!-- d98c2f50 -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment thread 11_webpack.md
Comment on lines +427 to +429
* @babel/preset-es2015
* @babel/preset-react
* @babel/preset-stage-2

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚖️ Poor tradeoff

🧩 Analysis chain

🌐 Web query:

Are @babel/preset-es2015and@babel/preset-stage-2 valid packages in Babel 7?

💡 Result:

Yes for “are they valid packages to install and reference”, but no for the intent of Babel 7 compatibility: both presets are deprecated/removed in Babel 7’s recommended preset set. 1) @babel/preset-es2015 - Babel’s docs recommend using @babel/preset-env instead of the old yearly preset approach; Babel notes that if you see a preset like babel-preset-es2015 you should migrate to preset-env. [1] - Babel also has documentation pages for @babel/preset-es2015, indicating the preset package name exists and is documented. [2] - However, the “yearly presets” were deprecated in Babel 6, and the recommended replacement for Babel 7 is @babel/preset-env. [1][3] 2) @babel/preset-stage-2 - Babel’s docs state that as of Babel 7, all the “stage” presets are deprecated. [4] - Babel’s presets documentation similarly says Stage-X (experimental) presets were deprecated and stopped publishing in Babel 7; it recommends specifying proposals as plugins rather than using a catch-all preset. [5] - Babel’s migration guidance also states “We are removing the stage presets in favor of explicit proposal usage.” [3] Practical takeaway - @babel/preset-es2015 is not the recommended choice in Babel 7 (migrate to @babel/preset-env). [1][3] - @babel/preset-stage-2 is deprecated and should not be relied on in Babel 7; migrate by using the specific proposal plugins instead. [4][5][3] If you tell me your current Babel config and intended target environments, I can suggest an equivalent Babel 7 config.

Citations:


Replace deprecated Babel presets for Babel 7 compatibility.

Lines 427–429 list @babel/preset-es2015 and @babel/preset-stage-2, both of which are deprecated and removed in Babel 7. Per Babel's official migration docs:

  • @babel/preset-es2015 should be replaced with @babel/preset-env
  • @babel/preset-stage-2 was removed entirely; use explicit proposal plugins instead (e.g., @babel/plugin-proposal-class-properties for class properties)

Update the snippet and install command to reflect the correct packages for Babel 7.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@11_webpack.md` around lines 427 - 429, Replace the deprecated presets listed
(`@babel/preset-es2015`, `@babel/preset-stage-2`) with Babel 7-compatible
packages: use `@babel/preset-env` instead of `@babel/preset-es2015`, and remove
`@babel/preset-stage-2` and add the specific proposal plugins you need (for
example `@babel/plugin-proposal-class-properties` for class fields); also update
any install commands to install `@babel/preset-env` and the chosen
`@babel/plugin-proposal-*` plugins instead of the removed presets.

@alpersonalwebsite
alpersonalwebsite merged commit 8479a83 into master May 11, 2026
2 checks passed
@alpersonalwebsite
alpersonalwebsite deleted the era-correctness-pass branch May 11, 2026 03:37
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.

1 participant