
Today’s Javascript, from an outsider’s perspective - llacb47
http://lea.verou.me/2020/05/todays-javascript-from-an-outsiders-perspective/
======
esperent
I had a similarly frustrating experience when I first set up Python to use
Django. The complete mess that is the Python 2/3 split (thankfully somewhat
better now after many years), trying to figure out what the hell pip and
pipenv were (this was before I was familiar with package management).

However, I initially learned some Python in university and I liked it then. We
just installed Idle and ran some simple scripts, and everything worked. That's
the right way to learn a language. If you dive straight into JS package
management, you are attempting to learn multiple things at the same time:

* Node.js environment

* Browser environment

* JavaScript syntax

* 'running a localhost'

* JavaScript modules

* NPM package management

You need to tackle these one by one. If you do them all at once, even with
prior experience in other languages, of course you're gonna have a bad time.

Really what I take away from this post is that the author is a bad teacher,
although the experience of her student is probably similar to what many people
experience when trying to learn by themselves.

There are many improvements that could be made to the JS ecosystem, but this
post does not do the current state justice. What it highlights, if anything,
is a problem with the available of a standardized learning path. But I'm not
sure what the solution to that would be.

~~~
pottertheotter
I've been learning Vue this year (I'm new to anything JavaScript so that means
I also had to learn JavaScript, Node, NPM, We pack, etc.). I'm getting a lot
better, but it has been a pretty frustrating experience. There are so many
different layers and they are constantly changing what they do and don't use
in another layer.

I've been working in Python for the last several years. There's definitely a
learning curve there, and I get frustrated with things all the time, but the
whole JavaScript ecosystem seems like such a mess compared to Python.

One of the things I miss the most about Python when working in JavaScript is
the documentation. And I mean the core documentation from Python.org. The
Tutorial is amazing [0]. And you can download the entire documentation already
in PDF. Maybe I'm one of the few, but when I'm learning something new it is
such a better process if I can leave my computer and read through a tutorial
and mark it up.

