@wenbo/fis3-postpackager-loader
Version:
241 lines (189 loc) • 7.36 kB
JavaScript
/**
* 将零散的js文件打包合成一个新文件。
*/
var common = require('./common.js');
var SourceMap = require('source-map');
var _ = fis.util;
var rSourceMap = /(?:\/\/\#\s*sourceMappingURL[^\r\n\'\"]*|\/\*\#\s*sourceMappingURL[^\r\n\'\"]*\*\/)(?:\r?\n|$)/ig;
module.exports = function(file, resource, ret, opts,index) {
var root = fis.project.getProjectPath();
var ignoreList;
var fileIndex;
resource.calculate();
// 把异步池子中 js 放到同步的池子中
/*if (opts.includeAsyncs) {
resource.asyncs.forEach(function(item) {
item.async = false;
item.id && (resource.loaded[item.id] = false);
resource[item.type === 'js' ? 'js' : 'css'].push(item);
});
resource.asyncs = [];
}*/
// normalize ignore.
if (opts.ignore) {
ignoreList = opts.ignore;
if (typeof ignoreList === 'string') {
ignoreList = ignoreList.split(/\s*,\s*/);
} else if (!Array.isArray(ignoreList)) {
ignoreList = [ignoreList];
}
ignoreList = ignoreList.map(function(item) {
return typeof item === 'string' ? _.glob(item) : item;
});
}
function isIgnored(item) {
if (!ignoreList || !ignoreList.length) {
return false;
}
var fileItem = null;
if (item.id) {
fileItem = resource.getFileById(item.id)
} else {
fileItem = resource.getFileByUrl(item.uri);
}
var filepath = fileItem ? file.subpath : item.uri;
var hitted = false;
ignoreList.every(function(reg) {
if (reg.test(filepath)) {
hitted = true;
return false;
}
return true;
});
return hitted;
}
function pack(list, fileTpl, sourceMap) {
fileIndex = index;
var i = 0;
var unpacked = [];
var item;
while (i < list.length) {
item = list[i];
if (item.id && !(item.pkg && !item.allInOne) && (!opts.ignore || !isIgnored(item))/**/) {
unpacked.push(item);
list.splice(i, 1);
// todo 可能还要删除其他东西。
} else {
//就算只有1个文件也要打包
if (unpacked.length > 0) {
_pack();
}/* else if (unpacked.length) {
list.splice(i, 0, unpacked[0]);
}*/
unpacked = [];
i++;
}
}
//就算只有1个文件也要打包
if (unpacked.length > 0) {
_pack();
} /*else if (unpacked.length) {
list.push(unpacked.pop());
}*/
function _pack() {
var filepath = getFilepath(fileTpl, file);
if (fileIndex>1) {
filepath = filepath.replace(/\.([^\.]+)$/i, function(ext) {
return '_' + fileIndex + ext;
});
}
var pkg = fis.file(root, filepath);
var has = [];
var sourceNode;
if (sourceMap) {
sourceNode = new SourceMap.SourceNode();
}
var content = '';
unpacked.forEach(function(item) {
var file = ret.idmapping[item.id];
var prefix = (!(opts.useTrack))?'':(file.isJsLike ? '/*!' + file.id + '*/\n;' : '/*!' + file.id + '*/\n');
var map = file.map = file.map || {};
map.aioPkg = pkg.getId();
has.push(file.getId());
// 派送事件
var message = {
file: file,
content: file.getContent(),
pkg: pkg
};
fis.emit('pack:file', message);
message.content = message.content.replace(rSourceMap, '');
if (sourceNode) {
sourceNode.add(prefix);
var mapFile = getMapFile(file);
if (mapFile) {
var json = JSON.parse(mapFile.getContent());
var smc = new SourceMap.SourceMapConsumer(json);
sourceNode.add(SourceMap.SourceNode.fromStringWithSourceMap(message.content, smc));
// mapFile.release = false;
} else {
sourceNode.add(contents2sourceNodes(message.content, file.subpath));
}
sourceNode.add('\n');
}
content += prefix + message.content + '\n';
});
if (sourceMap) {
var mapping = fis.file.wrap(pkg.dirname + '/' + pkg.filename + pkg.rExt + '.map');
var code_map = sourceNode.toStringWithSourceMap({
file: pkg.subpath
});
var generater = SourceMap.SourceMapGenerator.fromSourceMap(new SourceMap.SourceMapConsumer(code_map.map.toJSON()));
mapping.setContent(generater.toString());
ret.pkg[mapping.subpath] = mapping;
content += pkg.isCssLike ? ('/*# sourceMappingURL=' + mapping.getUrl() + '*/') : ('//# sourceMappingURL=' + mapping.getUrl());
}
pkg.setContent(content);
list.splice(i, 0, {
id: pkg.id,
uri: pkg.getUrl(),
attrs: unpacked[0].attrs
});
resource._map['pkg'][pkg.getId()] = {
type: 'js',
uri: pkg.getUrl(),
has: has
};
ret.pkg[pkg.subpath] = pkg;
fileIndex++;
}
function getMapFile(file) {
// 同时修改 sourcemap 文件内容。
var derived = file.derived;
if (!derived || !derived.length) {
derived = file.extras && file.extras.derived;
}
if (derived && derived[0] && derived[0].rExt === '.map') {
return derived[0];
}
return null;
}
//定制化目录处理, 可以传函数进来
function getFilepath(fun, file) {
if(typeof(fun) == "function"){
return fun(file);
}
return common.tokenizePath(fun, {
filepath: file.subpath,
filename: file.filename,
hash: file.getHash()
});
}
function contents2sourceNodes(content, filename) {
var chunks = [];
var lineIndex = 0;
content.replace(/.*(\r\n|\n|\r|$)/g, function(line) {
lineIndex++;
chunks.push(new SourceMap.SourceNode(lineIndex, 0, filename, line));
});
var node = new SourceMap.SourceNode(1, 0, filename, chunks);
node.setSourceContent(filename, content);
return node;
}
return fileIndex
}
const jsPackIndex = pack(resource.js, opts.js || 'pkg/${filepath}_aio.js', opts.sourceMap);
const cssPackIndex = pack(resource.css, opts.css || 'pkg/${filepath}_aio.css', opts.sourceMap);
// console.log(jsPackIndex,cssPackIndex);
return Math.max(jsPackIndex,cssPackIndex);
};