progressive transpilation and the road to es2015 in production

Post on 11-Feb-2017

49 Views

Category:

Engineering

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

1

The Road to ES2015 in ProductionJacques Favreau

2What time is it?

Doom time!

3

• Const & Let

• Arrow Functions

• Destructuring

• Backtick/Template Strings

• Default Parameters

💧

Where we are today:

Limited ES2015

4What are we trying to do?

Goals

👼 Best experience for our users.

🤓 Best experience for our developers.

5

🤓 Senior UI Engineer @ Netflix

😅 Squad lead for the Web Core team

😍 Travel

😭 Clever code

Who?

Jacques Favreau

formComplete = function(){ var u = user.getUser(); var ct = 0 + (typeof(u.nickname)==='string' && u.nickname.length>0) + (typeof(u.websiteUrl)==='string' && u.websiteUrl.length>0) + (typeof(u.linkedin)==='string' && u.linkedin.length>0) + (typeof(u.locationString)==='string' && u.locationString.length>0) + (typeof(u.title)==='string' && u.title.length>0) + (typeof(u.bio)==='string' && u.bio.length>0) + (typeof(u.imageUrl)==='string' && u.imageUrl.length>0) + (typeof(u.resume)==='string' && u.resume.length>0) + (u.employerSharing && true); return Math.ceil(ct/0.09);};

6 What’s the future look like?

1.Are we stuck?

2.Rethinking what we ship, and why

3.ES2015 in the browser

4.Balancing UX and DX now and in the future

7With great transpilation comes great…

Hidden Cost

http://enomis94.deviantart.com

8Where we are today

Heavy on DX

Transpiled to ES5 Polyfill ES2015

Modern

Transpiled to ES5Polyfill ES2015Polyfill ES5

Legacy

No Support

Unsupported

9Where we are today

Heavy on DX

🤓🤓 🤓🤓

👼👼 👼👼💧

💧 💧

💧

10Where we are today

Heavy on DX

Transpiled to ES5 Polyfill ES2015

Modern

Transpiled to ES5Polyfill ES2015Polyfill ES5

Legacy

No Support

Unsupported

11

Ok, so let’s go the other way

12We could go the other way

Heavy on UX

ES3

Supported

No Support

Unsupported

ES5ES5 Polyfill

13We could go the other way

Heavy on UX

👼👼 👼👼

💧💧

💧 💧

14

How can we do better?

15 Things change

1.Modern browsers speak ES2015

2.Not all browsers are modern browsers

http://sanlaris.deviantart.com

16 Things change

Is getting ES2015 into the browser a good thing for our users?

17 Things change

20 to 40% over-the-wire payload reduction!

18 Things change

Browsers have varying support.

19Haven’t we done this?

Shoulders of Giants!

We have a long history of polyfilling in the browser

20

ES5 Code

Modern

ES5 CodePolyfill ES5Shim/Shams

Legacy

No Support

Unsupported

Flatten the earth:

Polyfilling

21

• Write expecting features

• Trade some performance for legacy browser support

Flatten the earth:

Polyfilling

22

<script src="//polyfill.io/v2/polyfill.js?features=es6,es5&flags=gated"></script>

Polyfills:

Ship only what you need

Flatten the earth:

Polyfilling

23What if we just shipped everything?

😭

I do not like the cone of shame

I do not like the cone of shame

24

Why is transpilation different?

(It’s not.)

25

👼 Best experience for our users.

🤓 Best experience for our developers.

Goals

26

So here it comes…

27

Netflix will start shipping native ES2015 to eligible browsers.

28

How?

29Our future:

Progressive Transpilation

ES2015

Modern

Legacy

No Support

Unsupported

Transpiled to ES5 Polyfill ES2015

Trailing

Transpiled to ES5 Polyfill ES2015Polyfill ES5

Shims

30Our future:

Progressive Transpilation

👼 Best experience for our users.

🤓 Best experience for our developers.

31Sidebar:

Look for other win opportunities

ES2015

Modern

Legacy

No Support

Unsupported

Transpiled to ES5 Polyfill ES2015Polyfill ES5

