85
YOU DON'T KNOW ES Modules @teppeis Node #21 June 29, 2016

You Don't Know ES Modules

Embed Size (px)

Citation preview

Page 1: You Don't Know ES Modules

YOU DON'T KNOW ES Modules

@teppeis

Node #21

June 29, 2016

Page 2: You Don't Know ES Modules

Hello!• Teppei Sato, @teppeis • Cybozu, Inc. / kintone

Page 3: You Don't Know ES Modules

kintone.com

Page 4: You Don't Know ES Modules

(Module )

https://gihyo.jp/dp/ebook/2015/978-4-7741-7477-8

Page 5: You Don't Know ES Modules

History of JavaScript Modules

Page 6: You Don't Know ES Modules

Module PatternExt.namespace("myNameSpace"); myNameSpace.app = function() { // private variables var privVar1 = 11;

// private functions var btn1Handler = function( button, event ) { }; // public space return { // public methods init: function() { // ... } }; }();

Page 7: You Don't Know ES Modules

AMD (RequireJS)

define(['require', 'dep1', 'dep2'], function(require) { var dependency1 = require('dep1'), dependency2 = require('dep2'); return function() {}; });

Page 8: You Don't Know ES Modules

CommonJS Module (CJS)

// foo.js module.exports = function() { // ... };

// main.js var foo = require('./foo');

Page 9: You Don't Know ES Modules

Page 10: You Don't Know ES Modules

• • ex) browserify, webpack

var moduleName = 'foo'; if (someCondition) { moduleName = 'bar'; } var module = require(moduleName);

Page 11: You Don't Know ES Modules

• • Node.js

• 3rd party • • •

Page 12: You Don't Know ES Modules

ES6 Modules

Page 13: You Don't Know ES Modules

export/import

// export.js export default function() { return "foo"; }

// import.js import foo from "./export.js"; foo();

Page 14: You Don't Know ES Modules

Awesome!•

• parse • •

• • write one, run anywhere!?

• `Module` is the new script • strict

• top level `this`: undefined • `await`: future reserved word

Page 15: You Don't Know ES Modules

Syntax

Page 16: You Don't Know ES Modules

Default export/import

// export.js export default function() { return "foo"; }

// import.js import foo from "./export.js"; foo();

Page 17: You Don't Know ES Modules

Named export/import

// export.js export function foo() { return "foo"; } export class Bar {} export var baz = "baz";

// import.js import {foo, Bar, baz} from "./export.js";

foo(); new Bar(); console.log(baz); // "baz"

Page 18: You Don't Know ES Modules

Mixed

// export.js export default function() { return "Default"; } export function foo() { return "Named"; }

// import.js import def, {foo} from "./export.js";

def(); // "Default" foo(); // "Named"

Page 19: You Don't Know ES Modules

Default

• ES6 Modules Default Export

• Named Export

import

• 1 module 1 export

Page 20: You Don't Know ES Modules

:

• default export

named export

Page 21: You Don't Know ES Modules

Default export property

// export.js export default { foo: "Default Property" }; export var foo = "Named";

// import.js import def, {foo} from "./export.js";

console.log(def.foo); // "Default Property" console.log(foo): // "Named"

Page 22: You Don't Know ES Modules

Static and Declarative

Page 23: You Don't Know ES Modules

Static•

• SyntaxError

• Browserify • •

Page 24: You Don't Know ES Modules

export default

SyntaxError!

// export.js export default function() { return "foo1"; } export default function() { return "foo2"; }

Page 25: You Don't Know ES Modules

import

SyntaxError!

// import.js import foo from "./missing-module.js";

Page 26: You Don't Know ES Modules

import

// export.js export function foo() { return "foo"; }

// import.js import bar from "./export.js";

SyntaxError!

Page 27: You Don't Know ES Modules

Rollup: tree shakinghttp://rollupjs.org/

Page 28: You Don't Know ES Modules

MS Edge https://blogs.windows.com/msedgedev/2016/05/17/es6-modules-and-beyond/

Page 29: You Don't Know ES Modules

Standard and Universal

Page 30: You Don't Know ES Modules

• ES Syntax

• • Node

• Write once, run anywhere!? • …

Page 31: You Don't Know ES Modules

Module is the new script

Page 32: You Don't Know ES Modules

Script or Module

• ES6 2

