Search code examples
jsonreactjswebpackbuildpostcss

Imported generated JSON in JSX causes Webpack build loop


I've got a small postcss plugin I've made that generates a JSON file off a colors.css variable file during webpack build.

My postcss plugin

const fs = require('fs');
const postcss = require('postcss');

const capitalize = (string) => string.charAt(0).toUpperCase() + string.slice(1);

const getPropName = (string) => {
  let name = clean(string.split('-'));
  name.shift();
  for(let k = 1; k < name.length; k++){ //start at 1 to skip 'color' prefix
    name[k] = capitalize(name[k].toString());
  }
  return name.join('');
};

const clean = (array) => {
  let i = array.length;
  while(i--){
    if (!array[i]) {         
      array.splice(i, 1);
      i++;
    }
  }
  return array;
};

module.exports = postcss.plugin('cssobject', (files, filters, options) =>
  (css) => {
    options = options || {
      destination: ''
    };
    // Processing code will be added here

    const getVariable = (variable) => {
      let result;
      css.walkRules((rules) => {
        rules.walkDecls((decl) => {
          const pointer = variable.replace('var(', '').replace(')','');
          if(!decl.prop.match(pointer)) return;
          result = decl.value;
        });
      });
      return result;
    };

    css.walkRules((rules) => { //hooks into CSS stream
      let i = files.length;
      let cssObject = {};
      while (i--) {
        if(!rules.source.input.from.match(files[i])) return; //scrubs against requested files

        rules.walkDecls((decl) => {
          let j = filters.length;
          while(j--){
            if(!decl.prop.match(filters[j])) return; //scrubs against requested rules
            let prop = getPropName(decl.prop);
            cssObject[prop] = (decl.value.match('var'))? getVariable(decl.value) : decl.value;
          }
        });
      }
      if (options.destination) {
        fs.writeFile(options.destination, JSON.stringify(cssObject), 'utf8');
      }
    });
  }
);

I'm then importing this JSON file into a react component JSX file to then parse JSON data into a visual guide of project's used colors under AA and AAA requirements... anywho

The problem I'm having is my webpack-dev-server keeps re-building over and over again cause it thinks a change has been made to the JSX file, when in fact it's only ever a change to the JSON file being imported.

Is there a standard way of importing generated files in to a JSX without causing infinite build loops?

I've already tried having the JSON file be saved well outside of the webpack dev's watch location, and still build loop remains.

Thanks in advance!


Solution

  • you can change you file's timestamp, the webpack will not build after you change your file

    const now = Date.now() / 1000;
    const lastModifyTime = now - 11;
    const lastAccessTime = now - 11;
    fs.utimesSync(jsonPath, lastModifyTime, lastAccessTime);
    

    Have a try, hope to help you.