This last week Andrew Blick filed
an issue on
glamorous
indicating that
the UMD build of glamorous
doesn't work with React 16. The problem is that
glamorous
does a lazy-require for the
prop-types
module and apparently
when building the UMD bundle,
rollup can't handle the CommonJS require
and make the UMD pass it in from the global
object.
You can see this problem
in the
glamorous@4.9.5
UMD file. The fact
that PropTypes
isn't included at the top with global.Glamor
and
global.React
is an indication of the issue. If you look further down, you'll
also see: PropTypes = require('prop-types')
and it's that require
statement
which is the problem. It's not transpiled due to the aforementioned issue.
This is the part where we get frustrated at our tools and their authors right?
Definitely not! What we do is we file an issue with a reproduction and suggest a solution! Then we implement the solution when the maintainer says they're good with the solution! Woo!
In my case, I had no idea where to start and I don't have time to look into it any further (I did, just have my fourth kid less than two weeks ago afterall). So I filed the issue with the reproduction in part to verify that the issue was Rollup. Then I started thinking about a good workaround.
Here's where codegen comes in.
babel-plugin-codegen
is
a babel plugin I wrote inspired by my other plugin
babel-plugin-preval
. Both
of these ship with a babel-macro
and they each have a companion package to make using that easier.
So I installed codegen.macro
and changed from a simple PropTypes = require('prop-types')
to this:
PropTypes = codegen`
if (process.env.BUILD_FORMAT === 'umd') {
module.exports = "(typeof window !== 'undefined' ? window : global).PropTypes"
} else {
module.exports = "require('prop-types')"
}
`
What codegen
does is it will take the string of code you provide and run it
like a regular module, then it takes the string of code that you export and will
replace itself with that string of code. Because this happens at build-time,
it's a great way to do these kinds of optimizations.
Note, generally it's advisable to avoid putting too much code in a string because you lose a lot of benefits like syntax highlighting and lintability, so if it's a fair amount of code in there, you can pull it out into another file and do:
PropTypes = codegen`module.exports = require('./prop-types-workaround')`
Anyway, these changes we've made will leave all the other builds as it was before, but for the UMD build, it'll pull PropTypes from the global.
What I love about this kind of workaround is that because it's using a
babel-macro
the magic involved is pretty optimized and localized. So it's much
more straightforward than other workarounds would be and literally took less
than 10 minutes.
I hope this is helpful to you! Good luck to you all! 👍