Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Three kinds of check, split by what each one can actually go wrong from.
#
# notes parses every snippet in the lesson files and resolves every relative link and image.
# Offline, seconds, so it runs on every push.
# examples installs, tests and builds each example project. This is the job that matters: every
# defect fixed in this branch was in the examples, and none of them was visible from the
# markdown. Three of the seven could not even be installed on a current npm.
# external-links fetches the outbound URLs. Scheduled monthly rather than per push, because a link to
# somebody else's site rots on a clock rather than on commits, and this repository went
# from 2020 to 2026 almost untouched: a push-triggered check would have looked on the few
# days it was edited and never in between.
#
# NODE_OPTIONS=--openssl-legacy-provider is set for the example jobs because webpack 4 hashes modules with
# md4 and OpenSSL 3 removed md4 from its default provider. Without it every webpack build here fails with
# ERR_OSSL_EVP_UNSUPPORTED before it starts. That is the era-appropriate answer for notes pinned to 2019
# tooling; upgrading webpack would fix it and would stop these being notes about the toolchain they describe.
#
# `npm install`, not `npm ci`: every example carries a yarn.lock and no package-lock.json.

name: checks

on:
push:
branches: [master]
pull_request:
schedule:
# 06:00 UTC on the first of each month.
- cron: '0 6 1 * *'
workflow_dispatch:

# Read-only. Nothing here writes anything, and the default token grants more than these need.
permissions:
contents: read

jobs:
notes:
if: github.event_name != 'schedule'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install --no-audit --no-fund
- run: npm run test:snippets
- run: npm run test:links

examples:
if: github.event_name != 'schedule'
runs-on: ubuntu-latest
strategy:
# Report every example rather than stopping at the first failure: the point is to know which ones work.
fail-fast: false
matrix:
example:
- basic-react-example-state
- basic-react-example-map-with-key
- basic-react-example-lifecycle
- basic-webpack-default
- react-redux-webpack-client
- react-redux-webpack-client-server
- react-redux-webpack-client-server-scripts
defaults:
run:
working-directory: examples/${{ matrix.example }}
env:
# webpack 4 needs md4; see the note at the top of this file.
NODE_OPTIONS: --openssl-legacy-provider
CI: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install --no-audit --no-fund
- run: npm test
- run: npm run build

external-links:
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install --no-audit --no-fund
- run: npm run test:links:external
68 changes: 65 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,64 @@ yarn-error.log*

# misc
.DS_Store
.env
.env.*

# Environment files. BOTH glob forms, because neither implies the other. `.env*`
# is a prefix glob and catches .env, .env.local and .envrc, the last of which
# direnv reads and people export credentials from. `*.env` is a suffix glob, for
# names like audit.env or production.env. This file used to list `.env` plus
# `.env.*`, and the dot is not cosmetic: `.env.*` requires a SECOND dot, so it
# never matched .envrc and nothing matched the suffix form at all.
#
# The negation re-includes the one file in this family you are meant to commit,
# and it has to come after the patterns it undoes, since the last matching rule
# wins.
.env*
*.env
!.env.example

# Credentials and secrets. None of these examples need any, which is exactly when
# an accidental commit happens.
secrets/
credentials*
*.pem
*.key

# SSH private keys, which *.pem and *.key do not cover: a key in its default
# filename has no extension at all. `id_rsa*` alone is not enough either, because
# ssh-keygen's default type is ed25519 now rather than rsa (man ssh-keygen:
# "ed25519 (the default)"). Enumerated rather than globbed as `id_*`, which would
# also match ordinary source files.
id_rsa*
id_ed25519*
id_ecdsa*
id_dsa*
*.ppk
.ssh/

# Local databases. Both sqlite spellings: the extension is a convention rather
# than a rule.
*.sqlite
*.sqlite3
*.db

# npm cache dir
.npm

# build output
build/
dist/

# Generated bundles inside the examples' public/ directories. `public/` cannot be
# ignored wholesale, because it also holds template.html, manifest.json,
# favicon.ico and an image, which are sources. These patterns are the webpack
# output that used to be committed alongside them, including the pre-compressed
# copies that express-static-gzip serves and the content-hashed CSS.
**/public/*bundle.js
**/public/*bundle.js.map
**/public/*bundle.js.gz
**/public/*bundle.js.br
**/public/*-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]*.css

# Runtime data
pids
*.pid
Expand All @@ -29,14 +76,29 @@ pids

# testing
coverage/
**/__snapshots__

# NOTE ON A RULE THAT USED TO BE HERE: `**/__snapshots__`.
#
# Jest snapshots belong in version control. With them ignored, a snapshot test
# has nothing to compare against on a fresh clone, and what it does instead
# depends on where it runs: measured on this repository's own Intro.test.js,
# jest WRITES a new snapshot and passes when it does not think it is in CI, and
# refuses to write and FAILS when it does. Neither outcome verifies anything, and
# the passing one is worse, because `toMatchSnapshot()` reads like an assertion
# while recording whatever it was handed.