[0]
[https://docs.python.org/3/tutorial/index.html](https://docs.python.org/3/tutorial/index.html)

~~~
nicbou
When I learned Vue, I just inclued the library with a script tag, and started
writing plain JavaScript around it.

That was about 3 years ago, and I just started using modules. Even then, I use
the native browser modules, no Webpack. With HTTP2, there is little cost to
requesting many small files.

Likewise, I don't use a CSS preprocessor in any of my projects. They aren't
that complicated.

Those projects have no build process. What you write is what you run
(WYWIWYR?). If the project is small enough I'll serve its root directory with
Python's SimpleHttpServer. Later, I might have nginx do it.

This allows me to get a project running in a minute. I add tools when they are
needed, because then I have the motivation to learn them and set them up
properly.

Such tools are required if you must coordinate the work of multiple
developers. Their cost is divided by the number of devs, and their benefits
multiplied.

If you're just a home gamer toying around, you can do without them.

------
Carpetsmoker
"Quickly" using the JavaScript tooling is somewhat akin to watching one or two
episodes of the 6th Game of Thrones season without watching anything else. You
really need to watch season 1-5 to understand what's going on.

The other day I wanted to publish a little script I've been maintaining for
years as a module easily usable by WebPack and whatnot, and that's much easier
said than done. I published it on npm and put some UMD magic thing in there,
and I _think_ it should work now ... but I'm not really sure to be honest
(still need to look at this and confirm).

Just searching "publish JavaScript module" and trying to make sense of the
WebPack isn't really all that helpful, not for me anyway, as I'm joining half-
way through season 6.

I have no opinion on the tooling _as such_ – I lack experience to have an
informed opinion – but it sure is confusing to "quickly" do something for
people who are not heavily involved in it (i.e. me)

~~~
normalnorm
> "Quickly" using the JavaScript tooling is somewhat akin to watching one or
> two episodes of the 6th Game of Thrones season without watching anything
> else. You really need to watch season 1-5 to understand what's going on.

I disagree. In both cases, you really only need one or two episodes to know
that the story is not going anywhere. It will only get more complicated and
convoluted without ever rewarding you, you will realize that no thought was
ever put into it, and you will only stay for the ride because of sunk costs.

~~~
majewsky
That's nice and all. Unfortunately, (to stay in the metaphor) the PM has
arranged to quiz you on the main plot points of season 6 three days from now,
so your best option is to find a good plot summary for seasons 1-5 on Youtube
somewhere.

~~~
quickthrower2
As time goes on the breath of questions increases so necessarily the depth
must decrease, due to all the history of the language (JS, C# or whatever).
You are not a code now you are an archaeologist. It was so much easier in the
year 2000!

------
qudat
> just run it in the browser

Yikes. I really do not think that was the solution to this problem and only
added a ton of complexity.

JS is in a unique position because it can run both code in a browser as well
as a server-side/scripting language. In order to do that with any level of
success, tooling is required. This tooling (dev server, webpack) builds on
other tooling (node, babel, typescript) which is where all this complexity
lives.

Furthermore, some packages are not worth installing and if you run into issues
with that package, then try something else. We have no information about the
package they tried to install and since the JS ecosystem encourages people to
publish to npm for virtually anything, this is one area where you really have
to be careful.

The lesson here is the same lesson with installing something like left-pad: be
careful what you install and read the source code to understand what it is
doing. Most of the time, these packages can be inlined easily. Just because a
library exists, doesn't mean you should use it. Most of the time for JS I'm
reading the library's source code to see if I can a) inline it or b) use it as
inspiration to build specifically what I need.

~~~
cookiengineer
> be careful what you install and read the source code to understand what it
> is doing.

That’s the reason why I started to love pika.dev ‘s package search. Webpack
still sucks and will ruin your day with hours of unnecessary configurations
and fixes.

On the other hand, when setting yourself a rule to use plain ESM only without
any build system, coding has been a joy.

The only thing that still sucks is UI frameworks, because all major frameworks
still require a shitty babel workflow in one form or the other. Vue.js has an
ESM module which is useless without babel (due to the .vue file format), and
Angular/React are still in the lets-invent-our-own-language fatigue.

~~~
pugio
Lately I've been developing with a JS workflow that's finally made me think
"hey this is fun!" again:

Chrome target, native ESM modules, VS Code with JSDoc annotations for types.
All libraries (chosen preferentially from microjs.com) are copied into
vendor/, and the front end is written in preact.js using htm [0] for native JS
tagged html strings, leading to code like:

    
    
      import ImageView from "./image-view.js";
      render({ trail_item, selector }, state) {
        /** @type {LinkItem} */
        let link_item = trail_item;
    
        let title = this.render_title(trail_item);
    
        let favicon = this.render_favicon(trail_item);
    
        let img = html`<ImageView src=${favicon} />`;
    
        return html`${img}${title}`;
      }
    

There's a VS Code extension which formats html`` strings as actual HTML, and
the Typescript checker built in to VS Code gives me advanced types and
autocomplete, all with a workflow that's as simple as "refresh page".

Granted, not every project can afford to target just evergreen browsers, but
for my use case it works perfectly and I finally feel like I have the perfect
blend of old-style web dev (in terms of refresh cycle) with modern language
features and typing. The overhead, both in page-weight and cognitive load, is
as small as I can make it.

EDIT: Modified my code sample to show how you can use Preact components in a
JSX-like way.

[0] [https://preactjs.com/guide/v10/getting-
started/#alternatives...](https://preactjs.com/guide/v10/getting-
started/#alternatives-to-jsx)

~~~
cousin_it
Yeah, the microjs approach is much nicer than the Node approach.

I think the mistake of modern JS (and many other languages) is conflating
source files with libraries. A better model is combining many source files
into one library file, which provides one toplevel name when imported. A good
example is how Three.js, which has a complex internal structure, gets
distributed as one file and provides one toplevel name THREE. And of course
there are many examples in C-land, where a large library can live behind a
single header file. A project should only depend on a handful of those, and
there should be few dependencies between them, so package management becomes
easy enough to do by hand - just drop a file in your project's vendor/
directory.

As a bonus, this fixes the problem of having many fine-grained imports. If
done right, your project's source files might not need any import statements
at all. Anything inside the project could be available without ceremony, as if
it was all one big file, and external libraries live in a handful of big
namespaces which are also available without ceremony.

~~~
vimslayer
I don't know enough about Three.js to say if that works well for them or not,
it probably does, but I don't think a future where all libraries would do this
would be very bright. If the library is big, you'd end up shipping a whole lot
of unused code to the client, making the end user bored and angry while
waiting the page to load (especially if they are the sort of person who hangs
around in Hacker News). In fact, the direction has been the exact opposite in
recent years! Look at how lodash has moved to exporting one function per one
file so you can include just as much of the library as you need.

~~~
cousin_it
I was mostly talking about how things should look to the programmer. The
compiler could still tree-shake the final version.

~~~
vimslayer
Sure, it's just that the person you were answering to--and this whole thread
really--seem to be advocating for just importing module files without any sort
of build step. Without a build step I also assumed tree shaking wouldn't be an
option. Tools that handle tree shaking, like Webpack and Rollup, aren't really
the simplest of JS tools anyway so if we are talking about simplicity of dev
experience, I'd argue that multiple direct file imports--how inconvenient it
may be--is still _simpler_ to get right than "single namespace import" \+ tree
shaking.

------
_bxg1
The module syntax inconsistency situation is atrocious but we're gradually
making the transition. Now that we have a clear destination, I suspect it will
be a non-issue in a few years. Projects like Deno and Pika are
accelerating/papering-over the transition.

I've been working in JS for years and I've _never_ encountered a module
containing a typescript file with a .js extension... That was extraordinarily
unfortunate. I don't think I've encountered a module containing Typescript at
all. Correct practice is to build to JS and include the optional type
declaration files. In my experience people are pretty good about that.

~~~
yawaramin
Now that I think about it, it was probably a Flow[1] file, they look a lot
like TypeScript but have a .js extension.

[1] flow.org

~~~
_bxg1
Ah, yeah. Flow files do, unfortunately, stick with the .js extension by
convention. However, it's still terrible practice to publish a node module
that doesn't include a plain JS version of everything.

------
fit2rule
I just don't use Javascript, for precisely this reason, ever. Nothing is worth
the hassle - no fancy libs to do spacing, or anything.

This is not progress - as someone who has been professionally programming for
30+years, this state of affairs is atrocious. Its the equivalent of buying a
5-bedroom house for your kids to grow up in, only to go in to your kids room
after 20 years and realise they are insane and should be committed.

~~~
resu_nimda
You could have a similar experience with virtually any other
language/platform. “Someone who doesn’t know anything about C had a lot of
trouble running some arbitrary C code they downloaded” wouldn’t raise a single
eyebrow.

Turns out your kids actually manage to use the tools they built just fine.

~~~
stephenr
> You could have a similar experience with virtually any other
> language/platform.

I'm sorry but I don't believe the issue is as bad in other environments.

I've managed to pick up and make small patches/enhancements to projects
written in Java, C, Ruby, Python - none of which I use regularly beyond the
bare minimum I need (usually to patch some tool I'm relying on).

"Modern" javascript is just a huge pile of WTF with "Are you fucking crazy?"
frosting to my eye.

> Turns out your kids actually manage to use the tools they built just fine.

The kids have a "new tool" every week because the "old tool" from last week
has some problem. That's hardly a sign of "just fine".

~~~
thrwaway69
Can you give some examples?

~~~
stephenr
Examples of the WTFs or examples of other projects I was able to work on with
little experience?

~~~
kinsho
The WTFs

~~~
quickthrower2
The biggest WTF for me is you want to solve problem X. Great someone has
written some code in a library to solve X. You want to understand it. Cool,
let's look at the source. It uses source transpiler #2 of the big 4, bundler
#1 of the big 5, ui library #33 of the big 50, and oh yeah it uses proxies to
make everything return a promise so g'luck debugging that.

------
kyeb
As a computer scientist who learned JavaScript this year, I strongly agree
with the sentiment here. I feel like I often spend more time debugging module
errors than my actual project.

Granted, once I understood the ecosystem more, I gradually began to grasp the
reason these issues are around. But still, it does make it incredibly
frustrating as a reasonably decent coder getting started in JavaScript.

~~~
rraghur
Like many others, I'm chiming in with a me-too... IMO the biggest problem is
that if you come back to JS after a hiatus, it's very likely that most of what
you thought you knew would probably have changed in the interim.

I mostly work on the backend.. However, I've done a decent amount of JS too.
In fact, back in 2015, even built a lot of the core parts of an SPA using a
mix of knockout & requirejs with minified bundles and dynamic loading and so
on. Given that it stuff put together from scratch, I though picking things up
after a couple of years away from js would be easy. Oh how wrong I was...

In 2017/18 sought to write a starter boilerplate with vue 2, Typescript and
.NET Core. I would have probably spent an order of magnitude effort more
fixing build issues and warnings than on the project. Once you hit bugs/issues
with 3rd party webpack modules (which is almost a given), it is not fun at
all.

I recently had to put up a one page visualization and was not looking forward
to it. Surprisingly, create-react-app just worked out of the box. Not much of
a data point - but still a pleasant experience.

~~~
lukeramsden
> Surprisingly, create-react-app just worked out of the box.

create-react-app is the only thing I've used in the ecosystem that hasn't
catastrophically broken for me due to some years-old issue.

Except for monorepos/yarn workspaces, that still doesn't have first class
support[0]

[0] [https://github.com/facebook/create-react-
app/issues/1333](https://github.com/facebook/create-react-app/issues/1333)

------
Animats
It's become easier to build with hard-compiled languages than with
interpretive ones. Interpretive ones shouldn't need "building", but they seem
to acquire build systems anyway. Compile and link systems at least diagnose
what's missing during the build process, not during execution.

~~~
de_watcher
I don't know why people do this. In more complex areas of programming the code
and tooling are simpler. It seems like any ecosystem just fills up to the
certain level of complexity regardless of the complexity of the original task
at hand.

~~~
osdiab
If web programmers had the choice to install an arbitrary language's runtime
in users' browsers, they would. But users have disparate browsers with
disparate JS implementations, so if you want to code in a sane language with
consistent behavior, you'll need to transpile and polyfill it.

You can't just distribute arbitrary binaries to users on the web, so web
developers have to deal with a layer of complexity that other programs don't
have to. That said, maybe WebAssembly will change this story.

~~~
de_watcher
> web developers have to deal with a layer of complexity that other programs
> don't have to

yep, other programs totally don't need to deal with different OS, graphics
APIs, GPU driverstacks and hardware architectures.

~~~
exogen
Those are all runtime concerns. They don't affect the literal syntax that you
write, as is the case with JavaScript. You can't feature-detect syntax.
Instead your entire program will just fail to parse.

~~~
de_watcher
So like shaders?

------
franciscop
I totally agree with the author here, but also would love to give some context
since we have lived something like this before on Javascript IMHO:

Callback hell around 2015. It used to be that if you wanted to do something
async you'd have to create a new callback. This led into callback hell[1],
which was specially bad back then on the backend.

Luckily after a migration that has taken many years, now most of the libraries
use async/await instead of callbacks. There was some time where this was extra
difficult because some code was using callbacks and some other code was using
async/await, but it's almost totally solved in 2020.

Which brings us to the article on hand. This is probably one of the biggest
issues, and a fake promise in Javascript right now: reuse code on the back-end
and front-end. The front-end side has been using `import` for almost a decade
with Webpack and friends but this was not easy on the back-end, so there was
not a practical way of reusing the code in a project.

Luckily since _last year_ Node.js supports import/export, and React supports
it in libraries. It took a while because it was not an easy issue. I expect
that more and more libraries will start to work only with import/export, and
hopefully in 1-5 years this will also be a non-issue.

[3] [http://callbackhell.com/](http://callbackhell.com/)

~~~
wvenable
> Luckily after a migration that has taken many years, now most of the
> libraries use async/await instead of callbacks.

Is that true? I was looking to port one of my C# projects to TypeScript/Node
and it uses gRPC and it's not async/await compatible. That's a pretty major
library in my opinion.

In the end I didn't end up porting my project because the lack of elegance
compared to the C# version was too depressing -- the C# code made heavy use of
async and porting without that was just too messy. I'll take another shot at
the project once this problem is _totally_ solved.

~~~
throwanem
I don't know which library you were looking at, but if it wasn't
[https://github.com/protobufjs/protobuf.js](https://github.com/protobufjs/protobuf.js),
it probably should be. That one uses promises, so is async/await compatible
(JS async/await is just sugar over promises) and I've seen it work well enough
in production use to have no reservations in recommending it.

~~~
wvenable
I googled "grpc typescript" and worked through the first few pages of links.
That particular library never came up. I'll take a look.

------
zdragnar
What experience DOES john have? I've had far worse experiences with ruby,
python, scheme, clojure, java and C.

If you want a language that requires zero learning to use, I am sad to say
that they are very far and few between. Sure, we have a clusterf*ck of a
module ecosystem and interoperability issues between preprocessors but it
isn't like that is a particularly novel problem either.

~~~
hombre_fatal
Now I want to see John try to build a client on another stack, like deciding
between Carthage vs CocoaPods vs etc. for his iOS hello-world and running into
the problems with that.

Or, hell, how about the packaging systems in Go or Python? "Yeahhh, we don't
really use X anymore, go ahead and use Y."

John certainly failed the perseverance test though.

~~~
paultopia
It's true that basically every language (except Rust?) has nightmarish
package/environment management/tooling ecosystem problems. Why is this,
anyway? It's a little nuts that it's easier to learn how to code than it is to
figure out how to install a module.

------
juped
I'm a dedicated Javascript hater, but I don't think this is a Javascript
problem. This seems to be how people (not me) have decided all software should
be organized now.

I don't get it. I really don't.

~~~
chadcmulligan
My thoughts are its to make something boring and uninteresting into something
complex and special - the process of complification I like to call it. Maybe
its to charge more to, like the old lawyers charge by the word scam.

~~~
thrwaway69
It's the result of code reuse and modularity taken to the extreme.

------
Lerc
I have hit a few of these myself and I have also hit similar needlessly
complicated issues in a bunch of languages. This particular instance also
suffers from the seam between Modern ES modules and legacy JS, which could be
better.

Learning a language involves learning a bunch of non-language arcana about the
environment, for no particular reason. Ideally you should be able to write the
helloWorld equivalent for any platform and have a single command to turn that
one file into a working program, but alas we have tool chains, configurations
and requirements standing in our way. I don't think it has to be like that,
but it all too frequently is. Deno seems to be making an admirable effort
towards making a thing that just works.

Developing for Android or iOS makes the JavaScript experience positively
direct.

------
tiborsaas
I had very similar experiences with Rust and C++ lately.

In Rust, all I wanted is to play an audio file... failed.

In C++ all I wanted is to play an MP3 file... failed. With an hours of work I
figured out how resources worked in Visual Studio and got a WAV file playing.

In Rust I installed a creative coding crate, it had 314 dependencies and the
deps folder was 540MB. My openframeworks C++ project is 1.6GB after a bit of
playing around in it :) But yeah, node_modules is heavy.

Bottom line is, when you are new to an environment and you aren't prepared to
fight a battle, you will bleed out quite fast.

~~~
canada_dry
Python...

    
    
       subprocess.Popen(['cvlc','--play-and-exit','{filename_here}'])
    

_(just being cheeky)_

------
throwaway_sun
> But why do I… ok fine, I’m going to start a localhost.

Is "start a localhost" a generic term? If someone told me to do that, I would
probably freeze in embarrassment -- no one has ever told me to do that in such
context-independent terms. Since this was about node/JS, did John install
express, or some other static file serving module? Or did he have an unrelated
tool that makes this trivial?

~~~
tonyhb
It's kind of a weird phrase. Would normally "start a server". But yes,
generally speaking, it's a one liner to expose $PWD:

python3 -m http.server

~~~
wrycoder
Which listens on localhost by default.

------
durnygbur
Looks to me like a regular workflow and typical gotchas... ability to resolve
this and similar is what pays the salary. Is Android, QT, Django, or Java
development any more straightforward?

Anegdotally my perception is that people oftentimes think "It's just stupid
JavaScript, let me paste it into HTML and run in a web browser, oh wait... why
it doesn't work?!".

If you think it's confusing then add Angular to this tiny app (it's from
Google so it must be good, right?).

~~~
Joeri
_If you think it 's confusing then add Angular to this tiny app_

Ironically had they run ng new followed by npm install the import instructions
would have worked out of the box.

In today’s javascript landscape you have to pick the template to start your
project from, because starting from scratch is way more difficult.

------
jameslk
So basically the entire series of issues can be rooted to the fact they're
trying to run TypeScript code in Node/a browser. This doesn't seem like an
issue with "today's JavaScript" but rather a symptom of either not reading the
docs or the module not having good docs. I wouldn't be able to compile Java
code with a C++ compiler.

Also that the package is published to _Node Package Manager_ with only a
TypeScript distribution seems very odd.

I do agree that the Node ecosystem could be easier to use, especially with the
myriad of transpilers and build tools. But this doesn't seem like a very
compelling anecdote to demonstrate it. Unless the point is that NPM package
authors should not be able to publish their package in languages other than
Node-flavored JS?

~~~
0xfffafaCrash
One of the problems with the js community is the idea that it is a good idea
to name just about anything that is js-ish in a file with a .js extension. I
love Dan Abramov, but I think a large part of the blame for this can be placed
on his feet for encouraging the use of js extensions for jsx. This sent a lot
of people down a dark path. File extensions serve a purpose. Even more so if
you don’t have a standardized header line disambiguating the contents of the
file. When you rely on tribal knowledge and sophisticated build tools that
rely on strange assumptions or the requirement to parse whole files with
different syntaxes just to know what you are looking at you have a problem.

If the c++ community had a tendency to name their java files with cpp, would
you be so forgiving?

~~~
jameslk
To be honest, I don't run into much JS code that doesn't have proper
extensions, but that's just been my experience for the past 6 or whatever
years I've been using Node.js. If I use JSX, I use .jsx as an extension.
Likewise for TS and TSX. And CoffeeScript in years past. I can't recall coming
across any NPM packages that couldn't run in Node. So I can't really relate.
Maybe it's confusing that there's different flavors of JS though with the same
file extension: browser-flavored JS and Node-flavored JS.

~~~
0xfffafaCrash
I wish I could say the same, but nearly half of the teams I've worked with on
web development go exclusively with .js because it's been pushed by prominent
members of the React community for "ergonomics"[0] (which here is just a fancy
way of saying devs can't be bothered to invest the two seconds it takes to
make file extensions accurate when switching to a superset language) The trend
of unreliable file extensions has lots of other nasty side effects on IDEs,
build tools, and browsers (e.g. [1])

[0]
[https://github.com/airbnb/javascript/pull/985#issuecomment-2...](https://github.com/airbnb/javascript/pull/985#issuecomment-239145468)

[1]
[https://bugs.chromium.org/p/chromium/issues/detail?id=659515](https://bugs.chromium.org/p/chromium/issues/detail?id=659515)

~~~
jameslk
I worked in Facebook briefly, and the reason why Dan (who also is/was at
Facebook) might be suggesting this is because this is the practice at
Facebook: all "JS" files use the same build system and file extension. Which
is to say, there's no JS, or TS, or even CommonJS APIs. It's all and always
Facebook-flavored Flow (with the occasional caveat).

And perhaps this is why it didn't seem obvious for Dan (I'm speculating) that
anyone would want to use multiple file extensions for things, but when you're
outside of Facebook's ecosystem and you have to set up your own build tools
and deal with all the pain it comes with, you realize stuff like this makes no
sense. Because ya know, maybe targeting by file extension in your build system
would make it easier to use the right transpiler (e.g. that's what Parcel
does). But that's just been my perspective being in both worlds.

------
irrational
So, this doesn't seem to be an issue with JavaScript per se. The issue seems
to be with the insane environment people have built up around JavaScript.
Typescript, node.js, npm, etc. If the code really had been plain vanilla
JavaScript that a person could use from an external JS file (just like we did
for 20 years) then none of this would have happened.

------
_hardwaregeek
My friend and I decided to start a project. This friend and I have had
discussions where he espoused how libraries like Webpack, React, Redux, etc.
just overcomplicate the web. I decided to humor him and do a "simple" stack of
lit-html, vanilla JS and ES6 modules (since they landed in browsers). It took
us maybe...a day to pedal that back? The first thing to go was doing ES6
imports in the browser. I forget the exact sequence of events but the MIME
issue definitely showed up, along with maybe an untrusted source issue. Say
what you will about Webpack, but native ES6 modules are definitely not here
yet.

~~~
hunterloftis
> a "simple" stack of lit-html, vanilla JS and ES6 modules

This is precisely how I’ve been building tableofsending.com and it’s been a
lovely experience.

You do need some babel/tsc/etc build step to reach a reasonable audience.

~~~
_hardwaregeek
Yeah I bet once you get the stack up and running, as well as smooth out the
inevitable early adopter bugs of lit-html, you'll have a great experience. The
subtext of this was my friend constantly telling me _easy_ and _simple_ it'd
be versus React. When in fact each stack has its tradeoffs and incidental
complexity.

~~~
spankalee
lit-html has been used in production for over 2 years now, on sites with
billions of page views a day. At this point no one new to it would be an early
adopter :)

The issue with module loading is a pretty fundamental one, though pretty
unrelated to web components.

Once you understand it, there are a large number of tools that make them work.
The core problem is that most modules available on npm are written with import
specifiers that assume the environment supports Node's module name result.
Browsers don't, so it won't load something like `import * as redux from
'redux';`

The solution is a tool that transforms package names into URLs. Webpack,
Rollup, Parcel, es-dev-server, Snowpack, Vite, unpkg.com, Polymer CLI, and
many more do this for you.

More and more of the ecosystem is moving to native modules and we're all going
to have to understand this issue.

~~~
_hardwaregeek
ReasonReact has been used in production for 3 years now, with billions of page
views a day. I'd still call it immature in many^[1] regards :D

The particular point of this project was to prove that each successive
simplification that my friend proposed, i.e. avoiding Webpack for native ES6
modules, using lit-html instead of React, etc. introduced its own complexity.
I'm not saying that these were all bad ideas, but just that they're
fundamentally tradeoffs. I'm quite sure lit-html is a great stack. But it's
not "better" than React any more than React is "better" than Angular.

[1]: Lack of async/await, or its equivalent, let+ in OCaml 4.08, is a big one.
Mediocre typings for browser APIs is another.

------
JMTQp8lwXL
Anybody who's an outsider is going to hit stumbling blocks. It's your choice
to feign ignorance or pick yourself up. A lot of languages have their
peculiarities and JavaScript is no exception. Would "Today's <Language X>,
from an Outsider's Perspective" look any different? Where X is a language
that's at least 20 years old.

------
trashfindhunter
> John gives up. Concludes never to touch Node, npm, or ES6 modules with a
> barge pole. > The End. > Note that John is a computer scientist that knows a
> fair bit about the Web: He had Node & npm installed, he knew what MIME types
> are, he could start a localhost when needed. What hope do actual novices
> have?

The ones who don't give up on the first night will likely have more luck (try,
try again).

~~~
alanbernstein
Or maybe John found it less aggravating to find or create another
implementation in a different language?

~~~
fastball
Well if he followed internet trends he'd try Rust next, which doesn't exactly
have the most straightforward package system either.

~~~
jtdev
Or, you know, Python, Ruby, Java, Go, C#, Swift, Kotlin, etc., etc., or any
number of other languages that are less of a foot-gun full of bizarre issues,
poorly maintained packages, and droves of Jr. devs eager to do clever things
that make the language and ecosystem psychotic.

~~~
TechBro8615
Python is good at many things, but packaging is _not_ one of them. The best
python package manager at the moment is Poetry, and it drew most of its
inspiration from npm and yarn...

Python packaging has historically been so bad that dotcloud invented docker in
an attempt to make it usable.

~~~
Carpetsmoker
But at least I can just download a .py file (or a bunch of files) and just
import them. Perhaps the biggest frustration/pain point in this article isn't
npm as such, but that you can't "just" use some JS module.

~~~
ggregoire
> But at least I can just download a .py file (or a bunch of files) and just
> import them.

Just importing doesn't seem to work for millions of people:

\- [https://stackoverflow.com/questions/4383571/importing-
files-...](https://stackoverflow.com/questions/4383571/importing-files-from-
different-folder) (1.5m views)

\- [https://stackoverflow.com/questions/14132789/relative-
import...](https://stackoverflow.com/questions/14132789/relative-imports-for-
the-billionth-time) (215k views)

\- [https://stackoverflow.com/questions/72852/how-to-do-
relative...](https://stackoverflow.com/questions/72852/how-to-do-relative-
imports-in-python) (325k views)

\- [https://stackoverflow.com/questions/1918539/can-anyone-
expla...](https://stackoverflow.com/questions/1918539/can-anyone-explain-
pythons-relative-imports) (100k views)

\- [https://stackoverflow.com/questions/1260792/import-a-file-
fr...](https://stackoverflow.com/questions/1260792/import-a-file-from-a-
subdirectory) (480k views)

\- [https://stackoverflow.com/questions/7505988/importing-
from-a...](https://stackoverflow.com/questions/7505988/importing-from-a-
relative-path-in-python) (136k views)

\- [https://stackoverflow.com/questions/9252543/importerror-
cann...](https://stackoverflow.com/questions/9252543/importerror-cannot-
import-name-x) (700k views)

\- [https://stackoverflow.com/questions/2325923/how-to-fix-
impor...](https://stackoverflow.com/questions/2325923/how-to-fix-importerror-
no-module-named-error-in-python) (430k views)

\- [https://stackoverflow.com/questions/15514593/importerror-
no-...](https://stackoverflow.com/questions/15514593/importerror-no-module-
named-when-trying-to-run-python-script) (250k views)

------
zapf
I have done close to a decade of work in js, with jQuery in 2008, all the way
to react and webpacker madness.

I hope someone builds a wasm based front end framework. I did a quick search
and MSFT seem to be on it with their Blazor framework. Unfortunately, I am not
in a hurry to go learn ASP.NET or C# anytime soon.

Maybe we need a frontend framework in Golang that compiles to WebAssembly. I
am rooting for Golang here, cause after a decade in Ruby/Python/JS, I am
really enjoying going back to typed languages.

But even a python/ruby to wasm web frontend framework will be awesome.
Anything that keeps me away from node hell.

~~~
onion2k
WASM compiles to what is _effectively_ a normal JS library that exports some
functions. You don't need a bundler to use that in an app, but as the
complexity grows you might want one. It's likely that WASM frameworks will
make that a simple process, but it'll probably end up working by using
something like Webpack behind the scenes just as things like create-react-app
do now. Take a look at [https://rustwasm.github.io/docs/wasm-
pack/](https://rustwasm.github.io/docs/wasm-pack/) for an example of what
people are working on to do this.

wasmbyexample has an example of how you can do it in Go right now -
[https://wasmbyexample.dev/examples/hello-world/hello-
world.g...](https://wasmbyexample.dev/examples/hello-world/hello-world.go.en-
us.html) \- you'll need to write that index.js file yourself, and that's when
you'll be back to using modern JS tooling as soon as you scale up to a real
app.

~~~
zapf
Thanks for those links. I found them really educational.

Does seem like we need some more tooling to avoid as much webpack pain as we
can.

------
marcandre
This resonates so much. I support some JS packages but I often wonder how
anyone gets anything done in general on the JS side, and why people seem to
accept the state of affairs. I'm spending most of my time with Ruby and it is
night and day.

~~~
BigJono
People get stuff done in JS by sidestepping all the bullshit. If you keep your
tooling simple and use a minimal amount of dependencies, then JS is one of the
languages/environments with the least bloat, not the most.

The big problem JS has is the same one PHP used to have when it was top dog.
Everyone is a fucking noob, including all the people writing all the advice
online. I find almost every JS resource to be unbearably bad, with the sole
exception of MDN. The vast majority of my learning these days comes from work
colleagues who also have a decent level of mastery.

So the real answer is probably that the people getting stuff done are happy
with the current state of affairs, because it works for them. And the people
that are unhappy are for the most part trying to change the current state of
affairs without fully understanding it, and making it worse. I think every
language suffers from this to some extent, JS just has a much worse ratio of
masters to beginners so the effect is exacerbated.

------
jaeming
Seems like the issue here was a lack of documentation. Almost every npm
package worth their salt details the various ways to get started with
something along these lines:

\- In the Browser:

    
    
      - Using Parcel/Webpack/Rollup.js...etc
    
      - From a CDN
    

\- In Node:

    
    
      - Using CommonJS
    
        - `const funcName = require('somePackage')`
    
      - Using Native ES Modules
        
        ...etc

------
ajross
> Turns out VS Code collapses folders with only 1 subfolder, which is why we
> hadn’t noticed.

OMG. Decades of life in emacs (emacs!) would never have prepared me for a
world where my editor would helpfully lie about the filesystem to me.

Yeah, this was horrifying to read. Obviously some of it is just normal churn,
and all environments have their own oral histories and weird quirks. But...
yikes.

~~~
monocasa
FWIW, it tries to make it clear, underlining each path component separately,
and with a path separator that sin't underlined in between.

It's nice for Java style packages that are all "src/com/company/project"
before you get into the meat of any code.

I agree though about how surprising it is.

------
lerax
This is so shitty and sad. I wish front-end dev could be more fun, with less
pain, confusion and suffering. I'm losting the hope over the years about any
browser stuff. :[

------
hypewatch
HTML/CSS/JS has been stretched so far beyond what it was originally designed
for.

JavaScript’s tooling will only get harder to work with as we push it to handle
more.

Eventually we’ll need to find something better than HTML/CSS/JS for developing
in the browser.

~~~
de_watcher
Yea, the original intent of js was to write small snippets of code to stitch
HTML together.

The neat "software distribution system" \- the web browser became very
popular. The wide adoption of the browser has forced js into the realm of the
general purpose languages because it was the language of that VM-browser.

------
benboughton1
I never really got the modern web app stack and Typescript/javascript
compiling until I was forced to use it through Angular CLI. Then it sort of
all made some sense. Having a defined structure in a complex stack helps
novice people a lot.

Before that it was all open up index.html template and import my js files for
my projects.

I am currently going through the same thing with Python/Django Rest Framework.
Another fairly well defined toolbox that some wouldn't like - but it helps
with learning good practices and you can lean on a community of developers
that have thought long and hard about how things are well structured.

------
oweiler
The most ridiculous thing is the guy in the comment section recommending
deno.js.

------
jpsimons
The problem is, these are the Node team's stated goals for ES Modules:

> It is worth mentioning that many of our design decisions were made with two
> primary goals. Spec compliance and Web Compatibility. It is our belief that
> the current implementation offers a future proof model to authoring ESM
> modules that paves the path to Universal JavaScript. Please read more in our
> documentation.

Sorry guys, those are the wrong goals! Just make CommonJS and ESM be mix and
match interoperatable. ESM wasn't designed to be a local disk build system.
Just have CommonJS behavior with ESM syntax for god's sakes.

------
ahupp
Today's JS ecosystem reminds me of how people used to talk about Lisp: "Extend
the language however you want, just write a macro!" And in practice that means
there's a million little language variants floating around there; you can have
different import semantics and language features and type systems and it's all
glued together with a big pile of configuration and tooling.

Obviously this flexibility has been good for progress of the JS ecosystem as
whole, but I hope the next 10 years are more sedate than the last 10.

------
runawaybottle
If you are on an older version of node and want ESM, but don’t want to use
.mjs, you can try:

[https://www.npmjs.com/package/esm](https://www.npmjs.com/package/esm)

The package.json should have something like this if they are going to use
import/export statements so anyone on older versions don’t have to worry about
it (it’s not native to Node yet without .mjs extension).

We can blame whoever didn’t set that up, or the instructions should have been
to just use require().

~~~
ravenstine
> it’s not native to Node yet without .mjs extension

Since v13, you can use ES modules without the .mjs extension if the nearest
package.json includes `"type": "module"`.

~~~
runawaybottle
Thank you, that’s good to know.

------
self_awareness
No offense to anyone, but this image wraps up how JavaScript, HTML and CSS
looks from my (outsider's) perspective:

[https://www.desktopbackground.org/download/1280x1024/2013/02...](https://www.desktopbackground.org/download/1280x1024/2013/02/25/536059_cat-
riding-fire-breathing-unicorn-photos-for-desktop_1680x1050_h.jpg)

------
jacobedawson
"Lo and behold, a pile of unnecessary error conditions, cryptic errors, and
lack of proper feedback.". Sounds like literally every initial experience I've
had with a new language / library / framework (also, life in general tbh).
Usually reduced by RTFM.

------
darepublic
to echo others here, python ecosystem is worse imo. And compared to cross
compiling C++ and C for ARM, js ecosystem seems like easy mode. You can always
just write a little script to attach your module to the window, if you feel
averse to webpack

~~~
markmark
I've been programming professionally a long time and had toyed with python
before for small scripts, but have only recently had to write larger amounts
of production code, and I was not prepared for how bad the python import
system is.

------
warpspin
I can sympathize with that. Actually I miss the times where you could just
drop a script into your project and have it work and still change it if
necessary without having 40MB of build time dependencies.

------
z3t4
The JavaScript ecosystem was perfect before 2015. Everything just worked! Then
either Hanlon's razor or sabotage. Instead of using the existing standard
module system, a new module system was invented that was so alien to the JS
ecosystem that now 5 years later it's still _broken_. I wish ES6 modules where
reverted and removed from the JS standard. Then the standard body not only
completely changed the syntax of the language itself, but it also now requires
a preprocessor/transpiler...

------
deanmkenzey
This doesn't really seem to be specific to Javascript. A beginner in pretty
much any language will have to go through these kind of issues.

------
aabbcc1241
As it has .js extension, beside typescript, it maybe flow.js script that
require babel transpilation as well.

------
sneak
I feel like the tremendous popularity of node caused the development team to
self-reinforce bad habits, but it’s just a theory.

I often wonder what the js ecosystem would look like with Google-working-on-Go
levels of runtime and package management design discipline.

One would really think Google would do this, especially considering that
Microsoft now has veto power over the npm repository and package format. Yarn
was a huge improvement but is still dependent upon the same broken backend
model.

AFAICT the success of the JS ecosystem is entangled with Google’s success.

~~~
_bxg1
The shortcomings of JS are rooted in its legacy baggage. Go had none of that.
JS today is a good language emerging from the ashes of a bad one, but there
are a lot of ashes, and some of them are impossible to completely shake off.

~~~
sneak
As much as I am not a fan of js-the-language, the problems TFA described and
that I addressed in GP are 100% independent of the language and are 100% in
the domain of tooling.

Literally nothing about javascript-the-language is why package.json is in a
file format that does not support comments, or why node_modules can’t be
renamed or hidden or cached properly across projects, or why any of the
cryptic import issues encountered by the author of TFA happened, or why yarn
had to be made because npm is (or at least was) nondeterministic.

The js packaging tooling sucks, and, more importantly, _has continued to suck
contiguously_ for at least ten years. Much like Python and Ruby (cryptographic
checksums, anyone?) and Debian/Ubuntu to some extent, I think nobody gives
enough of a shit (or has the skills and experience and inclination) to unfuck
it, or has just become blind to it over ten+ years of it sucking in the same
way (much like autoconf).

It is entirely unfuckable. No part of it is baked into javascript. Go’s was
fucked, and they did an epic job of unfucking it with the module and caching
system. The same could be done for JS.

It would require forking node to handle imports sanely, and replacing npm/yarn
packages (as well as the backend npm package repository they talk
to)—surmountable tasks.

------
ikaria91
Literally my experience trying to use something to calculate distance between
two points

~~~
layoutIfNeeded
Have you tried Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y -
b.y)) maybe?

~~~
quickthrower2
Even better:

    
    
        npm i pythag
        npm i complex-sqrt
    
        // then
    
        var pythag = require('pythag');
        var sqrtrt = (z) => require('complex-sqrt')(z,0);
        let x = 3
        const y = 4
        var result = sqrtrt(pythag(x, y))

~~~
layoutIfNeeded
I can't tell if you're joking :S

------
ikaria91
Literally what I went through as well just trying to use a distance between
two points module... I wish I was a cool front end kid.... but this type of
experience is exactly what turns me off from front end dev

~~~
lerax
I wish that type of experience would be uncommon, rare, exceptions... But in
my perspective is the real true state of front-end today. Everything is broken
from a outside perspective, so much changes happened that for me learning the
overall Common Lisp specification (from 1000+ pages) it's more easy to do JS
dev stuff on browser.

------
axegon_
For years on I kept saying that Java is the worst language ever because of the
tons of unnecessary boilerplate and it's "you're doing it my way or you are
not doing it" approach. But over the last year I've come to realize that
javascript has become much worse. A good engineer and community are identified
by their ability to say "OK, you know what, this turned out to be a very
stupid idea, let's start over and scrap this". However w3, mozilla, opera and
every other organization behind js have turned into a full blown North Korean
dictatorship and everyone who suggests that there should be alternative, they
get chased down with pitchforks and never heard from again. And even if they
have a constructive argument as to why everything that is going on is wrong.
I'm sure that sooner or later this will bite back those organizations really
REALLY hard. Basically we are in the baby boomer era of js - 30 children, 17
cars, all at least 6 liter v8's, hardly getting across the street without
refueling, etc. And I'm betting that in a few years time they will be the web-
equivalent of climate change and holocaust deniers.

------
methodin
Seems like this should be directed at the particular packaged and not the
ecosystem as a whole? I do feel the pain of "I just want to try this out" and
it's assumed I have webpack and all the other tooling already setup to do so,
though.

------
root_axis
All the hand-wringing over the difficulties of js just doesn't seem to track
with the reality I live every day. I've been hiring engineers for years and
_by far_ the most common skillset comes in the form of contemporary js
framework knowledge, especially among juniors. Ask them to debug a native app
build and they panic like the output on the screen is hieroglyphics instead of
a log of useful information that they can leverage to solve their problem.
Many times they're so confused they won't even google the errors because they
can't distinguish the error text from the compiler info logs, and that's
working with swift/kotlin, I can't even imagine what things would be like if
we had any c or cpp projects. This stuff just isn't that hard.

~~~
brailsafe
I can't really tell what you're getting at here. It would definitely track
that your juniors know only this stuff, because often times that's all they've
been exposed to and usually for a specific type of labour. It's not really
generalized knowledge. It's also not difficult, but it's not trivial to
explain or get started with, unless of course you're starting at the highest
level and glossing over the details. It arguably should be, and at one point
it was very trivial.

~~~
root_axis
> _it would definitely track that your juniors know only this stuff_

It doesn't track with the narrative that it's difficult to get started with,
in fact, it shows that the opposite is true since these skills are very common
among novices. Native application development is much more challenging
learning curve for novices.

> _details. It arguably should be, and at one point it was very trivial._

Create-react-app and similar tooling make things very trivial, but the
suggestion that things were trivial "at one point" and no longer so is
obviously false since whatever trivialities you're referring to work just fine
today as they did in 1998.

