Thứ Tư, 31 tháng 5, 2017

Waching daily Jun 1 2017

Sharing is Caring - Patterns for JavaScript Library Design

[Applause] MAGGIE: Hi, everybody.

How are you doing today?

You are hitting the end of the conference, it's like the tired part, but we are going

to be okay.

So I'm here to talk to you about API design for JavaScript libraries and how you can do

some sharing, so I will say up on the screen are my two kids and the oldest, Dalton, really

likes to tell you that caring is sharing when he wants to eat the food on your dinner plate.

So who am I?

I really think that you need know nothing other than semicolons, tabs, all the code

in the slide is semicolons, tabs.

In all seriousness I work for Microsoft, I'm a crisis management engineer, so if you are

hosted on Azure and your things are not working, I am the person who is on the phone being

like: everyone wake up!

I am a maintainer of Moment.js, there are two of us here today, I don't know if some

of you saw Matt's talk earlier, but I am a maintainer of Moment.js and in addition I

am the JS Foundation's representative to TC3 ... 9 and I represent the JS Foundation which

is awesome and supports JavaScript projects in the ecosystem.

I will tell you, if you have made a JavaScript commit to an open source project we represent

you so if you would like representation, we are your representation as an open source

committer, and on that note I am the champion of the date re-work proposal that was talked

about earlier, so if you are interested in what's happening in JavaScript date, I am

working on that, but today that is not what we are talking about.

Today what we are talking about is libraries.

Is anybody here besides me a library author?

Okay, all right.

I am going to bring up some libraries and if it's one of yours and I got it wrong, you

shout real loud: you got that library wrong, Maggie.

So what is a library?

There are a lot of definitions for the word library, but what I am going to go with is:

a library is a bit of code that's useful when it's packaged up and distributed to other

people.

This could be internal or external, so there are tons of external libraries that we know

about, like LoDash, jQuery, Request and I think everybody in the room nearly knows every

one of those, right?

Internally there's a tendency to make internal libraries.

I know at Microsoft we have millions of internal libraries for the purposes of logging and

analytics.

Oh my gosh, I add internal libraries to everything for that.

For the purpose of this talk I do want to define what is not a library.

I am going to say things like Express or Angular or webpack are not libraries for the purpose

of this talk.

Instead, Express or Angular would be a framework.

They do a whole lot more than provide some useful code.

They tell you how you should code.

Webpack on the other hand would be a full tool suite so I'm not going to consider those

things libraries.

One other thing I am going to mention about this talk is that I'm going to get out examples

of some of the libraries I have listed at the top, and we might think of those libraries

as like lame, like it's from 2007, guys, but the bottom line is these libraries have survived

a really long time.

So we are really into the new hotness in JavaScript but for the purposes of this talk I have stuck

to libraries that we are all npm installing several years later because longevity is good.

Call me lame, it's okay, I can live with it.

So here is what we think a library is like.

Whose kids behave like this all the time, like happy and playing?

All right, so here is what having a library is actually like.

Does anybody have this toy besides me?

This is a toy only a grandparent would give you.

There's two kids, some buttons and some whipped cream.

[Laughter] What is what having a library is like out

in the open source space.

Like that looked really fun, and then boom.

Kept in the open source space it actually looked leek this.

Tim Wood, awesome guy, he was like: I'm going to share, I am going to care - and here we

are four years later with 2,400 closed issues and 176 open.

That's what having a library is like.

And your best defence against that is making it well.

So what makes a library good?

Small size.

I never want to hear about it again.

Great code!

Your users don't use your code.

They are never going to look at it.

Encourages functional programming practices: it's big right now, isn't it?

Wait, wait, this is JavaScript, the amazing mocha ... tool chain that I spent 12 weeks

assembling, that made my library good.

Guys, ease of use.

Ease of use.

Nobody wants to learn your library.

They won't.

Those 2,400 odd GitHub issues, 50% of them are, "I didn't read your documentation".

It's okay to make it simple.

You don't have to get into fancy patterns.

Your users are just going to go: what's partial application?

So I am going to break this out into four areas.

One: invocation.

How do I invoke my library?

How do I actually call it?

Two, configuration.

This is a huge part of any library, it doesn't do what I want it to do unless it changes

its configuration this way.

Three, defaults.

What should the default behaviours of my library be?

And finally errors, which are no easy thing to deal with.

So invocation.

Basically for any library there's two kind of simple ways to invoke it.

One is static invocation, right?

You just call a function.

So here we have two great libraries that I think everyone here has probably touched,

a request from Node and this is aesthetic invocation, I want to get Google.com and I

get a call back.

It's just static.

