Skip to content

Instantly share code, notes, and snippets.

@Josh68
Created July 25, 2018 05:50
Show Gist options
  • Save Josh68/107172aa24dc23c862fdf34a6970cc15 to your computer and use it in GitHub Desktop.
Save Josh68/107172aa24dc23c862fdf34a6970cc15 to your computer and use it in GitHub Desktop.
Determine whether to run patternlab build based on changed files in a compilation
import patternEngines from 'patternlab-node/core/lib/pattern_engines';
import plConfig from '../../../patternlab-config.json';
const pluginName = 'CompilationFilesChangedPlugin';
class CompilationFilesChangedPlugin {
constructor({ patternlab }) {
this.startTime = Date.now();
this.prevTimestamps = new Map();
this.pluginIterator = 0;
this.supportedTemplateExtensions = patternEngines.getSupportedFileExtensions();
// the following method does not exist - how to get this list from PL?
this.supportedDataExtensions = plConfig.supportedDataExtensions || [];
this.cleanPublic = plConfig.cleanPublic || false;
process.argv.forEach((val, index) => {
if (val.includes('cleanPublic')) {
val = val.split('=');
this.cleanPublic = JSON.parse(val[1]);
}
});
this.plCore = patternlab;
this.checkBuildNecessary = this.checkBuildNecessary.bind(this);
}
apply(compiler) {
if (compiler.hooks) {
compiler.hooks.afterEmit.tapAsync(pluginName, this.checkBuildNecessary);
} else {
compiler.plugin('after-emit', this.checkBuildNecessary);
}
}
checkBuildNecessary(compilation, callback = () => {}) {
let buildPatterns = false;
let changedPatternFilesArr = [];
const hasPrevTimestamps = this.prevTimestamps.size > 0;
// remove leading dot from each filetype extension before creating regex,
// then concat the data (or content) types from a hard-coded string array
const patternFileTypes = this.supportedTemplateExtensions
.map(ext => ext.slice(1))
.concat(this.supportedDataExtensions)
.join('|');
const patternFiletypeTextRegex = new RegExp(`.*\\.(${patternFileTypes})$`);
const changedFileKeys = [...compilation.fileTimestamps.keys()];
const changedFiles = changedFileKeys.filter(
function(watchfile) {
if (typeof this === 'undefined' || !hasPrevTimestamps) {
return false;
}
return (
(this.prevTimestamps.get(watchfile) || this.startTime) <
(compilation.fileTimestamps.get(watchfile) || Infinity)
);
}.bind(this)
);
changedPatternFilesArr =
(this.supportedTemplateExtensions.length > 0 || this.supportedDataExtensions.length > 0)
? changedFiles.filter(filePath =>
patternFiletypeTextRegex.test(filePath)
)
: changedFiles;
// Assumption: Build only when timestamps show that a pattern file (template file) has changed
// First iteration always assumes that patterns need to be built:
buildPatterns =
this.pluginIterator === 0 || changedPatternFilesArr.length > 0;
this.prevTimestamps = compilation.fileTimestamps; // update the timestamps for next iteration
this.pluginIterator++;
buildPatterns ? this.plCore.build(callback, this.cleanPublic) : callback();
}
}
export default CompilationFilesChangedPlugin;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment