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 fsReadOptions = { encoding: 'utf8' };
|
||||||
var extend = require('raptor-util/extend');
|
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() {
|
function createDefaultTagDef() {
|
||||||
return {
|
return {
|
||||||
attributes: {
|
attributes: {
|
||||||
'*': {
|
'*': {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
targetProperty: null,
|
targetProperty: null,
|
||||||
preserveName: false
|
preserveName: false
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function scanRequireExtensions(baseFilename) {
|
function getFileMap(dirname) {
|
||||||
// .js is the most common case so check that first
|
var fileMap = {};
|
||||||
var path = baseFilename + '.js';
|
var files = fs.readdirSync(dirname);
|
||||||
|
|
||||||
if (fs.existsSync(path)) {
|
files.forEach(file => {
|
||||||
return path;
|
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) {
|
var fileMap = getFileMap(tagDirname);
|
||||||
if (extension === '.js') {
|
|
||||||
// We already checked .js above
|
for(var i = 0; i < searchFiles.length; i++) {
|
||||||
continue;
|
var name = searchFiles[i].name;
|
||||||
}
|
var type = searchFiles[i].type;
|
||||||
path = baseFilename + extension;
|
var path = getPath(name, fileMap);
|
||||||
if (fs.existsSync(path)) {
|
|
||||||
return path; // short circuit loop
|
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} tagsConfigPath path to tag definition file
|
||||||
* @param {String} tagsConfigDirname path to directory of tags config file (should be path.dirname(tagsConfigPath))
|
* @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 tagName = prefix + childFilename;
|
||||||
var tagDirname = nodePath.join(dir, 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 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 tagDef = null;
|
||||||
|
|
||||||
var hasTagFile = false;
|
var hasTagJson = false;
|
||||||
if (fs.existsSync(tagFilePath)) {
|
if (fs.existsSync(tagJsonPath)) {
|
||||||
hasTagFile = true;
|
hasTagJson = true;
|
||||||
// marko-tag.json exists in the directory, use that as the tag definition
|
// marko-tag.json exists in the directory, use that as the tag definition
|
||||||
try {
|
try {
|
||||||
tagDef = JSON.parse(stripJsonComments(fs.readFileSync(tagFilePath, fsReadOptions)));
|
tagDef = JSON.parse(stripJsonComments(fs.readFileSync(tagJsonPath, fsReadOptions)));
|
||||||
} catch(e) {
|
} 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 {
|
} else {
|
||||||
tagFilePath = null;
|
tagJsonPath = null;
|
||||||
tagDef = createDefaultTagDef();
|
tagDef = createDefaultTagDef();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tagDef.renderer && !tagDef.template && !tagDef['code-generator'] && !tagDef['node-factory'] && !tagDef.transformer) {
|
if (!hasFile(tagDef)) {
|
||||||
if (rendererFile) {
|
var fileWasSet = findAndSetFile(tagDef, tagDirname);
|
||||||
tagDef.renderer = rendererFile;
|
if(!fileWasSet) {
|
||||||
} else if (indexFile) {
|
if (hasTagJson) {
|
||||||
tagDef.renderer = indexFile;
|
throw new Error('Invalid tag file: ' + tagJsonPath + '. Neither a renderer or a template was found for tag. ' + JSON.stringify(tagDef, null, 2));
|
||||||
} 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));
|
|
||||||
} else {
|
} else {
|
||||||
// Skip this directory... there doesn't appear to be anything in it
|
// Skip this directory... there doesn't appear to be anything in it
|
||||||
continue;
|
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 templateCode = fs.readFileSync(tagDef.renderer || tagDef.template, fsReadOptions);
|
||||||
let extractedTagDef = tagDefFromCode.extractTagDef(templateCode);
|
let extractedTagDef = tagDefFromCode.extractTagDef(templateCode);
|
||||||
if (extractedTagDef) {
|
if (extractedTagDef) {
|
||||||
@ -148,14 +179,14 @@ module.exports = function scanTagsDir(tagsConfigPath, tagsConfigDirname, dir, ta
|
|||||||
|
|
||||||
let tagDependencyChain;
|
let tagDependencyChain;
|
||||||
|
|
||||||
if (tagFilePath) {
|
if (tagJsonPath) {
|
||||||
tagDependencyChain = dependencyChain.append(tagFilePath);
|
tagDependencyChain = dependencyChain.append(tagJsonPath);
|
||||||
} else {
|
} else {
|
||||||
tagDependencyChain = dependencyChain.append(tagDirname);
|
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;
|
tag.name = tag.name || tagName;
|
||||||
taglib.addTag(tag);
|
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