Or good old 27 million downloads a month LoDash, who here hasn't used it - I am asking for

filter, and I get back a filtered list.

Awesome.

Static invocation is a great pattern.

I would not shy away from it.

For logging libraries this is the way to go.

It's easy, you just say dot log, dot error, it's easy for people to figure out, they don't

have to think too hard about what's going on so this is my go-to if I want to write

a simple library.

It has a drawback though.

Here is LoDash without using any of the chaining or functional features.

If I want to get the sum of some odd numbers doubled.

We are going down - like this almost looks like a Christmas tree but it's not, it's just

LoDash.

All right, so when you start getting into this kind of trap with your library then you

are probably going to move to doing something like a factory function.

Now, many libraries have done really well with the factory function.

Up here, I have Q - everybody has used Q, right?

Oh yes, it returns promises, doesn't it?

Q fundamentally is a library that makes promises, and then you can do what you will with those

promises.

JQuery, good old ubiquitous jQuery makes jQuery objects.

Who learnt that when they first started coding ten years ago?

And Moment, my library.

By the way, I am going to shred Moment in my examples.

I will tell you of my pain.

But Moment again is a factory library.

You invoke Moment and you get back a Moment object.

And these kinds of things allow for some really, really good patterns to happen.

A factory function is what's going to allow you to go into a chaining API or at least

is one very good way to do that, so here we can see Q, again we are doing F call, which

is going to give us a promise back, and then fundamentally we can chain on another promise

and chain on another promise because we just keep on getting promises all the way down,

so this is a super helpful way to invoke a library, to have it give an object back and

then have that give an object back.

There are some problems with chaining but on the whole it works well for a lot of people.

Here is chaining API, here I'm adding three days to the current time, then going to the

start, and then going to a year ago.

God knows why I would want to do that but people have.

It reads really easy, I'm not questioning where is this invocation in the world, I'm

just cruising along.

JQuery, again like for all that we like to rip on jQuery for the bad programming practices,

man does this get our work done?

I still bring in jQuery if I have a static ASVC web page.

Why not?

So the next set of patterns that I would like to look at are configuration patterns.

Almost every library in the world is going to need some form of configuration, and it

can get pretty difficult for people to figure out how to do.

So we will take a quick look at Moment.

This is Moment like circa 2012.

It was great.

You had a date string and you could either pass it into the Moment constructor and let

the Moment constructor deal with it or you could specify a format to make sure that the

constructor got the right thing.

This is beautiful.

This was easy.

Moment 2017.

Constructor.

Here, you can construct with an array, you can construct a Moment from another Moment

object that will give you a copy, you can construct a Moment from a date, I guess that

makes sense; you can do a date string with a format in the English language or any other

language; you can use strict mode which will force you to match the pattern that you are

supplying; you could combine language in strict mode, oh, multiple formats, maybe you are

expecting four or five formats, I am going to throw an array in there and I still need

to support language and strict mode.

Whoa!

Like that was intense.

By the way, having this overloaded constructor where your constructor is expecting like a

billion options, I think - so Moment uses ES6 modules and I think to actually parse

out this constructor it happens in about ten files that are all about 100 lines of code

each, just to parse this madness it's like type checking and then what does this actually

mean?

This isn't that great.

I am going to give some credit here to my colleagues on the ECMA402 Committee.

They have been putting together the new internationalisation API.

Has anybody used those?

Oh yeah, the international API so the standards said how are we going to do configuration

because localisation takes a heck of a lot of configuration and they came up with this

really simple paradigm, and for all that it isn't fancy, I love it.

I think it's really going to serve JavaScript's users over time, and it's this.

I am going to create a new date time format here.

I must know the locale for the format.

The locale is required, right?

So I put the required parameter here, and then everything else I need to know I put

in an options object.

Now, this is used the world over, in a million libraries, and it's used because it works.

I'm easily specifying hour, minute, second and time zone formats without having a mess

in my constructor, without having to chain defaults to the global object.

None of that is happening.

So options, objects, it seems simple, it seems almost stupid for me to say but they are going

to get you a long way in cleaning up constructors like I showed you with Moment.

The other thing they do and again good old jQuery, you are beautiful - you really were

- is they have simple business logic.

If you go into options object less than then say you want the user to be able to define

a behaviour in the library you are going to be able to do something like that with this,

here we have jQuery AJAX requests and if I want to file a 404 I can parse a custom function.

This is beautiful.

This is easy for the user.

So basically, when it comes to configuration, do required parameters at the beginning of

your constructor and then tie the options object to the end.

This is going to be the easiest way for anybody to invoke your library.

Defaults.

Now, defaults are a fascinating topic, and they are difficult to get right.

