How to handle npm modules which include es6
eoinmurray opened this issue Β· 22 comments
This is my babel-loader import in my webpack.config.js
file
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react', 'es2015']
}
}
],
I try to run this to make minified code with webpack -p --config webpack.config.js
It works fine unless I have the module qs.js included, which uses the keyword let
throughout.
The authors of qs.js
recommend transpiling qs using babel ljharb/qs#141.
I achieved this in the compilation step by removing exclude: /node_modules/
but I think thats messy as it babelify's every module included in my application.
Is there a more elegant way to do this, without needed to manage my own version of qs.js
Any word on this?
@eoinmurray you can exclude all node modules except qs using the following:
exclude: /node_modules\/(?!qs)/
This will let babel transpile qs without touching every other node module.
If you need to exclude more than one module you can extend the exception list like so:
exclude: /node_modules\/(?![module1|module2])/
Hope that helps :)
This is great thanks, totally solves the issue!
Above second regex didn't work me. Regex for including multiple modules, that worked for me, is:
exclude: /node_modules\/(?!(module1|module2)\/).*/
thanks @jonnymbgood for the right pointers though!
/node_modules\/(?!(async\-es|lodash\-es)\/).*/
doesn't work for me.
/node_modules\/(?![async\-es|lodash\-es])/
works well.
It looks like perhaps this has since been fixed in qs
(see ljharb/qs#141 (comment)).
But for future reference, I've created a webpack helper to automatically detect dependencies such as this one that may require Babel transpilation. See https://github.com/andersdjohnson/webpack-babel-env-deps. It should work if a module specifies engines
correctly in its package.json
, or module
which is a transpile-eligible entry a package can specify.
I've struggled with this also and this solutions, adding the exclude negative lookahead didn't solved my problem, but 50% of it. I had to add to the include as well.. For ex.
exclude: /node_modules\/(?!(event-class-es6))/,
include: path.join(__dirname, 'node_modules', 'event-class-es6'),
we should use exclude
and include
to make this work
not sure if this is a feature or a bug
It's odd that the two posters above only got it working when they added both the exclude
and include
entries. For me it works with just the include
line. (though, in my case I had to add a fs.realpathSync
call, since I had my node-module symlinked)
{
test: /\.(jsx?|tsx?)$/,
// we have babel ignore most node_modules, but we tell it to transpile the scripts within MY_MODULE
include: [
path.resolve(rootPath, "src"),
fs.realpathSync(path.resolve(rootPath, "node_modules", "MY_MODULE"))
],
loader: "babel-loader",
options: [...]
},
same problem but different use case. i am using lerna to create packages for different modules. so my packages have this kind of pattern node_modules/@packages/ui-components
i tried to both include and exclude but it doesn't work.
I built a package called are-you-es5 that checks which of your dependencies aren't ES5 and builds the exclude
regex you need for your specific set of packages, based on @jonnymbgood's solution. I could really use some testers/contributors for the package to run it in different projects and make sure it behaves well in all cases.
For your information, there's a plugin that may help simplifying things: next-plugin-transpile-modules
You could use an array for the dependencies, it's a little nicer to edit this way. And you don't have to escape module names.
const transpileDependencies = [
'module1',
'module2'
]
loaders: [
{
exclude: new RegExp(`node_modules/(?!(${transpileDependencies.join('|')})/).*`)
}
]
I know I've compiled node_modules in the past using something like the above methods that use exclude. They weren't working for me this time, as of babel 7 which seems to ignore node_modules automatically
This worked:
import { resolve } from 'path';
// ...
{
test: /\.(js|jsx|ts|tsx)$/,
include: [
resolve('src'),
// These dependencies have es6 syntax which ie11 doesn't like.
resolve('node_modules/@rehooks/component-size'),
resolve('node_modules/react-spring'),
],
use: ['babel-loader'],
},
If anyone's still confused by changes in Babel 7 (I was), you have to switch to using babel.config.js
in order to affect modules in node_modules
:
https://babeljs.io/docs/en/configuration#babelconfigjs
@eoinmurray you can exclude all node modules except qs using the following:
exclude: /node_modules\/(?!qs)/
This will let babel transpile qs without touching every other node module.
If you need to exclude more than one module you can extend the exception list like so:
exclude: /node_modules\/(?![module1|module2])/
Hope that helps :)
worksοΌοΌοΌοΌοΌοΌοΌοΌοΌοΌ
If you're experiencing this issue with Next.js, use next-transpile-modules
! My setup was a Dockerized Next.js app and a local npm module that wasn't being transpilled.
What if the package that should be transpiled contains its own node_modules package that should be transpiled as well? How it can be handled?
Thanks
Project (Babel/Webpack/Typescript)
- node_modules
- dependencyA (ES6)
- node_modules
- nested_dependency (ES6)
- node_modules
- dependencyA (ES6)
worth mentioning is that (for me at least) the build time was much quicker, especially in watch mode with webpack when using only include and not even bothering with exclude. node_modules seems to be ignored by default, and simply explicitly including what you need to be transpiled instead appears to be faster:
const path = require('path');
include: [
path.resolve(__dirname + '/assets/src/js'), // your default js source
...['module-to-be-transpiled', 'another-module-to-be-transpiled'].map((moduleName) => (
path.resolve(__dirname + '/node_modules/' + moduleName)
))
]
node_modules\/(?!(module1|module2))
works
[]
matches a single character in the row, but wrapping modules in ()
matches a sequence.
So my code is like this:
const modulesToTranspile = ['module1', 'module2', '@corp/long-module-name'];
// webpack config
include: modulesToTranspile.map(moduleName =>
path.resolve(__dirname, `../../../../node_modules/${moduleName}`)
),
exclude: [new RegExp(`node_modules\/(?!(${modulesToTranspile.join('|')}))`)]
The docs state it very clear: https://webpack.js.org/configuration/module/#condition