-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inconsistent multiple extension handling between Module._findPath and Module.load #4778
Comments
What version of Node are you using? The following script (and the variations of it that I tried) work for me on v5.4.1. 'use strict';
const assert = require('assert');
const fs = require('fs');
const file = './test.foo.bar';
fs.writeFileSync(file, 'NOT_JS', 'utf8');
require.extensions['.foo.bar'] = (module, path) => {
console.log('required .foo.bar', path);
};
assert.throws(() => {
require(file);
});
require.extensions['.bar'] = (module, path) => {
console.log('required .bar', path);
};
delete require.extensions['.foo.bar']
assert.doesNotThrow(() => {
require(file);
}); |
Sorry, to be clear, the |
Ok, here is the reproduction: 'use strict';
const fs = require('fs');
fs.writeFileSync('./test.foo.bar', 'NOT_JS', 'utf8');
require.extensions['.foo.bar'] = (module, path) => {};
// delete require.extensions['.foo.bar'];
require.extensions['.bar'] = (module, path) => {
console.log(`loaded ${path}`);
};
require('./test'); Toggle the commented out line to see the issue. This seems, to me, like something that should be fixed, but module system. What do others think? |
This commit adds tests for several known issues. Refs: nodejs#1901 Refs: nodejs#728 Refs: nodejs#4778 Refs: nodejs#947 Refs: nodejs#2734 PR-URL: nodejs#5653 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
@sgentle Fortunately, this is no longer true. And while we are unlikely to add new features or change the intended behavior of existing features, fixing bugs in |
Files with multiple extensions are not handled by require-module system therefore if you have file 'file.foo.bar' and require('./file') it won't be found even while using require.extensions['foo.bar'] but before this commit if you have require.extensions['foo.bar'] and require.extensions['bar'] set then the latter will be called if you do require('./file') but if you remove the former the former ('foo.bar') property it will fail. This commit makes it always fail in such cases. Fixes: nodejs#4778
Let's start by making a file with multiple extensions:
test.foo.bar
So we already know that
require.extensions
doesn't work with multiple extensions:And that it will use the last component of the extension instead:
Which is all perfectly obvious and by design. But did you know that the path searching uses the whole extension? Which means:
However:
In summary: to hook the requiring of a file with multiple extensions without specifying it, you must:
require.extensions
for the last component of the extension to your hook functionrequire.extensions
for the entire extension to any value.This is due to differences in how
Module._findPath
andModule.load
deal with extensions: the former adds each extension inrequire.extensions
to the basename and tests it for existence (viatryExtensions
). The latter works the other way around; it removes everything up to the last part of the extension (viapath.extname
) and then checks if it is present inrequire.extensions
.I know it's policy not to fix bugs in
module
that might help compile-to-js languages, but I figure someone else might come across the same problem and this report could be useful to them.The text was updated successfully, but these errors were encountered: