Modular JavaScript - are there any approaches apart CommonJS and AMD to consider?
Asked Answered
F

7

11

I'm currently preparing an evaluation JavaScript modularization approaches for my corp. We are in process of defining "JavaScript Best Practices" for our projects, modularization is one of the central questions.

From my research so far revealed two leading approaches:

With a huge number of loaders, plugins, libraries etc. around them.

Apart from that there's also goog.provide/goog.require from the Google Closure Library.

Are there further approaches to consider? Any important/relevant specs I missed?

Our requirements, briefly:

  • Structure JavaScript code in separate files.
  • Load relevant modules in the runtime.
  • ...without having to include every single file as script tag.
  • Must not be necessary to maintain an index of JavaScript files.
  • Support aggregation and minification - ability to build and use a single minified/optimized JavaScript file.
  • Be able to use modules in different combinations - there are often different web pages/clients which need different subsets of modules.
  • Supporting documentation (with JSDoc?).
  • Suitable for testing.
  • Suitable for web, cross-browser.
  • Reasonable IDE support.

Potentially:

  • Aligned with ES6 modules.
  • Suitable for Node.js and mobile platforms (like PhoneGap/Cordova).

New suggestions from answers:


Side notes:

  • The question is not about which approach is better.
  • I am not asking for specific libraries and tools, but rather for approaches and specifications.
  • I am not specifically asking for an off-site resource. (If there's no SO tag for this, it's probably not reasonable for us to consider it.)
  • A note on frameworks like or . This is not really suitable in the frame of this quesion. If the project needs a framework (be it AngularJS or ExtJS) then there's mostly no modularization question as the framework must deliver modularization OOTB. If the project does not need a framework, it is an overkill to bring a framework because of the modularization. This is one of the reasons I am specifically not asking about libraries/tools.
Folkrock answered 17/11, 2014 at 9:19 Comment(12)
@closer I am specifically not asking for opinions.Folkrock
This question belongs to Programmers.StackexchangeDarrel
See medium.com/@trek/…. Also, I'm not quite sure why you've put "aligned with ES6 modules" as a "potential requirement", when it itself is a solution, in tandem with an ES6 transpiler such as Traceur.Wallaroo
Why do you yet another pattern...? Just stick to what works.Padegs
Have you considered the possibility that "do nothing" satisfies all your requirements?Wallaroo
@torazaburo At least we have to structure JavaScript code in separate files, so I don't see how "do nothing" can satisfy that.Folkrock
@torazaburo You're right about ES6 modules. It is an option to consider.Folkrock
@self I'm not inventing yet another pattern, I want to evaluate existing patterns. To do this, I have to know which patterns exists. My personal knowledge is limited, therefore I ask ask the community.Folkrock
You probably asked "What apart sync or async module loading to consider?". Ok, I think you probably looking for javascript issue, not node.js. What is the main target of javascript module loading? Do not block the user i/o. So let's google for javascript async module loading query. Wow! Look at this - addyosmani.com/writing-modular-jsSyblesybley
@Pinal The link is very helpful, was already posted in the answers. My primary requirements is not async, my primary requirement is code organisation.Folkrock
@Folkrock Code organisation don't imply what lib use or not. Code organisation is about how use this or that library. Select lib and use it best practice.Syblesybley
@Pinal As you may or may not have noticed, I'm specificaly not asking about libs, I am gathering approaches to evaluate. Do you happen to have a further modularization approach for me to consider?Folkrock
A
1

How about ES Harmony?

quote from here: http://addyosmani.com/writing-modular-js/

Note: Although Harmony is still in the proposal phases, you can already try out (partial) features of ES.next that address native support for writing modular JavaScript thanks to Google's Traceur compiler. To get up and running with Traceur in under a minute, read this getting started guide. There's also a JSConf presentation about it that's worth looking at if you're interested in learning more about the project.

hopeThatHelps

Attribute answered 25/11, 2014 at 17:30 Comment(2)
A good link, thank you. ES Harmony is to consider. The disadvantage is an additional build step which may be an overkill for projects with few JS files and small audience (we have a >1Mio projects used by <10 people).Folkrock
From my PoV this is the best answer. You have suggested an approach which was not considered in the question.Folkrock
P
1

Another option: the AngularJS module system, as described here. This is really only useful on the client side, however.

Playpen answered 22/11, 2014 at 16:52 Comment(1)
Please see this comment on framework. (In response to ExtJS suggestion, but applies to AngularJS as well.)Folkrock
C
1

You wrote "I am not asking for specific libraries and tools, but rather for approaches and specifications." however you can look closer to ExtJS 5 environment which fulfils all your requirements.

If you are not interested in such commercial product you can just get to know patterns and solutions in it.

Relation to your requirements:

Structure JavaScript code in separate files.

It implement Object-Oriented Programming paradigm so you can create classes, subclasses, objects, mixins, plugins. It connect class-based programming and prototype-based programming.

Worth noting MVVM architecture (View, Controller, ViewModel), data binding, data session (records/entities client-side management).

Config system is also quite interesting. It's very handy. The config property is merged from parent class to subclasses and also during object creation you can pass config which will be merged too. It is very useful when we want have customizable and flexible components.

Load relevant modules in the runtime.

Each class may has requires or uses directive which are used when builing application to one file. You can also manually load files.

...without having to include every single file as script tag.

In dev env files are loaded dynamically (asynchronous or synchronous).

In prod env necessary files has been built to one minified file.

Support aggregation and minification - ability to build and use a single minified/optimized JavaScript file.

You can build application with Sencha cmd tool (and do a few other things).

