提交 27dae4d2 编写于 作者: A Alex Dima

Bundler: generate bundleInfo, remove duplicated TS boilerplate

上级 d3267ffd
......@@ -128,6 +128,7 @@ function toBundleStream(bundledFileHeader, bundles) {
* - resources (svg, etc.)
* - loaderConfig
* - header (basically the Copyright treatment)
* - bundleInfo (boolean - emit bundleInfo.json file)
* - out (out folder name)
*/
exports.optimizeTask = function(opts) {
......@@ -141,6 +142,7 @@ exports.optimizeTask = function(opts) {
return function() {
var bundlesStream = es.through(); // this stream will contain the bundled files
var resourcesStream = es.through(); // this stream will contain the resources
var bundleInfoStream = es.through(); // this stream will contain bundleInfo.json
bundle.bundle(entryPoints, loaderConfig, function(err, result) {
if (err) { return bundlesStream.emit('error', JSON.stringify(err)); }
......@@ -155,6 +157,16 @@ exports.optimizeTask = function(opts) {
filteredResources.push('!' + resource);
});
gulp.src(filteredResources, { base: 'out-build' }).pipe(resourcesStream);
var bundleInfoArray = [];
if (opts.bundleInfo) {
bundleInfoArray.push(new File({
path: 'bundleInfo.json',
base: '.',
contents: new Buffer(JSON.stringify(result.bundleData, null, '\t'))
}));
}
es.readArray(bundleInfoArray).pipe(bundleInfoStream);
});
var otherSourcesStream = es.through();
......@@ -175,7 +187,8 @@ exports.optimizeTask = function(opts) {
loader(bundledFileHeader),
bundlesStream,
otherSourcesStream,
resourcesStream
resourcesStream,
bundleInfoStream
);
return result
......
......@@ -23,11 +23,12 @@ function bundle(entryPoints, config, callback) {
loader.config(config);
loader(Object.keys(entryPointsMap), function () {
var modules = loader.getBuildInfo();
var resultFiles = emitEntryPoints(modules, entryPointsMap);
var partialResult = emitEntryPoints(modules, entryPointsMap);
var cssInlinedResources = loader('vs/css').getInlinedResources();
callback(null, {
files: resultFiles,
cssInlinedResources: cssInlinedResources
files: partialResult.files,
cssInlinedResources: cssInlinedResources,
bundleData: partialResult.bundleData
});
}, function (err) { return callback(err, null); });
}
......@@ -44,6 +45,10 @@ function emitEntryPoints(modules, entryPoints) {
var sortedModules = topologicalSort(modulesGraph);
var result = [];
var usedPlugins = {};
var bundleData = {
graph: modulesGraph,
bundles: {}
};
Object.keys(entryPoints).forEach(function (moduleToBundle) {
var info = entryPoints[moduleToBundle];
var rootNodes = [moduleToBundle].concat(info.include || []);
......@@ -58,6 +63,7 @@ function emitEntryPoints(modules, entryPoints) {
var includedModules = sortedModules.filter(function (module) {
return allDependencies[module];
});
bundleData.bundles[moduleToBundle] = includedModules;
var res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules);
result = result.concat(res.files);
for (var pluginName in res.usedPlugins) {
......@@ -79,7 +85,60 @@ function emitEntryPoints(modules, entryPoints) {
plugin.finishBuild(write);
}
});
return result;
return {
files: removeDuplicateTSBoilerplate(result),
bundleData: bundleData
};
}
function removeDuplicateTSBoilerplate(destFiles) {
// Taken from typescript compiler => emitFiles
var BOILERPLATE = [
{ start: /^var __extends/, end: /^};$/ },
{ start: /^var __assign/, end: /^};$/ },
{ start: /^var __decorate/, end: /^};$/ },
{ start: /^var __metadata/, end: /^};$/ },
{ start: /^var __param/, end: /^};$/ },
{ start: /^var __awaiter/, end: /^};$/ },
];
destFiles.forEach(function (destFile) {
var SEEN_BOILERPLATE = [];
destFile.sources.forEach(function (source) {
var lines = source.contents.split(/\r\n|\n|\r/);
var newLines = [];
var IS_REMOVING_BOILERPLATE = false, END_BOILERPLATE;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (IS_REMOVING_BOILERPLATE) {
newLines.push('');
if (END_BOILERPLATE.test(line)) {
IS_REMOVING_BOILERPLATE = false;
}
}
else {
for (var j = 0; j < BOILERPLATE.length; j++) {
var boilerplate = BOILERPLATE[j];
if (boilerplate.start.test(line)) {
if (SEEN_BOILERPLATE[j]) {
IS_REMOVING_BOILERPLATE = true;
END_BOILERPLATE = boilerplate.end;
}
else {
SEEN_BOILERPLATE[j] = true;
}
}
}
if (IS_REMOVING_BOILERPLATE) {
newLines.push('');
}
else {
newLines.push(line);
}
}
}
source.contents = newLines.join('\n');
});
});
return destFiles;
}
function emitEntryPoint(modulesMap, deps, entryPoint, includedModules) {
var mainResult = {
......
......@@ -70,9 +70,20 @@ export interface IConcatFile {
sources: IFile[];
}
export interface IBundleData {
graph: IGraph;
bundles: {[moduleId:string]:string[];};
}
export interface IBundleResult {
files: IConcatFile[];
cssInlinedResources: string[];
bundleData: IBundleData;
}
interface IPartialBundleResult {
files: IConcatFile[];
bundleData: IBundleData;
}
export interface ILoaderConfig {
......@@ -100,16 +111,17 @@ export function bundle(entryPoints:IEntryPoint[], config:ILoaderConfig, callback
loader(Object.keys(entryPointsMap), () => {
let modules = <IBuildModuleInfo[]>loader.getBuildInfo();
let resultFiles = emitEntryPoints(modules, entryPointsMap);
let partialResult = emitEntryPoints(modules, entryPointsMap);
let cssInlinedResources = loader('vs/css').getInlinedResources();
callback(null, {
files: resultFiles,
cssInlinedResources: cssInlinedResources
files: partialResult.files,
cssInlinedResources: cssInlinedResources,
bundleData: partialResult.bundleData
});
}, (err) => callback(err, null));
}
function emitEntryPoints(modules:IBuildModuleInfo[], entryPoints:IEntryPointMap): IConcatFile[] {
function emitEntryPoints(modules:IBuildModuleInfo[], entryPoints:IEntryPointMap): IPartialBundleResult {
let modulesMap: IBuildModuleInfoMap = {};
modules.forEach((m:IBuildModuleInfo) => {
modulesMap[m.id] = m;
......@@ -124,6 +136,10 @@ function emitEntryPoints(modules:IBuildModuleInfo[], entryPoints:IEntryPointMap)
let result: IConcatFile[] = [];
let usedPlugins: IPluginMap = {};
let bundleData:IBundleData = {
graph: modulesGraph,
bundles: {}
};
Object.keys(entryPoints).forEach((moduleToBundle:string) => {
let info = entryPoints[moduleToBundle];
......@@ -142,6 +158,8 @@ function emitEntryPoints(modules:IBuildModuleInfo[], entryPoints:IEntryPointMap)
return allDependencies[module];
});
bundleData.bundles[moduleToBundle] = includedModules;
let res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules);
result = result.concat(res.files);
......@@ -166,7 +184,61 @@ function emitEntryPoints(modules:IBuildModuleInfo[], entryPoints:IEntryPointMap)
}
});
return result;
return {
files: removeDuplicateTSBoilerplate(result),
bundleData: bundleData
};
}
function removeDuplicateTSBoilerplate(destFiles:IConcatFile[]):IConcatFile[] {
// Taken from typescript compiler => emitFiles
let BOILERPLATE = [
{ start: /^var __extends/, end: /^};$/ },
{ start: /^var __assign/, end: /^};$/ },
{ start: /^var __decorate/, end: /^};$/ },
{ start: /^var __metadata/, end: /^};$/ },
{ start: /^var __param/, end: /^};$/ },
{ start: /^var __awaiter/, end: /^};$/ },
];
destFiles.forEach((destFile) => {
let SEEN_BOILERPLATE = [];
destFile.sources.forEach((source) => {
let lines = source.contents.split(/\r\n|\n|\r/);
let newLines: string[] = [];
let IS_REMOVING_BOILERPLATE = false, END_BOILERPLATE: RegExp;
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
if (IS_REMOVING_BOILERPLATE) {
newLines.push('');
if (END_BOILERPLATE.test(line)) {
IS_REMOVING_BOILERPLATE = false;
}
} else {
for (let j = 0; j < BOILERPLATE.length; j++) {
let boilerplate = BOILERPLATE[j];
if (boilerplate.start.test(line)) {
if (SEEN_BOILERPLATE[j]) {
IS_REMOVING_BOILERPLATE = true;
END_BOILERPLATE = boilerplate.end;
} else {
SEEN_BOILERPLATE[j] = true;
}
}
}
if (IS_REMOVING_BOILERPLATE) {
newLines.push('');
} else {
newLines.push(line);
}
}
}
source.contents = newLines.join('\n');
});
});
return destFiles;
}
interface IPluginMap {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册