From 6982934c61fab3411d5b36aee67783a3d78c3c06 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Mon, 24 Dec 2018 13:31:26 +0300 Subject: [PATCH] feat: support `[contenthash]` --- README.md | 11 +++++++++++ lib/interpolateName.js | 4 +++- test/interpolateName.test.js | 5 +++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bb04c19..83346c6 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,11 @@ The following tokens are replaced in the `name` parameter: * `[folder]` the folder of the resource is in. * `[emoji]` a random emoji representation of `options.content` * `[emoji:]` same as above, but with a customizable number of emojis +* `[contenthash]` the hash of `options.content` (Buffer) (by default it's the hex digest of the md5 hash) +* `[:contenthash::]` optionally one can configure + * other `hashType`s, i. e. `sha1`, `md5`, `sha256`, `sha512` + * other `digestType`s, i. e. `hex`, `base26`, `base32`, `base36`, `base49`, `base52`, `base58`, `base62`, `base64` + * and `length` the length in chars * `[hash]` the hash of `options.content` (Buffer) (by default it's the hex digest of the md5 hash) * `[:hash::]` optionally one can configure * other `hashType`s, i. e. `sha1`, `md5`, `sha256`, `sha512` @@ -171,6 +176,8 @@ The following tokens are replaced in the `name` parameter: * and `length` the length in chars * `[N]` the N-th match obtained from matching the current file name against `options.regExp` +In loader context `[hash]` and `[contenthash]` are the same, but we recommend using `[contenthash]` for avoid misleading. + Examples ``` javascript @@ -178,6 +185,10 @@ Examples loaderUtils.interpolateName(loaderContext, "js/[hash].script.[ext]", { content: ... }); // => js/9473fdd0d880a43c21b7778d34872157.script.js +// loaderContext.resourcePath = "/app/js/javascript.js" +loaderUtils.interpolateName(loaderContext, "js/[contenthash].script.[ext]", { content: ... }); +// => js/9473fdd0d880a43c21b7778d34872157.script.js + // loaderContext.resourcePath = "/app/page.html" loaderUtils.interpolateName(loaderContext, "html-[hash:6].html", { content: ... }); // => html-9473fd.html diff --git a/lib/interpolateName.js b/lib/interpolateName.js index 30bcef2..1b1c1b4 100644 --- a/lib/interpolateName.js +++ b/lib/interpolateName.js @@ -67,8 +67,10 @@ function interpolateName(loaderContext, name, options) { if(content) { // Match hash template url = url + // `hash` and `contenthash` are same in `loader-utils` context + // let's keep `hash` for backward compatibility .replace( - /\[(?:([^:]+):)?hash(?::([a-z]+\d*))?(?::(\d+))?\]/ig, + /\[(?:([^:]+):)?(?:hash||contenthash)(?::([a-z]+\d*))?(?::(\d+))?\]/ig, (all, hashType, digestType, maxLength) => getHashDigest(content, hashType, digestType, parseInt(maxLength, 10)) ) .replace( diff --git a/test/interpolateName.test.js b/test/interpolateName.test.js index dda96c8..0c88df9 100644 --- a/test/interpolateName.test.js +++ b/test/interpolateName.test.js @@ -24,10 +24,15 @@ describe("interpolateName()", () => { [ ["/app/js/javascript.js", "js/[hash].script.[ext]", "test content", "js/9473fdd0d880a43c21b7778d34872157.script.js"], + ["/app/js/javascript.js", "js/[contenthash].script.[ext]", "test content", "js/9473fdd0d880a43c21b7778d34872157.script.js"], ["/app/page.html", "html-[hash:6].html", "test content", "html-9473fd.html"], + ["/app/page.html", "html-[contenthash:6].html", "test content", "html-9473fd.html"], ["/app/flash.txt", "[hash]", "test content", "9473fdd0d880a43c21b7778d34872157"], + ["/app/flash.txt", "[contenthash]", "test content", "9473fdd0d880a43c21b7778d34872157"], ["/app/img/image.png", "[sha512:hash:base64:7].[ext]", "test content", "2BKDTjl.png"], + ["/app/img/image.png", "[sha512:contenthash:base64:7].[ext]", "test content", "2BKDTjl.png"], ["/app/dir/file.png", "[path][name].[ext]?[hash]", "test content", "/app/dir/file.png?9473fdd0d880a43c21b7778d34872157"], + ["/app/dir/file.png", "[path][name].[ext]?[contenthash]", "test content", "/app/dir/file.png?9473fdd0d880a43c21b7778d34872157"], ["/vendor/test/images/loading.gif", path => path.replace(/\/?vendor\/?/, ""), "test content", "test/images/loading.gif"], ["/pathWith.period/filename.js", "js/[name].[ext]", "test content", "js/filename.js"], ["/pathWith.period/filenameWithoutExt", "js/[name].[ext]", "test content", "js/filenameWithoutExt.bin"]