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
WIP: Fallback to the process.cwd to search for modules #12986
base: main
Are you sure you want to change the base?
Conversation
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/44169/ |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 36eb2cf:
|
|
||
try { | ||
return require.resolve(standardizedName, { | ||
paths: [dirname], | ||
paths: dirnames, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately this doesn't work because we compile away this call for compatibility with older Node.js versions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is that the additional parameter not just ignored for older node versions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
require.resolve
is tranpiled to an in-house polyfill:
Lines 260 to 269 in b3e2bcd
((v,w)=>(v=v.split("."),w=w.split("."),+v[0]>+w[0]||v[0]==w[0]&&+v[1]>=+w[1]))(process.versions.node, "8.9") | |
? require.resolve | |
: (/* request */ r, { paths: [/* base */ b] }, M = require("module")) => { | |
let /* filename */ f = M._findPath(r, M._nodeModulePaths(b).concat(b)); | |
if (f) return f; | |
f = new Error(\`Cannot resolve module '\${r}'\`); | |
f.code = "MODULE_NOT_FOUND"; | |
throw f; | |
} | |
`, |
I think we can support general paths
by applying M._nodeModulePaths(#).concat(#)
to every element.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently Babel presets/plugins are resolved against the dirname of the input file. In most cases when Babel and the app libraries are installed within the same root folder, this is equivalent to resolve from process.cwd()
, but that's not the case when the Babel plugins are separated from app codes.
Note that although dirname
defaults to process.cwd()
, it is always the dirname of the input source when we create a plugin/preset descriptor from babel config
export function createUncachedDescriptors( |
which is invoked by root()
, env()
... in
function makeChainWalker<ArgT: { options: ValidatedOptions, dirname: string }>({ |
I guess this is also why CRA and many other dev tools use require.resolve
or require
instead, because Babel by default does not resolve from process.cwd()
.
Note that we can not remove defaults for dirname
here as it is supposed to work with babel.createConfigItem
API.
I think the PR is in a good direction. I would like to hear others opinion.
We also should document how Babel resolve plugins/presets on https://babeljs.io/docs/en/babel-core#configitem-type
|
||
try { | ||
return require.resolve(standardizedName, { | ||
paths: [dirname], | ||
paths: dirnames, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
require.resolve
is tranpiled to an in-house polyfill:
Lines 260 to 269 in b3e2bcd
((v,w)=>(v=v.split("."),w=w.split("."),+v[0]>+w[0]||v[0]==w[0]&&+v[1]>=+w[1]))(process.versions.node, "8.9") | |
? require.resolve | |
: (/* request */ r, { paths: [/* base */ b] }, M = require("module")) => { | |
let /* filename */ f = M._findPath(r, M._nodeModulePaths(b).concat(b)); | |
if (f) return f; | |
f = new Error(\`Cannot resolve module '\${r}'\`); | |
f.code = "MODULE_NOT_FOUND"; | |
throw f; | |
} | |
`, |
I think we can support general paths
by applying M._nodeModulePaths(#).concat(#)
to every element.
Note that there has already been a lot of discussion about supporting custom resolutions, but they have also been rejected since JS configs can already use |
@alexander-schranz I cloned your repository, but I don't understand what problem it tries to show. The error you are seeing is not from https://github.com/alexander-schranz/build-error-reproducer/blob/2142a91af9d8ffafcf3c2a65fb9ed93277d33fc5/assets/admin/babel.config.json#L9. Babel is correctly able to resolve that The error comes from https://github.com/alexander-schranz/build-error-reproducer/blob/2142a91af9d8ffafcf3c2a65fb9ed93277d33fc5/vendor/sulu/sulu/src/Sulu/Bundle/AdminBundle/Resources/js/.babelrc#L4, and that package clearly specifies |
That should not be the case running in all this repository again Maybe babel is the false repository to fix the issue as I node itself has the problem to resolve it correctly. Npm install all dependencies correctly also the dependencies of the linked packages like it should but node can not correctly resolve the path to them as it seems not take the process.cwd into account where the dependency actually was installed. |
Does adding a additional path change this? Possible that to implement this just as dirname where node should look for it. So as fallback? I think I'm missing the impact. Any place where we can hook in that it would only look in process.cwd before throwing the no module found error so its really just a fallback to the process.cwd directory and doesn't have any inpact to the other cases you listed?
Oh I see, I'm really not sure if the problem should maybe be fixed on the node side so I will put this currently on hold maybe I can get there some feedback. Thx you both for the fast response, really appreciate this! |
Tbh I don't think that this will/should be fixed on Node.js's side either. Babel plugins are like normal Since in your case "you" ( However, when using npm's console.log(require("classnames"));
module.exports = {
"presets": ["@babel/preset-env", "@babel/preset-react"],
"plugins": [
["@babel/plugin-proposal-decorators", {"legacy": true}],
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-transform-flow-strip-types",
["@babel/plugin-proposal-class-properties", {"loose": true}]
]
}
|
@nicolo-ribaudo we don't want that the babel plugins which are needed to compile to be added as resolve: {
modules: ['node_modules', nodeModulesPath],
},
resolveLoader: {
modules: ['node_modules', nodeModulesPath],
}, It would be great if the webpack function resolveStandardizedName(
type: "plugin" | "preset",
name: string,
dirname: string = process.cwd(),
resolverDirNames: array = []
) {
const dirnames = [dirname, ...resolverDirNames]; |
@alexander-schranz I now see why we didn't understand each other: Babel packages are a build-time dependency, while all the other dependencies I still think this should be solved not on the Babel or Node.js side but by reorganizing how
|
If you have some uncommen directory structure like: https://github.com/alexander-schranz/build-error-reproducer. Babel can not find the plugins or presets. See issue babel/babel-loader#895. A fallback to the process.cwd does fix it, not sure if this need is the correct place to fix this, also if other places need to keep in mind.