代码重构 java 脚本编译器
code refactoring a java script compiler
我试图理解一个 JavaScript 包编译器并重新设计了基本结构。
每次编译字符串时,都会将其添加到 SrcTable
数组中。并扔到输出端。
但是,要获得输出,必须将 SrcTable
声明为全局。 but the example from which i am building this code has that variable declared as local。
我想了解:-
1.Why 我不能在这里声明变量为本地变量吗?
2. 我需要更改什么才能使其像本地一样工作?
srcTable
在 preprocessors.compiler
变量中。
function resolveRequest(request) {
var match = request.match(/^\s*import\s+(.*)$/),
imports = {};
if (match) {
match[1].replace(/\s*([\w.\-$]+)(?:\s+as\s+([\w.\-$]+))?,?/g, function(_, from, as) {
imports = {
from: from,
as: as || from
};
});
}
return imports;
}
var preprocessors = {
import: "var importExpr = /^(\s*)(import\s+[^=+*\"'\r\n;\/]+|from\s+[^=+\"'\r\n;\/ ]+\s+import\s+[^=+\"'\r\n;\/]+)(;|\/|$)/gm;" +
"function replace(raw, p1, p2, p3) {" +
" return p1 + 'jsio(\"' + p2 + '\")' + p3;" +
"};" +
"exports = function(src) {" +
" return src.replace(importExpr, replace);" +
"};",
compiler: "srcTable = [];" + // this array needs to be local
" exports = function (src) {" +
" var jsioNormal = " + /^(.*)jsio\s*\(\s*(['"].+?['"])\s*(,\s*\{[^}]+\})?\)/gm + "\n;" +
" var match = jsioNormal.exec(src);\n" +
" if(match) {" +
" var request = eval(match[2]);\n" +
" jsio(request, ['import', 'compiler']);\n" +
" } \n" +
" srcTable.push(src);"+
" return '';\n" +
" };" +
" exports.compile = function(request) {" +
" jsio(request, ['import', 'compiler']);" +
" };" +
" exports.generateSrc = function (callback) {"+
" callback(srcTable);"+
" };"
};
function _require(previousCtx, request, p) {
var p = p || ['import'];
var request = resolveRequest(request);
var src = eval(request.from);
p.forEach(function(name, index) {
var args = name == 'import' ? [] : null;
var preprocessor = jsio('import preprocessors.' + name, args);
src = preprocessor(src);
});
var code = "(function (__) { with (__) {" + src + "}});";
var fn = eval(code);
var context = makeContext();
fn(context);
previousCtx[request.as] = context.exports;
return context.exports;
}
function makeContext() {
return {
jsio: function(request, p) {
return _require(this, request, p);
},
exports: {}
};
}
var jsio = makeContext().jsio;
var example = {
app: "import example.calculator as calculator;" +
" calculator.add(2, 3);",
calculator: "import example.print as print;" +
" exports = {" +
" add: function (a, b) {" +
" print(a+b);" +
" }" +
" }",
print: "exports = function(res) {" +
" console.log(res);" +
" }"
};
var compiler = jsio('import preprocessors.compiler;');
compiler.compile('import example.app;');
compiler.generateSrc(function(src) {
console.log(src);
});
由于代码是使用 java-script with
上下文编译的,因此,评估代码的函数需要缓存,否则每次都会编译相同的代码,将重新创建实例。
所以解决方案是
function resolveRequest(request) {
var match = request.match(/^\s*import\s+(.*)$/),
imports = {};
if (match) {
match[1].replace(/\s*([\w.\-$]+)(?:\s+as\s+([\w.\-$]+))?,?/g, function(_, from, as) {
imports = {
from: from,
as: as || from
};
});
}
return imports;
}
var preprocessors = {
import: "var importExpr = /^(\s*)(import\s+[^=+*\"'\r\n;\/]+|from\s+[^=+\"'\r\n;\/ ]+\s+import\s+[^=+\"'\r\n;\/]+)(;|\/|$)/gm;" +
"function replace(raw, p1, p2, p3) {" +
" return p1 + 'jsio(\"' + p2 + '\")' + p3;" +
"};" +
"exports = function(src) {" +
" return src.replace(importExpr, replace);" +
"};",
compiler: "var srcTable = [];\n" +
" exports = function (src) {\n" +
" var jsioNormal = " + /^(.*)jsio\s*\(\s*(['"].+?['"])\s*(,\s*\{[^}]+\})?\)/gm + "\n;" +
" var match = jsioNormal.exec(src);\n" +
" if(match) {\n" +
" var request = eval(match[2]);\n" +
" jsio(request, ['import', 'compiler']);\n" +
" } \n" +
" srcTable.push(src);\n" +
" return '';\n" +
" };\n" +
" exports.compile = function(request) {\n" +
" jsio(request, ['import', 'compiler']);\n" +
" };\n" +
" exports.generateSrc = function (callback) {\n" +
" callback(srcTable);\n" +
" };\n"
};
var _cache_context = [];
function _require(previousCtx, request, p) {
var p = p || ['import'];
var request = resolveRequest(request);
var src = loadModule(request).src;
p.forEach(function(name, index) {
var args = name == 'import' ? [] : null;
var preprocessor = jsio('import preprocessors.' + name, args);
src = preprocessor(src);
});
if (src) {
if (!_cache_context[request.from]) {
var code = "(function (__) { with (__) {\n" + src + "\n}});";
var fn = eval(code);
var context = makeContext();
fn(context);
_cache_context[request.from] = context.exports;
}
previousCtx[request.as] = _cache_context[request.from];
return previousCtx[request.as];
}
}
function loadModule(request){
var src = eval(request.from);
return {
src: src,
path: request.from
}
}
function makeContext() {
return {
jsio: function(request, p) {
return _require(this, request, p);
},
exports: {}
};
}
var jsio = makeContext().jsio;
var example = {
app: "import example.calculator as calculator;" +
" calculator.add(2, 3);",
calculator: "import example.print as print;" +
" exports = {" +
" add: function (a, b) {" +
" print(a+b);" +
" }" +
" }",
print: "exports = function(res) {" +
" console.log(res);" +
" }"
};
var compiler = jsio('import preprocessors.compiler;');
compiler.compile('import example.app;');
compiler.generateSrc(function(src) {
console.log(src);
});
我试图理解一个 JavaScript 包编译器并重新设计了基本结构。
每次编译字符串时,都会将其添加到 SrcTable
数组中。并扔到输出端。
但是,要获得输出,必须将 SrcTable
声明为全局。 but the example from which i am building this code has that variable declared as local。
我想了解:-
1.Why 我不能在这里声明变量为本地变量吗?
2. 我需要更改什么才能使其像本地一样工作?
srcTable
在 preprocessors.compiler
变量中。
function resolveRequest(request) {
var match = request.match(/^\s*import\s+(.*)$/),
imports = {};
if (match) {
match[1].replace(/\s*([\w.\-$]+)(?:\s+as\s+([\w.\-$]+))?,?/g, function(_, from, as) {
imports = {
from: from,
as: as || from
};
});
}
return imports;
}
var preprocessors = {
import: "var importExpr = /^(\s*)(import\s+[^=+*\"'\r\n;\/]+|from\s+[^=+\"'\r\n;\/ ]+\s+import\s+[^=+\"'\r\n;\/]+)(;|\/|$)/gm;" +
"function replace(raw, p1, p2, p3) {" +
" return p1 + 'jsio(\"' + p2 + '\")' + p3;" +
"};" +
"exports = function(src) {" +
" return src.replace(importExpr, replace);" +
"};",
compiler: "srcTable = [];" + // this array needs to be local
" exports = function (src) {" +
" var jsioNormal = " + /^(.*)jsio\s*\(\s*(['"].+?['"])\s*(,\s*\{[^}]+\})?\)/gm + "\n;" +
" var match = jsioNormal.exec(src);\n" +
" if(match) {" +
" var request = eval(match[2]);\n" +
" jsio(request, ['import', 'compiler']);\n" +
" } \n" +
" srcTable.push(src);"+
" return '';\n" +
" };" +
" exports.compile = function(request) {" +
" jsio(request, ['import', 'compiler']);" +
" };" +
" exports.generateSrc = function (callback) {"+
" callback(srcTable);"+
" };"
};
function _require(previousCtx, request, p) {
var p = p || ['import'];
var request = resolveRequest(request);
var src = eval(request.from);
p.forEach(function(name, index) {
var args = name == 'import' ? [] : null;
var preprocessor = jsio('import preprocessors.' + name, args);
src = preprocessor(src);
});
var code = "(function (__) { with (__) {" + src + "}});";
var fn = eval(code);
var context = makeContext();
fn(context);
previousCtx[request.as] = context.exports;
return context.exports;
}
function makeContext() {
return {
jsio: function(request, p) {
return _require(this, request, p);
},
exports: {}
};
}
var jsio = makeContext().jsio;
var example = {
app: "import example.calculator as calculator;" +
" calculator.add(2, 3);",
calculator: "import example.print as print;" +
" exports = {" +
" add: function (a, b) {" +
" print(a+b);" +
" }" +
" }",
print: "exports = function(res) {" +
" console.log(res);" +
" }"
};
var compiler = jsio('import preprocessors.compiler;');
compiler.compile('import example.app;');
compiler.generateSrc(function(src) {
console.log(src);
});
由于代码是使用 java-script with
上下文编译的,因此,评估代码的函数需要缓存,否则每次都会编译相同的代码,将重新创建实例。
所以解决方案是
function resolveRequest(request) {
var match = request.match(/^\s*import\s+(.*)$/),
imports = {};
if (match) {
match[1].replace(/\s*([\w.\-$]+)(?:\s+as\s+([\w.\-$]+))?,?/g, function(_, from, as) {
imports = {
from: from,
as: as || from
};
});
}
return imports;
}
var preprocessors = {
import: "var importExpr = /^(\s*)(import\s+[^=+*\"'\r\n;\/]+|from\s+[^=+\"'\r\n;\/ ]+\s+import\s+[^=+\"'\r\n;\/]+)(;|\/|$)/gm;" +
"function replace(raw, p1, p2, p3) {" +
" return p1 + 'jsio(\"' + p2 + '\")' + p3;" +
"};" +
"exports = function(src) {" +
" return src.replace(importExpr, replace);" +
"};",
compiler: "var srcTable = [];\n" +
" exports = function (src) {\n" +
" var jsioNormal = " + /^(.*)jsio\s*\(\s*(['"].+?['"])\s*(,\s*\{[^}]+\})?\)/gm + "\n;" +
" var match = jsioNormal.exec(src);\n" +
" if(match) {\n" +
" var request = eval(match[2]);\n" +
" jsio(request, ['import', 'compiler']);\n" +
" } \n" +
" srcTable.push(src);\n" +
" return '';\n" +
" };\n" +
" exports.compile = function(request) {\n" +
" jsio(request, ['import', 'compiler']);\n" +
" };\n" +
" exports.generateSrc = function (callback) {\n" +
" callback(srcTable);\n" +
" };\n"
};
var _cache_context = [];
function _require(previousCtx, request, p) {
var p = p || ['import'];
var request = resolveRequest(request);
var src = loadModule(request).src;
p.forEach(function(name, index) {
var args = name == 'import' ? [] : null;
var preprocessor = jsio('import preprocessors.' + name, args);
src = preprocessor(src);
});
if (src) {
if (!_cache_context[request.from]) {
var code = "(function (__) { with (__) {\n" + src + "\n}});";
var fn = eval(code);
var context = makeContext();
fn(context);
_cache_context[request.from] = context.exports;
}
previousCtx[request.as] = _cache_context[request.from];
return previousCtx[request.as];
}
}
function loadModule(request){
var src = eval(request.from);
return {
src: src,
path: request.from
}
}
function makeContext() {
return {
jsio: function(request, p) {
return _require(this, request, p);
},
exports: {}
};
}
var jsio = makeContext().jsio;
var example = {
app: "import example.calculator as calculator;" +
" calculator.add(2, 3);",
calculator: "import example.print as print;" +
" exports = {" +
" add: function (a, b) {" +
" print(a+b);" +
" }" +
" }",
print: "exports = function(res) {" +
" console.log(res);" +
" }"
};
var compiler = jsio('import preprocessors.compiler;');
compiler.compile('import example.app;');
compiler.generateSrc(function(src) {
console.log(src);
});