• Tidak ada hasil yang ditemukan

Chapter 2 ■ hello World

29

Chapter 2 ■ hello World

Listing 2-6. Package.json: Adding Scripts for Transformation ...

"scripts": {

"compile": "babel src –presets react –out-dir static", "watch": "babel src –presets react –out-dir static –watch", "test": "echo \"Error: no test specified\" && exit 1"

}, ...

Go ahead and run the new command using npm watch. You will notice that it does one transform, but doesn’t return to the shell. It’s actually waiting in a permanent loop, watching for changes to the source files. Test out its effect by making a small change to App.jsx and saving the file. You’ll see that it prints out a fresh line like this for every change:

src/App.jsx -> static/App.js

Refresh your browser after the new line is printed when a change in App.jsx is made and ensure that your changes are reflected in the application.

React Library

Although it is possible to serve the React library scripts also from the server and gain a little more speed during development, we won’t be doing this just yet. The reason is that in a later step, we’ll be bundling not just the React library but also other libraries and the application’s JavaScript files together using a tool called Webpack. The added benefit of moving the React scripts to the server right now is very minimal.

ES2015

Until now, we were using ES5 (old JavaScript) to write your client-side code. Let’s switch to ES2015 instead. This not only gives us a few useful features, but it also makes the code more readable by allowing short-hand syntaxes such as arrow functions. We’ll also be able to use extra conveniences that React gives you by using ES2015 classes.

For the server-side code, we didn’t have to do anything special; we just wrote the code in ES2015. But we can’t do this for the client-side code because not all browsers uniformly support ES2015 specifications. Luckily, babel provides the ability to deal with ES2015 in addition to JSX into ES5 JavaScript. Conversion from one specification of JavaScript to another is called transpiling (though you may also use compiling in the rest of the book to mean the same thing). Let’s install another babel plugin for this:

$ npm install –save-dev babel-preset-es2015

Chapter 2 ■ hello World

31 Let’s now modify the compile npm scripts in package.json to include an ES2015 compilation in addition to React transformation. The changed script commands are shown in Listing 2-7, with the changes highlighted in bold.

Listing 2-7. package.json: Including ES2015 Transformation ...

"scripts": {

"compile": "babel src --presets react,es2015 --out-dir static", "watch": "babel src --presets react,es2015 --out-dir static --watch", "test": "echo \"Error: no test specified\" && exit 1"

}, ...

All the new syntaxes and language features can now be used in your client-side code.

But there’s one more thing: ES2015 also comes with many built-in objects and extensions, which are not syntactic changes. For example, the Promise object is an ES2015

specification, as is the array find() method. These are not supported by older browsers such as Internet Explorer 11 and earlier. And, a transpile is not enough to add these new capabilities.

If you must support those browsers and want to use these built-in functions, you need to add support to the browser via a JavaScript library. These are called polyfills, things that supplement browser capabilities or global functions. If the browser natively supports a certain feature, a polyfill will choose to use the native objects or methods rather than use the JavaScript-based supplement. There are individual polyfills for various features; for example, you will find a polyfill for Promises. But rather than install individual polyfills, let’s use the babel recommended polyfill that emulates a full ES2015 environment. This is called babel-polyfill. Let’s use this, like the React libraries, from a CDN. So, change the index.html to include the babel-polyfill library as shown in Listing 2-8.

Listing 2-8. index.html: Changes for Including ES2015 Polyfill ...

<title>Pro MERN Stack</title>

<script src=

"https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.13.0/polyfill.js">

</script>

<script src=

"https://cdnjs.cloudflare.com/ajax/libs/react/15.2.1/react.js">

</script>

...

Now we’re ready to use ES2015 in App.jsx. Let’s replace the contents with the code in Listing 2-9, which you’ll examine soon.

Chapter 2 ■ hello World

Listing 2-9. App.jsx: Rewritten in ES2015

const contentNode = document.getElementById('contents');

const continents = ['Africa','America','Asia','Australia','Europe'];

const message = continents.map(c => `Hello ${c}!`).join(' ');

const component = <p>{message}</p>; // A simple JSX component

ReactDOM.render(component, contentNode); // Render the component inside the  content Node

Compile the new App.jsx by running npm run watch or npm run compile. If you already running npm run watch, you will need to break that process using Ctrl-C and restart it. That’s because it needs to load the changes to the watch command which now includes the ES2015 preset.

Refresh your browser (you should be running npm start in a different console by now), and you should now see a greeting for each continent rather than the entire world.

Let’s discuss the new code, which includes a few ES2015 features and also one React feature.

...

const contentNode = ...

...

In ES2015, the const and let keywords replace the var keyword. You use const to declare constants (variables that don’t change once assigned). You use let to declare and initialize a variable that may take other values during the course of the script execution.

In the above piece of code, we used const to say that the variable contentNode is not going to be assigned later on to anything else.

...

continents.map(c => ...) ...

This is an arrow function. It’s a shorthand for defining a function taking a single parameter and returning an expression. Note that there is no return keyword, it reads as

“c maps to `Hello ${c}!`”.

...

`Hello ${c}!`

...

Chapter 2 ■ hello World

33 Pay close attention to the quotes: these are back-ticks and not single-quotes. This construct is called a template string. You can plug in variables using ${} within the string, and the variables will be expanded inline, just like string interpolation in perl and python.

In fact, you can use any JavaScript expression rather than just a variable.

...

const component = <p>{message}</p>;

...

Similar to ES2015 string interpolation, this is a JSX feature. The curly braces allow you to insert JavaScript expressions inside JSX, and these will be replaced by the value of the expression. This works not only for HTML text nodes but also within attributes. For example, the class name for an element can be a JavaScript variable.