records, typo

This commit is contained in:
Tobias Koppers 2013-05-31 12:22:40 +02:00
parent df98aca36e
commit f84f000149
9 changed files with 221 additions and 59 deletions

View File

@ -4,7 +4,7 @@
# Introduction
webpack is a bundler for modules. The main purpose is to bundle javascript files for useage in browser.
webpack is a bundler for modules. The main purpose is to bundle javascript files for usage in browser.
**TL;DR**

View File

@ -31,6 +31,12 @@ module.exports = function(optimist) {
.string("output-library-target").describe("output-library-target")
.string("records-input-path").describe("records-input-path")
.string("records-output-path").describe("records-output-path")
.string("records-path").describe("records-path")
.string("target").describe("target")
.boolean("cache").describe("cache")

View File

@ -184,6 +184,18 @@ module.exports = function(optimist, argv, convertOptions) {
options.output.libraryTarget = value;
});
ifArg("records-input-path", function(value) {
options.recordsInputPath = path.resolve(value);
});
ifArg("records-output-path", function(value) {
options.recordsOutputPath = path.resolve(value);
});
ifArg("records-path", function(value) {
options.recordsPath = path.resolve(value);
});
ifArg("target", function(value) {
options.target = value;
});

View File

@ -35,6 +35,9 @@ function Compilation(compiler) {
this.modules = [];
this._modules = {};
this.cache = null;
this.records = null;
this.nextFreeModuleId = 1;
this.nextFreeChunkId = 1;
this.assets = {};
this.errors = [];
this.warnings = [];
@ -347,21 +350,32 @@ Compilation.prototype.seal = function seal(callback) {
this.processDependenciesBlockForChunk(module, chunk);
}, this);
this.applyPlugins("optimize");
this.applyPlugins("optimize-modules", this.modules);
this.applyPlugins("after-optimize-modules", this.modules);
this.applyPlugins("optimize-chunks", this.chunks);
this.applyPlugins("after-optimize-chunks", this.chunks);
this.applyPlugins("revive-modules", this.modules, this.records);
this.applyPlugins("optimize-module-order", this.modules);
this.applyModuleIds();
this.applyPlugins("optimize-chunk-order", this.chunks);
this.applyChunkIds();
this.applyPlugins("optimize-module-ids", this.modules);
this.applyPlugins("after-optimize-module-ids", this.modules);
this.applyPlugins("record-modules", this.modules, this.records);
this.applyPlugins("revive-chunks", this.chunks, this.records);
this.applyPlugins("optimize-chunk-order", this.chunks);
this.applyChunkIds();
this.applyPlugins("optimize-chunk-ids", this.chunks);
this.applyPlugins("after-optimize-chunk-ids", this.chunks);
this.applyPlugins("record-chunks", this.chunks, this.records);
this.sortItems();
this.createChunkAssets();
this.summarizeDependencies();
this.applyPlugins("record", this, this.records);
this.applyPluginsAsync("optimize-chunk-assets", this.chunks, function(err) {
if(err) return callback(err);
this.applyPlugins("after-optimize-chunk-assets", this.chunks);
@ -418,62 +432,22 @@ Compilation.prototype.processDependenciesBlockForChunk = function processDepende
};
Compilation.prototype.applyModuleIds = function applyModuleIds() {
var i = this.cache && this.cache["nextModuleId"] || 1;
var usedIds = {0:true};
this.modules.forEach(function(module) {
if(module.id === null) {
if(module.lastId > 0) {
if(!usedIds[module.lastId]) {
usedIds[module.lastId] = true;
module.id = module.lastId;
return;
}
}
module.id = i++;
module.id = this.nextFreeModuleId++;
}
});
if(this.cache) this.cache["nextModuleId"] = i;
}, this);
};
Compilation.prototype.applyChunkIds = function applyChunkIds() {
var i = this.cache && this.cache["nextChunkId"] || 1;
var usedIds = {0:true};
if(this.cache) {
if(!this.cache.chunks)
this.cache.chunks = {};
var keys = Object.keys(this.cache.chunks).slice();
var cacheChunks = this.cache.chunks;
this.cache.chunks = {};
}
this.chunks.forEach(function(chunk) {
if(chunk.id === null) {
if(this.cache) {
for(var j = 0; j < keys.length; j++) {
var chunkId = keys[j];
var cacheChunk = cacheChunks[chunkId];
if(usedIds[cacheChunk.id]) continue;
if(chunk.blocks.some(function(block) {
return cacheChunk.blocks.indexOf(block) >= 0;
})) {
usedIds[cacheChunk.id] = true;
chunk.id = cacheChunk.id;
break;
}
}
}
if(chunk.id === null)
chunk.id = i++;
if(this.cache) {
this.cache.chunks["c"+chunk.id] = {
id: chunk.id,
blocks: chunk.blocks
};
}
chunk.id = this.nextFreeChunkId++;
}
if(!chunk.ids)
chunk.ids = [chunk.id];
}, this);
if(this.cache) this.cache["nextChunkId"] = i;
};
Compilation.prototype.sortItems = function sortItems() {

View File

@ -23,14 +23,18 @@ var RequireEnsureItemDependency = require("./dependencies/RequireEnsureItemDepen
function Watching(compiler, handler, watchDelay) {
this.startTime = null;
this.running = false;
this.invalid = false;
this.error = null;
this.stats = null;
this.handler = handler;
this.watchDelay = watchDelay;
this.compiler = compiler;
this._go();
this.running = true;
this.compiler.readRecords(function(err) {
if(err) return this._done(err);
this._go();
}.bind(this));
}
Watching.prototype._go = function() {
@ -44,8 +48,13 @@ Watching.prototype._go = function() {
this.compiler.emitAssets(compilation, function(err) {
if(err) return this._done(err);
if(this.invalid) return this._done();
return this._done(null, compilation);
this.compiler.emitRecords(function(err) {
if(err) return this._done(err);
return this._done(null, compilation);
}.bind(this));
}.bind(this));
}.bind(this));
}.bind(this));
@ -101,6 +110,10 @@ function Compiler() {
this.inputFileSystem = null;
this.separateExecutor = null;
this.recordsInputPath = null;
this.recordsOutputPath = null;
this.records = {};
this.fileTimestamps = {};
this.contextTimestamps = {};
@ -130,17 +143,25 @@ Compiler.prototype.run = function(callback) {
this.applyPluginsAsync("run", this, function(err) {
if(err) return callback(err);
this.compile(function(err, compilation) {
this.readRecords(function(err) {
if(err) return callback(err);
this.emitAssets(compilation, function(err) {
this.compile(function(err, compilation) {
if(err) return callback(err);
var stats = compilation.getStats();
stats.startTime = startTime;
stats.endTime = new Date().getTime();
this.applyPlugins("done", stats);
return callback(null, stats);
this.emitAssets(compilation, function(err) {
if(err) return callback(err);
this.emitRecords(function(err) {
if(err) return callback(err);
var stats = compilation.getStats();
stats.startTime = startTime;
stats.endTime = new Date().getTime();
this.applyPlugins("done", stats);
return callback(null, stats);
}.bind(this));
}.bind(this));
}.bind(this));
}.bind(this));
}.bind(this));
@ -210,6 +231,36 @@ Compiler.prototype.emitAssets = function(compilation, callback) {
};
Compiler.prototype.emitRecords = function emitRecords(callback) {
if(!this.recordsOutputPath) return callback();
this.outputFileSystem.writeFile(this.recordsOutputPath, JSON.stringify(this.records, undefined, 2), callback);
};
Compiler.prototype.readRecords = function readRecords(callback) {
if(!this.recordsInputPath) {
this.records = {};
return callback();
}
this.inputFileSystem.stat(this.recordsInputPath, function(err) {
// It doesn't exist
// We can ignore this.
if(err) return callback();
this.inputFileSystem.readFile(this.recordsInputPath, function(err, content) {
if(err) return callback(err);
try {
this.records = JSON.parse(content);
} catch(e) {
e.message = "Cannot parse records: " + e.message;
return callback(e);
}
return callback();
}.bind(this));
}.bind(this));
};
Compiler.prototype.createChildCompiler = function(compilation, compilerName, outputOptions) {
var childCompiler = new Compiler();
for(var name in this._plugins) {
@ -248,6 +299,7 @@ Compiler.prototype.newCompilation = function(params) {
compilation.fileTimestamps = this.fileTimestamps;
compilation.contextTimestamps = this.contextTimestamps;
compilation.name = this.name;
compilation.records = this.records;
this.applyPlugins("compilation", compilation, params);
return compilation;
};

View File

@ -13,6 +13,7 @@ module.exports = DependenciesBlock;
DependenciesBlock.prototype.addBlock = function(block) {
this.blocks.push(block);
block.parent = this;
}
DependenciesBlock.prototype.addVariable = function(name, expression, dependencies) {

113
lib/RecordIdsPlugin.js Normal file
View File

@ -0,0 +1,113 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
function RecordIdsPlugin() {
}
module.exports = RecordIdsPlugin;
RecordIdsPlugin.prototype.apply = function(compiler) {
compiler.plugin("compilation", function(compilation) {
compilation.plugin("record-modules", function(modules, records) {
records.nextFreeModuleId = compilation.nextFreeModuleId;
if(!records.modules) records.modules = {};
if(!records.modules.byIdentifier) records.modules.byIdentifier = {};
modules.forEach(function(module) {
var identifier = module.identifier();
records.modules.byIdentifier[identifier] = module.id;
});
});
compilation.plugin("revive-modules", function(modules, records) {
if(records.nextFreeModuleId)
compilation.nextFreeModuleId = records.nextFreeModuleId;
if(!records.modules || !records.modules.byIdentifier) return;
var usedIds = {0: true};
modules.forEach(function(module) {
if(module.id !== null) return;
var identifier = module.identifier();
var id = records.modules.byIdentifier[identifier];
if(usedIds[id]) return;
usedIds[id] = true;
module.id = id;
});
});
function getDepBlockIdent(block) {
var ident = [];
while(block.parent) {
var p = block.parent;
var idx = p.blocks.indexOf(block);
var l = p.blocks.length - 1;
ident.unshift(idx + "/" + l);
block = block.parent;
}
if(!block.identifier) return null;
ident.unshift(block.identifier());
return ident.join(":");
}
compilation.plugin("record-chunks", function(chunks, records) {
records.nextFreeChunkId = compilation.nextFreeChunkId;
if(!records.chunks) records.chunks = {};
if(!records.chunks.byName) records.chunks.byName = {};
if(!records.chunks.byBlocks) records.chunks.byBlocks = {};
chunks.forEach(function(chunk) {
var name = chunk.name;
var blockIdents = chunk.blocks.map(getDepBlockIdent).filter(Boolean);
if(name) records.chunks.byName[name] = chunk.id;
blockIdents.forEach(function(blockIdent) {
records.chunks.byBlocks[blockIdent] = chunk.id;
});
});
});
compilation.plugin("revive-chunks", function(chunks, records) {
if(records.nextFreeChunkId)
compilation.nextFreeChunkId = records.nextFreeChunkId;
if(!records.chunks) return;
var usedIds = {0: true};
if(records.chunks.byName) {
chunks.forEach(function(chunk) {
if(chunk.id !== null) return;
if(!chunk.name) return;
var id = records.chunks.byName[chunk.name];
if(usedIds[id]) return;
usedIds[id] = true;
chunk.id = id;
});
}
if(records.chunks.byBlocks) {
var argumentedChunks = chunks.filter(function(chunk) {
return chunk.id === null
}).map(function(chunk) {
return {
chunk: chunk,
blockIdents: chunk.blocks.map(getDepBlockIdent).filter(Boolean)
}
}).filter(function(arg) {
return arg.blockIdents.length > 0;
});
var blockIdentsCount = {};
argumentedChunks.forEach(function(arg, idx) {
arg.blockIdents.forEach(function(blockIdent) {
var id = records.chunks.byBlocks[blockIdent]
if(!id) return;
var accessor = id + ":" + idx;
blockIdentsCount[accessor] = (blockIdentsCount[accessor] || 0) + 1;
});
});
blockIdentsCount = Object.keys(blockIdentsCount).map(function(accessor) {
return [blockIdentsCount[accessor]].concat(accessor.split(":").map(Number));
}).sort(function(a, b) {
return b[0] - a[0];
})
blockIdentsCount.forEach(function(arg) {
var id = arg[1];
if(usedIds[id]) return;
var idx = arg[2];
var chunk = argumentedChunks[idx].chunk;
if(chunk.id !== null) return;
usedIds[id] = true;
chunk.id = id;
});
}
});
});
};

View File

@ -16,8 +16,7 @@ var PrefetchPlugin = require("./PrefetchPlugin");
var SingleEntryPlugin = require("./SingleEntryPlugin");
var MultiEntryPlugin = require("./MultiEntryPlugin");
var CachePlugin = require("./CachePlugin");
var UglifyJsPlugin = require("./optimize/UglifyJsPlugin");
var RecordIdsPlugin = require("./RecordIdsPlugin");
var APIPlugin = require("./APIPlugin");
var ConstPlugin = require("./ConstPlugin");
@ -35,6 +34,7 @@ var RequireContextPlugin = require("./dependencies/RequireContextPlugin");
var RequireEnsurePlugin = require("./dependencies/RequireEnsurePlugin");
var RequireIncludePlugin = require("./dependencies/RequireIncludePlugin");
var UglifyJsPlugin = require("./optimize/UglifyJsPlugin");
var OccurenceOrderPlugin = require("./optimize/OccurenceOrderPlugin");
var LimitChunkCountPlugin = require("./optimize/LimitChunkCountPlugin");
var MinChunkSizePlugin = require("./optimize/MinChunkSizePlugin");
@ -66,6 +66,8 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
compiler.apply.apply(compiler, options.plugins);
}
compiler.outputPath = options.output.path;
compiler.recordsInputPath = options.recordsInputPath || options.recordsPath;
compiler.recordsOutputPath = options.recordsOutputPath || options.recordsPath;
switch(options.target) {
case "web":
compiler.apply(
@ -138,6 +140,8 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
new FlagIncludedChunksPlugin()
);
compiler.apply(new RecordIdsPlugin());
if(options.optimize && options.optimize.occurenceOrder)
compiler.apply(new OccurenceOrderPlugin(options.optimize.occurenceOrderPreferEntry));

View File

@ -1,6 +1,6 @@
{
"name": "webpack",
"version": "0.10.0-beta17",
"version": "0.10.0-beta18",
"author": "Tobias Koppers @sokra",
"description": "Packs CommonJs/AMD/Labeled Modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jade, coffee, css, less, ... and your custom stuff.",
"dependencies": {