diff --git a/lib/createResolver.js b/lib/createResolver.js new file mode 100644 index 000000000..c0ba8ca10 --- /dev/null +++ b/lib/createResolver.js @@ -0,0 +1,51 @@ +function startsWith(string, searchString) { + var stringLength = string.length; + var searchLength = searchString.length; + + // early out if the search length is greater than the search string + if(searchLength > stringLength) { + return false; + } + var index = -1; + while(++index < searchLength) { + if(string.charCodeAt(index) !== searchString.charCodeAt(index)) { + return false; + } + } + return true; +} + +module.exports = function createResolver(alias) { + if(typeof alias !== "object" || Array.isArray(alias)) { + return function(url) { return url }; + } + + alias = Object.keys(alias).map(function(key) { + var onlyModule = false; + var obj = alias[key]; + if(/\$$/.test(key)) { + onlyModule = true; + key = key.substr(0, key.length - 1); + } + if(typeof obj === "string") { + obj = { + alias: obj + }; + } + obj = Object.assign({ + name: key, + onlyModule: onlyModule + }, obj); + return obj; + }); + + return function(url) { + alias.forEach(function(obj) { + var name = obj.name; + if(url === name || (!obj.onlyModule && startsWith(url, name + "/"))) { + url = obj.alias + url.substr(name.length); + } + }); + return url; + } +} diff --git a/lib/loader.js b/lib/loader.js index 388508eab..b55b35f9c 100644 --- a/lib/loader.js +++ b/lib/loader.js @@ -6,6 +6,7 @@ var loaderUtils = require("loader-utils"); var processCss = require("./processCss"); var getImportPrefix = require("./getImportPrefix"); var compileExports = require("./compile-exports"); +var createResolver = require("./createResolver"); module.exports = function(content, map) { @@ -15,6 +16,7 @@ module.exports = function(content, map) { var root = query.root; var moduleMode = query.modules || query.module; var camelCaseKeys = query.camelCase || query.camelcase; + var resolve = createResolver(query.alias); if(map !== null && typeof map !== "string") { map = JSON.stringify(map); @@ -69,19 +71,7 @@ module.exports = function(content, map) { var match = result.urlItemRegExp.exec(item); var idx = +match[1]; var urlItem = result.urlItems[idx]; - var url = urlItem.url; - var loaderOptions = this.options.cssLoader; - if (loaderOptions && loaderOptions.alias) { - var alias = loaderOptions.alias; - Object.keys(alias).forEach(function(aliasName) { - var aliasValue = alias[aliasName]; - var onlyModule = /\$$/.test(aliasName); - if (onlyModule) aliasName = aliasName.substr(0, aliasName.length - 1); - if ((!onlyModule && url.indexOf(aliasName + "/") === 0) || url === aliasName) { - url = aliasValue + url.substr(aliasName.length); - } - }); - } + var url = resolve(urlItem.url); idx = url.indexOf("?#"); if(idx < 0) idx = url.indexOf("#"); var urlRequest; diff --git a/test/aliasTest.js b/test/aliasTest.js index 6fdbd2d2f..19ebaf162 100644 --- a/test/aliasTest.js +++ b/test/aliasTest.js @@ -3,28 +3,28 @@ var test = require("./helpers").test; describe("alias", function() { - var css = ".className { background: url(./path/to/file.png); }"; - var exports = { - without: [ - [1, ".className { background: url({./path/to/file.png}); }", ""] - ], - onlyModule: [ - [1, ".className { background: url({module/file.png}); }", ""] - ], - exactMatch: [ - [1, ".className { background: url({module/file.png}); }", ""] - ], - notExactMatch: [ - [1, ".className { background: url({./path/to/file.png}); }", ""] - ] - }; + var css = ".className { background: url(./path/to/file.png); }"; + var exports = { + without: [ + [1, ".className { background: url({./path/to/file.png}); }", ""] + ], + onlyModule: [ + [1, ".className { background: url({module/file.png}); }", ""] + ], + exactMatch: [ + [1, ".className { background: url({module/file.png}); }", ""] + ], + notExactMatch: [ + [1, ".className { background: url({./path/to/file.png}); }", ""] + ] + }; - function aliasOptions(alias) { - return { options: { context: "", cssLoader: { alias: alias }}} - } + function aliasOptions(alias) { + return { query: { alias: alias }} + } - test("without", css, exports.without); - test("onlyModule", css, exports.onlyModule, aliasOptions({ "./path/to": "module" })); - test("exactMatch", css, exports.exactMatch, aliasOptions({ "./path/to/file.png$": "module/file.png" })); - test("notExactMatch", css, exports.notExactMatch, aliasOptions({ "./path/to/file.jpg$": "module/file.jpg" })); + test("without", css, exports.without); + test("onlyModule", css, exports.onlyModule, aliasOptions({ "./path/to": "module" })); + test("exactMatch", css, exports.exactMatch, aliasOptions({ "./path/to/file.png$": "module/file.png" })); + test("notExactMatch", css, exports.notExactMatch, aliasOptions({ "./path/to/file.jpg$": "module/file.jpg" })); });