requirejsalmond

Absolute path for almond when using require.js optimize


I'm trying to get my code to optimize to a single file using what is apparently a non-standard setup and I'm struggling to understand what all the different paths mean.

Imagine I'm making a variant of r the requirejs command-line tool that includes almond. So I want to be able to wrap with almond using the almond included with my tool.

My directory structure

someAppFolder
|
+--main.js

In an related folder

myRPlusAlmondBuilder
|
+--myRPlusAlmonBuilder.js
|
+--node_modules
   |
   +--almond
   |  |
   |  +--almond.js
   |
   +--requirejs
      |
      ...

So, I want myRPlusAlmondBuilder to be able to build a single JS bundle from main.js like this

cd myRPlusAlmondBuilder
node myRPlusAlmondBuilder.js someAppFolder/main.js

Here's a simple myRPlusAlmondBuilder.js

var requirejs = require('requirejs');
var path = require('path');

var filename = process.argv[2];                
var dirname = path.dirname(filename);          
var barename = path.basename(filename, ".js"); 

var config = {
  baseUrl: dirname,
  name: "node_modules/almond/almond",
  include: barename,
  insertRequire: [barename],
  out:     "out.js",
  wrap:    true,
};

// show the values 
console.log(JSON.stringify(config, undefined, "  "));

requirejs.optimize(config, function() {
  console.log("result is in:", config.out);
}, function(err) {
  console.error(err);
});

calling it like this

cd myRPlusAlmondBuilder.js
node myRPlusAlmondBuilder.js /Users/gregg/temp/delme-requirejs/someAppFolder/main.js

but I get

{
  "baseUrl": "/Users/gregg/temp/delme-requirejs/someAppFolder",
  "name": "node_modules/almond/almond",
  "include": "main",
  "insertRequire": [
    "main"
  ],
  "out": "out.js",
  "wrap": true
}
{ [Error: Error: ERROR: module path does not exist: /Users/gregg/temp/delme-requirejs/someAppFolder/node_modules/almond/almond.js for module named: node_modules/almond/almond. Path is relative to: /Users/gregg/temp/delme-requirejs/myRPlusAlmondBuilder

Trying these other values for name all fail

// dot in front 
name: "./node_modules/almond/almond",

// .js on end
name: "node_modules/almond/almond.js",

// .dot in front and .js on end
name: "./node_modules/almond/almond.js",

// absolute path to almond.js with .js
name: path.join(__dirname, "node_modules/almond/almond.js"),

// absolute path to almond.js without .js
name: path.join(__dirname, "node_modules/almond/almond"),

The ones with ".js" get

[Error: Error: ENOENT, no such file or directory '/Users/gregg/temp/delme-requirejs/someAppFolder/node_modules/almond/almond.js'
at Error (native)
]

The ones with the full path get

[Error: Error: ENOENT, no such file or directory '/Users/gregg/temp/delme-requirejs/someAppFolder//Users/gregg/temp/delme-requirejs/myRPlusAlmondBuilder/node_modules/almond/almond.js'
at Error (native)
]

Using a relative path from main.js to almond works

name: path.relative(dirname, path.join(__dirname, "node_modules/almond/almond.js")),

But that won't work in windows if the tool in in C:/somefolder/myRPlusAlmond and the file in in D:/someAppFolder/main.js

Is there any way to use absolute paths for almond?


Solution

  • I found one way which is to add a path for almond

    var config = {
      baseUrl: dirname,
      name: "__dontclash_almond__/almond",
      include: barename,
      insertRequire: [barename],
      out:     "out.js",
      wrap:    true,
      paths: {
        __dontclash_almond__: path.join(__dirname, "node_modules/almond"),
      }.
    };
    

    Seems kind of hacky because I have to hope I don't clash with a user chosen name. Of course it's unlikely to clash