Trailing

Transpiled to ES5 Polyfill ES2015Polyfill ES5

Shims

32

ES2015

Modern

Legacy

No Support

Unsupported

Transpiled to ES5 Polyfill ES2015Polyfill ES5

Trailing

Fallback

Sidebar:

We ship fallback to legacy browsers

33Our future:

Progressive Transpilation

👼 Best experience for our users.

🤓 Best experience for our developers.

34

Let’s do it!

35On 🔥

Let’s do this!

Well… There are a few hurdles.

36On 🔥

Let’s do this!

1. Build systems lack support

2. Minifiers don’t work

3. Targeting browsers is hard

4. Browsers are broken and lie

37Issue #1:

Build systems

Issue #1:

Build systems lack ES2015 support

38Issue #1:

Build systems

Issue #1:

Build systems lack ES2015 support

39Issue #1:

Build systems

😞

Issue #1:

Build systems lack ES2015 support

40Issue #1:

Build systems

Solution #1:

There are some build systems that do

support ES2015 as a target!

41

const babelConfig = { modern: { presets: [] }, trailing: { presets: ['es2015'] }};

return gulp.src(glob) // Run babel with the modern config .pipe(babel(babelConfig.modern)) // Save the modern JS version. .pipe(gulp.dest('generated/modern/')) // Run Babel with trailing config. .pipe(babel(babelConfig.trailing)) // Save the trailing JS version. .pipe(gulp.dest('generated/trailing/'));

Just don’t use the

ES2015 preset.

Solutions to issue #1:

Workflows that work

42

{ "compilerOptions": { "module": "amd", "target": "es6" }}ES2015 supported as

a target.

Solutions to issue #1:

Workflows that work

43Issue #2:

Minfiers

Issue #2: Minifiers don’t work

44

Issue #2: Minifiers don’t work

Issue #2:

Minfiers

45Issue #2:

Minfiers

…but they’re working on it!

46Solutions to Issue #2:

Bable as a minifier

While we wait…

babel-preset-minify-es2015

47

It’s still a win!

Solutions to Issue #2:

Bable as a minifier

48Issue #3:

Who gets what?

Issue #3: Targeting browsers is hard

49

We unabashedly use the User Agent string

“[A]n ever-growing pack of lies[…]“

- Patrick H. Lauke

Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10136

Solution to Issue #3:

Our old friend, UA

50

On first load, it’s all we have

¯\_( )_/¯

Solution to Issue #3:

Our old friend, UA

51

Select browsers with ES2015 support.

kangax.github.io/compat-table/es6/

At this time, our ES2015 browsers are:

- Chrome 51

- Firefox 49

- Edge 14

- Safari 10

Solution to Issue #3:

Our old friend, UA

52Issue #4:

Browsers lie

Issue #4: Browsers can and do lie.

53Solution to issue #4:

Test for lying browsers

Execute a bit of Javascript

and test for lies.

54

✓ unicode✓ proxies✓ symbols✓ subclassable built-ins✓ promises✓ math + number + string APIs✓ array + object APIs✓ binary and octal literals

Solution to issue #4:

Test for lying browsers

✓ arrows✓ classes✓ enhanced object literals✓ template strings✓ destructuring✓ default + rest + spread✓ let + const✓ iterators + for..of✓ generators

55

class ಠ_ಠ extends Array{ constructor(j = 'a', ...c) { const q = (({u: e}) => { return { [`s${c}`]: Symbol(j) }; })({}); super(j, q, ...c); }}new Promise((f) => { const a = function* (){ return "\u{20BB7}".match(/./u)[0].length === 2 || true; }; for(let vre of a()){ const [uw, as, he, re] = [new Set(), new WeakSet(), new Map(), new WeakMap()]; break; } f(new Proxy({}, {get: (han, h) => h in han ? han[h] : "42".repeat(0o10)}));}).then(bi => new ಠ_ಠ(bi.rd));

Solution to issue #4:

Test for lying browsers

Execute a bit of Javascript

and test for lies.

56

eval( 'class ಠ_ಠ extends Array{constructor(j="a",...c){const q=(({u:e})=>{return{[' + '`s${c}`]:Symbol(j)}})({});super(j,q,...c)}}new Promise(f=>{const a=function' + '*(){return"\u{20BB7}".match(/./u)[0].length===2||true};for(let vre of a()){' + 'const[uw,as,he,re]=[new Set,new WeakSet,new Map,new WeakMap];break} f(new ' + 'Proxy({},{get:(han,h)=>h in han?han[h]:"42".repeat(8)}))}).then(bi=>new ಠ_ಠ(bi.rd));');

Execute a bit of Javascript

and test for lies.

Solution to issue #4:

Test for lying browsers

57

try { eval( 'class ಠ_ಠ extends Array{constructor(j="a",...c){const q=(({u:e})=>{return{[' + '`s${c}`]:Symbol(j)}})({});super(j,q,...c)}}new Promise(f=>{const a=function' + '*(){return"\u{20BB7}".match(/./u)[0].length===2||true};for(let vre of a()){' + 'const[uw,as,he,re]=[new Set,new WeakSet,new Map,new WeakMap];break} f(new ' + 'Proxy({},{get:(han,h)=>h in han?han[h]:"42".repeat(8)}))}).then(bi=>new ಠ_ಠ(bi.rd));' );} catch (e) {

}

Execute a bit of Javascript

and test for lies.

Solution to issue #4:

Test for lying browsers

58

try { eval( 'class ಠ_ಠ extends Array{constructor(j="a",...c){const q=(({u:e})=>{return{[' + '`s${c}`]:Symbol(j)}})({});super(j,q,...c)}}new Promise(f=>{const a=function' + '*(){return"\u{20BB7}".match(/./u)[0].length===2||true};for(let vre of a()){' + 'const[uw,as,he,re]=[new Set,new WeakSet,new Map,new WeakMap];break} f(new ' + 'Proxy({},{get:(han,h)=>h in han?han[h]:"42".repeat(8)}))}).then(bi=>new ಠ_ಠ(bi.rd));' );} catch (e) { document.cookie = 'esSupportLevel=5; expires=' + (new Date((new Date()).getTime() + 2678400000)).toGMTString() + '; path=/ ;domain=netflix.com'; if(location.reload){location.reload(true);}else{location.href = location.href;}}

Execute a bit of Javascript

and test for lies.

Solution to issue #4:

Test for lying browsers

59

<script> try { eval( 'class ಠ_ಠ extends Array{constructor(j="a",...c){const q=(({u:e})=>{return{[' + '`s${c}`]:Symbol(j)}})({});super(j,q,...c)}}new Promise(f=>{const a=function' + '*(){return"\u{20BB7}".match(/./u)[0].length===2||true};for(let vre of a()){' + 'const[uw,as,he,re]=[new Set,new WeakSet,new Map,new WeakMap];break} f(new ' + 'Proxy({},{get:(han,h)=>h in han?han[h]:"42".repeat(8)}))}).then(bi=>new ಠ_ಠ(bi.rd));' ); } catch (e) { document.cookie = 'esSupportLevel=5; expires=' + (new Date((new Date()).getTime() + 2678400000)).toGMTString() + '; path=/ ;domain=netflix.com'; if(location.reload){location.reload(true);}else{location.href = location.href;} }</script>

Execute a bit of Javascript

and test for lies.

Solution to issue #4:

Test for lying browsers

60 What we’re doing (for now)

1. Build Babel as a transpiler.

2. Minifiers Babel plugins > babel-minify

3. Targeting User Agent to target supporting browsers

4. Lies Evaluated ES2015 to test; cookie fallback

61Our future:

Progressive Transpilation

ES2015

Modern

Legacy

No Support

Unsupported

Transpiled to ES5 Polyfill ES2015

Trailing

Fallback

62Mission accomplished

Goals balanced ⚖

*For now

*

👼 Best experience for our users.

🤓 Best experience for our developers.

63

Jem Young @jemyoung

Jacques Favreau @betaorbust

Questions?

Come ask us!

top related