Correct a bunch of incorrect/outdated references (#2457)

- Babel 7 has a whole different module API
- Traceur is basically dead
- JSX != HTML
- Some bits are just obvious from context what they are
- ES6 docs shouldn't be auto-installing JSX support
- Also, I decided it was worth clearing up some misleading docs in
  surrounding areas.
This commit is contained in:
Isiah Meadows 2019-07-06 03:41:01 -04:00 committed by GitHub
parent 76e8eaab5e
commit a23bcea7ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 95 additions and 98 deletions

View file

@ -24,19 +24,14 @@ If you want to use Webpack and Babel together, [skip to the section below](#usin
To install Babel as a standalone tool, use this command:
```bash
npm install babel-cli babel-preset-es2015 babel-plugin-transform-react-jsx --save-dev
npm install @babel/cli @babel/preset-env --save-dev
```
Create a `.babelrc` file:
```json
{
"presets": ["es2015"],
"plugins": [
["transform-react-jsx", {
"pragma": "m"
}]
]
"presets": ["@babel/preset-env"]
}
```
@ -51,19 +46,14 @@ babel src --out-dir bin --source-maps
If you're already using Webpack as a bundler, you can integrate Babel to Webpack by following these steps.
```bash
npm install babel-core babel-loader babel-preset-es2015 babel-plugin-transform-react-jsx --save-dev
npm install @babel/core babel-loader @babel/preset-env --save-dev
```
Create a `.babelrc` file:
```json
{
"presets": ["es2015"],
"plugins": [
["transform-react-jsx", {
"pragma": "m"
}]
]
"presets": ["@babel/preset-env"]
}
```
@ -81,7 +71,7 @@ module.exports = {
module: {
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
exclude: /\/node_modules\//,
loader: 'babel-loader'
}]
}

View file

@ -25,15 +25,15 @@
Represents an HTML element in a Mithril view
```javascript
m("div", {class: "foo"}, "hello")
// represents <div class="foo">hello</div>
m("div.foo", {style: {color: "red"}}, "hello")
// renders to this HTML:
// <div class="foo" style="color: red">hello</div>
```
You can also [use HTML syntax](https://babeljs.io/repl/#?code=%2F**%20%40jsx%20m%20*%2F%0A%3Ch1%3EMy%20first%20app%3C%2Fh1%3E) via a Babel plugin.
You can also use an HTML-like syntax called [JSX](jsx.md), using Babel to convert it to equivalent hyperscript calls. This is equivalent to the above.
```markup
/** jsx m */
<div class="foo">hello</div>
```jsx
<div class="foo" style="color: red">hello</div>
```
---
@ -60,7 +60,7 @@ Mithril provides a hyperscript function `m()`, which allows expressing any HTML
```javascript
m("div", {id: "box"}, "hello")
// equivalent HTML:
// renders to this HTML:
// <div id="box">hello</div>
```
@ -141,7 +141,7 @@ m("a.link[href=/]", {
class: currentURL === "/" ? "selected" : ""
}, "Home")
// equivalent HTML:
// renders to this HTML:
// <a href="/" class="link selected">Home</a>
```
@ -335,7 +335,7 @@ var Greeter = {
// consume it
m(Greeter, {style: "color:red;"}, "world")
// equivalent HTML:
// renders to this HTML:
// <div style="color:red;">Hello world</div>
```

View file

@ -113,7 +113,7 @@ m.render(document.body, "hello world")
Modularization is the practice of separating the code into files. Doing so makes it easier to find code, understand what code relies on what code, and test.
CommonJS is a de-facto standard for modularizing JavaScript code, and it's used by Node.js, as well as tools like [Browserify](http://browserify.org/) and [Webpack](https://webpack.js.org/). It's a robust, battle-tested precursor to ES6 modules. Although the syntax for ES6 modules is specified in Ecmascript 6, the actual module loading mechanism is not. If you wish to use ES6 modules despite the non-standardized status of module loading, you can use tools like [Rollup](http://rollupjs.org/), [Babel](https://babeljs.io/) or [Traceur](https://github.com/google/traceur-compiler).
CommonJS is a de-facto standard for modularizing JavaScript code, and it's used by Node.js, as well as tools like [Browserify](http://browserify.org/) and [Webpack](https://webpack.js.org/). It's a robust, battle-tested precursor to ES6 modules. Although the syntax for ES6 modules is specified in Ecmascript 6, the actual module loading mechanism is not. If you wish to use ES6 modules despite the non-standardized status of module loading, you can use tools like [Rollup](http://rollupjs.org/) or [Babel](https://babeljs.io/).
Most browser today do not natively support modularization systems (CommonJS or ES6), so modularized code must be bundled into a single JavaScript file before running in a client-side application.

View file

@ -13,23 +13,24 @@
JSX is a syntax extension that enables you to write HTML tags interspersed with JavaScript. It's not part of any JavaScript standards and it's not required for building applications, but it may be more pleasing to use depending on your team's preferences.
```jsx
var MyComponent = {
view: function() {
return m("main", [
m("h1", "Hello world"),
])
}
function MyComponent() {
return {
view: () =>
m("main", [
m("h1", "Hello world"),
])
}
}
// can be written as:
var MyComponent = {
view: function() {
return (
<main>
<h1>Hello world</h1>
</main>
)
}
function MyComponent() {
return {
view: () => (
<main>
<h1>Hello world</h1>
</main>
)
}
}
```
@ -38,7 +39,7 @@ When using JSX, it's possible to interpolate JavaScript expressions within JSX t
```jsx
var greeting = "Hello"
var url = "http://google.com"
var link = <a href={url}>{greeting + "!"}</a>
var link = <a href={url}>{greeting}!</a>
// yields <a href="http://google.com">Hello!</a>
```
@ -66,17 +67,18 @@ If you want to use Webpack and Babel together, [skip to the section below](#usin
To install Babel as a standalone tool, use this command:
```bash
npm install babel-cli babel-preset-es2015 babel-plugin-transform-react-jsx --save-dev
npm install @babel/cli @babel/preset-env @babel/plugin-transform-react-jsx --save-dev
```
Create a `.babelrc` file:
```
```json
{
"presets": ["es2015"],
"presets": ["@babel/preset-env"],
"plugins": [
["transform-react-jsx", {
"pragma": "m"
["@babel/plugin-transform-react-jsx", {
"pragma": "m",
"pragmaFrag": "'['"
}]
]
}
@ -93,17 +95,18 @@ babel src --out-dir bin --source-maps
If you're already using Webpack as a bundler, you can integrate Babel to Webpack by following these steps.
```bash
npm install babel-core babel-loader babel-preset-es2015 babel-plugin-transform-react-jsx --save-dev
npm install @babel/core babel-loader @babel/preset-env @babel/plugin-transform-react-jsx --save-dev
```
Create a `.babelrc` file:
```json
{
"presets": ["es2015"],
"presets": ["@babel/preset-env"],
"plugins": [
["transform-react-jsx", {
"pragma": "m"
["@babel/plugin-transform-react-jsx", {
"pragma": "m",
"pragmaFrag": "'['"
}]
]
}
@ -111,7 +114,7 @@ Create a `.babelrc` file:
Next, create a file called `webpack.config.js`
```javascript
```jsx
const path = require('path')
module.exports = {
@ -123,7 +126,7 @@ module.exports = {
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
exclude: /\/node_modules\//,
loader: 'babel-loader'
}]
}
@ -136,7 +139,7 @@ This configuration assumes the source code file for the application entry point
To run the bundler, setup an npm script. Open `package.json` and add this entry under `"scripts"`:
```
```json
{
"name": "my-project",
"scripts": {
@ -155,7 +158,7 @@ npm start
To generate a minified file, open `package.json` and add a new npm script called `build`:
```
```json
{
"name": "my-project",
"scripts": {
@ -167,7 +170,7 @@ To generate a minified file, open `package.json` and add a new npm script called
You can use hooks in your production environment to run the production build script automatically. Here's an example for [Heroku](https://www.heroku.com/):
```
```json
{
"name": "my-project",
"scripts": {
@ -184,58 +187,56 @@ You can use hooks in your production environment to run the production build scr
JSX is essentially a trade-off: it introduces a non-standard syntax that cannot be run without appropriate tooling, in order to allow a developer to write HTML code using curly braces. The main benefit of using JSX instead of regular HTML is that the JSX specification is much stricter and yields syntax errors when appropriate, whereas HTML is far too forgiving and can make syntax issues difficult to spot.
Unlike HTML, JSX is case-sensitive. This means `<div className="test"></div>` is different from `<div classname="test"></div>` (all lower case). The former compiles to `m("div", {className: "test"})` and the latter compiles to `m("div", {classname: "test"})`, which is not a valid way of creating a class attribute. Fortunately, Mithril supports standard HTML attribute names, and thus, this example can be written like regular HTML: `<div class="test"></div>`.
Unlike HTML, JSX is case-sensitive. This means `<div className="test"></div>` is different from `<div classname="test"></div>` (all lower case). The former compiles to `m("div", {className: "test"})` and the latter compiles to `m("div", {classname: "test"})`, which is not a valid way of creating a class attribute. Fortunately, Mithril supports standard HTML attribute names, and thus, this example can be written like regular HTML: `<div class="test"></div>`. Also, unlike HTML, JSX is based on XML, so you can do things like `<div class="test" />` as equivalent to `<div class="test"></div>`, where in HTML you can only use the second.
JSX is useful for teams where HTML is primarily written by someone without JavaScript experience, but it requires a significant amount of tooling to maintain (whereas plain HTML can, for the most part, simply be opened in a browser)
JSX is useful for teams where HTML is primarily written by someone without JavaScript experience, but it requires a significant amount of tooling to maintain (whereas plain HTML can, for the most part, simply be opened in a browser).
Hyperscript is the compiled representation of JSX. It's designed to be readable and can also be used as-is, instead of JSX (as is done in most of the documentation). Hyperscript tends to be terser than JSX for a couple of reasons:
- it does not require repeating the tag name in closing tags (e.g. `m("div")` vs `<div></div>`)
- it does not require repeating the tag name in closing tags when children are present (e.g. `m("div", m("span"))` vs `<div><span /></div>`)
- static attributes can be written using CSS selector syntax (i.e. `m("a.button")` vs `<a class="button"></a>`)
In addition, since hyperscript is plain JavaScript, it's often more natural to indent than JSX:
```jsx
//JSX
var BigComponent = {
activate: function() {/*...*/},
deactivate: function() {/*...*/},
update: function() {/*...*/},
view: function(vnode) {
return [
{vnode.attrs.items.map(function(item) {
return <div>{item.name}</div>
})}
<div
ondragover={this.activate}
ondragleave={this.deactivate}
ondragend={this.deactivate}
ondrop={this.update}
onblur={this.deactivate}
></div>
]
}
function BigComponent() {
function activate() { /* ... */ }
function deactivate() { /* ... */ }
function update() { /* ... */ }
return {
view: ({attrs}) => (
<>
{attrs.items.map((item) => <div>{item.name}</div>)}
<div
ondragover={activate}
ondragleave={deactivate}
ondragend={deactivate}
ondrop={update}
onblur={deactivate}
/>
</>
)
}
}
// hyperscript
var BigComponent = {
activate: function() {/*...*/},
deactivate: function() {/*...*/},
update: function() {/*...*/},
view: function(vnode) {
return [
vnode.attrs.items.map(function(item) {
return m("div", item.name)
}),
m("div", {
ondragover: this.activate,
ondragleave: this.deactivate,
ondragend: this.deactivate,
ondrop: this.update,
onblur: this.deactivate,
})
]
}
function BigComponent() {
function activate() { /* ... */ }
function deactivate() { /* ... */ }
function update() { /* ... */ }
return {
view: ({attrs}) => [
attrs.items.map((item) => m("div", item.name)),
m("div", {
ondragover: this.activate,
ondragleave: this.deactivate,
ondragend: this.deactivate,
ondrop: this.update,
onblur: this.deactivate,
})
]
}
}
```
@ -247,6 +248,6 @@ Needless to say, since hyperscript is pure JavaScript, there's no need to run a
### Converting HTML
In Mithril, well-formed HTML is valid JSX. Little effort other than copy-pasting is required to integrate an independently produced HTML file into a project using JSX.
In Mithril, well-formed HTML is generally valid JSX. Little more than just pasting raw HTML is required for things to just work. About the only things you'd normally have to do are change unquoted property values like `attr=value` to `attr="value"` and change void elements like `<input>` to `<input />`, this being due to JSX being based on XML and not HTML.
When using hyperscript, it's necessary to convert HTML to hyperscript syntax before the code can be run. To facilitate this, you can [use the HTML-to-Mithril-template converter](http://arthurclemens.github.io/mithril-template-converter/index.html).
When using hyperscript, you often need to translate HTML to hyperscript syntax to use it. To help speed up this process along, you can use a [community-created HTML-to-Mithril-template converter](http://arthurclemens.github.io/mithril-template-converter/index.html) to do much of it for you.

View file

@ -743,7 +743,7 @@ In certain situations, you may find yourself needing to interoperate with anothe
Here's an example with React:
```javascript
```jsx
class Child extends React.Component {
constructor(props) {
super(props)

View file

@ -133,9 +133,15 @@ module.exports = {
}
```
By default, Mithril views are described using [hyperscript](hyperscript.md). Hyperscript offers a terse syntax that can be indented more naturally than HTML for complex tags, and in addition, since its syntax is simply JavaScript, it's possible to leverage a lot of JavaScript tooling ecosystem: for example [Babel](es6.md), [JSX](jsx.md) (inline-HTML syntax extension), [eslint](http://eslint.org/) (linting), [uglifyjs](https://github.com/mishoo/UglifyJS2) (minification), [istanbul](https://github.com/gotwarlost/istanbul) (code coverage), [flow](https://flowtype.org/) (static type analysis), etc.
By default, Mithril views are described using [hyperscript](hyperscript.md). Hyperscript offers a terse syntax that can be indented more naturally than HTML for complex tags, and since its syntax is just JavaScript, it's possible to leverage a lot of JavaScript tooling ecosystem. For example:
Let's use Mithril hyperscript to create a list of items. Hyperscript is the most idiomatic way of writing Mithril views, but [JSX is another popular alternative that you could explore](jsx.md) once you're more comfortable with the basics:
- You can use [Babel](es6.md) to transpile ES6+ to ES5 for IE and to transpile [JSX](jsx.md) (an inline HTML-like syntax extension) to appropriate hyperscript calls.
- You can use [ESLint](http://eslint.org/) for easy linting with no special plugins.
- You can use [Terser](https://github.com/terser-js/terser) or [UglifyJS](https://github.com/mishoo/UglifyJS2) (ES5 only) to minify your code easily.
- You can use [Istanbul](https://github.com/istanbuljs/nyc) for code coverage.
- You can use [TypeScript](https://www.typescriptlang.org/) for easy code analysis. (There are [community-supported type definitions available](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/mithril), so you don't need to roll your own.)
Let's start off with hyperscript and create a list of items. Hyperscript is the idiomatic way to use Mithril, but [JSX](jsx.md) works pretty similarly.
```javascript
// src/views/UserList.js