ECMAScript Modules vs objects-as-namespaces - javascript

I've been using Modules that are presented with ES6 for a while. While I (instinctively) know that it is better to use them, I struggle to explain why.
With modules;
I can do dependency declaration (not injection). I do not have to use a script tag for each javascript file I load.
Before modules, objects served as namespaces. Now that we have modules, we have namespaces which is a better paradigm for code organization.
Else than this, why should I use modules ?
What advantage they provide over just using objects as namespaces ?
EDIT:
Thanks to the comments of Bergi and Randy Casburn, I am now able to point out two more things.
With Module Pattern(which i been calling object-as-namespaces) we have same functionality. But we get it through closures. In Modules, we have separate files. Features of a separate file is harder to be violated.
Modules hide their internal features. It drives us towards thinking about better software design.

Answering my own question. Thanks for the comments.
Modularity is a must for software. Before ES Modules, we achieved modules through Module Pattern(which is simply putting related things in an object). By ES6, Modules are native. And native is always the better option.
In Module Pattern, we made modules with closures. In ES Modules we code them in seperate files.
Seperate files adds another layer of protection against code violation.
Modules drive us to design better software.
With ES Modules we have export keyword which gives us freedom to choose what to expose.
We also have import keyword to pick whatever we want from a module.
With ES6 Modules we can now include Javascript modules which are in seperate files into our web app without the need to include them in script tags.

Related

Why do some npm packages have an es directory?

I've noticed some libraries have duplicated code in an es folder. Why do developers do that?
examples:
Developers can ship their packages in a few different flavours, depending on how the user (e.g. you) wants to use them.
If you want to use the module code (i.e. import), or you want to use es2015 (i.e. the require), or you even might want to use it in a browser environment (standalone - think .min file).
The folders names are meaningless, developers can call them whatever they want, but they'll probably put their non-transpiled (i.e. import) modules in an es or esm directory
Keep in mind that just because you are "import"-ing their module doesn't mean that their module uses imports. Most nowadays are still transpiled before being shipped so the code you're import-ing is probably require-ing stuff.
It's kind of complicated...

What is difference between Module Loader and Module Bundler in JavaScript?

Can someone provide some information about Module Loaders and Module Bundlers in JavaScript?
What are the differences?
When should I use a Module Loader and when a Module Bundler?
Why do we need them at all?
Module loaders and bundlers both make it more actionable to write modular JavaScript applications. Let me give you some background:
Module loaders
A module loader is typically some library that can load, interpret and execute JavaScript modules you defined using a certain module format/syntax, such as AMD or CommonJS.
When you write modular JavaScript applications, you usually end up having one file per module. So when writing an application that consist of hundreds of modules it could get quite painful to make sure all files are included and in the correct order. So basically a loader will take care of the dependency management for you, by making sure all modules are loaded when the application is executed. Checkout some popular module loaders such as RequireJS and SystemJS to get an idea.
Module bundlers
Module bundlers are an alternative to module loaders. Basically they do the same thing (manage and load interdependent modules), but do it as part of the application build rather than at runtime. So instead of loading dependencies as they appear when your code is executed, a bundler stitches together all modules into a single file (a bundle) before the execution. Take a look at Webpack and Browserify as two popular options.
When to use what?
Which one is better simply depends on your application's structure and size.
The primary advantage of a bundler is that it leaves you with far fewer files that the browser has to download. This can give your application a performance advantage, as it may decrease the amount of time it takes to load.
However, depending on the number of modules your application has, this doesn't always have to be the case. Especially for big apps a module loader can sometimes provide the better performance, as loading one huge monolithic file can also block starting your app at the beginning. So that is something you have to simply test and find out.
ES6/ES2015 Update
Note that ECMAScript 2015 (or ES6) comes with it's own, native implementation of modules. You can get a quick intro here and here.

Packaging AngularJs apps

