class: center, middle # Node.js: Where are we now, where are we going? --- # Who am I? * Anna Henningsen * addaleax on Twitter + Github * she/her * Active Node.js contributor since December 2015 * Node.js TSC
--- name: how-did-i # How did I get into Node core? ```js setTimeout(1000, 1000, function() { console.log('hi!'); }); ``` --- template: how-did-i (don’t ask me why) ``` > TypeError: callback.call is not a function at ontimeout [as _onTimeout] (timers.js:195:34) at Timer.listOnTimeout (timers.js:92:15) ``` --- template: how-did-i ```diff @@ -177,6 +177,10 @@ exports.enroll = function(item, msecs) { exports.setTimeout = function(callback, after) { + if (typeof callback !== 'function') { + throw new TypeError('"callback" argument must be a function'); + } + after *= 1; // coalesce to number or NaN if (!(after >= 1 && after <= TIMEOUT_MAX)) { ``` --- # Why am I talking about this? - I didn’t know much about what was happening inside Node.js - A lot of people in the community don’t -- - There’s a hidden world here --- # Node 10 is near Past & upcoming changes: - ESM, HTTP/2, async_hooks, N-API - Promises, URL, TextDecoder - V8 6.6 / 6.7, WebAssembly, no more Debug API - Error system changes - Longer-term things, e.g. ChakraCore Let’s go into more detail --- # ES Modules - Experimental, but available - `.mjs`: Sorry, this is happening - But that doesn’t have to be the end of it - `import.meta` is there - Async loading - It’s not going to work 100 % like Babel - Names imports for CJS: Maybe not? --- # ES Modules ```js import fs from 'fs'; // Works import { readFile } from 'fs'; // Probably will work import { foo } from './other-esm-module'; // Works import.meta.url; // URL of the current file import.meta.require; // Probably will work ``` --- # HTTP/2 - Experimental in Node 10, but probably not much longer - Cleaner API than HTTP/1 - Compatibility API is available - Multiplexing + push streams! --- # HTTP/2 ```js const server = http2.createServer(); server.on('stream', (stream, headers) => { // stream is a Duplex stream.respond({ 'content-type': 'text/html', ':status': 200 }); stream.end('
Hello World
'); }); server.listen(8443); ``` --- # Diagnostics: async_hooks - What is in the event loop? - What is causing what: Tracking context - Replaces `domain`s almost completely - Native addon authors: Watch out! - Still experimental, API has rough edges --- # Diagnostics: async_hooks ```js async_hooks.createHook({ init(id, type, trigger) { process._rawDebug('init', id, type, trigger) }, before(id) { process._rawDebug('before', id) }, after(id) { process._rawDebug('after', id) }, destroy(id) { process._rawDebug('destroy', id) } }).enable(); fs.readFile(__filename, console.log); ``` --- # Diagnostics: async_hooks ```txt init 6 FSREQWRAP 1 before 6 init 7 FSREQWRAP 6 after 6 destroy 6 before 7 init 8 FSREQWRAP 7 after 7 destroy 7 before 8 init 9 FSREQWRAP 8 … ``` --- # Diagnostics: perf_hooks - Browser API ported to Node - Support for Node-specific events - Low-overhead timers - Experimental ```js performance.mark('A'); doSomeLongRunningProcess(() => { performance.mark('B'); performance.measure('A to B', 'A', 'B'); const measure = performance.getEntriesByName('A to B')[0]; console.log(measure.duration); }); ``` --- # N-API - Not experimental in Node 10 🎉 - Better everything - ABI-stable, C or C++ - Much much (much) cleaner ```c++ Value AddFortyTwo(const CallbackInfo& info) { Value argument = info[0]; int32_t result = argument.ToNumber().Int32Value() + 42; return Number::New(info.Env(), result); } ``` --- # Promises - `async/await` is … *really* nice. - `await` support in the REPL - `util.promisify`: Node 8+ - `fs/promises`: Coming in Node 10 - Async iterators: Coming! --- # Errors - `error.code` is being standardized in Node - Error message changes: no longer semver-major ```js > net.createServer().listen([1,2,3]) Error [ERR_INVALID_OPT_VALUE]: The value "[ 1, 2, 3 ]" is invalid for option "options" at Server.listen (net.js:1528:9) > _err.code 'ERR_INVALID_OPT_VALUE' ``` --- # Workers - Work in a fork - Improve the embedder use case a lot as well - Maybe soon? - **Do you know somebody who is very familiar with the Windows C API? Help wanted!** ```js const { Worker, isMainThread, postMessage } = require('worker'); if (isMainThread) { const worker = new Worker(__filename); worker.on('message', (message) => { ... }); worker.on('exit', (code) => { ... }); } else { postMessage('Hi!'); } ``` --- # V8 - WebAssembly is there, and it’s fast - Node 8+ has TurboFan + Ignition - There’s a whole new JS compiler pipeline 🎉 - `vm.runInDebugContext()` is no longer there - Native module API: Pretty stable! - Node is in V8’s CI - For Node 10.0.0: V8 6.6 with ABI of 6.7 - Possibly a few updates on top of that later --- # ChakraCore - Long-term effort - Has own public releases, check them out! # OpenSSL integration - Would have liked to support 1.0.2, 1.1.0, 1.1.1 for Node 10? - OpenSSL 1.0.2 is supported until end of 2019 - OpenSSL 1.1.1 comes with TLS v1.3 support - (Honestly: I’m not sure where we’re standing at this point) --- # ⚠ Reminder: No more `new Buffer()`! - Buffer constructor is deprecated - Check your code for vulnerabilities! - `new Buffer(string)` ← Is `string` always a string? - Zero-fills now. Please don’t rely on that. - Runtime deprecation: Coming in Node 10, outside `node_modules` -- ```js const json = JSON.parse(request.body); response.write(new Buffer(json.someString)); ``` --- # Streams … streams? - Complex, with noticeable overhead :( - New low-level streams API might be coming - Large re-work on the C++ side - Goal: C++-only fast path for `.pipe()` --- # Finally: So long, Node 4 - Node 4 is supported until April 2018 - Node 6 is supported until **April 2019** - Node 8 is supported until **December 2019** - Node 9 is supported until June 2018 - Node 10 is coming out next week! --- # That’s it! - Thank you for listening! - If you have questions, feel free to talk to me / ping me - If you have a Node.js wishlist, feel free to talk to me / ping me - Node.js is Open Source. You can contribute! Slides @ https://addaleax.net/talk-berlinjs/