The state of JavaScript modules
medium.com
medium.com
As opposed to now, where even the smallest “app” has hundreds if not thousands of dependencies for the most basic of functionality (‘need to iterate an array, better bring lodash’), often there being multiple copies of the same dependency due to conflicting versions?
(I accept this is something of a rose-tinted over-simplification, but a paragraph titled "An ancient fear" probably deserves some slightly flippant commentary.)
- You have to maintain a full list of your files, in order, to include them in your html page (in dev mode) and concat (for prod mode)
- If you want to know on what other module a given module depends on, you have to hunt every call in the source code
- You can never remove a dependency on an external lib as you can never be sure it's not used somewhere
- Upgrading a lib was a pain
Compared to every other language, it was a huge pain point. It's not by chance that so many people started to work on implementing modules for JS, there was a real need.
And while some report benefits and advancement, I have to tell you, the amount of tools you have to pull in these days just get some single page interaction going... Just stop. And we need to draw a line between "progress" for the language and its libraries vs introducing features without discipline. The more features a language has, the harder it will be for open source and industry to develop consensus on what's idiomatic.
Want to know another language feature? Being stable.
I swear, it's like the language reinvents itself every year. Give me some sort of promise when you'll leave the standard alone, then I'll wait for the community to form best practices / libraries to catch up. After the dust settles, I'll invest time reading up on the standard.
Ain't trying to jab javascript. Love the language, community is top tier, but everything these days from build tools to libraries seems like a moving target.
The same happens with modules although having written several require.js like loaders I find the ES system a little bit lacking.
> I swear, it's like the language reinvents itself every year. Give me some sort of promise when you'll leave the standard alone, then I'll wait for the community to form best practices / libraries to catch up. After the dust settles, I'll invest time reading up on the standard.
Sorry to disappoint you but this will never happen, especially not in JavaScript. Actually the standard is released every year that's why we have ES2015, ES2016... But that's just the way things work in IT: people keep changing things and we are supposed to follow.
> ... seems like a moving target.
Yes, exactly. But that seems to be "by design" rather than "by accident", see Fire and Motion [0].
[0]: https://www.joelonsoftware.com/2002/01/06/fire-and-motion/
const x = require;
const m = x('crypto');
Here I'm requiring a module but it's hard to follow for a tool that Crypto is being imported.The proliferation of class systems in JS before ES6 classes. Building a tool (IDE for example) to support all of them would be a complex problem.
See also interviews with Anders Hejlsberg (e.g. [0]) where he explicitly mentions that TypeScript type system's primary focus is allowing better tooling support for developers (like press dot and see what's there, safe refactorings).
[0]: https://devchat.tv/js-jabber/209-jsj-typescript-with-anders-...
Requires are impossible to statically analyze in some pathological cases, which is why more rigidly defined imports made it into the ES2015 spec.
That's totally unrelated to classes vs. functions or any of the other things you've mentioned.
1 - the magnitude of the language's popularity.
2 - just how young modern javascript really is.
Javascript is either the most popular language in the world, or the second most popular after C. Even in in Java's height somewhere in the early 2000s it was never as popular as JS is right now, and it was much more homogeneous in terms of developers - js is written by designers, people with no formal education, even children.
Modern javascript is only a few years old, even jQuery came out just 10 years ago, but javascript that was used not as a scripting language really only came with the popularity of chrome and SPAs, somewhere around 6-7 years ago.
Taking these things into perspective, I don't think it's reasonable to expect (or request) for JS development to stabilize - Java is still not stable 20 years in, and it was in a similar state of upheaval as JS as recent as 8 years ago.
C is so decentralized that we don't even think about it's stability the same way we do other languages - there were (and maybe still are) multiple competing standards for the language itself, and compilers regularly won't compile code that works in other compilers.
It's about this: I wrote a module for my project, I want to import it in my project and everywhere else where it might be useful, in one, SINGULAR way, which doesn't change for at least 18 months, please. I'd like to be able to write ES 2016/2017 and not caring how it gets compiled to ES5; can't you people just finally agree on one way of doing things?
You people who mostly (or exclusively) code JS simply don't understand that many of us code in 5+ languages every week and we want to be productive.
If I have to read on a new standard and a new and shiny way of managing dependencies every 8-10 weeks and if you think that's okay, then you seem to fail to grasp how unproductive this is. For you it might be a full-time job. For me, and many others, it's a distraction because we have to do a lot of stuff in several languages and we'd much appreciate it if the JS folk would just calm the hell down for a bit.
If I get into a new team and there are 3 devs already writing JS, it's highly unproductive because it feels like you have to very regularly catch up with the JS ecosystem. Not to mention the strong peer-pressure factor of "cool kids use X, Y or Z". And this is a very underestimated phenomena by so many devs -- and it exists in almost every team.
I went all out with it, learned it inside out, learned how to use Gulp, Bower, etc.
Then along comes Angular2 and it's completely different. Bower is deprecated, Gulp isn't widely used any more. It's all WebPack and Yarn.
I have spent some time with Angular2 and it is good. There's a lot to like, but it is exhausting having to learn everything I already know how to do in AngularJS again in a different framework, especially when I know I could just fire up AngularJS, get the old gang back together with Gulp/Bower etc and be done in a fraction of the time, because there's nothing new to learn.
So I've been learning Android development (in the context of Xamarin.Android) over the past year, and I am now at the point where I can do pretty much whatever I want to do in Android comfortably, and have shipped a couple of apps.
In the past month I've been learning Xamarin.iOS and it is starting to (slowly) click with me. I'm getting close to that know enough to be dangerous phase.
I feel as though these are better investments of my time. I am confident that Android and iOS will still be around in five years. Even if Xamarin isn't, Xamarin maps so closely to native development that if Microsoft gets bored of it, I could use Android Studio and XCode instead and still know what's going on.
I can't say the same for Angular, React, Vue, Webpack, Yarn, Aurelia, Ionic, etc etc. I have zero confidence that they will still be around in five years, and I don't want to learn any more client-side JS frameworks until the industry settles down and matures a bit.
If I need to build a single page app, AngularJS it is for the next year or two, because even if it isn't cool anymore, it's still fine.
The "churn" we feel is really just a confusion from having so many new options while only wanting or needing a handful of simple/stable ones. This is troublesome because there aren't market forces(per se) or companies with researchers to limit our choices for us, like a spaghetti sauce company figuring out which 3 flavors of sauce to sell. If you can distance yourself from needing to be relevant, you'll be fine. Learn JavaScript and keep up with browser and Node.js advances; that's really the majority of what we need to do to stay relevant.
But if you want to minify your code, and bundle it, and use SCSS/LESS/SASS and compile that to CSS, and if you don't want to execute the various tools manually every time, then you need tools. And yes, since these are pretty simple tools, it's easy to reinvent them, to try out a new mix of them. Gulp vs grunt? Yeah, grunt's config was horrible. But people still like magical config files, so we are back with them with webpack. And people want to use better state management, and shadow DOM, and so on, but they still like to view their sites in browsers, not just through TC39 glasses, so they use babel, but that itself evolved over the years. And so on.
And WebAssembly. And TypeScript. Because static typing is really helpful. And isomorphic whatever. And tools for that. And tools for development. (Nodemon, hot code replacement, unit testing, code coverage, e2e testing, and so on.)
And even though everything is a moving target, the good bits are still doing pretty well. (Yarn is pretty good thanks to the lockfile, but obviously npm is doing well. Webpack lives on but AngularCLI actually works so no need to handcraft webpack config; and gulp works too, if you want to get simple.)
And you don't need to wait for others to tell you what's best. Look at your visitors/users, think about their needs, and look at what tools can help you serve them best. Are you making sites for blind people? Use/support tools that are thinking about WAI-ARIA/semantic markup. If you deal with mobile users? Optimize for speed, service workers, write non-chatty [REST] APIs, push content to CDNs, and think about PRPL ( https://developers.google.com/web/fundamentals/performance/p... ). If you serve big enterprises, use tools that provide IE4.01 compatibility, and so on.
> Are you making sites for blind people? Use/support tools that are thinking about WAI-ARIA/semantic markup.
I think developers should always have accessibility in their mind. People (or organizations they work for) may choose to use IE8 and yes, it makes sense to draw a line somewhere regards to supporting browsers. They can decide if an upgrade effort is worth to use your application. However people do not choose to have less abilities and it's possible that they can't do anything to change that. I'm not a dictator who says everyone must use all the accessibility best-practices but usually there's a small effort which can be made with huge gains.
And I agree with doing the minimum. There was a great site that shows sites as they "look" like to a screen reader, but I can't find it now. (But it was very much like WAVE http://wave.webaim.org )
You mean forward compatible. Which is unlike in Java.
New code (e.g. with ES6 features) doesn't work in older JS engines / browsers -- that's why we have transpilers.
But your code is "futureproof". The spec/language/VM is backward compatible with old code. (In the sense that you can drop in the new version and old code runs.)
Like I say, I'm new to this area so don't have much of a frame of reference but `npm` is nothing short of brilliantly neat, and hassle free.
With regards to the different language varieties `babel` sorts all that out - you can use your flavour of JS as you see fit and it all gets compiled to orthodox cross-browser JS.
Seriously pleased with what these features provide to the development environment.
> "Oh, why are you using Backbone? That's an old and obsolete technology. You should learn React/Vue/Elm."
(Vue is easy to learn for new devs, though)
The dev is not familiar with functional programming or other paradigms that React suggests or requires you to know. He may be in a early learning process where Backbone/jQuery makes it easier for him to start on building webapps.
I have no problem with jQuery (I still use it on animation heavy websites), but Backbone wasn't a good framework IMHO. it was not very useful and it lacked the component model that is well understood by web frameworks today (backbone didn't support composite views).There is no reason to use Backbone nowadays.
I think Vue.js is a good replacement for the people who seek simplicity and a clear data model. And it doesn't require any asset pipeline or whatever, it's just a little JS file.
Angular 2,4,whatever and Embers are frameworks that oozes with complexity, for very little benefits in my opinion.
Nested views were problematic, undeniably, and did lead in the real world to a big old mess that wasn't much better than the jQuery spaghetti it was intended to replace, with events bubbling all over the place and unnecessary re-rendering and so on. I led a team that built a big Backbone app, back when it was very much in vogue, and it was certainly hard to get this stuff right in practice - perhaps not impossible, but harder than one would have preferred.
Shaming shouldn't be a thing, but It's fair to say no one should start a backbone project in 2017, unless it was dead simple, in which case you can use pretty much any tech anyway.
However, that doesn't mean the new libraries/tools/technologies are just created because "oh it's been a year and we're still using knockoutjs/react/angular/webpack/yarn!", but because a slight paradigm shift happened - at least for some people - and they feel that backbone is not the ideal tool for their job. (Maybe they felt backbone is too barebones, and went for angular, then felt that too heavy, and tried React and settled for Inferno.js.)
I don't understand what's stopping you from doing that. There are many perfectly fine jQuery/Backbone/Angular/etc apps that are chugging along perfectly fine. There's no reason for you to adopt new technology unless it makes your life easier.
And therein lies the problem -- for a long time developing an SPA in JS was absolutely terrible. And it's getting better, and getting better due to efforts of people who love the language. Webpack didn't beat Gulp because Corporate Sponsor X adopted it, Webpack beat Gulp because some guy wrote it and it turned out to be awesome. To me that's worth more than upsetting the curmudgeons who complain about perceived fatigue.
Extremely tangential, but does anybody actually love javascript? We've been in a captive situation with this deeply flawed hack for 20 years.
Once WebAssembly is mature enough to fulfill its promise, and after that once we've burned through the generation born into this JS captivity, is anyone going to want use it anymore?
Like, if it were magically possible to use anything else natively in the browser today, would the next big thing be another 10 million person-hours put into yet another angle on working around JS's flaws... or something in another less clunky language entirely, never to return?
I know that I do, and it's my language of choice. That's not to say that it wasn't deeply flawed for a long time, but now both the technology and standard practices have evolved to where I really enjoy writing it and using it.
It's all just too damn confusing.
1) Pick a build tool (gulp, grunt, webpack - if you don't want an option, use webpack). You don't need a build tool but it helps with transpilation and it's a good base for the future.
2) Make or copy/adapt your build tool's config file to use Babel so you can use the latest ES version but compile down to work in browsers. You'll have to Google but these exist all over the place and they aren't confusing.
3) Pick a front end framework. Do you like Vue? It doesn't really matter because they're all doing basically the same thing in slightly different ways (like Rails, Django, Sinatra, Flask, etc).
You're good to go. It's not more difficult than setting up a Python, C, or any other environment, you simply have options. Hell, if you're doing terminal apps, you gotta decide between ncurses, blessed, termbox, raw escape sequences and so on. The JS world really isn't different than anything else.
> It's not more difficult than setting up a Python, C, or any other environment, you simply have options
It's decidedly more complicated than Python. Being on par with C is hardly appropriate for a dynamic language.
To be clear, I really do appreciate the help, and I absolutely will tackle this someday (soon). Still, JavaScript has a serious problem here.
More to the point, even if what you said were true, the tooling is still absurdly complicated in the JS world. Your comment is a mix of of a red herring and whataboutism.
There should be tools that help you write and update a setup.py.
In my experience, this was always the hardest part. I started using python in 1999, and I never really had any problems setting up dev environments or doing any of the other things that Glyph discusses at length at that link. As I said above, distribution is the difficulty. The javascript "complications" about which some complain at every opportunity are only possible because distribution is so easy.
If comparing the pros and cons of two languages in response to another such comparison is "whataboutism", then I have no fucking idea what that term means.
The issue at hand is not whether Python is superior to JS. Rather, we're talking about a specific problem in the JS world -- the apparent need for tooling and its so-called "dependency hell".
Bringing deployment into the conversation is whataboutism.
However, once you've done it yourself, you understand that it's overstated. I can setup a template for a JS project quicker than I can a Python one these days. You have to learn how to do that, yeah (which is the annoying part), but it's not hard, just scary cause without having worked with it, all you see is options.
Tools are here to solve problems. Don't bother with them until you have that problem yourself. If you one day decide you want to set up things like auto-minification, image compression, CSS-preprocessing, then look into build script options. Otherwise, it'll just overwhelm you.
Plus it's literally a 20 line config file to do so.
module.exports = {
entry: './src/app.js',
output: {
path: './bin',
filename: 'app.bundle.js',
},
module: {
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}]
}
}
Include your app.bundle.js file in your webpage and you are good to go.https://medium.com/webpack/announcing-the-new-webpack-cli-75...
With React pushing hard to use JSX and discontinuing the in-browser JSX-to-JS transformation step, this is no longer completely true. You have to introduce the tooling from the start. (Yes, technologically you are not forced to use JSX and can use JS, but this is clearly declared as unwanted in the React ecosystem.)
I think that core js evolution has slowed down. There is not that many new things in ES2017 compared to ES2016.
Some libraries still evolve a lot but that will probably slow down over time. Some tools evolve but that is slower than the libraries. It was a few years between webpack 1 and 2, for example.
I just started contributing to an open source project with a lot of JavaScript without any modules or even IIFE wrappers, everything is global. Just 1 year ago I would solve the problem with a new build system but now I'll just gradually introduce ES6 features, and I will not do any module refactorings because in 6 months I can probably just introduce standard modules without any build step.
When modules ship, 90% of what you need for a SPA will be available natively in browsers. If you are building a complex product, complexity will naturally increase, with build steps for various reasons.
You can include React in an HTML script tag just like you could jQuery 5+ years ago and use it like that just fine.
The issue with JS is that it's a language used for lots of different things, and one of those things is front-end web development which is, like you said, very unstable and currently in a state of enormous flux.
You say we need to draw a line between the language and the libraries, but then you go on to say the language seems to reinvent itself every year.
Now that I'm finally used to ES6, here comes some other frankenstein with more flesh bolted on.
At what point will Javascript relax and stop reinventing itself and what works? When will stability become a core goal for the Javascript thought-leaders?
I haven't worked with .NET and C# for years but I bet I could feel right at home today. I couldn't say the same for Javascript.
After ~2016: "Stop improving JavaScript, I can't keep up!"
(Not a personal attack, just general sentiment I've observed)
One major issue I have with JS is that the standard library is severely lacking in the basics. We have Promises but Math.round only rounds to the nearest integer. We have generators but no string formatting (the template syntax is not a replacement).
The bad parts are still here that's the problem. The language didn't improve so much that it got new features. But var, ==, type coercion and co still exist.
They all have alternatives, and linters can help restrict you to those alternatives. As a developer, that makes it pretty doable.
I presume you too can appreciate why they can't simply be removed.
It's the price of improving the language + backwards compatibility.
Or you could use codemods to update your code base in an automated way. See: https://github.com/cpojer/js-codemod
Today Meteor has mostly overcome its initial NIH obsession and thus mostly become irrelevant unless you're already a Meteor user.
It's never the right choice to jump on whatever bandwagon is all the rage at any given moment. Just look at what's been around and is still seeing active development if you want something with a long lifetime.
Personally to a newcomer to JS who wants something that'll work for a while I would probably recommend Ember or if they want something slightly more newsworthy I would recommend Angular.
On the other hand if you want to learn JS as a language and aren't afraid to go through a number of iterations of picking and discarding libraries, I would recommend what I prefer myself: React, followed up by Redux once you've outgrown toy applications.
You'd be surprised. It is shockingly different now - they are in the early stages of exactly what happened to JS.
I'm sure the outcome will be really beneficial for everyone, but at the moment it's very confusing if you aren't constantly monitoring it and keeping up-to-date.
> At what point will Javascript relax and stop reinventing
> itself and what works?
I am afraid part of the reason for this is continuous effort to put a square peg into a round hole (by this I mean the "web for everything, JS for everything" attitude), so it will go on for a while.How many of those people have written at least 10k+ lines of JavaScript?
These changes are hard, but they are undeniably improving the language.
And as many others have stated repeatedly, it is not necessary to chase the bleeding edge. For example, I just learned React for the first time a few weeks ago, and I'm glad I waited (I haven't started using Redux yet either). I'm also still using browserify instead of webpack. And so on.
1. These package managers and build systems and all that are fairly replacable in terms of implementation. They all just give you some namespace management, but the actual JS code is usually the same or very similar.
2. I'm using vanilla JavaScript, so even though I have to reinvent the wheel from time to time, I don't have to support outdated APIs, bother people with further dependencies, and save bandwidth. And given that I'm lucky enough not having to worry about backwards compatibility, I can leverage all the Maps, Sets, UintxArrays and other modern JavaScript goodness that was previously delegated to libraries.
The one thing that I really miss is that most (all?) JS module implementations really seem to be focused on static compile workflows. Sure, for deployments you want that, for development JS as a very dynamic language would offer much better support for live programming systems if the module systems would play along nicely. One reason why I personally was excited to see that the loader proposal initially considered custom locate/fetch/define behavior added via hooks but more recent discussions about bringing it forward seem to dismiss that. I think for great tooling a module system that supports both deployment as well as development needs is necessary and would really add to the JS ecosystem.
[1] https://github.com/systemjs/systemjs [2] https://github.com/whatwg/loader
That's what baffles me coming from Java and C#; I can have dynamically loaded modules with strongly typed interfaces in these ecosystems, but not in any JS module system.
JavaScript is not a typed language (yet?) so it's like expecting pigs to fly.
This is great and in no way the same as Python 3; with this old packages are compatible with newer ones, it is newer ones the ones that will not be compatible with older ones (not ideal, but still acceptable IMO).
> Since this approach is based on explicit import and export statements, it is vastly more effective than simply running an automated minifier to detect unused variables in the compiled output code.