So in my current setup. I'm running webpack/babel via gulp from the root directory on the machine, which means that all the modules are in ~/node_modules. The webpack config and the files that it needs to transcompile and such are sitting on a mounted drive. The error I'm seeing is:
Error: Couldn't find preset "es2015" relative to directory <insert directory in mounted drive here>
And here's my conf file.
var path = require('path');
module.exports = {
聽 entry: __dirname+'/main.js',
聽 output: {
path: __dirname,
filename: 'bundle.js'
},
resolve: {
root: [
path.resolve('~/'),
path.resolve('./')
],
modulesDirectories: [
'node_modules'
],
},
聽 module: {
聽 聽聽loaders: [
{ test: /\.less$/,
loader: 'style-loader!css-loader!less-loader'
},
{
test: /\.css$/,
loader: 'style!css'
},
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
聽 },
};
So the reason I'm seeing this issue obviously has something to do with the fact that babel is looking for the modules in the wrong directory, however for the life of me I can't seem to get it to respect the values inside resolve.root. I'm probably missing something very obvious, so I'd appreciate a bit of help.
Okay, so after digging through all of the source-code, I discovered that this is actually a fundamental issue with the way babel loads its presets. Specifically on line 319 of option-manager.js, it does a require.resolve on the directory of the file coming in from entry, which means regardless of where the working directory is or what parameters you set up in webpack, it will always try to resolve on the dirname variable which is generated from the current working file.
In other words without overwriting that method, it is impossible to run babel in a directory tree that does not include the node_modules folder.
My solution to this is a fairly hamfisted one of: "Use gulp to copy the code which needs to be babblefied to a temp directory in whatever working directory I'm in. Compile it. Then move it back. Huzzah for I/O costs!"
Most common issue with babel-loader but sadly any of the PRs that try to fix this have been shut down. This is how you work around it.
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: [
require.resolve('babel-preset-es2015')
]
}
}
The above works just as well but I used the following syntax instead:
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true,
presets: ['babel-preset-env'].map(require.resolve), <<< This line
},
},
],
},
I'm triaging old issues on babel-loader. Since this has been inactive for ages, I'm going to close it. Feel free to re-open if there's still something to discuss, but I'm assuming at this point it's been too long to address in a useful way.
Babel 6 weirdly resolved presets relative to the file being compiled which generally causes issues when using symlinked files. While this should be mostly resolved in Babel 7, I'll also mention that we now have a cwd option for those absolutely sure that they want to adjust Babel's concept of the working directory.
@loganfsmyth I'm in Babel 7.11 and babel-loader 8.2 and this problem still persists. Maybe it should still be open.
@briandipalma's tip in https://github.com/babel/babel-loader/issues/299#issuecomment-259713477 does indeed work around the problem.
I'll also mention that we now have a cwd option for those absolutely sure that they want to adjust Babel's concept of the working directory.
I would like to also note, I don't want to change babel-loader's cwd, I just want it to resolve plugins and presets in a custom location, or better yet, for it to automatically understand config file's location and to also resolve in that location.
The custom location my plugins and presets is in a node_modules folder of a dependency (a cli tool) inside my project's node_modules.
Basically, I am running Webpack (v4.44) with babel-loader in my project, and the plugins and presets are in my-project/node_modules/the-cli-tool/node_modules/@babel
If I run babel in my project, it works fine with a configuration like the following, where the configuration is located inside of my-project/node_modules/the-cli-tool:
module.exports = {
plugins: [
['@babel/plugin-proposal-optional-chaining', {}],
['@babel/plugin-proposal-nullish-coalescing-operator', {}],
],
presets: [
['@babel/preset-typescript', {isTSX: true, allExtensions: true, onlyRemoveTypeImports: true}],
['babel-preset-solid', {moduleName: '@lume/element'}],
],
}
But if I run Babel via Webpack+babel-loader, then the plugins and presets can not be found, unless I convert the babel config (which is inside of my-project/node_modules/the-cli-tool) to this:
module.exports = {
plugins: [
['@babel/plugin-proposal-optional-chaining', {}],
['@babel/plugin-proposal-nullish-coalescing-operator', {}],
].map(p => [require.resolve(p[0]), p[1]]), // <<< HERE
presets: [
['@babel/preset-typescript', {isTSX: true, allExtensions: true, onlyRemoveTypeImports: true}],
['babel-preset-solid', {moduleName: '@lume/element'}],
].map(p => [require.resolve(p[0]), p[1]]), // <<< HERE
}
Without doing this, Webpack fails with errors like the following. Note that the-cli-tool references in the stack trace do not appear inside of my-project, which is due to the fact that the-cli-tool is npm linked into my-project, which may further complicate where modules are located on disk.
sample of Webpack errors
ERROR in ./dist/attribute.test.js
Module build failed (from ../cli/node_modules/babel-loader/lib/index.js):
Error: Cannot find module '@babel/plugin-proposal-optional-chaining' from '/home/trusktr/src/my-project'
at Function.resolveSync [as sync] (/home/trusktr/src/the-cli-tool/node_modules/resolve/lib/sync.js:90:15)
at resolveStandardizedName (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/files/plugins.js:101:31)
at resolvePlugin (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/files/plugins.js:54:10)
at loadPlugin (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/files/plugins.js:62:20)
at createDescriptor (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-descriptors.js:154:9)
at /home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-descriptors.js:109:50
at Array.map (<anonymous>)
at createDescriptors (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-descriptors.js:109:29)
at createPluginDescriptors (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-descriptors.js:105:10)
at /home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-descriptors.js:63:53
at cachedFunction (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/caching.js:62:27)
at cachedFunction.next (<anonymous>)
at evaluateSync (/home/trusktr/src/the-cli-tool/node_modules/gensync/index.js:251:28)
at sync (/home/trusktr/src/the-cli-tool/node_modules/gensync/index.js:89:14)
at plugins (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-descriptors.js:28:77)
at mergeChainOpts (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-chain.js:383:26)
ERROR in ./dist/LumeElement.test.js
Module build failed (from ../cli/node_modules/babel-loader/lib/index.js):
Error: Cannot find module '@babel/plugin-proposal-optional-chaining' from '/home/trusktr/src/my-project'
at Function.resolveSync [as sync] (/home/trusktr/src/the-cli-tool/node_modules/resolve/lib/sync.js:90:15)
at resolveStandardizedName (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/files/plugins.js:101:31)
at resolvePlugin (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/files/plugins.js:54:10)
at loadPlugin (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/files/plugins.js:62:20)
at createDescriptor (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-descriptors.js:154:9)
at /home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-descriptors.js:109:50
at Array.map (<anonymous>)
at createDescriptors (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-descriptors.js:109:29)
at createPluginDescriptors (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-descriptors.js:105:10)
at /home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-descriptors.js:63:53
at cachedFunction (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/caching.js:62:27)
at cachedFunction.next (<anonymous>)
at evaluateSync (/home/trusktr/src/the-cli-tool/node_modules/gensync/index.js:251:28)
at sync (/home/trusktr/src/the-cli-tool/node_modules/gensync/index.js:89:14)
at plugins (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-descriptors.js:28:77)
at mergeChainOpts (/home/trusktr/src/the-cli-tool/node_modules/@babel/core/lib/config/config-chain.js:383:26)
Most helpful comment
Most common issue with babel-loader but sadly any of the PRs that try to fix this have been shut down. This is how you work around it.