I recently updated am still trying to update wcag-contrast
from a very plain-vanilla ES5 module to an ES6 module using Flow. This is partially to test the theory that modern modules will be a better target for documentation: so wcag-contrast can be a target.
The module in question: https://github.com/tmcw/wcag-contrast
Previously the setup was
- No build step
- Tests with mocha and expect.js
My goals are:
- A module that has ES6 export statements, so tools like Rollup can properly import portions of it
- Flow types included with that module, so dependent modules can typecheck properly.
Seems like the module
field just doesn't get much use: babel, for instance, only uses the main
field for all of its sub-packages. Maybe it's just too much to ask? Just seems weird to only use import&export internally and never use the fields for cross-module imports.
Afterwards the target is:
- index.js contains ES6+Flow code
- index-es5.js - contains ES5 code, exposed via main field in package.json
- index-es6.js - contains ES6 code, exposed by module field in package.json (see module field docs)
I could also try to go a step farther and bundle dependencies. That'd require using Rollup, Webpack, or Browserify. I'll go one step at a time, because this is already kind of tricky:
So, first off, I'll need
{
"env": {
"main": {
"presets": ["flow"],
"plugins": [
"transform-es2015-modules-commonjs"
]
},
"module": {
"plugins": [
"transform-flow-strip-types"
]
}
}
}
Which, well, is equivalent to this, because the Flow preset just includes one transformer.
{
"env": {
"main": {
"plugins": [
"transform-flow-strip-types",
"transform-es2015-modules-commonjs"
]
},
"module": {
"plugins": [
"transform-flow-strip-types"
]
}
}
}
I'm going to use jest
for tests. It's what I use in documentation.js and has lots of momentum.
Unfortunately, jest tests kind of break with this, and the explanation is painful at best:
If you are using a more complicated Babel configuration, using Babel's
env
option, keep in mind that Jest will automatically defineNODE_ENV
astest
. It will not usedevelopment
section like Babel does by default when noNODE_ENV
is set.
Hmm, so, ah - okay
The env key will be taken from process.env.BABEL_ENV, when this is not available then it uses process.env.NODE_ENV if even that is not available then it defaults to "development". https://babeljs.io/docs/usage/babelrc/#env-option
So BABEL_ENV defaults to NODE_ENV, and jest sets NODE_ENV to test. So, I'll add a test
environment. Which will be the same as main
. Kind of annoying, but not a dealbreaker.
{
"env": {
"test": {
"plugins": [
"transform-es2015-modules-commonjs",
"transform-flow-strip-types"
]
},
"main": {
"plugins": [
"transform-flow-strip-types",
"transform-es2015-modules-commonjs"
]
},
"module": {
"plugins": [
"transform-flow-strip-types"
]
}
}
}
Okay, so then tests run. Now, to build those entry points:
"build": "npm run build-main && npm run build-module && npm run build-types",
"build-main": "BABEL_ENV=main babel index.js > index-es5.js",
"build-module": "BABEL_ENV=module babel index.js > index-es6.js",
And, Flow
"build-types": "cp index.js index-es5.js.flow && cp index.js index-es6.js.flow",
It looks like Flow reads index-es5.js.flow
only, not -es6.js.flow
. I can't find any info on how Flow resolves entries in its configuration, maybe google-fu is just failing.
Current dev deps:
"babel-cli": "^6.24.1",
"babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
"babel-plugin-transform-flow-strip-types": "^6.22.0",
"flow-bin": "^0.51.1",
"jest": "^20.0.4"