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

Convert noteblocks for learn/tools_and_testing folder #35078

Merged
merged 3 commits into from
Jul 25, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ page-type: learn-module-chapter

It is now time to look at Google's Angular framework, another popular option that you'll come across often. In this article we look at what Angular has to offer, install the prerequisites and set up a sample app, and look at Angular's basic architecture.

> **Note:**
> [!NOTE]
> This tutorial targets [Angular version 17](https://angular.io/guide/update-to-version-17) and was last revised in March 2024 (`Angular CLI: 17.3.0`).

<table>
Expand Down Expand Up @@ -191,7 +191,8 @@ You use a selector just like regular HTML tags by placing it within other templa
When a selector is in a template, the browser renders the template of that component whenever an instance of the selector is encountered.
This tutorial guides you through creating two components and using one within the other.

> **Note:** The name of the component above is `ItemComponent` which is also the name of the class.
> [!NOTE]
> The name of the component above is `ItemComponent` which is also the name of the class.
> The names are the same simply because a component is nothing but a class supplemented by a TypeScript decorator.

Angular's component model offers strong encapsulation and an intuitive application structure.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,8 @@ When you use a property in the template, you must also declare it in the class.
An `@Input()` serves as a doorway for data to come into the component, and an `@Output()` acts as a doorway for data to go out of the component.
An `@Output()` has to be of type `EventEmitter`, so that a component can raise an event when there's data ready to share with another component.

> **Note:** The `!` in the class's property declaration is called a [definite assignment assertion](https://www.typescriptlang.org/docs/handbook/2/classes.html#--strictpropertyinitialization). This operator tells TypeScript that the `item` field is always initialized and not `undefined`, even when TypeScript cannot tell from the constructor's definition. If this operator is not included in your code and you have strict TypeScript compilation settings, the app will fail to compile.
> [!NOTE]
> The `!` in the class's property declaration is called a [definite assignment assertion](https://www.typescriptlang.org/docs/handbook/2/classes.html#--strictpropertyinitialization). This operator tells TypeScript that the `item` field is always initialized and not `undefined`, even when TypeScript cannot tell from the constructor's definition. If this operator is not included in your code and you have strict TypeScript compilation settings, the app will fail to compile.

Use `@Input()` to specify that the value of a property can come from outside of the component.
Use `@Output()` in conjunction with `EventEmitter` to specify that the value of a property can leave the component so that another component can receive that data.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ If everything is working correctly, you should see a page like this:

![The default start page when you create a new Ember app, with a cartoon mascot, saying congratulations](ember-start-page.png)

> **Note:** on Windows systems without [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/windows/wsl/install), you will experience slower build-times overall compared to macOS, Linux, and Windows _with_ WSL.
> [!NOTE]
> on Windows systems without [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/windows/wsl/install), you will experience slower build-times overall compared to macOS, Linux, and Windows _with_ WSL.

## Summary

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ export default class HeaderComponent extends Component {

The `@action` decorator is the only Ember-specific code here (aside from extending from the `Component` superclass, and the Ember-specific items we are importing using [JavaScript module syntax](/en-US/docs/Web/JavaScript/Guide/Modules)) — the rest of the file is vanilla JavaScript, and would work in any application. The `@action` decorator declares that the function is an "action", meaning it's a type of function that will be invoked from an event that occurred in the template. `@action` also binds the `this` of the function to the class instance.

> **Note:** A decorator is basically a wrapper function, which wraps and calls other functions or properties, providing additional functionality along the way. For example, the `@tracked` decorator (see slightly later on) runs code it is applied to, but additionally tracks it and automatically updates the app when values change. [Read JavaScript Decorators: What They Are and When to Use Them](https://www.sitepoint.com/javascript-decorators-what-they-are/) for more general information on decorators.
> [!NOTE]
> A decorator is basically a wrapper function, which wraps and calls other functions or properties, providing additional functionality along the way. For example, the `@tracked` decorator (see slightly later on) runs code it is applied to, but additionally tracks it and automatically updates the app when values change. [Read JavaScript Decorators: What They Are and When to Use Them](https://www.sitepoint.com/javascript-decorators-what-they-are/) for more general information on decorators.

Coming back to our browser tab with the app running, we can type whatever we want, and when we hit <kbd>Enter</kbd> we'll be greeted with an alert message telling us exactly what we typed.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ To create a component, we use the `ember generate component` command, followed b

`header.hbs` is the template file where we'll include the HTML structure for just that component. Later on we'll add the required dynamic functionality such as data bindings, responding to user interaction, etc.

> **Note:** The `header.js` file (shown as skipped) is for connection to a backing Glimmer Component Class, which we don't need for now, as they are for adding interactivity and state manipulation. By default, `generate component` generates template-only components, because in large applications, template-only components end up being the majority of the components.
> [!NOTE]
> The `header.js` file (shown as skipped) is for connection to a backing Glimmer Component Class, which we don't need for now, as they are for adding interactivity and state manipulation. By default, `generate component` generates template-only components, because in large applications, template-only components end up being the majority of the components.

`header-test.js` is for writing automated tests to ensure that our app continues to work over time as we upgrade, add features, refactor, etc. Testing is outside the scope of this tutorial, although generally testing should be implemented as you develop, rather than after, otherwise it tends to be forgotten about. If you're curious about testing, or why you would want to have automated tests, check out the [official Ember tutorial on testing](https://guides.emberjs.com/release/tutorial/part-1/automated-testing/).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ Your code will be richer and more professional as a result, and you'll be able t

## React tutorials

> **Note:** React tutorials last tested in January 2023, with React/ReactDOM 18.2.0 and create-react-app 5.0.1.
> [!NOTE]
> React tutorials last tested in January 2023, with React/ReactDOM 18.2.0 and create-react-app 5.0.1.
>
> If you need to check your code against our version, you can find a finished version of the sample React app code in our [todo-react repository](https://github.com/mdn/todo-react). For a running live version, see <https://mdn.github.io/todo-react/>.

Expand All @@ -57,7 +58,8 @@ Your code will be richer and more professional as a result, and you'll be able t

## Ember tutorials

> **Note:** Ember tutorials last tested in May 2020, with Ember/Ember CLI version 3.18.0.
> [!NOTE]
> Ember tutorials last tested in May 2020, with Ember/Ember CLI version 3.18.0.
>
> If you need to check your code against our version, you can find a finished version of the sample Ember app code in the [ember-todomvc-tutorial repository](https://github.com/NullVoxPopuli/ember-todomvc-tutorial/tree/master/steps/00-finished-todomvc/todomvc). For a running live version, see <https://nullvoxpopuli.github.io/ember-todomvc-tutorial/> (this also includes a few additional features not covered in the tutorial).

Expand All @@ -76,7 +78,8 @@ Your code will be richer and more professional as a result, and you'll be able t

## Vue tutorials

> **Note:** Vue tutorial last tested in January 2023, with Vue 3.2.45.
> [!NOTE]
> Vue tutorial last tested in January 2023, with Vue 3.2.45.
>
> If you need to check your code against our version, you can find a finished version of the sample Vue app code in our [todo-vue repository](https://github.com/mdn/todo-vue). For a running live version, see <https://mdn.github.io/todo-vue/>.

Expand All @@ -101,7 +104,8 @@ Your code will be richer and more professional as a result, and you'll be able t

## Svelte tutorials

> **Note:** Svelte tutorials last tested in August 2020, with Svelte 3.24.1.
> [!NOTE]
> Svelte tutorials last tested in August 2020, with Svelte 3.24.1.
>
> If you need to check your code against our version, you can find a finished version of the sample Svelte app code as it should be after each article, in our [mdn-svelte-tutorial](https://github.com/opensas/mdn-svelte-tutorial) repo. For a running live version, see our Svelte REPL at <https://svelte.dev/repl/378dd79e0dfe4486a8f10823f3813190?version=3.23.2>.

Expand All @@ -124,7 +128,8 @@ Your code will be richer and more professional as a result, and you'll be able t

## Angular tutorials

> **Note:** Angular tutorials last tested in April 2021, with Angular CLI (NG) 11.2.5.
> [!NOTE]
> Angular tutorials last tested in April 2021, with Angular CLI (NG) 11.2.5.

- [1. Getting started with Angular](/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_getting_started)
- : In this article we look at what Angular has to offer, install the prerequisites and set up a sample app, and look at Angular's basic architecture.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ Let's look at some of the other advantages offered by frameworks. As we've allud

Because each of the frameworks in this module have a large, active community, each framework's ecosystem provides tooling that improves the developer experience. These tools make it easy to add things like testing (to ensure that your application behaves as it should) or linting (to ensure that your code is error-free and stylistically consistent).

> **Note:** If you want to find out more details about web tooling concepts, check out our [Client-side tooling overview](/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview).
> [!NOTE]
> If you want to find out more details about web tooling concepts, check out our [Client-side tooling overview](/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview).

### Compartmentalization

Expand Down Expand Up @@ -262,7 +263,8 @@ You should seriously consider the support matrix and DSLs of a framework when ma
| Vue | Modern (IE9+ in Vue 2) | HTML-based | HTML-based, JSX, Pug | [official docs](https://cli.vuejs.org/guide/browser-compatibility.html) |
| Ember | Modern (IE9+ in Ember version 2.18) | Handlebars | Handlebars, TypeScript | [official docs](https://guides.emberjs.com/v3.3.0/templates/handlebars-basics/) |

> **Note:** DSLs we've described as "HTML-based" do not have official names. They are not really true DSLs, but they are non-standard HTML, so we believe they are worth highlighting.
> [!NOTE]
> DSLs we've described as "HTML-based" do not have official names. They are not really true DSLs, but they are non-standard HTML, so we believe they are worth highlighting.

### Does the framework have a strong community?

Expand Down Expand Up @@ -296,7 +298,8 @@ A few popular CMS systems include [Wordpress](https://wordpress.com/), [Joomla](

All of the frameworks covered in this module support server-side rendering as well as client-side rendering. Check out [Next.js](https://nextjs.org/) for React, [Nuxt](https://nuxt.com/) for Vue (yes, it is confusing, and no, these projects are not related!), [FastBoot](https://github.com/ember-fastboot/ember-cli-fastboot) for Ember, and [Angular Universal](https://angular.io/guide/universal) for Angular.

> **Note:** Some SSR solutions are written and maintained by the community, whereas some are "official" solutions provided by the framework's maintainer.
> [!NOTE]
> Some SSR solutions are written and maintained by the community, whereas some are "official" solutions provided by the framework's maintainer.

### Static site generators

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ console.log(editButtonRef.current);

You'll see that the value of `editButtonRef.current` is `null` when the component first renders, but if you click an "Edit" button, it will log the `<input>` element to the console. This is because the ref is populated only after the component renders, and clicking the "Edit" button causes the component to re-render. Be sure to delete this log before moving on.

> **Note:** Your logs will appear 6 times because we have 3 instances of `<Todo />` in our app and React renders our components twice in development.
> [!NOTE]
> Your logs will appear 6 times because we have 3 instances of `<Todo />` in our app and React renders our components twice in development.

We're getting closer! To take advantage of our newly referenced elements, we need to use another React hook: `useEffect()`.

Expand Down Expand Up @@ -297,7 +298,8 @@ Let's add the `tabindex` attribute — written as `tabIndex` in JSX — to the h
</h2>
```

> **Note:** The `tabindex` attribute is excellent for accessibility edge cases, but you should take **great care** not to overuse it. Only apply a `tabindex` to an element when you're sure that making it focusable will benefit your user somehow. In most cases, you should utilize elements that can naturally take focus, such as buttons, anchors, and inputs. Irresponsible usage of `tabindex` could have a profoundly negative impact on keyboard and screen reader users!
> [!NOTE]
> The `tabindex` attribute is excellent for accessibility edge cases, but you should take **great care** not to overuse it. Only apply a `tabindex` to an element when you're sure that making it focusable will benefit your user somehow. In most cases, you should utilize elements that can naturally take focus, such as buttons, anchors, and inputs. Irresponsible usage of `tabindex` could have a profoundly negative impact on keyboard and screen reader users!

### Getting previous state

Expand All @@ -321,7 +323,8 @@ const prevTaskLength = usePrevious(tasks.length);

Here we are invoking `usePrevious()` to track the previous length of the tasks array.

> **Note:** Since we're now utilizing `usePrevious()` in two files, it might be more efficient to move the `usePrevious()` function into its own file, export it from that file, and import it where you need it. Try doing this as an exercise once you've got to the end.
> [!NOTE]
> Since we're now utilizing `usePrevious()` in two files, it might be more efficient to move the `usePrevious()` function into its own file, export it from that file, and import it where you need it. Try doing this as an exercise once you've got to the end.

### Using `useEffect()` to control our heading focus

Expand Down Expand Up @@ -349,7 +352,8 @@ Most of the time, you can be an effective contributor to a React project even if

`useRef()` and `useEffect()` are somewhat advanced features, and you should be proud of yourself for using them! Look out for opportunities to practice them more, because doing so will allow you to create inclusive experiences for users. Remember: our app would have been inaccessible to keyboard users without them!

> **Note:** If you need to check your code against our version, you can find a finished version of the sample React app code in our [todo-react repository](https://github.com/mdn/todo-react). For a running live version, see <https://mdn.github.io/todo-react>.
> [!NOTE]
> If you need to check your code against our version, you can find a finished version of the sample React app code in our [todo-react repository](https://github.com/mdn/todo-react). For a running live version, see <https://mdn.github.io/todo-react>.

In the very last article we'll present you with a list of React resources that you can use to go further in your learning.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ We had unique `id` attributes before we created the `<Todo />` component. Let's
<Todo name="Repeat" id="todo-2" />
```

> **Note:** The `completed` prop is last here because it is a boolean with no assignment. This is purely a stylistic convention. The order of props does not matter because props are JavaScript objects, and JavaScript objects are unordered.
> [!NOTE]
> The `completed` prop is last here because it is a boolean with no assignment. This is purely a stylistic convention. The order of props does not matter because props are JavaScript objects, and JavaScript objects are unordered.

Now go back to `Todo.jsx` and make use of the `id` prop. It needs to replace the `<input />` element's `id` attribute value, as well as its `<label>`'s `htmlFor` attribute value:

Expand Down Expand Up @@ -243,7 +244,8 @@ const DATA = [
];
```

> **Note:** If your text editor has an [ESLint](https://eslint.org/) plugin, you may see a warning on this `DATA` const. This warning comes from the ESLint configuration supplied by the Vite template we used, and it doesn't apply to this code. You can safely suppress the warning by adding `// eslint-disable-next-line` to the line above the `DATA` const.
> [!NOTE]
> If your text editor has an [ESLint](https://eslint.org/) plugin, you may see a warning on this `DATA` const. This warning comes from the ESLint configuration supplied by the Vite template we used, and it doesn't apply to this code. You can safely suppress the warning by adding `// eslint-disable-next-line` to the line above the `DATA` const.

Next, we'll pass `DATA` to `<App />` as a prop, called `tasks`. Update your `<App />` component call inside `src/main.jsx` to read like this:

Expand Down Expand Up @@ -383,7 +385,8 @@ function FilterButton() {
export default FilterButton;
```

> **Note:** You might notice that we are making the same mistake here as we first made for the `<Todo />` component, in that each button will be the same. That's fine! We're going to fix up this component later on, in [Back to the filter buttons](/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_filtering_conditional_rendering#back_to_the_filter_buttons).
> [!NOTE]
> You might notice that we are making the same mistake here as we first made for the `<Todo />` component, in that each button will be the same. That's fine! We're going to fix up this component later on, in [Back to the filter buttons](/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_filtering_conditional_rendering#back_to_the_filter_buttons).

## Importing all our components

Expand Down
Loading