[MUSIC PLAYING]
SAM EL-HUSSEINI: I'm Sam, a software engineer
here on the Kids Coding team at Google.
Today I'm going to be talking about NPM with Blockly.
A big theme at last year's conference
was that people wanted easier ways to integrate Blockly
into their applications.
If you're a web app developer, you're
probably familiar with NPM.
It's almost the de facto way of building web apps these days.
Developers don't really need to worry
about exactly what is inside of each of these modules,
as long as they are able to import what they need,
and Webpack or some other bundler
is able to pull all of these dependencies
into your application.
The obvious thing was to actually publish Blockly
onto NPM.
There's a bit more than just publishing our built files.
We actually need to interface with all
of these bundlers in such a way that they can understand
what each of our modules are.
So over the last six months or so,
we've taken hold of the Blockly package, which
was owned by one of our community members.
And they had just published the sources onto NPM,
so if you just wanted a way to acquire the sources,
that was an OK way to do it.
You still needed to configure Webpack or your bundlers
to know where are the built files
and what to pull into your application,
or you could just copy things over
into some public directory, and then
import it like this, which is the traditional way that we've
seen, so far, of how you include Blockly in your application.
Since then, we've taken hold of the package.
Now we own it, and we can publish
to it, which was actually quite an interesting process.
This is what we've traditionally done.
With NPM, we are able to surface each of our modules as--
we've decided to go with a UMD module.
And part of the reasoning for that--
if you know what UMD is, it's just
a way to include multiple different module systems.
So JavaScript has quite a few-- almost seven, I think--
and a lot of bundlers out there are
able to interact with things that are built
in a different module system.
So something could be built with SystemJS,
and it can just pull it in, wrap it around,
and be able to include it in your different module system.
Let's say you used AMD or something like that.
The most popular ones, somewhat incompatible in some ways,
are CommonJS and AMD.
And that's why we have something that's
a UMD, which is just a way to say,
"I want to be able to use the same module for both,
whether it's being used in CommonJS, which is what node
uses, as well as AMD, which is one
of the module systems for web developers."
If we do that, then we're able to use
the same NPM package, the same modules, in both environments.
And that was one of the big goals that we had.
We don't necessarily want to publish different applications
for node developers versus web developers.
You just want Blockly?
We'll give you Blockly, and you don't
need to worry about the internal details of how
we're doing that.
So this is part of that.
And the other nice thing about that
is that we also were able to publish TypeScript definition
files as well.
So if you're a TypeScript developer,
then as you import these modules,
you will get the types that are relevant to these modules,
and all sorts of autocomplete, [INAUDIBLE],,
and things like that will just show up.
We do have a third.
In that UMD module, we do publish also for global.
And that's not as useful, except in some test environments.
It's just a way for us to, essentially,
do what we traditionally have done,
which is allow you to include things with script tags.
But it's still the module.
It's just able to figure out that, actually, I'm
not in a module system.
I'm just in the web page, and I can just
load the actual things the same way we used to load things.
How do you get started?
If you've used NPM before, and I assume that's why you're here,
it's as simple as just including it as one of your dependencies,
hitting NPM install, and then you've
got Blockly in your application.
Well, you've got Blockly as a dependency installed
on your computer, but you need to still import it
into your application.
As you develop with that, one of the ways that you can import it
is by using "import Blockly from 'blockly'."
Part of the talk today isn't really about how NPM works,
but about what you're actually importing when you do this.
This is just a default import of Blockly,
which is going to include some of our submodules,
and we've decided these are the defaults.
So when you do this, you're including
Blockly core, which is essentially equivalent
to blockly_compressed.
You're including the built-in blocks, which
is blocks_compressed, the JavaScript generator,
and the English locale files.
If you're using a different language
that's not going to work for you.
If you want a different generator, such as Python,
that's also not going to work for you.
And if you want to optimize your application-- for example,
if you don't use any of the built-in blocks,
and you don't want to actually ship those built files--
then you don't want to do just this.
You want to be more specific in what you're importing.
Like I said, that's basically the equivalent
of doing just that in this old world.
If you want to be more specific, that's what you would do.
You would actually, instead, include the submodules.
So in this case, I'm including Blockly
from blockly/core, which is the core--
the blockly_compressed.
You'll import the blocks, which is the built-in blocks.
I'm importing the Python generator, in this case,
and the French locale files.
This is just a way for me to say that, hey, this
is telling Blockly to use this specific locale.
It's a set locale down here.
So I've managed to include the Python generator there
with the French locale files.
If I'm in Node, it's going to look pretty similar.
Node uses require instead of import, so more or less
the same kind of format.
And I haven't changed any for the submodules that I'm using.
Everything's referencing the same thing,
but I'm in node here.
If for some reason you use AMD this way,
then that's how you would use it.
I think this is RequireJS.
That's how you would include Blockly
and the specific submodules.
What we've actually done-- we've also added a number of samples.
We know that a lot of people work in different frameworks,
some of the popular ones, and we don't really
want to make any specific judgment about what is
necessarily the best way to go.
But we have some of the more commonly used frameworks
out there-- samples for them.
That includes a React, Angular sample, a Vue sample.
Those are the hot web frameworks today.
There might be more.
This is a call, also, for you guys.
If you use a different framework,
please build a sample.
It will help other people, and it's
as simple as using what that basic framework uses
as boilerplate, and just adding Blockly into it
and publishing it onto this repo.
We also include a Webpack, a Node sample,
a RequireJS sample, and then we also have a UMD sample.
And to clarify between what I was mentioning as UMD earlier--
this is actually the four core blocks
wrapped into one package.
That lets us do things like have people get it
from unpackage.js, which is a CDM that
says, "I just want Blockly.
I'm not too concerned about exactly picking and choosing
my modules, and I just want everything in the one file."
So there are samples to help you get started.
That's the list of them there.
I did mention TypeScript definitions earlier.
Like I said, they're bundled in.
If you've used TypeScript before,
generally, one of the ways that people get the TypeScript
definitions is by installing a different package.
Usually, it's underscore on DefinitelyTyped,
at type/blockly.
But we decided to include them as part of the package.
It's a more common thing these days to just bundle them in,
and then you don't have to worry about acquiring the TypeScript
definitions yourself.
And for Node.js support, like I said,
it's all included with the same submodules.
You don't have to change any of the names,
and that's just going to work in Node.
We do have a jsdom dependency.
NPM will take care of installing that.
That's just our way to be able to use the XML serializer
and deserializer in Node.
The package has been out for about a couple of months now,
and so far, we've seen a few community members adopt it,
not just for their own applications,
but people are building other layers of packages out there.
So if you're in the React world, we
have a community member that's built a Blockly React
component, which is based on the official Blockly NPM package.
So if you know how NPM works, that
will acquire, under the hood, our package.
But you don't have to actually worry
about importing that yourself.
If you're in React, you can just import blockly-react,
and you will get the entire stack of dependencies there.
It's only been out there for a few months.
Hopefully, we'll see more wrappers around this
to help you get started in that specific world.
A blockly-react compare.
If you look at some of the samples,
it's doing a couple of things to mesh the two worlds together,
injecting Blockly at the right time.
In React, that's when you load the component.
And so that's just helping even further bridge
the gap for somebody that just wants Blockly
in a specific framework.
I can now take some questions.
Yes.
AUDIENCE: [INAUDIBLE].
SAM EL-HUSSEINI: Yes.
Currently, the way that the package is published,
the TypeScript definitions only work if you use that default,
the "import blockly from 'blockly'."
If you're using a submodule, I didn't quite set it up right.
I know how to set it up right now,
so hopefully, in the next release, they'll be up,
and you can actually import the submodule
and still get the right definition files.
Until then, that's the only way to use that.
There is a way to get around that,
and that is to include the triple-slash directive
yourself.
If you add that reference path in your application that
references the node module/blockly/blockly.d.ts,
that will include Blockly for you,
and then you could still use blocky/core and blockly/blocks.
That sort of thing.
AUDIENCE: You mentioned that getting the Blockly
[INAUDIBLE] package was a little bit interesting?
Is it a good story?
SAM EL-HUSSEINI: It's just that somebody else owns it,
and NPM wanted to do their due diligence
and make sure that not some random person is trying
to acquire some other package.
It's a community-driven thing, so they're
pretty good about transferring things like that.
They know that people lose track of things or move
on to other things, but it's a lengthy process
to prove that you're who you say you are,
and also that you mean no harm.
[MUSIC PLAYING]
AUDIENCE: Cool.