Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Helper to create .flowconfig module name mapper
#!/usr/bin/env node
/**
* Flowtype understands Node (or Haste) imports but not Webpack.
*
* Many codebases have webpack set up like:
* src/foo.js
* src/components/Bar.jsx
*
* And then import them like `require('foo')` or `require/components/Bar.jsx`
*
* Flow doesn't understand this by default. A solution that used to work was to convince
* it that `src` was a source of Node modules (https://github.com/facebook/flow/issues/382)
*
* In Flow 0.57 they introduced an optimization to "only check the files in
node_modules/ which are direct or transitive dependencies of the non-
node_modules code." (https://github.com/facebook/flow/blob/master/Changelog.md#0570)
* Because the trick above made Flow think your app modules were another source of node_modules,
* now the app source would not be focused either. You could see this in Flow logs by
* almost all app files being omitted from the "focused" count.
*
* A working alternative is to explicitly define `module.name_mapper` directives for each
* child of your root directory, to tell Flow how to resolve those files. (Thanks to
* https://github.com/cdebotton/react-universal/commit/e57aadbcbd8be4e2031f308187392f44d02b44f9#commitcomment-19062820
* for the idea.)
*
* This script generates the directives you need in [options] of your `.flowconfig`.
*
* Set ROOT_APP_DIR if yours is not src/.
*/
const fs = require('fs');
const path = require('path');
const ROOT_APP_DIR = 'app/j';
const files = fs.readdirSync(ROOT_APP_DIR);
const jsList = [];
const dirList = [];
for (const filename of files) {
if (filename.startsWith('.')) continue;
const isDirectory = fs.statSync(path.join(ROOT_APP_DIR, filename)).isDirectory();
if (isDirectory) {
dirList.push(filename);
} else {
const moduleName = path.basename(filename, '.js');
jsList.push(moduleName);
}
}
console.log(`# Generated by https://gist.github.com/turadg/4c11ef9ac1af7b41276d0acc4d4bf8c8 with root ${ROOT_APP_DIR}`);
const dirMatcher = dirList.join('\\|');
console.log(
`module.name_mapper='^\\(${dirMatcher}\\)\\/\\(.*\\)$' -> '<PROJECT_ROOT>/${ROOT_APP_DIR}/\\1/\\2'`
);
console.log(
`module.name_mapper='^\\(${dirMatcher}\\)$' -> '<PROJECT_ROOT>/${ROOT_APP_DIR}/\\1/index'`
);
const jsMatcher = jsList.join('\\|');
console.log(`module.name_mapper='^\\(${jsMatcher}\\)$' -> '<PROJECT_ROOT>/${ROOT_APP_DIR}/\\1'`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.