• 15.1.9 `ScriptEvaluationJob(sourceText)` • 15.2.1.16.1 `ParseModule(sourceText)`

• Script Module •

Page 33: You Don't Know ES Modules

Module

• strict

• top level scope, not global scope • top level `this`: undefined • `await`: future reserved word

• top level await

• HTML comment

Page 34: You Don't Know ES Modules

in Modules

// SyntaxError! (strict mode) with (obj) {}

console.log(this); // undefined

var foo = 1; // module local, not global

var await = 1; // SyntaxError! (future reserved word)

<!-- console.log() --> // SyntaxError! (HTML comment)

Page 35: You Don't Know ES Modules

https://twitter.com/domenic/status/743981311568785408

Page 36: You Don't Know ES Modules

ECMAScript

Page 37: You Don't Know ES Modules

ECMAScript•

• module fetch •

• Loader API • • API

Page 38: You Don't Know ES Modules

• • : whatwg/html

• Node.js: nodejs/node-eps • Loader API

• whatwg/loader

Page 39: You Don't Know ES Modules

Loading semantics whatwg/loader

Page 40: You Don't Know ES Modules

whatwg/loader• This repository consolidates work on the

ECMAScript module loading semantics with the integration points of Web browsers, as well as Node.js.https://github.com/whatwg/loader

• `<script>`

