Node 12

Node.js features

  • ES6 Module support
  • Native Modules
  • V8 7.4
  • TLS 1.3
  • New Heap Limits
  • llhttp parser
  • Worker threads
  • Node Startup improvements

ES6 Module support

  • import, export in .js files
  • use '--experimental-modules'
  • package.json type field
  • .cjs extension
  • Explicit filenames
  • import ‘./file.js’, not import ‘./file’

Native Modules

  • NAPI
  • C, C++ API
  • Not reliant on JS Engine

V8 7.4

  • Parsing has doubled since 6.1
  • 20% less memory usage
  • async 11 times faster since Node 7
  • #private fields
  • 1_000_000 readable Numbers
  • BigInt 2123000000n
  • i18n support
  • flatMap support
class Greet {
  /* No constructor required to set properties at instantiation */
  #name = 'World';
  get name() {
    return this.#name;
  }
  set name(name) {
    this.#name = name;
  }
  sayHello() {
    console.log(`Hello, ${this.#name}`);
  }
}

TLS 1.3

  • Current SSL
  • TLS 1.2 previous standard
  • Spec Introduced two years ago 
  • Most clients should support
  • OpenSSL 1.1.1

Change Heap Limits

  • Change the memory footprint
  • Previous 700MB (32-bit systems)
  • Previous 1400MB (64-bit systems)
  • Node will now determine the heap sizes based on the available memory
  • Heap Dump inspection

llhttp parser

  • New C TypeScript based http parser
  • replaces the existing http_parser in Node
  • Fixes security issues with http_parser
  • Much faster

Worker Threads

  • Fewer resources than cluster API
  • Good for long running synchronous code
  • Worker created as a Promise
  • Can send messages between threads
const {
  Worker, isMainThread, parentPort, workerData
} = require('worker_threads');

if (isMainThread) {
  module.exports = function parseJSAsync(script) {
    return new Promise((resolve, reject) => {
      const worker = new Worker(__filename, {
        workerData: script
      });
      worker.on('message', resolve);
      worker.on('error', reject);
      worker.on('exit', (code) => {
        if (code !== 0)
          reject(new Error(`Worker stopped with exit code ${code}`));
      });
    });
  };
} else {
  const { parse } = require('some-js-parsing-library');
  const script = workerData;
  parentPort.postMessage(parse(script));
}

Node Startup Improvements

  • Related to v8 7.4 upgrade
  • 30% improvement startup caching 

Next.js

React

  • View framework by Facebook
  • Can be used on Web and other platforms
  • Microsoft announced support Windows
  • ReactJax if you want to learn more
  • ReactJax JaxNode joint meeting next month

Isomorphic Apps?

Four Types of React

  • React.js => SPA
  • React Native => Native App
  • Gatsby.js => Static HTML
  • Next.js => SPA, Server-Side Rendering

Next.js

  • Created by Guillermo Rauch, creator of socket.io and Zeit.co  
  • Solves SEO and allows multiple endpoints
  • Includes Link router and getInitialProps
  • Use Express for server side rendering (SSR)
  • Can create static web sites with Next.js (Use Gatsby instead)

SPA

  • Single Page Applications
  • React, Angular, Aurelia Backbone, Ember
  • Great for Web Apps
  • Not necessary for most Web Apps
  • Bad for SEO

Traditional Web Apps

  • Support multiple endpoints
  • PHP, JSP, ASPX, CFM all allow for pages
  • MVC based frameworks allow for routes
  • Express.js uses routes in lew of pages

Best of Both Worlds

  • Compose with React
  • File-system routing
  • Code-splitting, only use imports used on the page
  • Prerender React views on the server

Next.js Project

  • package.json
  • /pages
  • /static

Getting Started

  • mkdir <yourprojectname> && cd <yourprojectname>
  • npm init
  • npm install --save next react react-dom
  • modify project.json to have the following scripts 
{
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  }
}

Index.js

// pages/index.js
// Notice we do not need to import react or react-dom
export default () => {
    return (<div>Hello JaxNode!</div>);
}

Prerender data

  • componentDidMount will work
  • Use getInitialProps to get any data before render
import axios from 'axios'

class weather extends React.Component {
    
    static async getInitialProps() {
        const results = await axios.get('https://someapi.com/restendpoint');
        const data = results.data.mydata;
        return { mydata: data };
    }

    render() {
        return (<div>Your data is {this.props.mydata}.</div>)
    }
}

export default weather;

Links in Next.js

  • import Link from next/link
  • Then use <Link /> component
import Link from 'next/link';

function Home() {
  return (
    <div>
      Click{' '}
      <Link href="/about">
        <a>here</a>
      </Link>{' '}
      to read more
    </div>
  );
}

export default Home;

Link props

  • href: the path inside pages directory + query string.
  • as: the path that will be rendered in the browser URL bar.
  • <Link as={`/p/${show.id}`}
               href={`/post?id=${show.id}`}>

Routes

  • Next based Router
  • Use with onClick events
import Router from 'next/router';

function ReadMore() {
  return (
    <div>
      Click <span onClick={() => Router.push('/about')}>here</span> to read more
    </div>
  );
}

export default ReadMore;

Server Side Rendering (SSR)

  • Next.js allows for SSR
  • Express traditionally uses PUG or HBS
  • Render using React

Using Express with Next

const express = require('express')
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app
  .prepare()
  .then(() => {
    const server = express()

    server.get('/p/:id', (req, res) => {
        const actualPage = '/post'
        const queryParams = { title: req.params.id }
        app.render(req, res, actualPage, queryParams)
    })

    server.get('*', (req, res) => {
      return handle(req, res)
    })

    server.listen(3000, err => {
      if (err) throw err
      console.log('> Ready on http://localhost:3000')
    })
  })
  .catch(ex => {
    console.error(ex.stack)
    process.exit(1)
  })

Styling

  • Styled JSX
  • Inline styles
  • Libraries for LESS and SASS
function HelloWorld() {
  return (
    <div>
      Hello world
      <p>scoped!</p>
      <style jsx>{`
        p {
          color: blue;
        }
        div {
          background: red;
        }
        @media (max-width: 600px) {
          div {
            background: blue;
          }
        }
      `}</style>
      <style global jsx>{`
        body {
          background: black;
        }
      `}</style>
    </div>
  );
}

export default HelloWorld;

Demo

Questions?

Resources

Node 12

By David Fekke

Node 12

New features in Node 12 and intro to Next.js

  • 997