Merge pull request #10454 from zodern/write-performance

This commit is contained in:
Ben Newman
2019-02-28 14:52:05 -05:00
2 changed files with 68 additions and 25 deletions

View File

@@ -232,6 +232,39 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
return partsOut.join(files.pathSep);
}
// Checks if a file with the same path and hash was written by
// the previous builder. If it was, it adds it to the cache and makes
// sure the parent directories exist and are part of the cache.
//
// Returns true if the file was already written
usePreviousWrite(relPath, hash, sanitize) {
relPath = this._normalizeFilePath(relPath, sanitize);
if (this.previousWrittenHashes[relPath] === hash) {
this._ensureDirectory(files.pathDirname(relPath));
this.writtenHashes[relPath] = hash;
this.usedAsFile[relPath] = true;
return true;
}
return false;
}
_normalizeFilePath(relPath, sanitize) {
// Ensure no trailing slash
if (relPath.slice(-1) === files.pathSep) {
relPath = relPath.slice(0, -1);
}
// In sanitize mode, ensure path does not contain segments like
// '..', does not contain forbidden characters, and is unique.
if (sanitize) {
relPath = this._sanitize(relPath);
}
return relPath;
}
// Write either a buffer or the contents of a file to `relPath` (a
// path to a file relative to the bundle root), creating it (and any
// enclosing directories) if it doesn't exist yet. Exactly one of
@@ -254,16 +287,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
//
// If `file` is used then it will be added to the builder's WatchSet.
write(relPath, {data, file, hash, sanitize, executable, symlink}) {
// Ensure no trailing slash
if (relPath.slice(-1) === files.pathSep) {
relPath = relPath.slice(0, -1);
}
// In sanitize mode, ensure path does not contain segments like
// '..', does not contain forbidden characters, and is unique.
if (sanitize) {
relPath = this._sanitize(relPath);
}
relPath = this._normalizeFilePath(relPath, sanitize);
let getData = null;
if (data) {
@@ -291,7 +315,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
// Write is called multiple times for assets when they have multiple urls for the same file
if (this.previousWrittenHashes[relPath] !== hash && this.writtenHashes[relPath] !== hash) {
// Builder is used to create build products, which should be read-only;
// users shouldn't be manually editing automatically generated files and
// expecting the results to "stick".

View File

@@ -176,6 +176,9 @@ import { PackageRegistry } from "../../packages/meteor/define-package.js";
const SOURCE_URL_PREFIX = "meteor://\u{1f4bb}app";
const MINIFY_PLAIN_FUNCTION = Buffer.from('function(', 'utf8');
const MINIFY_RENAMED_FUNCTION = Buffer.from('function __minifyJs(', 'utf8');
// files to ignore when bundling. node has no globs, so use regexps
exports.ignoreFiles = [
/~$/, /^\.#/,
@@ -546,6 +549,9 @@ class File {
// disk).
this.sourcePath = options.sourcePath;
// Allows not calculating sri when it isn't needed
this._skipSri = options.skipSri
// info is just for help with debugging the tool; it isn't written to disk or
// anything.
this.info = options.info || '?';
@@ -619,7 +625,9 @@ class File {
hashes.push(this._inputHash);
}
hashes.push(this.sri());
if (!this._skipSri) {
hashes.push(this.sri());
}
this._hash = watch.sha1(...hashes);
}
@@ -628,7 +636,7 @@ class File {
}
sri() {
if (! this._sri) {
if (! this._sri && !this._skipSri) {
this._sri = watch.sha512(this.contents());
}
@@ -1160,6 +1168,7 @@ class Target {
data: resource.data,
cacheable: false,
hash: resource.hash,
skipSri: !!resource.hash
};
const file = new File(fileOptions);
@@ -1326,13 +1335,10 @@ class Target {
// expression, which some minifiers (e.g. UglifyJS) either fail to
// parse or mistakenly eliminate as dead code. To avoid these
// problems, we temporarily name the function __minifyJs.
file._contents = Buffer.from(
file.contents()
.toString("utf8")
.replace(/^\s*function\s*\(/,
"function __minifyJs("),
"utf8"
);
file._contents = Buffer.concat([
MINIFY_RENAMED_FUNCTION,
file.contents().slice(MINIFY_PLAIN_FUNCTION.length)
]);
dynamicFiles.push(jsf);
@@ -1364,15 +1370,24 @@ class Target {
function handle(source, dynamic) {
source._minifiedFiles.forEach(file => {
// Remove the function name __minifyJs that was added above.
file.data = file.data
.toString("utf8")
.replace(/^\s*function\s+__minifyJs\s*\(/,
"function(");
if (typeof file.data === 'string') {
file.data = Buffer.from(
file.data
.replace(/^\s*function\s+__minifyJs\s*\(/,
"function("),
"utf8"
);
} else if (dynamic) {
file.data = Buffer.concat([
MINIFY_PLAIN_FUNCTION,
file.data.slice(MINIFY_RENAMED_FUNCTION.length)
]);
}
const newFile = new File({
info: 'minified js',
arch,
data: Buffer.from(file.data, 'utf8'),
data: file.data,
hash: inputHashesByJsFile.get(source),
});
@@ -2744,6 +2759,10 @@ var writeFile = Profile("bundler writeFile", function (file, builder, options) {
let data = file.contents();
const hash = file.hash();
if (builder.usePreviousWrite(file.targetPath, hash)) {
return;
}
if (options && options.sourceMapUrl) {
data = addSourceMappingURL(data, options.sourceMapUrl);
} else {