You can use three predefined env (development, testing, production) or create your own (based on config files and ant).

Be able to use modules in different combinations - there are often different web pages/clients which need different subsets of modules.

You can use workspaces and packages.

Supporting documentation (with JSDoc?).

JS Duck, tutorial

Suitable for testing.

You can do unit tests (PhantomJS, JSLint, PhantomLint, Jasmine).

You can use dedicated framework like Siesta or other popular testing frameworks like Selenium.

Suitable for web, cross-browser.

From offical website:

Deliver apps on the widest selection of browsers and operating systems with a single code base. Ext JS 5 leverages HTML5 features on modern browsers while maintaining compatibility and functionality for legacy browsers. Confidently deliver apps to your end users regardless of what browser they are using.

Support: Safari 6+, Firefox, IE 8+, Chrome, Opera 12+, Safari/iOS, Safari / iOS 6+, Chrome/Android, Chrome / Android 4.1+, IE 10+ / Win 8

Supports Cordova and PhoneGap application.

Reasonable IDE support.

I don't know very good IDE with dedicated support for ExtJS but I work on Webstorm and it's fine. Library sources are inside project so autocompletion works (but not 100% perfect).

Conclusion

I don't want to glorify ExtJS 5. Environment is quite mature and stable but latest version of framework (v5) has a couple bugs and not everything is great. However I could go deeper and get to know principles of that framework which are reasonable, driven in good direction but sometimes bad implemented ;)

Coauthor answered 22/11, 2014 at 17:3 Comment(2)
Thank you for the elaborate answer. I'm afraid, ExtJS would be too big to consider in the frame of the modularization question. It is a full-fledged framework. "Which framework?" is another question. If the project needs a framework (be it AngularJS or ExtJS) then there's no modularization question as the framework delivers modularization OOTB. If the project does not need a framework, it is an overkill to bring a framework because of the modularization.Folkrock
@Folkrock I agree however if you know some framework then there is no difference how big is your application. Most of frameworks can be used in small and big projects. Your requirements are quite complex and can be covered only by many tools or one good framework ;)Coauthor
A
1

How about ES Harmony?

quote from here: http://addyosmani.com/writing-modular-js/

Note: Although Harmony is still in the proposal phases, you can already try out (partial) features of ES.next that address native support for writing modular JavaScript thanks to Google's Traceur compiler. To get up and running with Traceur in under a minute, read this getting started guide. There's also a JSConf presentation about it that's worth looking at if you're interested in learning more about the project.

hopeThatHelps

Attribute answered 25/11, 2014 at 17:30 Comment(2)
A good link, thank you. ES Harmony is to consider. The disadvantage is an additional build step which may be an overkill for projects with few JS files and small audience (we have a >1Mio projects used by <10 people).Folkrock
From my PoV this is the best answer. You have suggested an approach which was not considered in the question.Folkrock
O
1

RequireJS is a good approach since it enables dynamic javascript module loading as well as it keeps the code clean. You can also minify the whole modules and it actually performs really fast. It also allows something called as shimming where you can specify the dependencies for a library or any js file such that whenever you try to load it, all the dependencies also follow

Oliverolivera answered 26/11, 2014 at 5:45 Comment(1)
Thank you. RequireJS is amd, so covered in the question.Folkrock
R
1

Take a look at systemJS:

Spec-compliant universal module loader - loads ES6 modules, AMD, CommonJS and global scripts.

Designed as a collection of small extensions to the ES6 specification System loader, which can also be applied individually.

Loads any module format, by detecting the format automatically. Modules can also specify their format with meta config. Provides comprehensive and exact replications of AMD, CommonJS and ES6 circular reference handling. Loads ES6 modules compiled into the System.register form for production, maintaining full circular references support. Supports RequireJS-style map, paths, bundles, shim and plugins. Tracks package versions, and resolves semver-compatibile requests through package version syntax - [email protected], package^@x.y.z. Loader plugins allow loading assets through the module naming system such as CSS, JSON or images. Designed to work with the ES6 Module Loader polyfill (9KB) for a combined total footprint of 16KB minified and gzipped. In future, with native implementations, the ES6 Module Loader polyfill should no longer be necessary. As jQuery provides for the DOM, this library can smooth over inconsistiencies and missing practical functionality provided by the native System loader.

Runs in IE8+ and NodeJS.

The creator of the lib -- Guy Bedford -- is a great presenter as well: systemJS presentation.

Rodger answered 26/11, 2014 at 11:43 Comment(2)
@Folkrock It is apart from regular, modern browsers. Take look at Bedford's presentation - it is pretty awesome.Rodger
Thanks for the clarification. It should be corrected on the page, I'll file an issue. This is clearly misleading...Folkrock
C
0

Take a look on a browserify. It implements interesting approach. With browserify you can write code that uses require in the same way that you would use it in Node.

Criminal answered 22/11, 2014 at 17:54 Comment(1)
Browserify is mainly CJS plus AMD via deamdify, so already covered in the question. Browserify is a good thing though.Folkrock
P
0

There are various libraries available for modular development, From which some full fill your criteria.

  • System.js System.js is modular development library with some basic features to work with IE8+ and nodejs. It also provides feature to develop modules and you can include it in your main file. For more information about System.js follow https://github.com/systemjs/systemjs
  • Require.js The best library for modular development. Provides various useful features and supports older browser too. It supports from IE 6+. Another useful feature of require.js is that it can be used with Rhinojs and nodejs. Implementation is simple as like you include modules in nodejs.
Porous answered 27/11, 2014 at 3:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.