requirejs vs google javascript closure dependency management - javascript

I've been using the google javascript closure library for a variety of components, and I've also used its dependency management. I'm curious as to how that compares to using requirejs for dependency management. Specifically, is there a particular reason to choose one over the other?
If I'm using the google closure library, would there be a logical reason to use requirejs to manage dependencies vs using the closure dependency management? Are there standards that requirejs follows that closure does not?

The Closure Library dependency management is intended to be provide an ordering of files to resolve dependencies and are removed by the Closure Compiler during compilation (rewritten as necessary to provide the namespaces as needed, actually). While the compiler has some experimental compile time support for AMD modules, they still need some work on the type checking front in particular to be a full replacement for Closure's goog.require. Even when compiler support is sufficient, goog.require does not require a full parse of the JS in order to do dependency management (I'm not familiar enough with RequireJS to know if this is the case) and so for large projects with many optional files goog.require are currently much more efficient.

Related

How does a packages typescript code is consumed by other packages?

When a package with typescript code is imported. will the consumer use typescript or transpiled code (e.g. typescript to ES5).
Scenario #1: If the consumer uses transpiled code (which is not in typescript). How is VSCode able to recommend auto completions from the packages types?
Scenario #2: If the packages are served with typescript files.
What happens if the consumer is not using typescript?
How does the bundling at the consumer end happen?
TL;DR
Scenario #1: This is the most common scenario for public NPM packages, editors use external .d.ts files that contain type declarations
Scenario #2: I've only seen this with internal libraries
1) You'd need to compile the TS by yourself, but that would probably not be necessary because there will almost always be a compiled-to-js version of the library, too
2) This could go many ways, best case is that the library gives you a pre-optimized JS that is just bundled with your code, worst case is that you have to make sure you have all the right dependencies installed for the library to be able to be compiled with your code and they need to be compatible with the dependencies you're using yourself. In my opinion this isn't worth the hassle, having type declarations for NPM packages is sufficient for the level of type safety TypeScript can provide.
The Long Version
There are dozens of variants how people distribute their TypeScript based code via NPM. Most big libraries I know ship their compiled (and often minified) JS and add .d.ts declaration files for editor support - these may be hand-written or produced by using tsc from a codebase. VSCode uses its TypeScript language server for JavaScript files, too, so in many cases it doesn't even need additional declaration files to provide you with basic autocompletion. Libraries can declare a types field inside the package.json, VSCode and other editors will find types there. There is a rather large community that maintains mostly inofficial type declarations for most libraries on definitelytyped - you may be out of luck for obscure ones.
A few examples
Material UI
Is written in JavaScript
Has hand-written TypeScript declarations (which may or may not be accurate)
React
Is written in JavaScript
Provides no TypeScript declarations with the NPM package but VSCode knows where to find inofficial external ones
Angular
Is written in TypeScript
Uses the deprecated typings field to point to its type declarations
jQuery
Is written in JavaScript
Again, has no provided type declarations but your editor probably knows how to fetch inoffical ones
Seneca
Is written in JavaScript
Has inoffical type declarations that are two years old at the time of writing - good luck finding out whether the API really hasn't changed
Important take-aways:
There is no single way people do things in the JS ecosystem and by extension the TS ecosystem
Most type declarations you're using are not official ones but the ones maintained by the community, mostly on definitelytyped
The types might be lying to you (may be out-of-date, just be plain wrong or for an older TS version)
TypeScript is a superset of JavaScript, it comes with all the same gotchas by definition
All types are erased at runtime, in the end you're running plain JavaScript with all that this entails

Modularity in Javascript

I know that if there are multiple JS files to be rendered by the browser, which apparently have identifiers inside, the global scope is polluted by this identifiers. I also know that one way to avoid this is using modules which(in my understanding) are just objects which have the aformentioned identifiers as members, thus sort of imitating C++ namespaces. I am also learning Node.js and there is a built in module system which eases this task so my question is: how to use modules in js files that are sent to the browser to be rendered?
Thanks.
Tools like browserify and WebPack are exactly what you are looking for (I personally prefer browserify over WebPack). Have a look at this answer, it explains a lot of your concerns.
In Node.JS, you can export a module using module.exports keyword, but you cannot just import those modules in your browser by just requiring them in a <script> tag. That's because, the browser doesn't understand the module system and everything works in the context of a global window object there, so module.exports simply becomes window.module.exports which I'm sure you'll not want. Hence you use tools like browserify that process the Node.JS scripts into something that your browser will understand.
This problem is usually solved by module bundlers or module loaders (e.g Webpack, Browserify, RequireJS). They are able to understand relations between your JS modules, skip unused modules and produce output that just works in your browser. All of that without the need to worry too much about global scope if you follow some conventions.
Some time ago, before ES6, two different approaches to this problem were widely used:
CommonJS:
var module = require('my-module');
widely known from Node.js
AMD:
define(['jquery'] , function ($) {
return function () {};
});
Which was suited for browser usage since it by design supported asynchronous loading of modules.
Then ES6 was introduced with native support for modules:
import * as lib from 'lib';
Main problem with new technology in web is that you often have variety of browsers to support which for a long time prevented developers from using new features. Nowadays, we have code transpilers and sophisticated code bundlers (e.g. Webpack). With their help you can use latest version of language, compile and bundle your code and at the end single "bundle.js" file is emitted which supports older browsers at the cost of slower execution times.

import and export in Javascript

According to this question How do I include a JavaScript file in another JavaScript file?. It seems a lots of people are interested in breaking big Javascript projects into small modules and export/import modules for code reuse.
After some research, import/export are designed for this feature. According to the references, they're initially defined in ES6.
Update
Latest version of main browsers shipped with this feature implemented. To have the latest status, please always refer to the References.
(If you're using nodejs, Modules (https://nodejs.org/dist/latest-v5.x/docs/api/modules.html) is the best aproach)
Refrerences:
https://developer.mozilla.org/en/docs/web/javascript/reference/statements/import
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
In the current versions of JS there are a few methods of doing this. Require uses the AMD design pattern, and is the standard for frontend dependency injection / module loading. Frameworks such as Angular use this method.
Here is a link to the require docs.
http://requirejs.org/
Time goes by... Today I would rather suggest using Babel (within browserify or webpack) to turn ES modules into plain old javascript.
Then you have the full power of import/export syntax.
Require/AMD/CommonJS is just getting deprecated anytime soon.

Ultimate JS module solution for UMD with dependencies?

I maintain and collaborate on some JavaScript modules written in CommonJS that are in need of high-quality UMD wrappers.
The dependencies are sourced from npm but have at least CommonJS and AMD support (or I can add it).
The CommonJS version goes on npm The UMD wrapped module will be pushed to bower
The wrapper must work in browsers (AMD + globals), and in Node.js (any and other CommonJS systems if possible). Any automation should preferably happen using Grunt (I'm pretty handy in grunt).
I've spend ages trawling Google en SO but it is a huge mess.
Some hopeful ones that don't quite cut it (or I am missing something, which is entirely possible):
browserify
gluejs
grunt-umd
I'm finding desperate constructs like this everywhere: http://rathercurio.us/building-umd-modules-with-dependencies-with-browserify , but I'm not really cool with such hackery.
Any good tips on this? I'll take any pointer or link or tip.
Edit: clarification: that last thing said, the ideal solution should not require us to assemble chunks of boilerplate template code by hand and create new bugs. I cool with configuring and specifying stuff though.
Your 1st and last stop should be urequire.org, the Universal Module Converter that does much more that just converting CommonJS and AMD javascript modules to UMD (or AMD or CommonJS or a standalone using rjs/almond).
It allows you to manipulate Module's code and dependencies while converting: inject, replace or remove code and dependencies, export to global objects (window) or your bundle, inject & optionally merge common code (like initializations), add runtime information, minify and much much more.
Most of that using simple but hugely powerful declarations & optionally callbacks for fine grained manipulation. It works with standalone config files (.js, .coffee, .json, .yml etc) and as-is as a gruntjs config
uRequire compiles from source modules written in javascript, coffeescript, livescriped, coco & icedcoffeescript without any plugins.
Forget boilerplate, code ceremony and repeating requires. The conversion templates are based on the well known UMDjs but can be customized via declarations to hide or provide functionality.
uRequire is opensource, MIT license and hosted on github and authored by me :-)

compiling javascript program with requirejs to remove require dependency

I have written a JavaScript app using requirejs to handle dependency injection. I have compiled the file, but I get the obvious error when including it as a script:
Uncaught ReferenceError: define is not defined
I would like my JavaScript app NOT to depend on an AMD loader if the developer decides not to use one. However, due to the complexity of the application, I would like to use it to handle my app's dependencies.
Is there a compiler available that compiles JavaScript to remove the AMD dependency? I've seen a little bit of buzz around Grunt, but haven't found any straight answers on whether or not this is a feature of Grunt.
You can't completely remove the require/define dependency, but you can replace it with a much smaller shim that doesn't introduce any significant performance penalty. See the How can I provide a library to others that does not depend on RequireJS? section of the Optimization guide:
If you are building a library for use on web pages that may not use RequireJS or an AMD loader, you can use the optimizer to combine all your modules into one file, then wrap them in a function and use an AMD API shim. This allows you to ship code that does not ship with all of RequireJS, and allows you to export any kind of API that works on a plain web page without an AMD loader.
almond is an AMD API shim that is very small, so it can be used in place of require.js when all of your modules are built into one file using the RequireJS optimizer. The wrap build config option will put a function wrapper around the code, or you can provide your own wrapper if you need to do extra logic.

Categories

Resources