Skip to content
This repository has been archived by the owner on Mar 17, 2021. It is now read-only.

Commit

Permalink
major update
Browse files Browse the repository at this point in the history
add filename template param
add tests
  • Loading branch information
sokra committed Aug 4, 2014
1 parent b97439c commit f7e80a8
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 23 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
/node_modules
/coverage
4 changes: 4 additions & 0 deletions .travis.yml
@@ -0,0 +1,4 @@
language: node_js
node_js:
- "0.10"
- "0.11"
30 changes: 22 additions & 8 deletions README.md
Expand Up @@ -7,28 +7,42 @@
``` javascript
var url = require("file!./file.png");
// => emits file.png as file in the output directory and returns the public url
// => returns i. e. "/public-path/0dcbbaa701328a3c262cfd45869e351f.png"
```

The filename is the md5 hash of the file. The extension of the required resource is appended.
By default the filename is the md5 hash of the file and the extension of the required resource is appended.

If you want to have custom pre- and postfix of your file:
You can configure a custom filename template for your file (query param `name`).

* `[ext]` the extension of the resource
* `[name]` the basename of the resource
* `[path]` the path of the resource relative to the `context` query parameter or option.
* `[hash]` the hash or the content
* query param `hash` allows to choose a algorithm (default `md5`)
* query param `digest` allows to choose the type of digest (default `hex`)
* query param `size` allows to choose the length of the hash in chars

Examples

``` javascript
require("file?prefix=js/&postfix=.script.js!./javascript.js");
require("file?name=js/[hash].script.[ext]!./javascript.js");
// => js/0dcbbaa701328a3c262cfd45869e351f.script.js

require("file?prefix=html-&size=6!./page.html");
require("file?name=html-[hash].html&size=6!./page.html");
// => html-109fa8.html

require("file?postfix!./flash.txt");
require("file?name=[hash]!./flash.txt");
// => c31e9820c001c9c4a86bce33ce43b679

require("file?hash=sha512!./image.png");
// => a720b9f140d13...781f1f78344.png
// use sha512 hash instead of md5
require("file?hash=sha512&size=7&digest=base64!./image.png");
// => gdyb21L.png
// use sha512 hash instead of md5 and with only 7 chars of base64

require("file?name=picture.png!./myself.png");
// => picture.png

require("file?[path][name].[ext]?[hash]!./dir/file.png")
// => dir/file.png?e43b20c069c4a01867c31e98cbce33c9
```

## License
Expand Down
27 changes: 27 additions & 0 deletions appveyor.yml
@@ -0,0 +1,27 @@
# appveyor file
# http://www.appveyor.com/docs/appveyor-yml

init:
- git config --global core.autocrlf input

# what combinations to test
environment:
matrix:
- nodejs_version: 0.10
- nodejs_version: 0.11

# combinations having this can fail
matrix:
allow_failures:
- nodejs_version: 0.11

install:
- ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version)
- npm install

build: off

test_script:
- node --version
- npm --version
- cmd: npm test
48 changes: 33 additions & 15 deletions index.js
Expand Up @@ -3,30 +3,48 @@
Author Tobias Koppers @sokra
*/
var loaderUtils = require("loader-utils");
var path = require("path");

module.exports = function(content) {
this.cacheable && this.cacheable();
if(!this.emitFile) throw new Error("emitFile is required from module system");
var query = loaderUtils.parseQuery(this.query);
var url;
if(query.name) {
url = query.name;
} else {
var prefix = query.prefix || "";
var postfix = query.postfix;
if(typeof postfix != "string") {
if(this.resource && typeof postfix != "boolean") {
var idx = this.resource.lastIndexOf(".");
if(idx > 0) postfix = this.resource.substr(idx);
else postfix = "";
} else postfix = "";
var filename = query.name || "[hash].[ext]";
var context = query.context || this.options.context;
var ext = "bin";
var basename = "file";
var directory = "";
if(this.resourcePath) {
var resourcePath = this.resourcePath;
var idx = resourcePath.lastIndexOf(".");
var i = resourcePath.lastIndexOf("\\");
var j = resourcePath.lastIndexOf("/");
var p = i < 0 ? j : j < 0 ? i : i < j ? i : j;
if(idx >= 0) {
ext = resourcePath.substr(idx+1);
resourcePath = resourcePath.substr(0, idx);
}
if(p >= 0) {
basename = resourcePath.substr(p+1);
resourcePath = resourcePath.substr(0, p+1);
}
directory = path.relative(context, resourcePath + "_").replace(/\\/g, "/").replace(/\.\.(\/)?/g, "_$1");
directory = directory.substr(0, directory.length-1);
if(directory.length === 1) directory = "";
}
var url = filename.replace(/\[hash\]/ig, function() {
var digest = query.hash || "md5";
var digestSize = query.size || 9999;
hash = new (require("crypto").Hash)(digest);
hash.update(content);
var hash = hash.digest("hex").substr(0, digestSize);
url = prefix + hash + postfix;
}
return hash.digest(query.digest || "hex").substr(0, digestSize);
}).replace(/\[ext\]/ig, function() {
return ext;
}).replace(/\[name\]/ig, function() {
return basename;
}).replace(/\[path\]/ig, function() {
return directory;
});
this.emitFile(url, content);
return "module.exports = __webpack_public_path__ + " + JSON.stringify(url);
}
Expand Down
7 changes: 7 additions & 0 deletions package.json
Expand Up @@ -6,6 +6,13 @@
"dependencies": {
"loader-utils": "0.2.x"
},
"devDependencies": {
"should": "~4.0.4",
"mocha": "~1.21.3"
},
"scripts": {
"test": "mocha -R spec"
},
"repository": {
"type": "git",
"url": "git@github.com:webpack/file-loader.git"
Expand Down
57 changes: 57 additions & 0 deletions test/correct-filename.test.js
@@ -0,0 +1,57 @@
var should = require("should");
var path = require("path");
var fileLoader = require("../");

function run(resourcePath, query, content) {
content = content || new Buffer("1234");
var result = null;
var context = {
resourcePath: resourcePath,
query: "?" + query,
options: {
context: "/this/is/the/context"
},
emitFile: function(url, content2) {
content2.should.be.eql(content);
result = url;
}
};
fileLoader.call(context, content);
return result;
}

function test(excepted, resourcePath, query, content) {
run(resourcePath, query, content).should.be.eql(excepted);
}

describe("correct-filename", function() {
it("should process defaults correctly", function() {
test("81dc9bdb52d04dc20036dbd8313ed055.txt", "/file.txt", "");
test("81dc9bdb52d04dc20036dbd8313ed055.png", "/file.png", "");
test("81dc9bdb52d04dc20036dbd8313ed055.txt", "file.txt", "");
test("81dc9bdb52d04dc20036dbd8313ed055.bin", "", "");
});
it("should process name correctly", function() {
test("file.txt", "/file.txt", "name=[name].[ext]");
test("file.png", "/file.png", "name=[name].[ext]");
test("file.txt", "file.txt", "name=[name].[ext]");
test("file.bin", "", "name=[name].[ext]");
test("file", "/file.txt", "name=[name]");
test("81dc9bdb52d04dc20036dbd8313ed055", "/file.txt", "name=[hash]");
test("81dc9bdb52d04dc20036dbd8313ed055/file.txt", "/file.txt", "name=[hash]/[name].[ext]");
test("file.txt", "/this/is/the/context/file.txt", "name=[path][name].[ext]");
test("dir/file.txt", "/this/is/the/context/dir/file.txt", "name=[path][name].[ext]");
test("dir/sub/file.txt", "/this/is/the/context/dir/sub/file.txt", "name=[path][name].[ext]");
test("_/_/dir/sub/file.txt", "/this/is/dir/sub/file.txt", "name=[path][name].[ext]");
test("dir/sub/file.txt", "/this/is/dir/sub/file.txt", "name=[path][name].[ext]&context=/this/is");
});
it("should process hash correctly", function() {
test("d93591bdf7860e1e4ee2fca799911215.txt", "/file.txt", "", new Buffer("4321"));
});
it("should process hash options correctly", function() {
test("81dc9.txt", "/file.txt", "size=5");
test("d4045.txt", "/file.txt", "hash=sha512&size=5");
test("gdyb21LQTcIANtvYMT7QVQ==.txt", "/file.txt", "digest=base64");
});

});

0 comments on commit f7e80a8

Please sign in to comment.