# Editor and OS noise.
.idea/
.vscode/
__pycache__/

# TS v1 declarations files
typings/

# Yarn Integrity file
.yarn-integrity

# webpack bundle stats
*stats.*

*-old*
1 change: 1 addition & 0 deletions 00_2_intro_JS-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ console.log([].push)

Result:
```javascript
// check: skip the returned function on its own, shown as the result of the call above
function (arr) {
let tempArr = [...arr]
tempArr.push(element)
Expand Down
2 changes: 1 addition & 1 deletion 01_0_starting.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ You can try `React online` through any of the major JS "sandboxes" or "playgroun
```

**For production:** @16.x.x
```javascript
```html
<script src="https://unpkg.com/react@16/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js" crossorigin></script>
```
Expand Down
4 changes: 3 additions & 1 deletion 02_1_props.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ Second, install the package `uuid` and use the `version 1` (aka, timestamp). The
Before:

```javascript
// check: skip the opening tag only, shown as the "before" of a before-and-after pair
<button
onClick={() =>
this.setState({
Expand All @@ -185,6 +186,7 @@ onClick={() =>
After:

```javascript
// check: skip the "after" half of a before-and-after pair: an opening tag on its own
<button
onClick={() =>
this.setState({
Expand All @@ -200,7 +202,7 @@ After:
Third, in your `Child component` destructure the object and use `timestamp` as value for the `key`.
Now, try again checking x-checkbox and clicking on Add.

I'm attaching the entire example with all the needed code in the folder: `examples/basic-react-example[map-with-key]`
I'm attaching the entire example with all the needed code in the folder: `examples/basic-react-example-map-with-key`

_Remember_: each key should be `unique` and `static` in the `context` of x-array. This means that if we have 2 different arrays that we are mapping, we can have same key values since these "IDs" are referring to elements of different array (just a shared addresses but on different States).

Expand Down
1 change: 1 addition & 0 deletions 03_local-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class App extends Component {
</div>
);
}
}
```

**What are Template literals...?**
Expand Down
2 changes: 1 addition & 1 deletion 05_controlled-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ export default App;

Result: (check your Dev Tools Console)

```javascript
```
Object { name: "Peter", lastName: "Pan", age: "30" } App.js:18
```

Expand Down
2 changes: 0 additions & 2 deletions 07_conditional-rendering.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ render() {
</div>
);
}
}
```

**Ternary operator**
Expand Down Expand Up @@ -76,7 +75,6 @@ render() {
</div>
);
}
}
```

#### Props and Functional component
Expand Down
2 changes: 1 addition & 1 deletion 08_redux.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ export default connect(mapStateToProps, actions)(App);

Result:

```javascript
```
Comment with id 1: {"postId":1,"id":1,"name":"id labore ex et quam laborum","email":"Eliseo@gardner.biz","body":"laudantium enim quasi est quidem magnam voluptate ipsam eos\ntempora quo necessitatibus\ndolor quam autem quasi\nreiciendis et nam sapiente accusantium"}
```

Expand Down
2 changes: 1 addition & 1 deletion 09_packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class Child extends Component {
yourNumbers: PropTypes.array
}
render() {
return ...
return null; // the render body is not the point on this page
}
}
```
Expand Down
10 changes: 5 additions & 5 deletions 10_unit-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Note: `create-react-app` already ships `jest` (currently in the 23/24 series, de

We are going to create **src/tempPolyfills.js**

```javascript
```
const requestAnimationFrame = (global.requestAnimationFrame = callback => {
setTimeout(callback, 0);
});
Expand Down Expand Up @@ -305,7 +305,7 @@ describe('<App />', () => {
wrapper.update();
});

it('updates the value of `friend` state's property', () => {
it("updates the value of the `friend` state property", () => {
console.log(wrapper.state());
expect(wrapper.state().friend).toEqual(theFriend);
});
Expand All @@ -321,7 +321,7 @@ describe('<App />', () => {
wrapper.find('button').simulate('submit');
});

it('adds the new friend to `friends` state's property', () => {
it("adds the new friend to the `friends` state property", () => {
console.log(wrapper.state());
expect(wrapper.state().friends[0]).toEqual(theFriend);
});
Expand Down Expand Up @@ -421,7 +421,7 @@ describe('<App />', () => {

Result:

```javascript
```
<div>
<h1 className="title">Add your friends!</h1>
<form onSubmit={[Function]}>
Expand Down Expand Up @@ -456,7 +456,7 @@ Just replace shallow with mount.

Result:

```javascript
```
<App>
<div>
<h1 className="title">Add your friends!</h1>
Expand Down
Loading
Loading