Let's look at this.

This is a clean HTTP request with a built in no JS APIs.

I assume a lot of people here have done this, the plain no library HTTP request and some

interesting stuff is going on.

What I want to do here is I want to get the Moment, so I am going to Tim R Wood/Moment,

okay, great, I assume I get requests and a few things get crazy here, I actually do like

continuous update stream, response body, but I want to call it this, I get a re-direct.

301, move permanently.

That's absolutely true because Tim moved the Moment repo to the Moment org years ago, but

now because I get a re-direct I am going to have to start this whole process again and

go look for the re-direct link that I got.

That's kind of a pain.

Request.

Anybody here a Request user?

This is a good library, it does a lot of good stuff for us but a big one is it will automatically

follow a re-direct so here when I kick off my request for Tim R Wood Moment, I actually

get back the repository I wanted with the data about it.

It just automatically followed the re-direct.

Now, what this is is best by default.

When was the last time that you got a re-direct link and didn't want to follow it?

Right.

I am sure it has happened and I am sure you can configure requests to not re-direct but

like seriously, this is like 95% of the time, 99% of the time, you are going to follow the

re-direct, so if there's an obvious right best answer like that's like well over 90%

case, then do it!

Right?

But here is a flip side, I am going to go back to Moment, nothing like trashing the

library that I love so much.

Here I have Moment and I'm parsing in this date string, let's pan out 1025 and I get

out 1725.

Why?

So here is what is actually going on with Moment.

Time is complicated and when I parse in 1025 to the base Moment constructor I get back

1725 because it's converting it to local time, minus 5 here, and then I came to Berlin time,

right?

If, in fact, I had wanted UTC, I would use the UTC constructor.

If I had wanted to stay in minus 5 I would use parse zone.

If I had wanted a different time zone, for instance New York, then I would use the time

zone constructor.

There's no good default here.

Like, honestly, are any of those like the thing that you do all the time, are any of

those a 95% case?

No.

And this single API flaw has caused more support issues in Moment.js than any other thing by

about three orders of magnitude.

People are like: why isn't this the day that I thought it was going to be?

And all they really had to do was this: instead of having that default just Moment paren constructor,

if we had made people choose and made them say Moment.local, they would have gone, "Oh,

local time", and it would have saved us I don't know how many hours.

The next time we ran a major version for me to deprecate the major constructor will be

all of 30 minutes of work and it is happening.

We are not living like this anymore.

Get to update all the docs.

Then you get to update your code.

So default only when there is a best answer.

If there are several likely behaviours, don't lock yourself into the trap of answering support

requests on all of them.

So the last thing I want to talk about is errors.

So errors at one time in JavaScript, we were like in happy fun land, like we are on the

bus, we will just ... the browser and it will be really great, then we will hit F12 and

it will be great, then this happens.

This is directly out of the Node.js docs.

Exception must be handled or the no process will be handled immediately.

Who has had this happen?

Oh yeah.

So we were like: you are going to use it on a server and then the error is going to happen

and we are going to crash the server?

Oh God!

And for a long time people got this idea that

libraries should never throw errors.

Never throw errors in a library, you will kill things.

But that's difficult too, so I actually like any good software engineer went to Twitter

and was like: does Node give any official guidance about this error thing several years

in?

And it exploded into a massive Twitter conversation that lasted like four hours.

And the only thing back I really got from Node is that Miles cares a lot about errors.

He wanted me to tell you, so Miles cares a lot about errors.

But the general consensus on the thread can be summed up as: throw an obvious developer

error.

So let's break that one down.

Here is Moment doing actually a pretty good job at its thing.

This is a date and it's probably user input, and user input is always potentially junk,

right?

So we don't want to every time a user enters a date, if that date isn't in the format that

we want, start exploding Node servers, so instead what happens is we very politely take

your input and we say: oh, you have tried to format this; invalid date.

And then maybe your one user with the bad input sees invalid date but at least we haven't

taken out your Node process.

So this is done.

Bad user input doesn't crash.

But then we have this other thing going on.

You need to get on Moment to get the hours date part, and this looks great, it gets us

back 13, and must be some time in the early afternoon that I ran this, but this is weird.

I misspell hours, I put in hurs, and I get back a Moment object.

I would completely expect to get a Moment object from that method invocation.

At the end of the day this wouldn't be deployed onto a server in production.

This is a developer time error.

And it's one that's potentially very difficult to find.

You will go digging through your code and you will be like: where is it?

Why do I see JSON where I should see a string?

What the heck?

And you will get all the way down to the library and you will be like: those people! [Laughter]

So let's see an example of this actually being really done well.

