tips for migrating a javascript app to using AMD (eg requirejs) - javascript

I have a javascript project were most modules are using some third party libs as 'global' dependencies (in particular jquery and jquery plugins)
I would like to "clean" the project (to express all libraries as requirejs dependencies.), however this is in my case a large task (lots of files, lots of third-party libs).
How could I make the migration easier / quicker ?
Can I "fake" using amd dependencies by wrapping the third-party libs in modules that just load them (with the order! plugin ?)
Is it safe to mix modules that load third-party libs as modulesand modules that directly use the global ?
If I wanted to automate things, are there any tools could I use to 'parse' a requirejs module to tell me if a particular symbol is used ?
Edit : What I mean by my last question is "Would it be possible to automatically rewrite my js files so that hey explicitely import dependencies instead of relying on browser globals ?"

Can I "fake" using amd dependencies by wrapping the third-party libs in modules that just load them
Yes you can, RequireJS has a shim config that is designed just for that.
Take a look at this article it will help you organize your JavaScript code with RequireJS http://www.stefanprodan.eu/2012/09/intro-requirejs-for-asp-net-mvc/

I had a similar question about the need of wrapping third party code in AMD modules. My conclusion was, that there are no benefits in my case (large Backbone app). So you should ask yourself if you really need to import jquery for example per AMD. This will end in modules where you import jquery every time, which is a lot of error prone boilerplate code.
So in short it makes no sense to use AMD for code that you will use in any case.

Related

script for both modules and non-module usage - JavaScript

This is my problem: I created a library to use within Chrome extensions. This library exports two classes, one of which should be imported in the background script and one in the content scripts.
The background script (and other scripts that are used in the extension pages) can handle modules, so I would like to use the native "import"/"export" feature of ES6 Modules.
The content scripts do not support modules. That means that if I use the "export" keyword in my library script, that will throw an error, and I won't be able to use the library anymore.
Currently, I'm not implementing modules at all, and that solves the problem, but I would like to implement this functionality, so that it can be used when someone has access to it.
Is there a way to offer my library functionality as both a module and a non-module for both kind of scripts? Is that actually something that I should do?
In the end, I set up two git branches:
1 - In the first one, I just kept the file without the "export", so no ES6 modules capabilities
2 - This other branch, I decided to set it up to be published on NPM, and in this one I exported my classes. If you use NPM for your development, it's already very probable that you also have a bundler like webpack to keep track of modules and dependencies.
Whenever I do a change, I do it in the master (no exports) branch, and then I merge the changes in the npm branch, to avoid writing the same code twice

Dynamic Loading Files in NPM Modules as Plugins (ES6 Import)

I am developing a NodeJS application, and was thinking about the best way to develop a plugin system. Currently, most components on the application are already decoupled in a way that they can be registered in and out to add and/or remove functionality. But currently, those components are still spread across many folders inside the app source. My goal would be to have a plugins folder, with a sub-folder for each plugin, and the application would scan said folder on startup to load the plugins. Also, as a nice plus, I'd love to load plugins from the node_modules (inspired by the way babel handles presets in version 6). I already have a fairly good idea how this system will work.
Now, my question is what is the best way to provide access to common files and classes, to the plugins. Let's say that I have a base class Receiver, and a plugin registers a custom receiver (which will extend the base class Receiver). How do I provide access for all theose classes to an external npm module without creating an object and passing each manually?
I use ES6 imports which replace the node's require function in my code, and use relative paths, but to be honest, I've never really understood how babel implements these module loaders and how could I use a dynamic module loader.

How to bundle CommonJS modules into a single UMD library file?

I'm writing a JS library and organizing the code in a hierarchy of CommonJS modules connected with require calls. Then in addition there are also external dependencies (like Underscore).
How can I bundle all my library modules into a single file (CommonJS+AMD) excluding the external dependencies which should remain as require calls?
I've experimented with Browserify and came close with --standalone and --external but when using Browserify again on the application that is using this bundled library it gets confused with the remaining require calls inside the bundled lib. And when I get rid of them with something like Derequire it will also strip out the require calls to external dependencies.
I tried to figure out how other libraries approach this but they mostly seem to have some custom concatenation scripts. Is there a simpler solution? Seems like it should be a common enough use case.
Try what you're already doing with standalone and external, then when you bundle the second time pass the noParse option to browserify (e.g. browserify({noParse: ['/abs/path/to/first/bundle']})). Or you could try minifying the first bundle. See also this answer.

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