whatwg/html (#83)

• roadmap

Page 41: You Don't Know ES Modules

Dynamic Loader API (reflection)

System.loader.import('./foo.js').then(foo => { // use foo! });

Page 42: You Don't Know ES Modules

Loader pipeline (hooks)

1. resolve 2. fetch 3. translate 4. instantiate

Page 43: You Don't Know ES Modules

Modules in browsers whatwg/html

Page 44: You Don't Know ES Modules

whatwg/html

• PR: https://github.com/whatwg/html/pull/443

• 4.12 The elements > Scripting • script

• 8.1 Web app APIs > Scripting • fetch, parse

Page 45: You Don't Know ES Modules

<script type=“module”>

External module <script type="module" src="./foo.js"></script>

Inline module <script type="module"> import fo from './foo.js'; console.log(foo()); </script>

Page 46: You Don't Know ES Modules

type=“module” •

• •

MIME ”module” type

MIME

Page 47: You Don't Know ES Modules

scope <script><script> var foo = 1; </script> <script type="module"> console.log(typeof foo); // undefined console.log(window.foo); // 1 var foo = 2; console.log(window.foo); // 1 console.log(foo); // 2 </script> <script type="module"> console.log(typeof foo); // undefined console.log(window.foo); // 1 var foo = 3; console.log(window.foo); // 1 console.log(foo); // 3 </script>

Page 48: You Don't Know ES Modules

• import

• URL

• "/", "./", "../" URL

• TypeError!

• URL

• inline: document base • external, imported: URL

• ".js"

Page 49: You Don't Know ES Modules

// OK import "https://example.com/lodash.js"; import "/lodash.js"; import "./lodash.js"; import "../lodash.js";

// NG import ".../lodash.js"; import "lodash.js"; import "lodash";

Page 50: You Don't Know ES Modules

defer

fetch

• fetch

• DOM

Page 51: You Don't Know ES Modules

async

fetch

module fetch •

<script type="module" src="./foo.js" async></script>

Page 52: You Don't Know ES Modules
Page 53: You Don't Know ES Modules

cors mode

• import

CORS

• CDN

// from `https://example.com/foo.html` import $ from 'https://cdn.example.com/jquery.js';

// cdn.example.com must send `Access-Control-Allow-Origin` header

Page 54: You Don't Know ES Modules

crossorigin• crossorigin import cookie

(credentials mode)

• default: omit • "anonymous": same-origin • "use-credentials": include

• cookie

JS

Page 55: You Don't Know ES Modules

Module Workers

• • module importScripts TypeError

// Web Worker const worker = new Worker("worker.js", {type: "module"});

// Service Worker navigator.serviceWorker.register("sw.js", {type: "module"});

Page 56: You Don't Know ES Modules

• realm URL

• URL HTTP 1

• realm

<script type="module"> import './foo.js'; // sends HTTP request </script> <script type="module"> import './foo.js'; // doesn't send request </script>

Page 57: You Don't Know ES Modules

• UTF-8 • meta Content-Type charset

• Content-Type JavaScript MIME Type

• Chrome/IE `X-Content-Type: nosniff`

• module export

• script src URL fetch

document insert

Page 58: You Don't Know ES Modules

• Edge: https://blogs.windows.com/msedgedev/2016/05/17/es6-modules-and-beyond/ • Preview

• Chrome: https://bugs.chromium.org/p/v8/issues/detail?id=1569 • Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=568953 • WebKit: https://bugs.webkit.org/show_bug.cgi?id=147340

• JSC const

Page 59: You Don't Know ES Modules

Modules in Node.js nodejs/node-eps

Page 60: You Don't Know ES Modules

ES6 Modules

Page 61: You Don't Know ES Modules

• npm Node.js

• Node.js V8

• V8 whatwg/loader

Page 62: You Don't Know ES Modules

https://flic.kr/p/4ZaDRz

Page 63: You Don't Know ES Modules

• •

Page 64: You Don't Know ES Modules

• ES Modules • • CJS Modules ES Modules

• import "cjs" • require("esm")

Page 65: You Don't Know ES Modules

ES Modules

• 2 : Module or Script

• ES6 • • `<script type=module>`

• Node.js CJS Script • • require, module, exports

Page 66: You Don't Know ES Modules

Module or Script?

// global scope? function foo(value) { // the arguments object is modified? value = value || ''; var args = [].slice.call(arguments); // what is `this`? args.unshift(this); return args; } foo(null);

Page 67: You Don't Know ES Modules

How to detect

• New Pragma: "use module"; • New file extension: .mjs • Content sniffing • package.json

Page 68: You Don't Know ES Modules

New Pragma: "use module";

• strict

`"use module”;`

• Cons • Unacceptable boilerplate tax • :

Page 69: You Don't Know ES Modules

New file extension: .mjs• ".mjs" Module

• `import './foo'` foo.mjs, foo.js

• Cons • "*.js"

• : .jsx

• Modules .mjs

• bin •

Page 70: You Don't Know ES Modules

Content sniffing

• Module

Script

• Cons • import/export •

Page 71: You Don't Know ES Modules

package.json (a): entry point• package.json module

• type=module

• Rollup jsnext:main

{ // ... "main": "old/index.js", "module": "lib/index.js", // ... }

Page 72: You Don't Know ES Modules

package.json (a): entry point• Cons

• package.json

• Module

• import ( )

import "foo/bar";

Page 73: You Don't Know ES Modules

package.json (b): white list

• package.json Module

• import

{ // files and directories: "modules": ["special.js", "lib", "bin/hello.js"],

// if package never uses CJS Modules "modules": ["."], }

Page 74: You Don't Know ES Modules

.mjs draft

Page 75: You Don't Know ES Modules

Defense of .js

Page 76: You Don't Know ES Modules

Defense of .js• https://github.com/dherman/defense-of-dot-js/ • Dave Herman, Yehuda Katz, Caridy Patiño • package.json (a)(b)

• modules.root pacakge.json

• ES Modules • .js .mjs

package.json

• interop : https://github.com/dherman/defense-of-dot-js/issues/6

Page 77: You Don't Know ES Modules

Unambiguous JavaScript Grammar

Page 78: You Don't Know ES Modules

Unambiguous JavaScript Grammar

• https://github.com/bmeck/UnambiguousJavaScriptGrammar • bmeck (Bradley Meck), jdalton • content sniff Module

import export

• 7 TC39 ( bmeck TC39 )

package.json CLI

Page 79: You Don't Know ES Modules

Unambiguous, but Redundant• https://github.com/bmeck/UnambiguousJavaScriptGrammar/issues/14

<script type="module"> console.log('hello'); export {}; // Required !!! </script>

Page 80: You Don't Know ES Modules

https://twitter.com/awbjs/status/743146150828482561

Page 81: You Don't Know ES Modules

• ES Modules

vs.

• TC39/ Node

• Node

Page 82: You Don't Know ES Modules

https://twitter.com/awbjs/status/744701901560651777

Page 83: You Don't Know ES Modules

IMO• JS Module • `type=module` • Universal! Node • Unambiguous export {} Node • • import(cjs) interop

Page 84: You Don't Know ES Modules
Page 85: You Don't Know ES Modules

• ES Modules

• ES /

• ES Modules •

• Node.js ES Modules

• 7 TC39 meeting