yusinto/relay-compiler-plus

Possible to use in --watch mode

Closed this issue · 2 comments

Does this accept the --watch flag, like relay-compiler?

Not at this time! But it should be easy to add. I’ll take a look. Thanks for the feedback!

I looked into it, and it turned out to be somewhat complicated by the fact that relay compiler has an internal graphql-compiler library, which has watchman specific parsers. So, i created my own. Here's the gist of it. It uses chokidar instead of watchman and I have it as part of my launcher.js script:

const graphqlRegex = /graphql`[\s\S]*?`/g;
const rcpGraphql = {};

function startRcp() {
  const rcpWatcher = chokidar.watch([
    'src/components/**/*.js',
    'src/routing/**/*.js',
    'src/mutations/**/*.js',
    'internal/config/graphql/schema-development.graphql'
  ],
  { ignored: '**/__generated__/**' });

  // get graphql strings of each file and diff them.

  const didGraphqlChange = (oldGqls, newGqls) => {

    // if graphql was added or removed, automatically changed
    if (oldGqls.length !== newGqls.length) {
      return true;
    }

    // otherwise go through each gql and compare with string equality
    for (let i = 0; i < oldGqls.length; i++) {
      const gql = oldGqls[i];

      if (gql !== newGqls[i]) {
        // early break out of this loop
        return true;
      }
    }

    return false;
  };

  rcpWatcher.on('add', (path, stats) => {
    const file = fs.readFileSync(path, 'utf8');
    const matches = file.match(graphqlRegex);

    // cache all matched graphql everything for the first time.
    if (matches) {
      console.log(`caching ${path} graphql`);
      rcpGraphql[path] = matches;
    }
  });

  rcpWatcher.on('change', (path, stats) => {
    // shouldRestart = true;

    const file = fs.readFileSync(path, 'utf8');
    const matches = file.match(graphqlRegex);

    // do we have any graphql in this file?
    if (matches.length) {
      const cachedMatches = rcpGraphql[path];

      // did we already have some graphql?
      if (cachedMatches) {
        // if we already had some graphql, and it changed, run rcp, otherwise do nothing
        if (didGraphqlChange(cachedMatches, matches)) {
          console.log(`Graphql for ${path} changed, running rcp`);
          // reset cache
          rcpGraphql[path] = matches;

          // and run
          runRcp();
        } else {
          console.log(`Graphql for ${path} unchanged, not running rcp`);
        }
      } else {
        // we have matches but they're not cached
        console.log(`relay file ${path} changed, recompiling`);

        // so cache them.
        rcpGraphql[path] = matches;

        // and recompile
        runRcp();
      }
    }
  });

  // run rcp once to get things started.
  runRcp();
}