mirror of https://github.com/webpack/webpack.git
Merge pull request #9391 from vankop/create-hash-typescript
esdoc(createHash)
This commit is contained in:
commit
0beeb7e30a
|
|
@ -71,7 +71,8 @@ module.exports = {
|
|||
};
|
||||
return acc;
|
||||
}, {})),
|
||||
extends: "extends"
|
||||
extends: "extends",
|
||||
constructor: "constructor"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1094,7 +1094,7 @@ export interface OutputOptions {
|
|||
/**
|
||||
* Algorithm used for generation the hash (see node.js crypto package)
|
||||
*/
|
||||
hashFunction?: string | (new () => import("../lib/util/createHash").Hash);
|
||||
hashFunction?: string | import("../lib/util/createHash").HashConstructor;
|
||||
/**
|
||||
* Any string which is added to the hash to salt it
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
"use strict";
|
||||
|
||||
const WebpackError = require("./WebpackError");
|
||||
const CURRENT_METHOD_REGEXP = /at ([a-zA-Z0-9_.]*)/;
|
||||
|
||||
/**
|
||||
* @param {string=} method method name
|
||||
* @returns {string} message
|
||||
*/
|
||||
function createMessage(method) {
|
||||
return `Abstract method${method ? " " + method : ""}. Must be overridden.`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function Message() {
|
||||
this.stack = undefined;
|
||||
Error.captureStackTrace(this);
|
||||
/** @type {RegExpMatchArray} */
|
||||
const match = this.stack.split("\n")[3].match(CURRENT_METHOD_REGEXP);
|
||||
|
||||
this.message = match && match[1] ? createMessage(match[1]) : createMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Error for abstract method
|
||||
* @example
|
||||
* class FooClass {
|
||||
* abstractMethod() {
|
||||
* throw new AbstractMethodError(); // error message: Abstract method FooClass.abstractMethod. Must be overriden.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
*/
|
||||
class AbstractMethodError extends WebpackError {
|
||||
constructor() {
|
||||
super(new Message().message);
|
||||
this.name = "AbstractMethodError";
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AbstractMethodError;
|
||||
|
|
@ -2294,7 +2294,7 @@ class Compilation extends Tapable {
|
|||
const module = modules[i];
|
||||
const moduleHash = createHash(hashFunction);
|
||||
module.updateHash(moduleHash);
|
||||
module.hash = moduleHash.digest(hashDigest);
|
||||
module.hash = /** @type {string} */ (moduleHash.digest(hashDigest));
|
||||
module.renderedHash = module.hash.substr(0, hashDigestLength);
|
||||
}
|
||||
// clone needed as sort below is inplace mutation
|
||||
|
|
@ -2329,7 +2329,7 @@ class Compilation extends Tapable {
|
|||
this.dependencyTemplates
|
||||
);
|
||||
this.hooks.chunkHash.call(chunk, chunkHash);
|
||||
chunk.hash = chunkHash.digest(hashDigest);
|
||||
chunk.hash = /** @type {string} */ (chunkHash.digest(hashDigest));
|
||||
hash.update(chunk.hash);
|
||||
chunk.renderedHash = chunk.hash.substr(0, hashDigestLength);
|
||||
this.hooks.contentHash.call(chunk);
|
||||
|
|
@ -2337,7 +2337,7 @@ class Compilation extends Tapable {
|
|||
this.errors.push(new ChunkRenderError(chunk, "", err));
|
||||
}
|
||||
}
|
||||
this.fullHash = hash.digest(hashDigest);
|
||||
this.fullHash = /** @type {string} */ (hash.digest(hashDigest));
|
||||
this.hash = this.fullHash.substr(0, hashDigestLength);
|
||||
}
|
||||
|
||||
|
|
@ -2353,7 +2353,7 @@ class Compilation extends Tapable {
|
|||
const hash = createHash(hashFunction);
|
||||
hash.update(this.fullHash);
|
||||
hash.update(update);
|
||||
this.fullHash = hash.digest(hashDigest);
|
||||
this.fullHash = /** @type {string} */ (hash.digest(hashDigest));
|
||||
this.hash = this.fullHash.substr(0, hashDigestLength);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,9 @@ class HashedModuleIdsPlugin {
|
|||
});
|
||||
const hash = createHash(options.hashFunction);
|
||||
hash.update(id);
|
||||
const hashId = hash.digest(options.hashDigest);
|
||||
const hashId = /** @type {string} */ (hash.digest(
|
||||
options.hashDigest
|
||||
));
|
||||
let len = options.hashDigestLength;
|
||||
while (usedIds.has(hashId.substr(0, len))) len++;
|
||||
module.id = hashId.substr(0, len);
|
||||
|
|
|
|||
|
|
@ -148,9 +148,8 @@ class JavascriptModulesPlugin {
|
|||
hash.update(m.hash);
|
||||
}
|
||||
}
|
||||
chunk.contentHash.javascript = hash
|
||||
.digest(hashDigest)
|
||||
.substr(0, hashDigestLength);
|
||||
const digest = /** @type {string} */ (hash.digest(hashDigest));
|
||||
chunk.contentHash.javascript = digest.substr(0, hashDigestLength);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ const getBefore = (str, token) => {
|
|||
const getHash = str => {
|
||||
const hash = createHash("md4");
|
||||
hash.update(str);
|
||||
return hash.digest("hex").substr(0, 4);
|
||||
const digest = /** @type {string} */ (hash.digest("hex"));
|
||||
return digest.substr(0, 4);
|
||||
};
|
||||
|
||||
const asRegExp = test => {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ const RequestShortener = require("./RequestShortener");
|
|||
const getHash = str => {
|
||||
const hash = createHash("md4");
|
||||
hash.update(str);
|
||||
return hash.digest("hex").substr(0, 4);
|
||||
const digest = /** @type {string} */ (hash.digest("hex"));
|
||||
return digest.substr(0, 4);
|
||||
};
|
||||
|
||||
class NamedModulesPlugin {
|
||||
|
|
|
|||
|
|
@ -405,7 +405,7 @@ class NormalModule extends Module {
|
|||
}
|
||||
hash.update("meta");
|
||||
hash.update(JSON.stringify(this.buildMeta));
|
||||
this._buildHash = hash.digest("hex");
|
||||
this._buildHash = /** @type {string} */ (hash.digest("hex"));
|
||||
}
|
||||
|
||||
build(options, compilation, resolver, fs, callback) {
|
||||
|
|
|
|||
|
|
@ -4,21 +4,50 @@
|
|||
*/
|
||||
"use strict";
|
||||
|
||||
/** @typedef {{new(): Hash}} HashConstructor */
|
||||
/**
|
||||
* @typedef {Object} Hash
|
||||
* @property {function(string|Buffer, string=): Hash} update
|
||||
* @property {function(string): string} digest
|
||||
*/
|
||||
const AbstractMethodError = require("../AbstractMethodError");
|
||||
|
||||
const BULK_SIZE = 1000;
|
||||
|
||||
class BulkUpdateDecorator {
|
||||
class Hash {
|
||||
/**
|
||||
* Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
|
||||
* @param {string|Buffer} data data
|
||||
* @param {string=} inputEncoding data encoding
|
||||
* @returns {this} updated hash
|
||||
*/
|
||||
update(data, inputEncoding) {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
|
||||
* @param {string=} encoding encoding of the return value
|
||||
* @returns {string|Buffer} digest
|
||||
*/
|
||||
digest(encoding) {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
}
|
||||
|
||||
exports.Hash = Hash;
|
||||
/** @typedef {typeof Hash} HashConstructor */
|
||||
|
||||
class BulkUpdateDecorator extends Hash {
|
||||
/**
|
||||
* @param {Hash} hash hash
|
||||
*/
|
||||
constructor(hash) {
|
||||
super();
|
||||
this.hash = hash;
|
||||
this.buffer = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
|
||||
* @param {string|Buffer} data data
|
||||
* @param {string=} inputEncoding data encoding
|
||||
* @returns {this} updated hash
|
||||
*/
|
||||
update(data, inputEncoding) {
|
||||
if (
|
||||
inputEncoding !== undefined ||
|
||||
|
|
@ -40,6 +69,11 @@ class BulkUpdateDecorator {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
|
||||
* @param {string=} encoding encoding of the return value
|
||||
* @returns {string|Buffer} digest
|
||||
*/
|
||||
digest(encoding) {
|
||||
if (this.buffer.length > 0) {
|
||||
this.hash.update(this.buffer);
|
||||
|
|
@ -51,18 +85,32 @@ class BulkUpdateDecorator {
|
|||
}
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
class DebugHash {
|
||||
/**
|
||||
* istanbul ignore next
|
||||
*/
|
||||
class DebugHash extends Hash {
|
||||
constructor() {
|
||||
super();
|
||||
this.string = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
|
||||
* @param {string|Buffer} data data
|
||||
* @param {string=} inputEncoding data encoding
|
||||
* @returns {this} updated hash
|
||||
*/
|
||||
update(data, inputEncoding) {
|
||||
if (typeof data !== "string") data = data.toString("utf-8");
|
||||
this.string += data;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
|
||||
* @param {string=} encoding encoding of the return value
|
||||
* @returns {string|Buffer} digest
|
||||
*/
|
||||
digest(encoding) {
|
||||
return this.string.replace(/[^a-z0-9]+/gi, m =>
|
||||
Buffer.from(m).toString("hex")
|
||||
|
|
|
|||
|
|
@ -905,7 +905,7 @@
|
|||
},
|
||||
{
|
||||
"instanceof": "Function",
|
||||
"tsType": "(new () => import('../lib/util/createHash').Hash)"
|
||||
"tsType": "import('../lib/util/createHash').HashConstructor"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
"use strict";
|
||||
|
||||
const AbstractMethodError = require("../lib/AbstractMethodError");
|
||||
|
||||
describe("WebpackError", () => {
|
||||
class Foo {
|
||||
abstractMethod() {
|
||||
return new AbstractMethodError();
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Foo {}
|
||||
|
||||
const expectedMessage = "Abstract method $1. Must be overridden.";
|
||||
|
||||
it("Should construct message with caller info", () => {
|
||||
const fooClassError = new Foo().abstractMethod();
|
||||
const childClassError = new Child().abstractMethod();
|
||||
|
||||
expect(fooClassError.message).toBe(
|
||||
expectedMessage.replace("$1", "Foo.abstractMethod")
|
||||
);
|
||||
expect(childClassError.message).toBe(
|
||||
expectedMessage.replace("$1", "Child.abstractMethod")
|
||||
);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue