cjs
cjs copied to clipboard
How to make it add `.js` to file paths?
Hello Guy,
I have some CommonJS modules that I'm trying to load in a "legacy" RequireJS project, and it has require statements like this:
// foo.js
require('./bar');
that seems to load bar/
relative to the current file, instead of bar.js
, so it gets a 404 error in my case.
Would it be safe to assume that if we detect this style of require statement that we can just append .js
to it? If so, I would be willing to make a PR.
Or, what other solution could there be? Is there some way to configure requirejs to make it work without modifying this plugin and without modifying the CommonJS sources?
I tried some map and paths configs like the following with no luck:
requirejs.config({
map: {
'*': {
'/path/to/bar': '/path/to/bar.js',
}
},
paths: {
'/path/to/bar': '/path/to/bar',
}
});
I'm not sure if it is possible to configure it.
I was able to get around the problem with this change: https://github.com/guybedford/cjs/pull/5
But I'm not sure what the implications are; it might need more care.
Now I'm having the problem that some of those files import, for example, things like lodash/split
, etc, from node_modules
. It's just a big'ol mess. I'm not sure what I need to further do to make it work with node_modules.
in my case, foo
is an NPM module, and I was able to set a map
for it like
requirejs.config({
map: {
'*': {
'foo': '/path/to/node_modules/foo/index.js',
}
}
});
That part works, and it seems it is able to load ./relative
files, but then messes up when importing other node_modules
.
Maybe I just have to make a map for everything, but I'm not sure how to do that while also adding the cjs!
prefix, which doesn't seem to work (requirejs tries to place cjs!
at the beginning of the import path.
I imagine I could go and make a map for each node module, but I would have to modify each node module source to have the cjs!
prefixes, I think that would work, but I'm trying to do this without modifying any of the dependencies.
I put some console.logs in the plugin, so it looks like this:
define("cjs", ["amd-loader"], function(amdLoader) {
console.log('csj-loader!')
var cjsRequireRegExp = /\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g;
return amdLoader("cjs", "js", function(name, source, req, callback, errback, config) {
source = source.replace(cjsRequireRegExp, function(match, dep) {
if(dep.substr(0, 1) == ".") {
if (dep.search(/\.js$/) == -1) dep = dep + '.js'
console.log(' ----- relative dep!', dep)
return" require('cjs!" + dep + "')"
}else {
console.log(' ----- module dep!', dep)
return" require('" + dep + "')"
}
});
callback("define(function(require, exports, module) { (function(){var define=undefined;" + source + " \n//# sourceURL=" + req.toUrl(name) + "\n})() });")
})
});
So, the relative deps work fine now, but the module deps don't. The output for those looks like this, for example:
----- module dep! react
Maybe I just need to output all of those, and make a map
config for them. Gonna keep trying...
I tried a map
config like
'cheerio': '/path/to/node_modules/foo/node_modules/cheerio/index.js',
but no luck. It also gives an error (among tons of other errors) like
Uncaught Error: Module name "lib/cheerio" has not been loaded yet for context: _. Use require([])
Does map
config work with paths inside the CommonJS modules?
Have you ever loaded node_modules
with requirejs before? If so, what'd you do?
I think I'll just fork the package in question, and add a build step to compile a UMD module. I think that's probably easier.