I am building Angular Apps, using 1.x and have been for some time now. I use Bower to install Angular and the various packages that go with it and some other bits and pieces like Shivs, JQuery, ChartJs etc etc. I love using Bower as it's nice and quick and keeps everything in a consistent place for me to reference. I use Grunt as well as my task-runner and so I'd also like to be able to automate this process for silky smooth development.
Now as my Angular knowledge has increased and the scale of the apps that I'm building are increasing, I'm finding myself including dozens of calls to files within the index.html and I really want to tidy all this up, ideally into a nice app.js making it all much more manageable, not only for myself but for anyone else coming in and working on these apps.
I've seen maaany tools like requirejs, browserify and commonjs to name but a few, which all provide the kind of functionality I'm after, but when reading various tutorials or watching conference talks on the process, they all seem to conflict with one another on which is the best. I know to some degree (as with all these competing technologies) it's personal preference, and I was leaning towards browserify, but apparently this removes bower from the flow and uses NPM instead. I'd like to stick with Bower if possible. I've really enjoyed using it.
Does anyone have any suggestions or best practices they can offer that might clear this up for me? Would a simple concat with grunt/gulp just be the way to go?
Any useful comments/answers would be much appreciated.
Many thanks.
Use ES6 Modules along with a module bundler (my recommendation would be Webpack).
As you have correctly identified RequireJS and commonjs evolved around different (and slightly conflicting) goals and are incompatible. ES6 modules is a standardized effort towards modular javascript that is already well supported by transpilers (eg. Babel).
This article provides a great introduction to this new feature:
Even though JavaScript never had built-in modules, the community has
converged on a simple style of modules, which is supported by
libraries in ES5 and earlier. This style has also been adopted by ES6:
Each module is a piece of code that is executed once it is loaded.
In
that code, there may be declarations (variable declarations, function
declarations, etc.).
By default, these declarations stay local to the
module.
You can mark some of them as exports, then other modules can
import them.
A module can import things from other modules. It refers
to those modules via module specifiers, strings that are either:
Relative paths ('../model/user'): these paths are interpreted
relatively to the location of the importing module. The file extension
.js can usually be omitted.
Absolute paths ('/lib/js/helpers'): point
directly to the file of the module to be imported.
Names ('util'):
What modules names refer to has to be configured. Modules are
singletons. Even if a module is imported multiple times, only a single
“instance” of it exists. This approach to modules avoids global
variables, the only things that are global are module specifiers.
Example of use of Javascript modules in practice:
//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

What is the best approach for TypeScript with ES6 modules?

I am starting a new Web project and trying TypeScript, mainly as an ES6 transpiler but also with the additional benefits of type checking, especially for existing libraries such as jQuery combined with the DefinitelyTyped type definitions.
Since the latest version, TypeScript supports both its own internal modules and ES6 modules, which calls "external" modules. Because ES6 is more standard than TypeScript, my intention is to use ES6/external modules rather than the traditional/internal TypeScript modules.
I have my own code defined in several files/modules, but I want the build to generate a single .js file that I can load from the browser.
The problem is that as far as I can tell, TypeScript is only able to generate a single output file when using its own module format. If I try to use ES6 external modules, then it generates a separate .js file for each .ts file.
This means I would need to concatenate them using browserify, but also I want source map support, which means that I should configure browserify for input and output source maps, then combine it with exorcist so the source map is extracted out of the bundle.
That looks like a very complex build setup. Isn't there a more straightforward way, maybe directly supported by TypeScript? What is the best approach? What do you recommend?
Let TypeScript do what it does best...
Add types to JavaScript be it ES5/ES6/ES7
Transpile to ES5
Resolve modules via the specified module syntax (commonjs, amd, umd, system)
Then find another tool that will take the separate files and combine them into a single bundled file (in the right order). My suggestions are to look into:
webpack
browserify
tsify
Are you looking for a solution in the browser? If so, I highly recommend my project Zwitterion. It removes the complicated build steps, and let's you include TypeScript directly into the browser with normal script tags. You can also use standard ES modules directly, with no extra setup. It uses SystemJS under the hood to achieve that. There is no source map support yet, but that should come. If you would like more information besides what's in the README, you can read "Zwitterion, forget the build step".

To require or not to require?

So I've been building a single page web app for a while now and I've been writing all my code in an extremely modular approach. I've been using the javascript module pattern for all modules and my main API uses the revealing module pattern to expose a small API for plugins and other modules.
So even if I've been writing my code like this someone mentioned I should be using require.js as it gives a better modular approach.
I decided that require.js doesn't really make it more modular so my next thought was how require.js separates out dependencies. Require.js forces you to name dependencies in each module file. But this to me seems to be a task I have to do for every module and I have a lot of modules. At the moment all my files are concatenated into a single javascript file in my grunt build process so really all my files are loaded at the start. I need most of my modules loaded at the start so it made sense to do this.
So my question is... Should I use require.js even though my code is modular and all my files are concatenated together and loaded at the start? Do i need to worry about dependencies or loading order? Any help/advise or previous experience when dealing with this situation would really help. Thanks
Have you had annoyances putting <script> tags in the correct order to handle dependencies right?
Having a requirejs config file where you declare the third-party code and your own code dependency tree is a much more organised approach than declaring <script> tags by yourself.
When you are testing your app in dev environment, wouldn't be helpful to have all those modules in separated files that are easier to debug instead of all of them concatenated?
With requirejs you can switch between optimised/concatenated/minified code used in production environment and a list of independent files representing each module in the development environment.
Are you creating a global variable for each module in your app?
Requirejs avoids creating a global variable for each module so your global scope doesn't get cluttered.
It's usually a good practice to follow conventions in the way you declare modules. Requirejs implements AMD specification that is a well thought way of loading modules in client javascript.
http://requirejs.org/docs/whyamd.html
It's way easier to follow conventions if they're already implemented in a mature framework. And sometimes we don't notice but between apps we do the same thing differently and that affects in the maintenance phase.
Take a look at the requirejs optimizer. Look all the options it give you. It allows you to exclude files, to change versions of a given module, to change the minification tool, to integrate the optimization process with other tools like grunt or bower, etc.
http://requirejs.org/docs/optimization.html
If you don't need any of this, then just continue doing it in your way.

Categories