mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
allow finding index.marko, rework the tag scanning to hit the filesystem less
This commit is contained in:
parent
af990a04b3
commit
1d3d14d01e
@ -23,38 +23,90 @@ var loader = require('./loader');
|
||||
var fsReadOptions = { encoding: 'utf8' };
|
||||
var extend = require('raptor-util/extend');
|
||||
|
||||
var tagFileTypes = [
|
||||
'template',
|
||||
'renderer',
|
||||
'transformer',
|
||||
'code-generator',
|
||||
'node-factory',
|
||||
];
|
||||
|
||||
var searchFiles = [
|
||||
{ name:'renderer', type:'renderer' },
|
||||
{ name:'index.marko', type:'template' },
|
||||
{ name:'index', type:'renderer' },
|
||||
{ name:'template.marko', type:'template' },
|
||||
{ name:'template.html', type:'template' },
|
||||
{ name:'code-generator', type:'code-generator' },
|
||||
{ name:'node-factory', type:'node-factory' },
|
||||
{ name:'transformer', type:'transformer' },
|
||||
];
|
||||
|
||||
function createDefaultTagDef() {
|
||||
return {
|
||||
attributes: {
|
||||
'*': {
|
||||
type: 'string',
|
||||
targetProperty: null,
|
||||
preserveName: false
|
||||
}
|
||||
attributes: {
|
||||
'*': {
|
||||
type: 'string',
|
||||
targetProperty: null,
|
||||
preserveName: false
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function scanRequireExtensions(baseFilename) {
|
||||
// .js is the most common case so check that first
|
||||
var path = baseFilename + '.js';
|
||||
function getFileMap(dirname) {
|
||||
var fileMap = {};
|
||||
var files = fs.readdirSync(dirname);
|
||||
|
||||
if (fs.existsSync(path)) {
|
||||
return path;
|
||||
files.forEach(file => {
|
||||
var extName = nodePath.extname(file);
|
||||
var baseName = file.slice(0, -1*extName.length);
|
||||
var fullPath = nodePath.join(dirname, file);
|
||||
fileMap[baseName] = fileMap[baseName] || {};
|
||||
fileMap[baseName][extName] = fullPath;
|
||||
fileMap[file] = fileMap[file] || {};
|
||||
fileMap[file].__path = fullPath;
|
||||
});
|
||||
|
||||
return fileMap;
|
||||
}
|
||||
|
||||
function getPath(filename, fileMap) {
|
||||
var file = fileMap[filename];
|
||||
|
||||
if(!file) return;
|
||||
if(file.__path) return file.__path;
|
||||
if(file.js) return file['.js'];
|
||||
|
||||
return file[Object.keys(file)[0]];
|
||||
}
|
||||
|
||||
function findAndSetFile(tagDef, tagDirname) {
|
||||
if(!fs.statSync(tagDirname).isDirectory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var extension in require.extensions) {
|
||||
if (extension === '.js') {
|
||||
// We already checked .js above
|
||||
continue;
|
||||
}
|
||||
path = baseFilename + extension;
|
||||
if (fs.existsSync(path)) {
|
||||
return path; // short circuit loop
|
||||
var fileMap = getFileMap(tagDirname);
|
||||
|
||||
for(var i = 0; i < searchFiles.length; i++) {
|
||||
var name = searchFiles[i].name;
|
||||
var type = searchFiles[i].type;
|
||||
var path = getPath(name, fileMap);
|
||||
|
||||
if(path) {
|
||||
tagDef[type] = path;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hasFile(tagDef) {
|
||||
for(var i = 0; i < tagFileTypes.length; i++) {
|
||||
if(tagDef[tagFileTypes[i]]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} tagsConfigPath path to tag definition file
|
||||
* @param {String} tagsConfigDirname path to directory of tags config file (should be path.dirname(tagsConfigPath))
|
||||
@ -87,50 +139,29 @@ module.exports = function scanTagsDir(tagsConfigPath, tagsConfigDirname, dir, ta
|
||||
|
||||
var tagName = prefix + childFilename;
|
||||
var tagDirname = nodePath.join(dir, childFilename);
|
||||
var tagFilePath = nodePath.join(tagDirname, 'marko-tag.json');
|
||||
var tagJsonPath = nodePath.join(tagDirname, 'marko-tag.json');
|
||||
var tag = null;
|
||||
|
||||
var rendererFile = scanRequireExtensions(nodePath.join(tagDirname, 'renderer'));
|
||||
var indexFile = scanRequireExtensions(nodePath.join(tagDirname, 'index'));
|
||||
var templateFile = nodePath.join(tagDirname, 'template.marko');
|
||||
var templateFileAlt = nodePath.join(tagDirname, 'template.html');
|
||||
var templateFileAlt2 = nodePath.join(tagDirname, 'template.marko.html');
|
||||
var codeGeneratorFile = scanRequireExtensions(nodePath.join(tagDirname, 'code-generator'));
|
||||
var nodeFactoryFile = scanRequireExtensions(nodePath.join(tagDirname, 'node-factory'));
|
||||
var tagDef = null;
|
||||
|
||||
var hasTagFile = false;
|
||||
if (fs.existsSync(tagFilePath)) {
|
||||
hasTagFile = true;
|
||||
var hasTagJson = false;
|
||||
if (fs.existsSync(tagJsonPath)) {
|
||||
hasTagJson = true;
|
||||
// marko-tag.json exists in the directory, use that as the tag definition
|
||||
try {
|
||||
tagDef = JSON.parse(stripJsonComments(fs.readFileSync(tagFilePath, fsReadOptions)));
|
||||
tagDef = JSON.parse(stripJsonComments(fs.readFileSync(tagJsonPath, fsReadOptions)));
|
||||
} catch(e) {
|
||||
throw new Error('Unable to parse JSON file at path "' + tagFilePath + '". Error: ' + e);
|
||||
throw new Error('Unable to parse JSON file at path "' + tagJsonPath + '". Error: ' + e);
|
||||
}
|
||||
} else {
|
||||
tagFilePath = null;
|
||||
tagJsonPath = null;
|
||||
tagDef = createDefaultTagDef();
|
||||
}
|
||||
|
||||
if (!tagDef.renderer && !tagDef.template && !tagDef['code-generator'] && !tagDef['node-factory'] && !tagDef.transformer) {
|
||||
if (rendererFile) {
|
||||
tagDef.renderer = rendererFile;
|
||||
} else if (indexFile) {
|
||||
tagDef.renderer = indexFile;
|
||||
} else if (fs.existsSync(templateFile)) {
|
||||
tagDef.template = templateFile;
|
||||
} else if (fs.existsSync(templateFileAlt)) {
|
||||
tagDef.template = templateFileAlt;
|
||||
} else if (fs.existsSync(templateFileAlt2)) {
|
||||
tagDef.template = templateFileAlt2;
|
||||
} else if (fs.existsSync(codeGeneratorFile)) {
|
||||
tagDef['code-generator'] = codeGeneratorFile;
|
||||
} else if (fs.existsSync(nodeFactoryFile)) {
|
||||
tagDef['node-factory'] = nodeFactoryFile;
|
||||
} else {
|
||||
if (hasTagFile) {
|
||||
throw new Error('Invalid tag file: ' + tagFilePath + '. Neither a renderer or a template was found for tag. ' + JSON.stringify(tagDef, null, 2));
|
||||
if (!hasFile(tagDef)) {
|
||||
var fileWasSet = findAndSetFile(tagDef, tagDirname);
|
||||
if(!fileWasSet) {
|
||||
if (hasTagJson) {
|
||||
throw new Error('Invalid tag file: ' + tagJsonPath + '. Neither a renderer or a template was found for tag. ' + JSON.stringify(tagDef, null, 2));
|
||||
} else {
|
||||
// Skip this directory... there doesn't appear to be anything in it
|
||||
continue;
|
||||
@ -138,7 +169,7 @@ module.exports = function scanTagsDir(tagsConfigPath, tagsConfigDirname, dir, ta
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasTagFile && (tagDef.renderer || tagDef.template)) {
|
||||
if (!hasTagJson && (tagDef.renderer || tagDef.template)) {
|
||||
let templateCode = fs.readFileSync(tagDef.renderer || tagDef.template, fsReadOptions);
|
||||
let extractedTagDef = tagDefFromCode.extractTagDef(templateCode);
|
||||
if (extractedTagDef) {
|
||||
@ -148,14 +179,14 @@ module.exports = function scanTagsDir(tagsConfigPath, tagsConfigDirname, dir, ta
|
||||
|
||||
let tagDependencyChain;
|
||||
|
||||
if (tagFilePath) {
|
||||
tagDependencyChain = dependencyChain.append(tagFilePath);
|
||||
if (tagJsonPath) {
|
||||
tagDependencyChain = dependencyChain.append(tagJsonPath);
|
||||
} else {
|
||||
tagDependencyChain = dependencyChain.append(tagDirname);
|
||||
}
|
||||
|
||||
tag = loader.tagLoader.loadTag(tagDef, tagFilePath || tagDirname, tagDependencyChain);
|
||||
tag = loader.tagLoader.loadTag(tagDef, tagJsonPath || tagDirname, tagDependencyChain);
|
||||
tag.name = tag.name || tagName;
|
||||
taglib.addTag(tag);
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -0,0 +1 @@
|
||||
Hello Frank!
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"tags-dir": "./tags"
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
---
|
||||
Hello ${data.name}!
|
||||
---
|
||||
@ -0,0 +1 @@
|
||||
<test-tag name="Frank"/>
|
||||
1
test/autotests/render/custom-tag-template-index/test.js
Normal file
1
test/autotests/render/custom-tag-template-index/test.js
Normal file
@ -0,0 +1 @@
|
||||
exports.templateData = {};
|
||||
Loading…
x
Reference in New Issue
Block a user