DEV Community

Brian Neville-O'Neill
Brian Neville-O'Neill

Posted on • Originally published at blog.logrocket.com on

What’s new in Create React App 2

Create React App 2.1, released at the end of October 2018, added official support for TypeScript. This, along with all of the improvements and features brought by the second version of Create React App, removes much of the complexity of creating and configuring a React app.

In this article, I’m going to cover the following features of Create React App 2:

  • TypeScript support
  • Service workers (unregistered by default)
  • Sass, CSS Modules, and PostCSS
  • React fragments short syntax
  • Babel macros
  • Custom proxy implementation
  • Yarn Plug’n’Play mode

For a complete list of all of the features (and some breaking changes), you can check out the official post about this version and the changelog of the project.

TypeScript support

For new applications, you only have to execute create-react-app with --typescript option:

npx create-react-app sample-typescript-app --typescript

If npx is not executing the latest version (2.1.1 at the time of this writing), specify the version of create-react-app:

npx create-react-app@2.1.1 sample-typescript-app --typescript

This will install the packages related to TypeScript and create a default tsconfig.json file. Here’s an extract of the command’s output:

Installing react, react-dom, and react-scripts...
+ react-dom@16.6.3
+ react@16.6.3
+ react-scripts@2.1.1
+ @types/react-dom@16.0.9
+ @types/react@16.7.3
+ @types/jest@23.3.9
+ @types/node@10.12.6
+ typescript@3.1.6
...
We detected TypeScript in your project (srcApp.test.tsx) and created a tsconfig.json file for you.
Your tsconfig.json has been populated with default values.

The file src/App.tsx will be identical to its JavaScript counterpart, however, if, for example, you add a functional component to the file like this:

//...
const Content = (props) => {
  return <div><h1>{props.title}</h1>{props.text}</div>;
 }

class App extends Component {
  // ...
}

An error concerning the props parameter type will be thrown:

Because now, you have to declare a type definition using React.SFC:

interface ContentProps {
  title: string,
  text: string,
 }

const Content: React.SFC<ContentProps> = (props) => {
  return <div><h1>{props.title}</h1>{props.text}</div>;
}

And if your IDE supports it (Visual Studio Code in the image below), it will show you the type of the component’s attribute and it will also catch type errors:

On the other hand, to add TypeScript to an existing Create React App app, first, manually install the TypeScript-related packages:

npm install --save typescript @types/node @types/react @types/react-dom @types/jest

Next, change the extension of the files from *.js to *.tsx and restart the application (if it’s running).

Service workers are unregistered by default

The structure of the project created by Create React App remains the same.

The only changes are related to service workers.

First, the file src/registerServiceWorker.js was renamed to src/serviceWorker.js and now, inside of this file, a config object is passed to the function registerValidSW to enable the callbacks onUpdate and onSuccess:

The second change is in src/index.js, the service worker is unregistered by default:

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();

You can learn more about service workers and progressive web apps here.

Sass, CSS Modules, and PostCSS

Create React App 2 gives you more options to style your application without the need for complex configurations, ejecting the application or using react-app-rewired.

The first option is Sass. To use it, first install node-sass:

npm install --save node-sass

Now you can create a Sass file (src/Message.scss). For example:

$theme-color: green;

.my-message {
color: $theme-color;
}

And use it in a component (src/Message.js) this way:


jsx
import React from 'react'
import './Message.scss'
const Message = props => {
return

  • {children}
  • } export default Message;
    On the other hand, with [CSS Modules](https://www.javascriptstuff.com/what-are-css-modules/), you don’t have to install more dependencies, you just have to follow the [name].module.css file naming convention.
    
    For example, if you have a Message.js component (shown in the previous example), you can define its styles in the file Message.module.css (remember that with CSS Modules you can [compose](https://bambielli.com/til/2017-08-11-css-modules-composes/) classes):
    


    jsx
    .my-theme {
    color: green;
    }
    .my-message {
    composes: my-theme;
    font-size: 20px;
    }

    And in the component, use the styles like this:
    


    jsx
    import styles from './Message.module.css'
    // ...

  • {children}

  • This way, at runtime, a CSS class with a semi-random name will be generated to locally scope those styles to the component:
    
    


    jsx

  • 
    Also, [postcss-flexbugs-fixes](https://github.com/luisrudge/postcss-flexbugs-fixes) and [postcss-preset-env](https://github.com/csstools/postcss-preset-env) ([supporting](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/webpack.config.js#L104) only [stage3+ features](https://preset-env.cssdb.org/features#stage-3)) are included in Create React App 2, which means vendor prefixes are added automatically and new CSS features for older browsers are polyfilled. You can learn more about it [here](https://facebook.github.io/create-react-app/docs/post-processing-css).
    
    ### React fragments short syntax
    
    It’s been a while since React 16.2 added support for [fragments](https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html) to return multiple children from a component’s render method:
    


    jsx
    render() {
    return (

    My Messages

    Message 1

    Message 2

    ); }
    However, as the JSX Fragment Syntax (or short syntax):
    


    jsx
    render() {
    return (
    <>

    My Messages

    Message 1

    Message 2

    </> ); }
    It’s only supported by Babel 7, you can use it now that Create React App 2 uses this version of Babel.
    
    However, remember that `<></>` is just syntax sugar for `<React.Fragment>` but without the option to use keys or other attributes.
    
    ### Babel macros
    
    In the context of Create React App 2, Babel macros allow you to use a special type of Babel plugins without any configuration.
    
    Let me explain.
    
    Babel plugins allow you to manipulate and transform code at build time. For example, there’s a [plugin](https://babeljs.io/docs/en/babel-plugin-transform-arrow-functions) that transforms arrow functions:
    
    


    jsx
    const a = (b) => b;

    
    To regular JavaScript functions:
    
    


    jsx
    const a = function (b) {
    return b;
    };

    
    However, one problem with Babel plugins is that you have to configure each one you want to use. Usually, this is done in .babel.rc, but when using Create React App, you don’t have access to this file unless you eject the application.
    
    Luckily, there is [babel-plugin-macros](https://www.npmjs.com/package/babel-plugin-macros), a plugin that defines a standard interface for…macros (i.e. plugins that perform build-time transformations).
    
    This way, you only have to add this plugin to your project (which is what Create React App does) to use any number of macros you want.
    
    And since macros are processed at build-time and not required at runtime, they should be specified as devDependencies.
    
    You can search [npm for the keyword babel-plugin-macros](https://www.npmjs.com/search?q=keywords:babel-plugin-macros) to find macros.
    
    Take, for example, the Babel plugin/macro [tagged-translations](https://github.com/vinhlh/tagged-translations), which translates text at build-time.
    
    Just add this library to a Create React App project with:
    
    


    jsx
    npm install --save-dev tagged-translations

    
    Add the file translations/default.json at the root of the project with a translation like the following:
    
    


    jsx
    {
    "Hello world": "Hola mundo"
    }

    
    And use it as a macro in your components (not as a plugin, [there’s a difference](https://github.com/kentcdodds/babel-plugin-macros#whats-the-difference-between-babel-plugins-and-macros)):
    


    jsx
    import t from 'tagged-translations/macro'

    class App extends Component {
    render() {
    return (

    {tHello world} ); } }
    As you can see in the following image, the translation happens when the bundle is created at build-time:
    
    ![](https://cdn-images-1.medium.com/max/954/0*TdByJTaiKWD2jFw2)
    
    ### Custom proxy implementation
    
    In the first version of Create React App, when making an API request you either had the option of hard-coding the complete URL of the request like this:
    


    jsx
    fetch('http://localhost:3001/messages')
    .then(res => {
    // ...
    })

    Or add a proxy field to the package.json file:
    
    


    jsx
    'proxy': 'http://localhost:3001/'

    
    To just use the path of the resource in the fetch call:
    


    jsx
    fetch('/messages')
    .then(res => {
    // ...
    })

    With Create React App 2, in addition to the methods shown above, you can configure a custom proxy by installing [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware):
    
    


    jsx
    npm install --save http-proxy-middleware

    
    And creating the file src/setupProxy.js to configure the proxy:
    


    jsx
    const proxy = require('http-proxy-middleware');
    module.exports = function(app) {
    // ...
    };

    This file will be imported automatically when the application starts, and it gives you access to an [Express](https://expressjs.com/) instance to do something like this:
    


    jsx
    const proxy = require('http-proxy-middleware');
    module.exports = function(app) {
    app.use(proxy('/api', { target: 'http://localhost:3001/' }));
    app.use(proxy('/public', { target: 'http://localhost:3002/' }));
    };

    #### Yarn Plug’n’Play mode
    
    Yarn Plug’n’Play mode allows your application to work without a `node_modules` directory.
    
    This way, the app dependencies are loaded from Yarn’s cache, rather than requiring copying them into the `node_modules` directory during the installation step. This has the added benefit of faster app creations.
    
    To use this feature, you’ll need [Yarn 1.12+](https://yarnpkg.com/lang/en/docs/install/), Node.js 8.9+, and be sure to create your React application with the option --use-pnp:
    
    


    jsx
    npx create-react-app light-app --use-pnp

    
    If the command executed successfully, in the file package.json, you will find an additional configuration option:
    
    


    jsx
    {
    ...
    "installConfig": {
    "pnp": true
    },
    ...
    }

    
    
    
    Also, you’ll get a .pnp directory with links to directories of Yarn’s cache and the file .pnp.js, which validates dependencies and provides the ability to search for them from the global cache instead of the `node_modules` directory.
    
    This is an experimental feature(at the time of this writing) so it might not work in all situations (for example, I didn’t work on my Windows 10 machine) and with tools that work with the `node_modules` directory directly.
    
    ### Conclusion
    
    Create React App 2 adds more options to ease the creation and configuration of React applications. Personally, the three new features I find most helpful are TypeScript, Saas and Babel macros.
    
    However, I have to say that for an existing application, if you don’t need these new features or if you have a working configuration using [react-app-rewired](https://github.com/timarney/react-app-rewired) or [craco](https://github.com/sharegate/craco), it’s probably not worth upgrading.
    
    Even the Create React App team [advise this](https://reactjs.org/blog/2018/10/01/create-react-app-v2.html):
    
    > Don’t feel pressured to upgrade anything. If you’re satisfied with the current feature set, its performance, and reliability, you can keep using the version you’re currently at! It might also be a good idea to let the 2.0 release stabilize a little bit before switching to it in production.
    
    But for new applications, you have many new features at your disposal.
    
    Happy hacking!
    * * *
    ### Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps
    
    [![](https://cdn-images-1.medium.com/max/1024/1*s_rMyo6NbrAsP-XtvBaXFg.png)](https://logrocket.com/signup/)<figcaption><a href="https://logrocket.com/signup/">https://logrocket.com/signup/</a></figcaption>
    
    [LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
    
    In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single page apps.
    
    [Try it for free.](https://logrocket.com/signup/)
    * * *
    The post [What's new in Create React App 2](https://blog.logrocket.com/whats-new-in-create-react-app-2-fe8f4f448c75/) appeared first on [LogRocket Blog](https://blog.logrocket.com).
    
  • Top comments (0)