Only process files that have changed.
metalsmith-changed will write a ctimes json-file to your build
-folder in order to keep track of changed files.
Must be used with metalsmith.clean(false)
, .clean(true)
(the default) disables metalsmith-changed and all files are passed on to the next plugin.
metalsmith-changed can also be disabled with force: true
and individual files can be ignored (always build) with forcePattern
.
var Metalsmith = require('metalsmith');
var changed = require('metalsmith-changed');
Metalsmith()
.clean(false)
.use(changed())
... // more plugins
.build(function (err) {
if (err) throw err;
});
Which is useful when watching files and livereloading:
const Metalsmith = require('metalsmith');
const changed = require('metalsmith-changed');
const livereload = require('metalsmith-livereload');
const nodeStatic = require('node-static');
const watch = require('glob-watcher');
const open = require('open');
const DIR = __dirname + '/test/fixtures/';
/**
* Build with metalsmith.
*/
const build = (clean = false) => (done) => {
console.log(`Building. clean: ${clean}.`);
Metalsmith(DIR)
.clean(clean)
.use(changed())
// .use(expensivePlugin()) // ie markdown -> html
.use(livereload({ debug: true }))
.build((err, files) => {
let filenames = Object.keys(files).join(', ');
console.log('Built: ' + filenames);
done(err);
});
};
/**
* Serve files.
*/
var serve = new nodeStatic.Server(DIR + 'build');
require('http').createServer((req, res) => {
req.addListener('end', () => serve.serve(req, res));
req.resume();
}).listen(8080);
/**
* Watch files.
*/
watch(DIR + 'src/**/*', { ignoreInitial: false }, build(false));
// watch(DIR + 'templates/**/*', build(true)); // force build of all files
/**
* Open browser.
*/
open('http://localhost:8080');
As ctimes are persisted to disk, this works nice with cli tools like watch run too.
If the option forcePattern
is defined, files matching the pattern(s) will not
be removed from building even if the file has not changed. forcePattern
should
be a string or an array of strings.
micromatch is used for matching the files.
Example:
Metalsmith()
.clean(false)
.use(changed({
forcePattern: [
'**/index.md', // always build index files
... // more patterns
]
}))
... // more plugins
.build(function(err){
if (err) throw err;
});
changed({
force: false, // build all files
forcePattern: false, // always build files matching these patterns
forceAllPattern: false, // force build of all files if files matching this pattern is changed
ctimes: 'metalsmith-changed-ctimes.json' // where to store ctimes, relative to the build folder
})
metalsmith-changed-ctimes.json
is written to your build
folder upon every build. metalsmith-changed
takes ctimes from files[n].stats.ctime
, so if a plugin creates files with .stats.ctime
, metalsmith-changed
can be used with it.
Files without stats.ctime
are always built.
npm build # babel
npm test
DEBUG=metalsmith-changed npm test # test with debug output
npm version patch|minor|major
npm publish