Who here - this is immutable, people used Immutable from Facebook?

Sure.

Good library.

What Immutable does is it makes collections.

Here we are going to make a map and any time we change this map it will make a new map

and this is this library doing it very well.

We are making a map, ABC, 123, then we set B and the first map still has 2 and the second

map has 50 so that's what it does.

Okay.

But it does something awesome here.

When I try to make a map of the number 1, which is like impossible, because like how

do you map the number 1, it actually tells me: hey, developer, we expected an array or

an iterable object.

Could you hand that over?

[Laughter] This is good.

When it comes to errors, if it's about the parser user input then you are going to want

to try to suppress as best you can for Node.js but if you can tell the dead fat finger something,

help them out and undo the fat finger.

In conclusion, just make stuff easy to use.

Don't get fancy, don't spend a lot of time thinking about: oh, what are the functional

paradigms I can use here and how beautiful can my code be and what tool chain can I have?

At the end of the day, some have lived for years not for anything other than the fact

that people picked them up and were able to use them quickly.

So put your investment as a library author, whether internal or external, right there.

For invocation, static your factory.

One of them is going to work out for you.

Chaining may really enhance your problem domain.

Objects for configuration, everybody knows them and they really do clean things up.

Defaults, careful, careful.

When there is an obvious right answer, then pick that to be your default, but don't pick

an arbitrary default.

Do not do it.

And finally, throw for those obvious developer areas that make it so your users aren't sitting

there complaining about how you are a horrible person and how they couldn't find this mysterious

bug in your code.

After that, just share.

Get out on GitHub, through your company get people contributing to your library internally

and be friendly and be open to new ideas.

All right, well, thanks, everybody.

I love questions, so ... [Applause] >> Wasn't that fantastic?

Come on, more rounds of applause, please.

Woo!

[Applause]

For more infomation >> Maggie Pint: Sharing is Caring - Patterns for JavaScript Library Design | JSConf EU 2017 - Duration: 25:38.

-------------------------------------------

Kareena Kapoor ! OMG ! SHOCKING - KAREENA BORROWED Kim Kardashain's MATERNITY WARDROBE here is proof - Duration: 4:22.

KAREENA BORROWED Kim Kardashain's MATERNITY WARDROBE here is proof

For more infomation >> Kareena Kapoor ! OMG ! SHOCKING - KAREENA BORROWED Kim Kardashain's MATERNITY WARDROBE here is proof - Duration: 4:22.

-------------------------------------------

Oklahoma teacher says move to Dallas is more than just for significant pay raise - Duration: 1:17.

THE REASON HER MOVE IS ABOUT

MORE THAN JUST MONEY.

>> I AM ALMOST DOUBLING MY

SALARY WITH A THROUGH OUR MOVE

TO THE SOUTH.

>> THEY MADE AN OFFER SHE COULD

NOT PASS UP.

>> I'LL GET TO BUILD A PROGRAM

FROM THE BOTTOM UP.

I'LL GET TO WORK WITH KIDS THAT

HAVEN'T HAD CONSISTENT TEACHERS

OR ADMINISTRATION.

>> DALLAS ISD HERE IN APRIL,

HOPING TO LURE TEACHERS FROM THE

SOONER STATE DOWN I-35 FOR

BETTER FUTURE AND PAY.

>> WE HAVE A LARGE NEED FOR

TEACHERS.

>> THE FORMER SANTA FE

ELEMENTARY SCHOOL TEACHER WILL

BEGIN TEACHING MIDDLE SCHOOL ART

NEXT SCHOOL YEAR, SHE SAYS THE

REASONS FOR LEAVING ARE SIMPLE.

>> PUBLIC EDUCATION IS STARTING

TO FAIL.

YOU HAVE CLASS SIZES DOUBLING

GOING FROM 20 PLUS KIDS TO 30

AND 35 KIDS IN ELEMENTARY

SCHOOL.

YOU'RE NOT GIVEN TEXTBOOKS.

NO RACES FOR -- NO RESOURCES FOR

TEACHERS.

>> WITH LEGISLATORS FAILING TO

PASS A MEASURE THIS SESSION TO

FUND TEACHER PAY RAISES, THE

SINGLE MOTHER SAYS OTHER

TALENTED TEACHERS ARE MAKING THE

SAME HEARTBREAKING DECISION TO

LEAVE THE STATE OR THE INDUSTRY

ALTOGETHER, TO BETTER THE LIVES

OF THEIR FAMILIES.

>> I AM REALLY HOPING I GET TO

COME BACK, BUT RIGHT NOW LOOKING

AT THE WAY THINGS ARE GOING, I

Không có nhận xét nào:

Đăng nhận xét