►
Description
Speakers: Vladimir de Turckheim
Latest version of Node.js feature loader hooks. These hooks can be used to update the behavior of the module loading in a Node.js application.
Let's play with that and build:
* a dependency injection tool
* a on-the-fly typescript loader
* a module loader to instanciate code from the network
and any other fun things we can imagine!
A
So
hello,
everyone
thanks
so
much
for
coming
to
my
talk.
We
will
talk
about
loaders,
who
can
no
js'
and
yeah
I
said
it
will
be
fun,
I
hope
it
will
be
fun.
So
if
you,
what
about
myself
I'm
Vladimir
the
check
em
I
handle
nodejs
for
a
security
company
name
screen,
we
do
other
languages
but
I'm
also
a
node.js,
carburetor
and
part
of
the
node.js
security
working
group.
So
if
you
have
security,
questions
regarding
nodejs
feel
free
to
ping.
Me
I'd
love
to
help.
A
Let's
first
ask
what
would
you
need
to
hook
modules
in
JavaScript
and
how
you
will
do
that?
So
do
you
add
a
way
to
know
every
modules
that
have
been
loaded
into
a
node.js
application?
It's
time
a
module
has
been
required.
You
want
to
know
about
it.
So
you've
got
two
main
solutions:
either
you
can
take
checks
or
cash.
So,
each
time
a
module
is
required
in
node
it's
placed
in
a
cache
that
is
accessible,
there's
a
user,
so
you
can
check
it.
A
Oh,
you
can
hook
into
nodejs
and
be
told
each
time
someone
do
require
and
import
a
module
so
cache
it's
pretty
straightforward
to
access
it.
You
can
all
test
it.
You
just
type
require
that
cache
and
you
will
see
a
massive
object
that
has
knowledge
about
the
modules
that
are
loaded
and
which
module
have
required
them.
So
you
have
the
wall
dependency
tree.
It's
not
the
NPM
tree.
It's
really
why
the
module
has
been
imported
in
node.js.
We
imported
it
and
hope.
That's
doable.
It
just
sits
there.
So
it's
pretty
free
to
access.
A
You
just
type
require
that
cache
and
you
have
access
to
that.
You
have
the
full
require
require
tree,
but
first
of
all
you
don't
know
when
to
check
it.
So
let's
say
you
want
to
instrument
nodejs,
it's
an
arbitrary
decision
to
check
the
cache
at
one
time
and
not
five
minute
later
you
don't
know
what
people
have
passed
as
an
argument
to
require.
You
just
know
what
is
the
module
that
has
been
loaded,
but
you
don't
know
that
require
Express,
actually
loaded,
expressjs,
slash
index
dot,
JSP
and
you
can't
rewrite
the
import.
A
You
can't
modify
the
module
as
it
is
loaded
in
no
js',
and
that
may
be
something
you
will
want
to
do
and
we'll
see
later.
Why
so?
The
other
solution
is
to
hook
into
require.
So
basically
you
should
not
do
that,
because
it's
overriding
a
private
method
in
nodejs.
That's
why
it
start
with
underscore
load
and
some
people
in
the
room.
We
throw
things
at
me.
If
you
do
that,
so
you
overwrite
module
that
load
and
that's
a
method
that
is
called
under
the
hood
may
require
each
time
something
is
loaded.
It
takes
two
arguments.
A
The
first
one
is
request,
which
is
a
string
that
has
been
passed
to
require,
and
the
second
is
parents
which
represent
the
which
represent
module
from
which
you
require.
So
in
our
case
on
line
four
I,
just
log
the
parents,
then
in
a
row,
then
the
request
to
tell
you
each
module
as
require
of
that.
So,
if
I
ran
that
we
have
the
log
at
the
bottom
and
we
know
that
dot
the
main
module
required
Express
and
that
user
of
integer
can
screen
demo
required
that
fresh,
lipstick,
Express,
etc.
A
A
Basically,
it's
what
every
APM
do
and
also
hood.
To
be
honest.
So
thanks
to
the
great
node.js
core
teams,
there
is
an
API
for
that
in
not
Cornell.
It's
still
experimental.
It's
designed
to
replace
the
so
called
behavior
ugly
monkey
patching
it's
a
clean
API
for
that
it's
a
synchronous
and
so
far
on
node
12,
because
I
tested
that
on
node
12
it
only
supports
es6
modules.
A
What
does
it
looks
like
that's
a
great
question:
six
files
can
get
so.
Let's
say:
I've
got
those
two
modules,
one
named
main
dot,
MJS
that
import
another
module
that
is
lived
at
MJS
and
live
that
MJ
at
rest
exposes
a
function
named
hello
that
returns
world.
So
if
you
start
node
with
experimental
modules
or
wizard
wizard,
flagons
latest
version
of
node,
the
code
will
actually
run
and
the
es6
modules
will
be
resolved.
A
No,
let's
try
to
hook
into
everything
that
is
imported,
so
we
create
a
file
named
loader
that
MJS
and
this
MOU.
This
file,
this
method
is
stripped
just
expose.
An
a
synchronous
function
named
resolve
that
what
we
do
on
line
3
this
function
takes
three
parameters.
The
first
one
is
a
specifier,
remember
the
load
method
we
were
using
before
it's
basically
the
same
first
arguments:
it's
what
people
have
imported
when
you
do
an
import
in
node.js
that
will
go
through
this
method
and
the
specifier
will
pass.
A
Then
you've
got
the
URL
of
the
parent
module
once
again
is
the
modules
that
have
imported
the
other
one
and
the
default
resolver,
which
is
basically
a
function
to
tell
node
how
to
resolve
the
URL.
What
we
do
in
this
loader,
we
just
consult
a
clog.
The
specifier
and
the
reserved
URL,
meaning
that
when
you
require
Express,
this
loader
will
resolve
the
full
path
to
the
express
main
file
and
log
that,
and
then
we
return
the
URL
and
in
an
object
with
the
property
name
format
that
is,
module,
meaning
a
node.
A
It's
a
standard,
es6
module,
you
can
load,
whereas
you
know
to
do
so.
We
start
the
program
with
no
experimental
module
loader,
and
then
we
give
the
loader
as
a
parameter
and
then
we
put
main
dot
MJS.
We
have
to
Runnings
this
time
because
we
are
using
another
experimental
feature.
So
it's
another
thing.
You
should
not
do
in
prediction,
but
then
you
start
to
have
logs.
A
So
it's
exactly
the
same
code
as
out
the
previous
slide,
but
we
can
see
that
slashes
over
the
check,
my
per
ton
project,
yeah,
I,
love,
whoops,
Tom,
hello,
main
dot.
Mj
is
actually
resolved
to
the
same
URL
and
on
the
second
to
last
line,
the
slash
leave
that
MJ
is
resolved
to
a
full
URL
to
where
the
module
is
actually
located
and
then,
of
course,
we've
got
the
world
that
is
the
hello
world
from
the
line
of
the
code.
A
A
Let's
do
example,
then,
who
here
loves
typescript,
yeah
I
like
to
have
script?
It's
a
great
language.
It
reminds
me
of
Java,
but
hey
I
like
it.
It's
a
great
language
and
the
nodejs
community
and
the
JavaScript
community
at
large
loves
typescript.
So,
let's
build
a
loader
that
will
intercept
everything
that
is
imported,
read
the
source
file
of
the
typescript
file.
You
are
trying
to
import
in
node.js,
transpile
it
to
JavaScript
and
tell
node
to
load
so
JavaScript.
A
A
So
here
we've
got
two
fives
indexed
at
TS
and
lived
at
TS.
You
can
see
that
despite
having
typescript
I,
don't
put
a
lot
of
types
in
my
examples,
but
it's
a
detail.
Can
we
run
that
with
one
command
without
any
real
stage?
Yeah,
it's
technically
typescript!
It's
a
dino
TS
file.
Can
we
run
that
in
one
comment?
Yes,
we
can
so
once
again
we
create
a
function.
That's
named
resolved
that
is
exported
in
the
loader
hook.
A
What
result
will
do
on
line
seven?
Is
that
if
the
specifier
meaning
the
module,
you
are
trying
to
import
the
string
you
pass
to
import
if
it
ends
with
dot.
Yes,
in
that
case,
it
will
ask
for
a
new
target,
which
is
just
a
variable
that
call
the
method
name
T,
as
this
will
check
that
later.
That
gives
actually
the
URL
through
a
JavaScript
file.
A
So
basically,
what
tears
is
does
is
it
takes
the
URL
to
a
typescript
file
and
will
return
the
URL
to
a
JavaScript
file
and
guarantees
that
your
JavaScript
file
exists
and
is
in
JavaScript.
So
let's
check
this
method,
it's
pretty
straight
away
on
online
aniline
8.
What
we
do
we
just
read
the
file.
We
read
the
typescript
file,
it's
just
a
well
premised
rid
of
FS
the
tweet
file.
So
we
get
the
source
code
in
typescript.
A
We
just
read
a
file,
then
we
call
the
typescript
module,
so
I
did
npm
install
typescript
and
I
got
the
module
type
script
that
I
imported
that
I
required
into
this
file.
It
exposed
a
method
named
transpile
module.
So
as
a
first
argument
to
this
method
on
line
9
I
just
give
it
the
source
code
in
typescript.
Ok,
I
give
an
option
to
tell
it:
please
don't
compile
the
import,
give
me
a
6
imports
and,
as
a
result,
I
obtain
a
huge
string
that
is
JavaScript
code
transpired
from
typescript.
That's
what
I
have
in
transpired.
A
It's
a
synchronous
code,
but
basically
it's
just
JavaScript
piece
of
code.
I
probably
should
put
that
in
a
worker
thread,
but
at
the
next
talk
in
the
same
old
stay
here
on
line
12.
What
I
do
I
just
write
this
javascript
code
into
a
file?
That
is
the
same
file
as
where
from
which
I
read
the
typescript,
but
just
I
replace
the
extension
from
TS
MJ
s,
that's
what
they
do
in
912
and
then
I
just
returned.
A
Actually
the
code
will
run
so
instead
of
giving
a
JavaScript
file
to
execute
node,
we
give
it
a
type
script
file
and
we
just
told
it
what
to
do
with
typescript,
which
is
pretty
straightforward.
We
don't
have
compilation,
we
don't
have
anything
to
do
before
running
this
code,
and
that
was
the
first
example
over
three.
Let's
do
another
totally
different
and
crazy
and
stupid
example.
This
one
is
a
remote
loader,
so
I
helped
some
people
disliked
package.json
and
popular
opinion.
I
love
package.json.
A
So
some
people
want
to
be
able
to
transparently
get
dependencies
from
the
internet,
not
knowing
where
it
comes
from
not
having
any
kind
of
hashing
security
or
anything
signatures.
And
let's
do
that,
so
we
create
a
loader
that
really
intercept
what's
imported,
exactly
the
same
thing
as
the
previous
one,
but
this
one
will
download
the
suicide
you
required
because
you
will
give
me
a
URL
to
requires
a
file.
I
will
write
it
on
the
disk
and
tell
nodejs
to
load
this
file.
A
So
here
again
an
example,
so
in
index
that
MJS
we've
got
import
stuff
from
as
remote
from
HTTP
slash,
slash
gives
the
date
abuser
content
that
can
video
check,
MDS,
50
glass
/lib
that
j/s
and
we
do
control.com
of
everything
that
comes
from
that
guest
and
in
HTTP
kiss
that
guitar
concert
/
Wladimir
that
you
can
leave,
that
is
we
just
have
export
cost
yellow
equals.
What
can
we
make
this?
What
can
we
just
start
node?
Have
it
no
download
the
code
and
do
the
thing?
A
Of
course
we
can,
because,
basically,
since
the
API
premier
providers
with
a
need
for
a
synchronous
method,
we
can
do
any
a
synchronous
code.
We
want
into
the
loader.
So
once
again
we
create
a
result,
function
that
takes
as
a
first
argument,
identifier
and
you
know
original
function
with
a
on
line
3.
If
the
identifier
specifier
start
with
HTTP
colon
space,
yeah
I
did
not
put
HTTP
I'm
crazy,
but
I
have
limitations.
Let's
use
HTTP
here.
A
What
we
do
is
we
just
await
rekted
gaps
so
right,
here's
a
cool
you
teens
to
do
load,
HT
to
download
an
HTTP
client
every
and
using
it
is
pretty
cool
and
promise
ready,
I'm
being
paid
by
the
people
on
the
first
round
to
follow
that
path.
Saying
that
so
you
just
rag
that
gets
the
specifier,
which
means
you
do
an
HTTP
request.
A
You
get
the
content,
it's
available
as
a
payload,
you
take
it
and
you
write
it
in
/tmp
TMP
that
may
MJS,
meaning
you
basically
just
do
loading
the
code
from
github
and
write
it
on
your
disk
before
executing
it,
which
is
probably
the
safest
thing
you
can
do
over
the
internet.
Right
then,
you
tell
node
to
resolve
the
file
based
on
the
real
default
resolver
to
open
the
file
you
have
just
written
in
the
disk
on
96.
Does
it
works,
of
course?
A
So
you
don't
know
experimental
modules,
loader
index,
that
MJS
test
index
that
MJS
and
it
will
display
that
you
are
trying
to
display
your
module,
which
has
a
property
named
arrow
with
a
very
world,
so
it
worked
and
of
course
you
can
make
the
typescript
thing
in
the
remote
thing.
If
you
want
I,
think
there's
a
project
name
like
that.
That
was
based
on
ten
thing.
You
might
forget,
work,
oh
geez,
but
you
can
mix
all
of
that
and
do
whatever
you
want.
Based
on
that,
so
it's
pretty
cool.
A
Let's
go
to
a
more
usable
use
case,
one
that
can
be
used
in
real
life
and
that
might
make
sense.
Maybe
the
typescript
thing
makes
sense.
Let's
do
dependency
injection,
so
testing
code
is
sometime
painful
and
some
people,
and
often
you
change
your
code
to
make
it
easier
to
test
and
I.
Actually
don't
like
changing
my
code
just
for
the
sake
of
making
things
more
easy
too
much.
I
want
to
write
code,
that
is
performance
that
is
easy
to
maintain.
A
A
So
what
we
will
do
is
we
will
do
a
loader
that
will
intercept
the
inputs.
This
one
doesn't
change
and
when
something
is
imported
it
will
replace
every
export
of
that
module
with
proxies,
and
it
will
expose
these
proxies
to
you.
So
you
can
manipulate
them
so
question
what
is
a
proxy
in
JavaScript
and
to
talk
about
proxies
that
we
need
to
talk
about
dogs.
So,
let's
say
let's
say
you
have
a
dog
class
and
online
to
ID
cares.
A
A
It
works
pretty
standard
Li.
So
if
we
come
so
that
log,
the
dog
will
get
kind,
good
name
only
care,
and
it's
a
dog.
If
we
asked
it
to
say
hello,
she
would
say
woof
woof,
my
name
is
only
Karen
a
good
luck
and
that
works
perfectly
well
and
one
morning
you
wake
up,
and
there
is
a
text
from
your
mother
showing
this.
A
So
the
dog
has
made
a
party
in
the
rubbish
at
home
and
my
parents
aren't
mad
at
it
and
maybe
we
miss
her
line.
The
dog,
maybe
maybe
only
carries
not
a
good
dog.
She
might
be
a
cow,
a
good
dog
thanks
for
nothing
in
French.
They
did
not
get
this
drug
so
yeah.
She
still
a
good
dog
she's,
just
a
Celtic
good
greeter.
Let's
underline
all
the
dogs
based
on
that.
A
So
we
want
to
find
a
way
to
make
only
Carol,
chaotic,
good
dog
but
she's
still
a
good
dog,
and
we
start
impacting
all
the
other
dogs
I
don't
want
to
change
the
constructor
of
God
of
dogs
just
because
one
dog
is
not
good.
Only
so
I
create
a
proxy,
so
online
whine
I
create
my
dog.
Only
can
you
new
dog
and
then
I've
created
a
proxy
around
it.
So
I
call
new
proxy
as
a
first
argument.
I
pass
the
object.
A
I
want
to
create
a
proxy
on
and,
as
a
second
argument,
I
pass
an
object
named
a
handler.
So
basically
what
we
will
do
here,
we
will
define
a
gator
on
three
properties,
so
the
handler
it's
just
an
object.
You
pass
properties
into
it.
They
are
written
in
the
MDM
documentation
and
we
realize
when
one
of
the
property
we
will
use
is
get
it's
a
trap,
then
get
meaning
that
each
time
someone
will
try
to
access
a
property
on
this
subject
returned
by
the
proxy
constructor.
This
piece
of
code
will
be
caught.
A
A
So
what
we
do
if
the
property
is
kind
instead
of
good,
we
return
charity
good
and
otherwise
we
return
reflect
that
get
which
is
basically
give
me
the
real
value
of
the
property
of
the
object,
because
if
I
called
targets
that
prop
it
will
be
an
infinite
loop,
so
I
do
reflect
the
debt
and
I
return.
The
original
property,
then
I
consulted
from
my
dog
and
then
I
asked
her
to
say
hello.
So,
as
a
result,
we
can
see
that
she's
still
a
dog
she
still
good
still
named
Annika.
The
base
object
hasn't
changed.
A
A
A
If
we
check
if
the
module
is
not
imported
from
itself,
it's
to
prevent
infinite
loop,
so
just
an
implementation
detail,
but
then
we
append
an
underscore
at
the
URL
on
line
7
it's
to
avoid
having
two
modules
with
the
same
URL,
because
what
we
will
do
is,
instead
of
having
a
raised
dot
format
which
is
module.
Remember
in
the
first
example
here
it's
dynamic.
It's
a
way
to
tell
nodejs
this
module.
You
won't
find
on
the
disk.
You
will
find
it
dynamically.
It
will
be
created
dynamically
from
the
loader
and
then
we
return
that.
A
So
what
we
do
we
remove?
First,
we
remove
the
last
element
of
the
URL.
Remember
it
and
Oscar
I
added
on
line
seven
here
we
remove
it
and
we
call
import,
and
since
we
call
import
again,
that's
why
we
had
to
check
for
an
infinite
loop.
Here
we
say
that
if
we
are
requiring
a
module
from
here,
then
we
require
the
main
module
so
in
mud
on
line
two
I
have
the
actual
made
real
module
loaded.
It
has
been
loaded
as
it
would
have
a
boy
imported
it
now.
I
can
rewrite
it.
A
So
first
of
all,
I
need
the
list
of
the
things
that
are
exported
by
this
module,
because
no
J's
will
want
that.
So
that's
what
I
do
on
line
three
address
do
object
that
keys
and
I
get
the
list
of
all
the
exports
of
the
module
I
per
an
extra
ones,
that
I
called
test
and
Oscar
much
and
that's
basically,
the
one
people
will
use
to
manipulate
or
proxies
so
I
push.
It
then
I
return
an
object
that
has
a
first
property
named
exports
that
contains
the
list
of
everything
that
is
exported
by
the
module.
A
No
problem,
everything
that
is
exported
by
the
module
and
then
we've
got
a
function
named,
execute
that
is
executive
when
the
module
is
dynamically
instantiated.
What
does
it
do?
It
creates
a
map
on
line
eight
retaining
much
and
I
set
experts
except
another
export.
The
test
mark
too
much
meaning
like
if
you
import
this
module.
If
you
import
a
modified
module,
there
will
be
an
extra
property
name
text
test
mark
that
really
expose
this
map.
We
created
on
line
eight
and
four
every
property
exported
in
the
module
that
the
for-loop
online
ten.
A
We
create
a
handler
object
that
is
empty,
JavaScript
object
on
line
11.
We
make
it
available
in
a
world
map,
meaning
that
we
are
making
the
handlers
of
our
proxy
available
through
the
map,
meaning
that,
if
I
have
a
method
named
X
exported.
My
map,
created
on
line
eight
mark
will
have
a
property
which
K
is
X
and
which
value
is
an
empty
object.
That
is
a
handler
for
proxy,
and
then
we
set
the
export
that
what
we
do
on
line
13.
A
A
So,
let's
try
it
out.
Let's
import
a
set
first,
and
then
we
import
a
module
named
Lib,
one
that
MJS
you
see
that
this
module
it
exports
a
method
named
main,
but
also
an
import
test
mock.
My
idea,
IDE
is
not
happy
with
that,
because
the
real
module
does
not
have
a
property
name
test.
Mark
that
why
some
tax
correlation
is
bad,
but
I
know
that
it
is
here
because
I
created
it
in
my
loader
and
I
made
it
available
in
this
proxy
in
this
file.
A
So
test
mark
is
actually
a
map,
so
in
line
six
I
check
that
main
returns,
hello
out
and
it
works
main-
is
a
function
that
returns
in
world.
So
that's
what's
happening
on
line
seven.
That
is
interesting
on
line
seven
I
take
test
mark,
so
it's
match
I
ask
for
the
property
which
is
behind
okay,
main
meaning.
It's
the
handler
all
the
proxy
on
the
function.
A
Name
main
I
know
it's
a
bit
deep
and
to
the
subject:
I
had
a
property
named
apply,
remember
I,
should
you
get
in
the
example,
but
the
dogs
apply
is
another
trap
and
proxy
that
will
be
called
each
time.
Someone
call
this
as
a
function
and
pretty
sure.
If
you
can
replace
and
define
with
a
proxy,
you
will
be
able
to
make
and
define
a
function.
A
First
of
all,
none
of
that
is
proud.
Reddy's.
Oh,
don't
don't
use
it,
you
know
it
was
a
talk
for
the
show.
Now
it
will
probably
be
extremely
useful
in
the
classroom,
but
certainly
we
probably
can
do
dino
things
with
that.
You
remember
like
running
JavaScript,
typescript,
transparently
getting
modules
from
remote
location
with
a
package.json.
Do
we
want
to
that?
That's
another
debate.
You
don't
want
to
get
into
that.
We
could
have
a
generic
API
for
transportation,
so
this
one
is
exciting.
A
Let's
say
that
type
script,
the
module
expose
a
method
named
transpire
for
node
and
that
CoffeeScript
for
the
people.
We
still
use
that
the
coffee
script
module
would
expose
a
method
named
transpire
followed,
and
maybe
even
we
could
imagine
weirder
things
like
even
m1
transpire
followed.
We
could
start
node
with
transportation.
A
Nah
t
then
put
the
name
of
any
NPM
module
like
you
would
say:
node
t
type
script
and
then
node
would
run
type
script
transparently.
For
you,
we
could
be
even
more
weirdos
with
that
and
go
one
step
further
and
pets
rushed
to
webassembly
transpiler
here,
and
you
would
do
node
and
cool
rest
fights
directly
for
node,
but
thanks
to
a
loader,
it
will
be
transpired
to
web
assembly
and
loaded
in
node,
or
you
could
do
that
with
OEM
scripting
to
load
any
c++
libraries
or
anything
that
compares
to
node
or
webassembly.