serve-spm
Version:
SPM middleware for debug.
126 lines (101 loc) • 2.96 kB
JavaScript
;
var extname = require('path').extname;
var readFile = require('fs').readFileSync;
var exists = require('fs').existsSync;
var urlparse = require('url').parse;
var File = require('vinyl');
var debug = require('debug')('serve-spm:parse');
var rules = require('./rules');
var stat = require('fs').statSync;
/*
Match local file from request url
url: request url
opt
- pkg: a father package
- rules: custom rules
*/
module.exports = function parse(url, opt) {
debug('find file of url %s in %s', url, opt.rootPkg.dest);
var myRules = Array.isArray(opt.rules) ? opt.rules.concat(rules) : rules;
url = urlparse(url);
/*
return a gulp File(vinyl) with some custom properties
- wrap: whether code should be wrapped by define
- url: request url Object parsed by `url`
- pkg: a father package
*/
var file = findFile(url, opt.pkg, opt.rootPkg, myRules);
if (!file) return;
// wrap define by default, except for
// 1. has ?nowrap in url
// 2. specified in rules
if (hasNoWrap(url)) {
file.wrap = false;
} else if (typeof file.wrap !== 'boolean') {
file.wrap = true;
}
file.url = url;
file.pkg = opt.pkg;
return file;
};
function hasNoWrap(url) {
var search = url.search;
return search && search.indexOf('nowrap') > -1;
}
function findFile(url, pkg, rootPkg, rules) {
for (var i in rules) {
debug('find file from rule[%s]', i);
var rule = rules[i];
var ret = rule(url, pkg, rootPkg) || {};
debug('rule result path: %s, wrap: %s', ret.path, ret.wrap);
// ignore when no result or result is invalid
if (!ret.path) {
continue;
}
// check filepath exists
var filepath = testFile(ret.path);
// check directory
if (filepath && stat(filepath).isDirectory()) {
return;
}
if (filepath) {
debug('matched %s -> %s on rule[%s]', url.pathname, filepath, i);
var file = new File({
base: pkg.dest,
path: filepath,
contents: readFile(filepath)
});
file.wrap = ret.wrap;
return file;
}
}
}
function testFile(filepath) {
var file;
// a.css.js$ -> a.css
// a.tpl.js$ -> a.tpl
// ...
if (/\.[a-z]+\.js$/.test(filepath)) {
file = filepath.slice(0, -3);
if (exists(file)) return file;
}
// a.js$ -> a.coffee
if (extname(filepath) === '.js') {
file = filepath.replace(/\.js$/, '.coffee');
if (exists(file)) return file;
}
// a.css$ -> a.less
// a.css$ -> a.scss, a.sass
// a.css$ -> a.styl
if (extname(filepath) === '.css') {
file = filepath.replace(/\.css$/, '.less');
if (exists(file)) return file;
// file = filepath.replace(/\.css$/, '.scss');
// if (exists(file)) return file;
// file = filepath.replace(/\.css$/, '.sass');
// if (exists(file)) return file;
// file = filepath.replace(/\.css$/, '.styl');
// if (exists(file)) return file;
}
if (exists(filepath)) return filepath;
}