Comparing version 0.0.12 to 0.0.13
116
index.js
@@ -1,85 +0,75 @@ | ||
// todo 用更好的方式继承 app.response. | ||
var response = require('./lib/response.js'); | ||
var swig = require('yog-swig'); | ||
var path = require('path'); | ||
var layer = require('./lib/layer.js'); | ||
var combine = require('./lib/combine.js'); | ||
var hacked = false; | ||
var _ = require('./lib/util.js'); | ||
var view = module.exports = { | ||
engines: { | ||
'swig': swig, | ||
}, | ||
create: function(settings, app) { | ||
var Engine; | ||
exports.init = function(settings, app) { | ||
var Engine; | ||
if (arguments.length === 1) { | ||
app = settings; | ||
settings = {}; | ||
} | ||
if (arguments.length === 1) { | ||
app = settings; | ||
settings = {}; | ||
} | ||
// 让 response.render 的时候,将 response 实例作为 locals 参数携带进来。 | ||
hackResponse(app); | ||
// 让 response.render 的时候,将 response 实例作为 locals 参数携带进来。 | ||
hackResponse(app); | ||
settings.views = app.get('views'); | ||
Engine = view.engines[settings.engine || 'swig']; | ||
settings.views = app.get('views'); | ||
Engine = _.resolveEngine(settings.engine || 'yog-swig'); | ||
return function(filepath, locals, done) { | ||
// 关于 response 来源,请查看 hackResponse 方法。 | ||
// 以及 lib/reponse.js | ||
var res = locals.response; | ||
return function(filepath, locals, done) { | ||
// 关于 response 来源,请查看 hackResponse 方法。 | ||
// 以及 lib/reponse.js | ||
var res = locals.response; | ||
// 创建一个新对象。 | ||
var options = mixin({}, settings); | ||
// 初始化 layer 层。 | ||
// 提供 addScript, addStyle, resolve, addPagelet 各种接口。 | ||
// 用来扩展模板层能力。 | ||
var prototols = layer(res.fis, res.bigpipe, settings.views); | ||
// 创建一个新对象。 | ||
var options = _.mixin({}, settings); | ||
// 初始化 layer 层。 | ||
// 提供 addScript, addStyle, resolve, addPagelet 各种接口。 | ||
// 用来扩展模板层能力。 | ||
var prototols = layer(res, settings); | ||
// 模本文件路径 | ||
options.view = filepath; | ||
var sentData = false; | ||
// 模板变量。 | ||
// locals._yog 用来指向 layer 层。 | ||
options.locals = mixin(locals, {_yog: prototols}); | ||
// 模本文件路径 | ||
options.view = filepath; | ||
var tpl = new Engine(options, prototols); | ||
// 模板变量。 | ||
// locals._yog 用来指向 layer 层。 | ||
options.locals = _.mixin(locals, {_yog: prototols}); | ||
tpl | ||
// 合并 tpl 流 和 bigpipe 流。 | ||
.pipe(combine(prototols)) | ||
new Engine(options, prototols) | ||
// 合并 tpl 流 和 bigpipe 流。 | ||
.pipe(combine(prototols)) | ||
// 直接输出到 response. | ||
.pipe(res); | ||
.on('data', function() { | ||
sentData = true; | ||
}) | ||
// 如果不需要调用 done 方法,可以直接 .pipe(res); | ||
// .on('data', function(chunk) { | ||
// res.write(chunk); | ||
// }) | ||
.on('error', function(error) { | ||
// 属于 chunk error | ||
if (sentData) { | ||
if (typeof settings.chunkErrorHandler === 'function') { | ||
settings.chunkErrorHandler(error, res); | ||
} else { | ||
res.write('<script>window.console && console.error("chunk error", "'+ error.message.replace(/"/g, "\\\"") +'")</script>'); | ||
} | ||
res.end(); | ||
} else { | ||
// 交给 express 去处理错误吧。 | ||
done(error); | ||
} | ||
}) | ||
// .on('end', function() { | ||
// done(); | ||
// }) | ||
// .on('error', function(reason) { | ||
// done(reason || 'tpl error!'); | ||
// }); | ||
} | ||
// 直接输出到 response. | ||
.pipe(res); | ||
} | ||
}; | ||
function mixin(a, b) { | ||
if (a && b) { | ||
for (var key in b) { | ||
a[key] = b[key]; | ||
} | ||
} | ||
return a; | ||
} | ||
// hack into response class. | ||
var hacked = false; | ||
function hackResponse(app) { | ||
@@ -86,0 +76,0 @@ if (hacked) return; |
@@ -9,2 +9,7 @@ var Transform = require('stream').Transform; | ||
// chain error | ||
stream.on('pipe', function(source) { | ||
source.on('error', this.emit.bind(this, 'error')); | ||
}); | ||
stream._transform = function(chunk, encoding, done) { | ||
@@ -28,2 +33,5 @@ var output = isQuickingMode ? '' : layer.filter(chunk.toString()); | ||
// chain error. | ||
.on('error', stream.emit.bind(stream, 'error')) | ||
.on('data', function(chunk) { | ||
@@ -36,6 +44,2 @@ stream.push(chunk); | ||
done(); | ||
}) | ||
.on('error', function(reason) { | ||
done(reason || 'bigpipe render error!'); | ||
}); | ||
@@ -42,0 +46,0 @@ } |
200
lib/layer.js
var path = require('path'); | ||
var _ = require('./util.js'); | ||
// 此事件在 pagelet 渲染前触发。 | ||
// 主要为了收集 js/css, 后面等 pagelet 渲染完后再把收集到的添加到 pagelet 中。 | ||
function beforePageletRender(pagelet, locals) { | ||
@@ -24,3 +27,3 @@ var layer = locals._yog; | ||
// 等待父 pagelet 渲染完毕。 | ||
pagelet.once('done', function() { | ||
pagelet.once('after', function() { | ||
subpagelets.forEach(function(args) { | ||
@@ -37,3 +40,3 @@ origin.apply(fork, args); | ||
// 将 layer 收集的 js/css 添加到 pagelet 中。 | ||
function afterPageletRender(pagelet, locals) { | ||
function beforePageletAnalyse(pagelet, locals) { | ||
var layer = locals._yog; | ||
@@ -45,2 +48,4 @@ | ||
var styles = layer.getStyles(); | ||
var css = layer.getCss(); | ||
var js = layer.getJs(); | ||
@@ -52,7 +57,7 @@ if (layer.getResourceMap()) { | ||
pagelet.addStyles(styles.embed); | ||
pagelet.addScripts(scripts.embed); | ||
pagelet.addStyles(styles); | ||
pagelet.addScripts(scripts); | ||
styles.urls && pagelet.addCss(styles.urls); | ||
scripts.urls && pagelet.addJs(scripts.urls); | ||
css && pagelet.addCss(css); | ||
js && pagelet.addJs(js); | ||
} | ||
@@ -70,4 +75,48 @@ | ||
var createHanlder = module.exports = function(fis, bigpipe, views) { | ||
var defaultOptions = { | ||
tpl: { | ||
css: '<% if (this.css) { %>' + | ||
'<% this.css.forEach(function(uri) { %>' + | ||
'<link rel="stylesheet" href="<%= uri %>" />' + | ||
'<% }); %>' + | ||
'<% } %>'+ | ||
'<% if (this.embedCss) { %>' + | ||
'<style type="text/css"><%= this.embedCss %></style>' + | ||
'<% } %>', | ||
js: '<% if (this.framework) { %>' + | ||
'<script type="text/javascript" src="<%= this.framework %>"></script>' + | ||
'<% } %>' + | ||
'<% if (this.sourceMap) { %>' + | ||
'<script type="text/javascript">require.resourceMap(<%= this.sourceMap %>);</script>' + | ||
'<% } %>' + | ||
'<% if (this.js) { %>' + | ||
'<% this.js.forEach(function(uri) { %>' + | ||
'<script type="text/javascript" src="<%= uri %>"></script>' + | ||
'<% }); %>' + | ||
'<% } %>' + | ||
'<% if (this.embedJs) { %>' + | ||
'<script type="text/javascript"><%= this.embedJs %></script>' + | ||
'<% } %>' | ||
} | ||
}; | ||
var createHanlder = module.exports = function(res, options) { | ||
options = _.mixin(_.mixin({}, defaultOptions), options); | ||
// 静态资源 api | ||
var fis = res.fis; | ||
// bigpipe api | ||
var bigpipe = res.bigpipe; | ||
// 模板目录 | ||
var views = options.views; | ||
var loaded = []; | ||
@@ -157,6 +206,8 @@ | ||
if (bigpipe && !hasEventLinstener(bigpipe, 'before-pagelet-render', beforePageletRender) ) { | ||
if (bigpipe && !hasEventLinstener(bigpipe, 'pagelet:render:before', | ||
beforePageletRender) ) { | ||
bigpipe | ||
.on('before-pagelet-render', beforePageletRender) | ||
.on('after-pagelet-render', afterPageletRender); | ||
.on('pagelet:render:before', beforePageletRender) | ||
.on('pagelet:analyse:before', beforePageletAnalyse); | ||
} | ||
@@ -171,3 +222,3 @@ | ||
/** | ||
* collect all inner js. | ||
* 添加内嵌 js | ||
* @param script the code between <script> and </script>. | ||
@@ -179,4 +230,31 @@ */ | ||
getScripts: function() { | ||
return scripts; | ||
}, | ||
/** | ||
* collect all inner css | ||
* 添加 js | ||
* @param {[type]} url [description] | ||
*/ | ||
addJs: function(url) { | ||
var info = fis && fis.getInfo(url, true); | ||
if (info) { | ||
this.load(url); | ||
} else { | ||
syncs.js = async.js || []; | ||
~syncs.js.indexOf(url) || syncs.js.push(url); | ||
} | ||
}, | ||
/** | ||
* 获取 js | ||
* @return {[type]} [description] | ||
*/ | ||
getJs: function() { | ||
return syncs.js; | ||
}, | ||
/** | ||
* 添加内联样式 | ||
* @param style the code between <style> and </style> | ||
@@ -188,3 +266,30 @@ */ | ||
getStyles: function() { | ||
return styles; | ||
}, | ||
/** | ||
* 添加样式 | ||
* @param {[type]} url [description] | ||
*/ | ||
addCss: function(url) { | ||
var info = fis && fis.getInfo(url, true); | ||
if (info) { | ||
this.load(url); | ||
} else { | ||
syncs.css = async.css || []; | ||
~syncs.css.indexOf(url) || syncs.css.push(url); | ||
} | ||
}, | ||
/** | ||
* 获取 css | ||
* @return {[type]} [description] | ||
*/ | ||
getCss: function() { | ||
return syncs.css; | ||
}, | ||
/** | ||
* 设置 framework js. | ||
@@ -223,16 +328,4 @@ * @param {[type]} js [description] | ||
fork: function(fis, bigpipe, views) { | ||
if (arguments.length === 0) { | ||
fis = this.fis; | ||
bigpipe = this.bigpipe; | ||
views = this.views; | ||
} else if (arguments.length === 1) { | ||
bigpipe = this.bigpipe; | ||
views = this.views; | ||
} else if (arguments.length === 2) { | ||
views = this.views; | ||
} | ||
var forked = createHanlder(fis, bigpipe, views); | ||
fork: function() { | ||
var forked = createHanlder(res, options); | ||
return forked; | ||
@@ -274,16 +367,2 @@ }, | ||
getScripts: function() { | ||
return { | ||
urls: syncs.js, | ||
embed: scripts | ||
} | ||
}, | ||
getStyles: function() { | ||
return { | ||
urls: syncs.css, | ||
embed: styles | ||
} | ||
}, | ||
filter: function(content) { | ||
@@ -304,44 +383,31 @@ if(~content.indexOf(this.JS_HOOK)) { | ||
var scripts = this.getScripts(); | ||
var js = ''; | ||
var jses = this.getJs(); | ||
var data = {}; | ||
var loadModjs = (scripts.urls || resourceMap) && framework; | ||
var loadModjs = (jses || resourceMap) && framework; | ||
var p; | ||
if (loadModjs) { | ||
//if need `mod.js`, keep it first. | ||
js += '<script src="' + framework + '"></script>'; | ||
if (resourceMap) { | ||
js += '<script type="text/javascript">require.resourceMap(' + JSON.stringify(resourceMap) + ');</script>'; | ||
} | ||
data.framework = framework; | ||
resourceMap && (data.sourceMap = JSON.stringify(resourceMap)); | ||
} | ||
if (scripts.urls) { | ||
if ((p = scripts.urls.indexOf(framework)) !== -1) { | ||
scripts.urls.splice(p, 1); //remove `mod.js` | ||
} | ||
jses && (data.js = jses); | ||
scripts.length && (data.embedJs = '!function() {' + | ||
scripts.join('}();\n!function() {') + '}();'); | ||
js += '<script type="text/javascript" src="' + scripts.urls.join('"></script>\n<script type="text/javascript" src="') + '"></script>'; | ||
} | ||
if (scripts.embed.length) { | ||
js += '\n<script type="text/javascript">\n!function() {' + scripts.embed.join('}();\n!function() {') + '}();</script>\n'; | ||
} | ||
return content.replace(this.JS_HOOK, js); | ||
return content.replace(this.JS_HOOK, _.tpl(options.tpl.js, data)); | ||
}, | ||
filterCss: function(content) { | ||
var css = ''; | ||
var styles = this.getStyles(); | ||
var csses = this.getCss(); | ||
var data = {}; | ||
if (styles.urls) { | ||
css += '<link rel="stylesheet" href="' + styles.urls.join('" />\n<link rel="stylesheet" href="') + '" />'; | ||
} | ||
csses && (data.css = csses); | ||
styles.length && (data.embedCss = styles.join('\n')); | ||
if (styles.embed.length) { | ||
css += '\n<style type="text/css">' + styles.embed.join('\n') + '</style>'; | ||
} | ||
return content.replace(this.CSS_HOOK, css); | ||
return content.replace(this.CSS_HOOK, _.tpl(options.tpl.css, data)); | ||
}, | ||
@@ -348,0 +414,0 @@ |
{ | ||
"name": "yog-view", | ||
"version": "0.0.12", | ||
"version": "0.0.13", | ||
"description": "An express.js middleware for optimizing the order of js\\css output, and enabling render template in bigpipe mode.", | ||
@@ -26,4 +26,4 @@ "main": "index.js", | ||
"dependencies": { | ||
"yog-swig": "~0.0.7" | ||
"caller": "0.0.1" | ||
} | ||
} |
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
19493
9
477
2
1
+ Addedcaller@0.0.1
+ Addedcaller@0.0.1(transitive)
+ Addeddeep-equal@0.1.2(transitive)
+ Addeddefined@0.0.0(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedjsonify@0.0.1(transitive)
+ Addedresumer@0.0.0(transitive)
+ Addedtape@2.3.3(transitive)
+ Addedthrough@2.3.8(transitive)
- Removedyog-swig@~0.0.7
- Removedamdefine@1.0.1(transitive)
- Removedasync@0.2.10(transitive)
- Removedcamelcase@1.2.1(transitive)
- Removeddecamelize@1.2.0(transitive)
- Removedminimist@0.0.10(transitive)
- Removedoptimist@0.6.1(transitive)
- Removedsource-map@0.1.34(transitive)
- Removedswig@1.3.2(transitive)
- Removeduglify-js@2.4.24(transitive)
- Removeduglify-to-browserify@1.0.2(transitive)
- Removedwindow-size@0.1.0(transitive)
- Removedwordwrap@0.0.20.0.3(transitive)
- Removedyargs@3.5.4(transitive)
- Removedyog-swig@0.0.18(transitive)