ceri-compiler
Version:
compiles template strings for ceriJS
195 lines (183 loc) • 5.72 kB
JavaScript
// out: ../lib/index.js
var acorn, compileFile, compilehtml, compilejs, escodegen, fs, makeMessage, merge, path, replaceExpression;
fs = require("fs");
path = require("path");
merge = require("webpack-merge");
acorn = require("acorn");
makeMessage = (type, node) => {
var condition, text;
if (type === "cwarn") {
type = "console.warn";
} else {
type = "throw new Error";
}
condition = escodegen.generate(node.arguments.shift());
text = node.arguments.map(escodegen.generate).join(" + ");
return `if(process.env.NODE_ENV!=='production' && ${condition}){${type}(${text})}`;
};
compilehtml = async function(v, html) {
var arr, cons;
if (v == null) {
throw new Error("ceri-compiler failed. No version for template provided.");
}
if ((v.split != null) && (arr = v.split(".")) && arr.length > 1) {
cons = require("consolidate");
html = (await cons[arr[0]].render(html, {}));
v = arr[1];
}
return require(`./compile${v}`)(html);
};
replaceExpression = async function(js, expr, cb) {
var e, indexOffset, move, node;
indexOffset = 0;
while ((indexOffset = js.indexOf(expr + "(", indexOffset)) > -1) {
node = acorn.parseExpressionAt(js, indexOffset);
if (node.type === "SequenceExpression") {
node = node.expressions[0];
}
try {
[js, move] = (await cb(js, node));
indexOffset += move;
} catch (error) {
e = error;
console.error(e);
indexOffset++;
}
}
return js;
};
escodegen = null;
compilejs = async function(v, js) {
var i, len, ref, type;
if (escodegen == null) {
escodegen = require("escodegen");
}
if (js == null) {
js = v;
v = null;
}
js = (await replaceExpression(js, "template", async function(js, node) {
var _v, html, linebreaks, result;
if (node.arguments[1] != null) {
_v = node.arguments[0].value;
html = node.arguments[1].value;
} else {
_v = v;
html = node.arguments[0].value;
}
result = (await compilehtml(_v, html));
linebreaks = html.split("\n").length - 1;
result += "\n".repeat(linebreaks);
js = js.substr(0, node.start) + result + js.substr(node.end);
return [js, result.length];
}));
ref = ["cwarn", "cerror"];
for (i = 0, len = ref.length; i < len; i++) {
type = ref[i];
js = (await replaceExpression(js, type, function(js, node) {
var result;
result = makeMessage(type, node);
js = js.substr(0, node.start) + result + js.substr(node.end);
return [js, result.length];
}));
}
return js;
};
compileFile = function(program, input) {
var output;
input = path.resolve(input);
output = path.resolve(program.out, path.basename(input));
if (fs.existsSync(input)) {
fs.readFile(input, {
encoding: "utf8"
}, async function(err, result) {
if (err) {
throw err;
}
result = (await compilejs(program.v, result));
return fs.writeFile(output, result, function(err) {
if (err) {
throw err;
}
});
});
}
return output;
};
module.exports = function(program) {
var bundleString, compiler, entry, entryString, es6Bundle, i, input, inputs, j, len, len1, outFiles, parsed, ref, requireString, webconf, webpack;
if (path.extname(__filename) === ".coffee") {
require("coffeescript/register");
}
if (program.html != null) {
return compilehtml(program.v, program.html, program.locals);
} else if (program.js != null) {
return compilejs(program.v, program.js);
} else if (program.out) {
program.out = path.resolve(program.out);
inputs = [];
ref = program.args;
for (i = 0, len = ref.length; i < len; i++) {
input = ref[i];
parsed = input.split(":");
if (parsed.length === 1) {
parsed.unshift(path.basename(parsed[0], ".js"));
}
if (fs.lstatSync(path.resolve(parsed[1])).isFile()) {
inputs.push(parsed);
}
}
outFiles = [];
for (j = 0, len1 = inputs.length; j < len1; j++) {
input = inputs[j];
outFiles.push([input[0], compileFile(program, input[1])]);
}
if (program.bundle) {
if (program.webpack) {
if (path.extname(program.webpack) === ".coffee") {
require("coffeescript/register");
}
webconf = require(program.webpack);
}
if (outFiles.length > 1) {
es6Bundle = path.resolve(program.out, "bundle.ES6.js");
requireString = outFiles.map(function(outfile) {});
`'${outfile[0]}':require('${outfile[1]}')`;
bundleString = `module.exports = {${requireString.join(',')}};`;
fs.writeFileSync(es6Bundle, bundleString);
}
entry = path.resolve(program.out, "entry.js");
requireString = outFiles.map(function(outfile) {
return `window.ceri['${outfile[0]}']=require('${outfile[1]}')`;
});
requireString.unshift("if(!window.ceri)window.ceri={}");
entryString = requireString.join('\n');
fs.writeFileSync(entry, entryString);
if (webconf == null) {
webconf = {};
}
webconf = merge(require(`${__dirname}/webpack.config`), {
entry: {
index: [entry]
},
output: {
path: program.out + "/"
}
}, webconf);
webpack = require("webpack");
compiler = webpack(webconf);
return compiler.run(function(err, stats) {
fs.unlinkSync(entry);
if (err) {
throw err;
}
console.log(stats.toString({
colors: true
}));
if (stats.hasErrors() || stats.hasWarnings()) {
return console.log("please fix the warnings and errors with webpack first");
}
});
}
}
};