Using non-transpiled modules and Webpack
TL;DR: use> include: function(absPath){ return (/[regex for the module(s) you want to include]/.test(absPath) || /src/.test(absPath)); }, instead of> exclude: /node_modules/,
I’m currently working on a project that required some client side validation for credit cards and found this amazing module with pretty much everything I needed in npm:
My project setup includes React, Redux and, of course, Webpack. So I npm-installed that bad boy and everything went as expected; it also worked like a charm with redux-form validators. But, as you know, there’s no such a thing as “smooth sailing” in web development: if something can go wrong it will. And it went.
The problem with non-transpiled modules
It turns out that the credit-card module is not distributed as a transpiled module so, when you install it you get the code in ES6. This wasn’t a problem for development but when the moment came for me to test the deployment/build scripts tragedy struck: the process simply failed and Webpack was showing one of those cryptic error messages we all know and love. I couldn’t believe it.
Damn it! I started checking for the usual stuff: node versions, outdated packages, cache… Nothing helped.
And then, it struck me like a lightning and I navigated to the credit-card directory just to confirm it: the code wasn’t distributed in ES5. That was the issue.
According to this GH issue, the module maintainer didn’t want to transpile the code because:
1. It’s just a pain to manage.
2. It’s weird to test because you’re testing es2015 code that works fine on Node, but people are using transpiled babel code on the client that isn’t tested at all.
3. You become dependent on the babel ecosystem which has had some serious bumps during the 5.x.x to 6.x.x transition.
4. By not using the actual source, you lose a lot of optimization flexibility from within webpack/browserify
To be fair those are valid reasons and even if you consider that they’re not you’ll have to deal with it, you either figure out how to fix it yourself or you use another package. I wanted to fix it but I’m not what you’d call a Webpack expert.
The more you know
Just to make it clear I didn’t stumble across the aforementioned issue until some time later so I spent some time stumbling across StackOverflow and Webpack’s docs
I knew I had to somehow transpile the module by myself, but I also knew I was excluding the node_modules folder so I started playing around with different combinations of exclude and include.
Then, I discovered that exclude takes precedence over include so, if you have both only the exclude will work. When I discovered this I was frustrated and, happily, stumbled across the issue so I decided to post a question and grab lunch.
Adam was kind enough to answer my question and I discovered something new: include can take a function that receives the absolute path of each file Webpack is processing and returns true or false depending on whether you want to include it or not. Then Webpack will run every file path though this function and operate over the file only if the result of executing it is true.
After that, configuring my build took like 2 minutes, I just added a couple of regular expressions to match the specific module (credit-card) and the src folder in my project:
include: function(absPath){ return (/credit-card/.test(absPath) || /src/.test(absPath)); },
instead of the original:
exclude: /node_modules/,
Also, Webpack’s documentation encourages the use of include over exclude so it was a double-kill.
Webpack is an amazing tool but it has a rather high entry barrier: the docs. I’d like to see a lot more articles about specific stuff like this that don’t always happens but can really make you lose your shit.
Have you ever stumbled across something like this?
Disclaimer: I’m not a native English speaker, so feel free to point out grammatical and/or syntactical errors. Every respectful comment is deeply appreciated.