Comparing version 0.0.8 to 0.2.0
147
lib/read.js
@@ -1,108 +0,83 @@ | ||
var fs = require('fs'); | ||
var normalize = require('path').normalize; | ||
var uglify = require('./uglify.js'); | ||
var less = require('less'); | ||
var stylus = require('stylus'); | ||
var fs = require('fs') | ||
var BasicCache = require('basiccache') | ||
var normalize = require('path').normalize | ||
var join = require('path').join | ||
var uglify = require('./uglify') | ||
var log = require('debug')('istatic') | ||
function waitStale(ttl, _t) { | ||
try { | ||
clearInterval(_t); | ||
} catch (e) {} | ||
_t = setInterval(function() { cache = {}; }, ttl * 1000); | ||
} | ||
var processRoot = process.cwd() | ||
var ONE_HOUR = 3600 * 1000 | ||
var processRoot = process.cwd(); | ||
var global_cache = {}; | ||
function _uglify(type, str, opt, doCompress) { | ||
function _uglify(type, content, opt, compress) { | ||
// apply filters | ||
if (opt && opt.filter) { | ||
str = opt.filter(str) || ''; | ||
content = opt.filter(content) || '' | ||
} | ||
if (!doCompress) return str; | ||
return uglify[type](str, opt); | ||
if (!compress) return content | ||
return uglify[type](content, opt) | ||
} | ||
function getContent(filepath, opts) { | ||
var filetype = filepath.split('.').slice(-1)[0] | ||
try { | ||
content = fs.readFileSync(filepath, opts.charset) | ||
} catch (e) { | ||
log('Reading %s failed: %s', filepath, e) | ||
if (opts.debug) throw e | ||
return '/* == istatic: read file failed: ' + filepath + ' == */' | ||
} | ||
if (filetype == 'css' || filetype == 'js') { | ||
content = _uglify(filetype, content, opts[filetype], opts.compress) | ||
} | ||
// add a deug line | ||
if (opts.debug) { | ||
content = '\n/* == istatic: ' + filepath + ' == */\n' + content | ||
} | ||
return content | ||
} | ||
module.exports = function theRead(options) { | ||
// inline static has to be very fast, | ||
// so we just store it in the memory forever. | ||
var cache = {}; | ||
var _t; | ||
var doCache = true; | ||
options = options || {} | ||
options = options || {}; | ||
var cache = new BasicCache({ | ||
expires: options.ttl ? options.ttl * 1000 : null, | ||
purgeInterval: ONE_HOUR | ||
}) | ||
var debug = options.debug = 'debug' in options ? options.debug : process.env.DEBUG | ||
var staticRoot = options.root ? normalize(options.root) : (processRoot + '/public/') | ||
var ttl = options.ttl; | ||
if (ttl > 5) { | ||
waitStale(ttl, _t); | ||
if (debug) { | ||
options.cache = options.compress = false | ||
} else { | ||
// if the ttl is less than 5 seconds, | ||
// we don't even cache it. | ||
doCache = false; | ||
if (!('cache' in options)) options.cache = true | ||
if (!('compress' in options)) options.compress = true | ||
} | ||
var staticRoot = options.root ? normalize(options.root) : (processRoot + '/public/'); | ||
if (staticRoot.slice(-1) != '/') staticRoot += '/'; | ||
// root always ends with a slash | ||
if (staticRoot.slice(-1) != '/') staticRoot += '/' | ||
return function theRead(filepath, opt) { | ||
var filetype = filepath.split('.').slice(-1)[0]; | ||
var root = filepath[0] == '/' ? processRoot : staticRoot; | ||
filepath = root + filepath; | ||
return function theRead(filepath, fresh) { | ||
var content | ||
var useCache = options.cache | ||
opt = opt || {}; | ||
for (var key in options) { | ||
if (key in opt) { | ||
} else { | ||
opt[key] = options[key]; | ||
} | ||
if (fresh) { | ||
useCache = false | ||
} | ||
var charset = opt.charset || 'utf-8'; | ||
var debug = process.env.DEBUG || opt.debug; | ||
var doCompress = 'compress' in opt ? opt.compress : true; | ||
var _doCache = opt.fresh ? false : doCache; | ||
filepath = (filepath[0] == '/' ? processRoot : staticRoot) + filepath | ||
var str = _doCache ? (cache[filepath] || global_cache[filepath]) : ''; | ||
if (str && _doCache) return str; | ||
try { | ||
str = fs.readFileSync(filepath, charset); | ||
} catch (e) { | ||
console.error('[istatic] Reading..', filepath, e); | ||
} | ||
switch (filetype) { | ||
case 'styl': | ||
filetype = 'css'; | ||
stylus.render(str, function(err, str) { | ||
if (err) console.error('[istatic] Compiling', filepath, err); | ||
else cache[filepath] = _uglify('css', str, opt.css, doCompress); | ||
}); | ||
case 'less': | ||
filetype = 'css'; | ||
less.render(str, function(err, str) { | ||
if (err) console.error('[istatic] Compiling', filepath, err); | ||
else cache[filepath] = _uglify('css', str, opt.css, doCompress); | ||
}); | ||
// better simple than none | ||
// once the render is done, we can safely return good css | ||
//case 'js': | ||
//case 'css': | ||
default: | ||
if (filetype == 'css' || filetype == 'js') { | ||
str = _uglify(filetype, str, opt[filetype], doCompress); | ||
if (useCache) { | ||
content = cache.get(filepath) | ||
if (content === undefined) { | ||
content = getContent(filepath, options) | ||
} | ||
cache.set(filepath, content) | ||
} else { | ||
content = getContent(filepath, options) | ||
} | ||
if (debug) str = '\n/* == istatic: ' + filepath + ' == */\n' + str; | ||
return content | ||
} | ||
} | ||
var ret = new String(str); | ||
// cache as a string object | ||
if (_doCache) cache[filepath] = global_cache[filepath] = ret; | ||
return ret; | ||
}; | ||
}; | ||
@@ -1,16 +0,13 @@ | ||
var uglifycss = require('uglifycss'); | ||
var uglifyjs = require('uglify-js'); | ||
var jsp = uglifyjs.parser; | ||
var pro = uglifyjs.uglify; | ||
var CleanCSS = require('clean-css') | ||
var uglifyjs = require('uglify-js') | ||
module.exports = { | ||
js: function(str, opt) { | ||
var ast = jsp.parse(str); | ||
ast = pro.ast_mangle(ast); | ||
ast = pro.ast_squeeze(ast); | ||
return pro.gen_code(ast, opt); | ||
js: function(code, opt) { | ||
opt = opt || {} | ||
opt.fromString = true | ||
return uglifyjs.minify(code, opt).code | ||
}, | ||
css: function(str, opt) { | ||
return uglifycss.processString(str, opt); | ||
css: function(code, opt) { | ||
return new CleanCSS(opt).minify(code) | ||
} | ||
}; | ||
} |
{ | ||
"name": "istatic", | ||
"version": "0.0.8", | ||
"homepage": "http://github.com/ktmud/express-istatic", | ||
"version": "0.2.0", | ||
"homepage": "http://github.com/ktmud/istatic", | ||
"description": "Add compressed inline css and scripts to your html, but write them as seperated files.", | ||
"keywords": [ "express", "static files include", "compression", "minify" ], | ||
"keywords": [ "express", "assets", "template", "static", "include", "compression", "minify" ], | ||
"author": "ktmud <jyyjcc@gmail.com> (http://ktmud.com)", | ||
"main": "./lib/istatic", | ||
"repository": "git@github.com/ktmud/express-istatic.git", | ||
"repository": "ktmud/istatic", | ||
"dependencies": { | ||
"less": ">= 1.0", | ||
"stylus": ">= 0.1", | ||
"uglify-js": ">= 1.0", | ||
"uglifycss": ">= 0.0.5" | ||
"debug": ">= 0.7.0", | ||
"basiccache": "^0.0.5", | ||
"uglify-js": "^2.4.13", | ||
"clean-css": "^2.1.8" | ||
}, | ||
"engines": { | ||
"node" : ">=0.4.0" | ||
"node" : ">=0.8.0" | ||
} | ||
} |
143
README.md
@@ -1,24 +0,24 @@ | ||
# Inline Static Files for express / connect / nodejs | ||
# Inline Static Files for your template | ||
## Why this? | ||
Add compressed inline css and scripts to your html, but write them as seperated files. | ||
1. Add compressed inline css and scripts to your html, but write them as seperated files. | ||
2. Access template's variables from a JS file. | ||
You don't have to worry about accessing the template's local variables. And you can even include a `.less` file. | ||
You may also like to have a loot at [autostatic](https://github.com/ktmud/autostatic). | ||
For concat and serve external css/jss, go have a look at [autostatic](https://github.com/ktmud/autostatic). | ||
## Usage: | ||
```javascript | ||
var istatic = require('istatic'); | ||
va app = express.createServer(); | ||
var istatic = require('istatic') | ||
va app = express.createServer() | ||
app.helpers({ | ||
app.locals({ | ||
istatic: istatic.serve({ compress: false }) | ||
}); | ||
}) | ||
``` | ||
The parameter passed to `istatic.serve` is an options object, which is optional. | ||
Available options are: | ||
Available options for `istatic.server([options])` are: | ||
@@ -40,3 +40,4 @@ <table> | ||
<th>ttl</th> | ||
<td>By default, the contents of your static files are cached in memory forever, until the process dies. You can set the <code>ttl</code> to a number of seconds, so the cache will be cleared every that much of time. | ||
<td>By default, the contents of your static files are cached in memory forever, until the process dies. | ||
You can set the <code>ttl</code> to a number of seconds, then the cache will be cleared every that much of time. | ||
</td> | ||
@@ -48,3 +49,3 @@ <td> | ||
<tr> | ||
<th>charset </th> | ||
<th>charset</th> | ||
<td>The charset of your static files.</td> | ||
@@ -56,5 +57,12 @@ <td> | ||
<tr> | ||
<th>compress </th> | ||
<th>compress</th> | ||
<td>Whether to compress the included contents.</td> | ||
<td> | ||
false | ||
</td> | ||
</tr> | ||
<tr> | ||
<th>cache</th> | ||
<td>Whether to cache file contents.</td> | ||
<td> | ||
true | ||
@@ -65,10 +73,13 @@ </td> | ||
<th>debug</th> | ||
<td>When set to true, will output the absolute path of included file.</td> | ||
<td> | ||
false || <code>process.env.DEBUG</code> | ||
When set to true, will output the absolute path of included file. | ||
And `compress` & `cache` will all be set to `false`. | ||
</td> | ||
<td> | ||
<code>process.env.DEBUG</code> | ||
</td> | ||
</tr> | ||
<tr> | ||
<th>js</th> | ||
<td>The options object for compressing a js file. It will be passed to <a href="https://github.com/mishoo/UglifyJS">UglifyJS</a>. </td> | ||
<td>Options passed to <a href="https://github.com/mishoo/UglifyJS">UglifyJS</a>, for compressing JS files.</td> | ||
<td> | ||
@@ -80,3 +91,3 @@ undefined | ||
<th>css</th> | ||
<td>The options object for compressing a css file. It will be passed to <a href="https://github.com/fmarcia/UglifyCSS">UglifyCSS</a></td> | ||
<td>Options passed to <a href="https://www.npmjs.org/package/clean-css">clean-css</a></td> | ||
<td> | ||
@@ -88,4 +99,6 @@ undefined | ||
For css and js options, you can define an `js.filter` or `css.filter`, to do some filtering(like remove `console.log()`) before compressing. | ||
For css and js options, you can also define a `js.filter` or `css.filter`, | ||
to do some extra filtering (like remove `console.log()`) **before** compressing. | ||
eg. | ||
@@ -97,3 +110,3 @@ | ||
filter: function(str) { | ||
return str.replace(/console.log(.+?)/, ''); | ||
return str.replace(/console.log(.+?)/, '') | ||
} | ||
@@ -108,34 +121,28 @@ } | ||
#{istatic(filename, [options])} | ||
```jade | ||
html | ||
title Sweet Page. | ||
head | ||
style. | ||
#{istatic(filename)} | ||
``` | ||
`filename` is the path of your static file. If it begins with a '/', the real path will be `process.cwd() + filename`. Otherwise, the file will be looked up from the root of your inline static files, as you configured before. | ||
`filename` is the path of your static file. | ||
You can set available options above, except for `root` and `ttl`. A `fresh` option is available for you to set this `istatic` call always read from file directly. | ||
**Be careful**, since `jade` can not correctly parse curly braces inside a couple of curly braces, don't write: | ||
script | ||
#{istatic('js/my.js', { showPath: (DEBUG ? true : false) })} | ||
Write like this instead: | ||
istatic_opt = { showPath: (DEBUG ? true : false) } | ||
script | ||
#{istatic('js/my.js', istatic_opt)} | ||
And it's definitely easier to read and maintain, too. | ||
## Templates' Local Variables: | ||
Just get in touch with them in the form you already very familiar with: | ||
Access template's render context (`locals`) inside your JS file, | ||
in the form you already very familiar with: | ||
#{data.title} | ||
**Attention:** no matter what templating language you are using, you must always use this syntax in your static files. | ||
And don't put `{}` inside the curly braces. This is for performance consideration. | ||
You can even excecute a local funtion just like what you will do in html templates: | ||
You can even excecute a local funtion just as what you will do in the template: | ||
#{usr.getId('haha...')} | ||
**Attention:** | ||
no matter what templating language you are using, you must always use this syntax in your static files. | ||
And don't put `{}` inside the curly braces. This is for performance consideration. | ||
<hr> | ||
@@ -145,30 +152,22 @@ | ||
**NOTE:** These APIs are not for templates. | ||
_These APIs are not for templates._ | ||
### istatic(filename, [options]) | ||
### istatic.serve([options]) | ||
Return the inlined string of some file. | ||
Return a function of `istatic(filename, [options])`, for reading files. | ||
Everytime you call `istatic` directly, it the `options` is given, these options will be saved as default options for any other later `istatic` or `istatic.serve` calls. | ||
The function is typically used as a template helper, the signature is: | ||
But when you call `istatic(filename, options)` from a template, the options **will not** be saved as default options. | ||
#### istatic(filename) | ||
APIs listed below are not suitable for an inside template call. | ||
Return the string content of given file. If `filename` begins with a `'/'`, the real path will be `process.cwd() + filename`. | ||
Otherwise, the file will be looked up from the `options.root`, as you configured in `istatic.serve(options)`. | ||
### istatic.serve([options]) | ||
To return a function of `istatic(filename, [options])`, to read the file. This is typically used as an express helper. | ||
### istatic.default(options) | ||
Specificly set default options for `istatic('filepath')`, which will be set implicitly at the first call of `istatic('filename', options)` or `istatic.serve(options)`. | ||
Explicitly set default options for any other `istatic.serve()` calls. | ||
The default options may have been set implicitly during the first call of `istatic.serve(options)`. | ||
### istatic.uglify.css(str, [options]) | ||
Uglify some css string. Options are passed to UglifyCSS. | ||
### istatic.uglify.js(str, [options]) | ||
Uglify some js string. Options are passed to UglifyJS. | ||
## Example | ||
@@ -179,20 +178,20 @@ | ||
```javascript | ||
var express = require('express'); | ||
var istatic = require('istatic'); | ||
var express = require('express') | ||
var istatic = require('istatic') | ||
var app1 = express.createServer(); | ||
var app2 = express.createServer(); | ||
var app1 = express.createServer() | ||
var app2 = express.createServer() | ||
app1.helpers({ | ||
app1.locals({ | ||
istatic: istatic.serve() | ||
}); | ||
app2.helpers({ | ||
}) | ||
app2.locals({ | ||
istatic: istatic.serve({ compress: false }) | ||
}); | ||
}) | ||
var compressed_css = istatic.uglify.css('.class1 { font: Arial; }'); | ||
var compressed_js = istatic.uglify.js('// some javascript codes..'); | ||
var compressed_css = istatic.uglify.css('.class1 { font: Arial }'); | ||
var compressed_js = istatic.uglify.js('// some javascript codes..') | ||
// will be compressed | ||
var str_pinyin_js = istatic('/utils/pinyin.js'); | ||
var str_pinyin_js = istatic('/utils/pinyin.js') | ||
@@ -202,4 +201,4 @@ app1.get('/example', function(req, res, next) { | ||
user: req.user | ||
}); | ||
}); | ||
}) | ||
}) | ||
``` | ||
@@ -218,3 +217,3 @@ | ||
var user = "#{user}" | ||
user && $.post('/log', { user: user }); | ||
user && $.post('/log', { user: user }) | ||
``` | ||
@@ -226,3 +225,3 @@ | ||
Copyright (c) 2012 Jesse Yang <jyyjcc@gmail.com> | ||
Copyright (c) 2012 Jesse Yang | ||
@@ -229,0 +228,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
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
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
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
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
11182
132
220
2
+ Addedbasiccache@^0.0.5
+ Addedclean-css@^2.1.8
+ Addeddebug@>= 0.7.0
+ Addedalign-text@0.1.4(transitive)
+ Addedbasiccache@0.0.5(transitive)
+ Addedcamelcase@1.2.1(transitive)
+ Addedcenter-align@0.1.3(transitive)
+ Addedclean-css@2.2.23(transitive)
+ Addedcliui@2.1.0(transitive)
+ Addedcommander@2.2.0(transitive)
+ Addeddecamelize@1.2.0(transitive)
+ Addedis-buffer@1.1.6(transitive)
+ Addedkind-of@3.2.2(transitive)
+ Addedlazy-cache@1.0.4(transitive)
+ Addedlongest@1.0.1(transitive)
+ Addedrepeat-string@1.6.1(transitive)
+ Addedright-align@0.1.3(transitive)
+ Addedsource-map@0.5.7(transitive)
+ Addeduglify-js@2.8.29(transitive)
+ Addeduglify-to-browserify@1.0.2(transitive)
+ Addedwindow-size@0.1.0(transitive)
+ Addedwordwrap@0.0.2(transitive)
+ Addedyargs@3.10.0(transitive)
- Removedless@>= 1.0
- Removedstylus@>= 0.1
- Removeduglifycss@>= 0.0.5
- Removed@adobe/css-tools@4.3.3(transitive)
- Removed@isaacs/cliui@8.0.2(transitive)
- Removed@pkgjs/parseargs@0.11.0(transitive)
- Removedansi-regex@5.0.16.1.0(transitive)
- Removedansi-styles@4.3.06.2.1(transitive)
- Removedbalanced-match@1.0.2(transitive)
- Removedbrace-expansion@2.0.1(transitive)
- Removedcolor-convert@2.0.1(transitive)
- Removedcolor-name@1.1.4(transitive)
- Removedcopy-anything@2.0.6(transitive)
- Removedcross-spawn@7.0.6(transitive)
- Removedeastasianwidth@0.2.0(transitive)
- Removedemoji-regex@8.0.09.2.2(transitive)
- Removederrno@0.1.8(transitive)
- Removedforeground-child@3.3.0(transitive)
- Removedglob@10.4.5(transitive)
- Removedgraceful-fs@4.2.11(transitive)
- Removediconv-lite@0.6.3(transitive)
- Removedimage-size@0.5.5(transitive)
- Removedis-fullwidth-code-point@3.0.0(transitive)
- Removedis-what@3.14.1(transitive)
- Removedisexe@2.0.0(transitive)
- Removedjackspeak@3.4.3(transitive)
- Removedless@4.2.2(transitive)
- Removedlru-cache@10.4.3(transitive)
- Removedmake-dir@2.1.0(transitive)
- Removedmime@1.6.0(transitive)
- Removedminimatch@9.0.5(transitive)
- Removedminipass@7.1.2(transitive)
- Removedneedle@3.3.1(transitive)
- Removedpackage-json-from-dist@1.0.1(transitive)
- Removedparse-node-version@1.0.1(transitive)
- Removedpath-key@3.1.1(transitive)
- Removedpath-scurry@1.11.1(transitive)
- Removedpify@4.0.1(transitive)
- Removedprr@1.0.1(transitive)
- Removedsafer-buffer@2.1.2(transitive)
- Removedsax@1.4.1(transitive)
- Removedsemver@5.7.2(transitive)
- Removedshebang-command@2.0.0(transitive)
- Removedshebang-regex@3.0.0(transitive)
- Removedsignal-exit@4.1.0(transitive)
- Removedsource-map@0.6.10.7.4(transitive)
- Removedstring-width@4.2.35.1.2(transitive)
- Removedstrip-ansi@6.0.17.1.0(transitive)
- Removedstylus@0.64.0(transitive)
- Removedtslib@2.8.1(transitive)
- Removeduglify-js@3.19.3(transitive)
- Removeduglifycss@0.0.29(transitive)
- Removedwhich@2.0.2(transitive)
- Removedwrap-ansi@7.0.08.1.0(transitive)
Updateduglify-js@^2.4.13