Fixes #363 - Auto hot reload for any extensions provided when installing the Node.js require hook. (#557)

This commit is contained in:
Austin Kelleher 2017-02-01 17:00:00 -05:00 committed by Michael Rawlings
parent 35517181e1
commit 5f20d12d21
11 changed files with 131 additions and 3 deletions

View File

@ -2,6 +2,7 @@ require('raptor-polyfill/string/endsWith');
const nodePath = require('path');
const fs = require('fs');
const nodeRequire = require('../node-require');
var compiler;
var marko;
@ -11,7 +12,6 @@ var widgets;
var modifiedId = 1;
var HOT_RELOAD_KEY = Symbol('HOT_RELOAD');
function cleaResolvePathCache() {
var modulePathCache = require('module').Module._pathCache;
if (!modulePathCache) {
@ -105,12 +105,53 @@ exports.enable = function() {
};
};
exports.handleFileModified = function(path) {
/**
* Checks whether a path ends with a custom Marko extension
*/
function _endsWithMarkoExtension(path, requireExtensions) {
for (var i = 0; i < requireExtensions.length; i++) {
if (path.endsWith(requireExtensions[i])) {
return true;
}
}
return false;
}
function normalizeExtension(extension) {
if (extension.charAt(0) !== '.') {
extension = '.' + extension;
}
return extension;
}
exports.handleFileModified = function(path, options) {
if (!fs.existsSync(path)) {
console.log('[marko/hot-reload] WARNING cannot resolve template path: ', path);
return;
}
options = options || {};
// Default hot-reloaded extensions
var requireExtensions = ['.marko', '.marko.html', '.marko.xml'];
if (options.extension) {
requireExtensions.push(options.extension);
}
if (options.extensions) {
requireExtensions = requireExtensions.concat(options.extensions);
}
var nodeRequireExtensions = nodeRequire.getExtensions();
if (nodeRequireExtensions) {
requireExtensions = requireExtensions.concat(nodeRequireExtensions);
}
for (var i = 0; i < requireExtensions.length; i++) {
requireExtensions[i] = normalizeExtension(requireExtensions[i]);
}
var basename = nodePath.basename(path);
function handleFileModified() {
@ -130,7 +171,7 @@ exports.handleFileModified = function(path) {
delete require.cache[filename];
}
});
} else if (path.endsWith('.marko') || path.endsWith('.marko.html') || path.endsWith('.marko.xml')) {
} else if (_endsWithMarkoExtension(path, requireExtensions)) {
handleFileModified();
delete require.cache[path];
delete require.cache[path + '.js'];

View File

@ -5,6 +5,7 @@ const path = require('path');
const resolveFrom = require('resolve-from');
const fs = require('fs');
const fsReadOptions = { encoding: 'utf8' };
const MARKO_EXTENSIONS = Symbol('MARKO_EXTENSIONS');
function normalizeExtension(extension) {
if (extension.charAt(0) !== '.') {
@ -123,12 +124,20 @@ function install(options) {
module._compile(compiledSrc, targetFile);
}
requireExtensions[MARKO_EXTENSIONS] = requireExtensions[MARKO_EXTENSIONS] ||
(requireExtensions[MARKO_EXTENSIONS] = []);
extensions.forEach((extension) => {
extension = normalizeExtension(extension);
requireExtensions[extension] = markoRequireExtension;
requireExtensions[MARKO_EXTENSIONS].push(extension);
});
}
install();
exports.install = install;
exports.getExtensions = function() {
return require.extensions[MARKO_EXTENSIONS];
};

View File

@ -0,0 +1 @@
template.temp*

View File

@ -0,0 +1 @@
-- Hello ${data.name}!

View File

@ -0,0 +1,24 @@
var fs = require('fs');
var nodePath = require('path');
exports.check = function(marko, hotReload, expect) {
var srcTemplatePath = nodePath.join(__dirname, 'template.html');
var templateSrc = fs.readFileSync(srcTemplatePath, { encoding: 'utf8' });
var tempTemplatePath = nodePath.join(__dirname, 'template.temp.html');
fs.writeFileSync(tempTemplatePath, templateSrc, { encoding: 'utf8' });
var template = marko.load(tempTemplatePath);
expect(template.renderSync({ name: 'John' }).toString()).to.equal('Hello John!');
fs.writeFileSync(tempTemplatePath, templateSrc + '!', { encoding: 'utf8' });
expect(template.renderSync({ name: 'John' }).toString()).to.equal('Hello John!');
hotReload.handleFileModified(tempTemplatePath, {
extension: '.html'
});
expect(template.renderSync({ name: 'John' }).toString()).to.equal('Hello John!!');
};

View File

@ -0,0 +1 @@
template.temp*

View File

@ -0,0 +1 @@
-- Hello ${data.name}!

View File

@ -0,0 +1,24 @@
var fs = require('fs');
var nodePath = require('path');
exports.check = function(marko, hotReload, expect) {
var srcTemplatePath = nodePath.join(__dirname, 'template.html');
var templateSrc = fs.readFileSync(srcTemplatePath, { encoding: 'utf8' });
var tempTemplatePath = nodePath.join(__dirname, 'template.temp.html');
fs.writeFileSync(tempTemplatePath, templateSrc, { encoding: 'utf8' });
var template = marko.load(tempTemplatePath);
expect(template.renderSync({ name: 'John' }).toString()).to.equal('Hello John!');
fs.writeFileSync(tempTemplatePath, templateSrc + '!', { encoding: 'utf8' });
expect(template.renderSync({ name: 'John' }).toString()).to.equal('Hello John!');
hotReload.handleFileModified(tempTemplatePath, {
extensions: ['.html']
});
expect(template.renderSync({ name: 'John' }).toString()).to.equal('Hello John!!');
};

View File

@ -0,0 +1 @@
template.temp*

View File

@ -0,0 +1 @@
-- Hello ${data.name}!

View File

@ -0,0 +1,24 @@
var fs = require('fs');
var nodePath = require('path');
exports.check = function(marko, hotReload, expect) {
var srcTemplatePath = nodePath.join(__dirname, 'template.html');
var templateSrc = fs.readFileSync(srcTemplatePath, { encoding: 'utf8' });
var tempTemplatePath = nodePath.join(__dirname, 'template.temp.html');
fs.writeFileSync(tempTemplatePath, templateSrc, { encoding: 'utf8' });
var template = marko.load(tempTemplatePath);
expect(template.renderSync({ name: 'John' }).toString()).to.equal('Hello John!');
fs.writeFileSync(tempTemplatePath, templateSrc + '!', { encoding: 'utf8' });
expect(template.renderSync({ name: 'John' }).toString()).to.equal('Hello John!');
hotReload.handleFileModified(tempTemplatePath, {
extensions: ['html']
});
expect(template.renderSync({ name: 'John' }).toString()).to.equal('Hello John!!');
};