Using RequireJS alongside non-AMD JavaScript files

amd, javascript, requirejs, typescript

Solution

Recent versions of RequireJS allow you to pretend that the plain JS files are actually AMD modules that just return nothing.

The most recent version I tried - 2.1.4 - actually allows you to treat plain JS files like modules. Example:

require(
    [
        'path/to/module' // <- AMD module
        ,'path/to/plainjs' // <- actually a plain JS file
    ]
    , function(module, plain){
        // module will be per define in that file.
        // plain will be 'undefined' type
    }
)

You can just mix module-like refs to plain JS files freely. As long as they are loaded in the right order, they will update whatever globals they update and you get what you want. Example:

require(['js/underscore'], function(){

    // nesting to insure Underscore, a prereq to BackBone
    // completes loading before backbone starts
    require(
        [
            'path/to/module' // <- AMD module
            ,'js/backbone' // <- actually a plain JS file
        ]
        , function(module){
            // module will be per define in that file.

            window.BackBone // is available for you

        }
    )

})

Note, while RequireJS used to require that you add ".js" to the end of the plain JS files to indicate that they are plain JS, in the examples above you do NOT use ".js" This, extension-less module reference allows the module ID to follow `paths` and `maps` aliases, while ids with `.js` are treated as literal and are never translated.

Problem

I'm trying to convert a JavaScript-heavy page to use TypeScript, with RequireJS to manage the module dependencies. The problem I've got is that, as well as the inter-dependencies between the TypeScript files, the page also depends on some common JavaScript files that are shared with other parts of the system, not yet converted to AMD. Is it very dangerous to put non-AMD scripts in normal `<SCRIPT>` tags above the tag for Require, and just assume that they're loaded? If that's a bad idea, what's a better way to handle this? Do I need to have AMD and non-AMD version of each script? Or do I need to convert all scripts so that they optionally call `define()`?

Original source