diff --git a/README.md b/README.md index eecf082d..8cc41620 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ To be compatible with existing css files (if not in CSS Module mode): |**`sourceMap`**|`false`|Enable/Disable Sourcemaps| |**`camelCase`**|`false`|Export Classnames in CamelCase| |**`importLoaders`**|`0`|Number of loaders applied before CSS loader| +|**`alias`**|`{}`|Create aliases to import certain modules more easily| The following webpack config can load CSS files, embed small PNG/JPG/GIF/SVG images as well as fonts as [Data URLs](https://tools.ietf.org/html/rfc2397) and copy larger files to the output directory. @@ -322,7 +323,7 @@ They are not enabled by default because they expose a runtime overhead and incre ### toString -You can also use the css-loader results directly as string, such as in Angular's component style. +You can also use the css-loader results directly as string, such as in Angular's component style. **webpack.config.js** @@ -430,6 +431,44 @@ By default, the exported JSON keys mirror the class names. If you want to cameli import { className } from 'file.css'; ``` +### Alias + +Rewrite your urls with alias, this is useful when it's hard to change url paths of your input files, for example, when you're using some css / sass files in another package (bootstrap, ratchet, font-awesome, etc.). + +#### Possible Options + +css-loader's `alias` follows the same syntax as webpack's `resolve.alias`, you can see the details at: https://webpack.js.org/configuration/resolve/#resolve-alias + +**webpack.config.js** +```js +{ + test: /\.scss$/, + use: [{ + loader: "style-loader" + }, { + loader: "css-loader", + options: { + alias: { + "../fonts/bootstrap": "bootstrap-sass/assets/fonts/bootstrap" + } + } + }, { + loader: "sass-loader", + options: { + includePaths: [ + path.resolve("./node_modules/bootstrap-sass/assets/stylesheets") + ] + } + }] +} +``` + +```scss +@charset "UTF-8"; +@import "bootstrap"; +``` +Check out this [working bootstrap example](https://github.com/bbtfr/webpack2-bootstrap-sass-sample). +

Maintainers

diff --git a/lib/createResolver.js b/lib/createResolver.js new file mode 100644 index 00000000..c0d89701 --- /dev/null +++ b/lib/createResolver.js @@ -0,0 +1,36 @@ +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 && url.startsWith(name + "/"))) { + url = obj.alias + url.substr(name.length); + } + }); + return url; + } +} diff --git a/lib/loader.js b/lib/loader.js index 8698160e..b55b35f9 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,7 +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 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 new file mode 100644 index 00000000..19ebaf16 --- /dev/null +++ b/test/aliasTest.js @@ -0,0 +1,30 @@ +/*globals describe */ + +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}); }", ""] + ] + }; + + 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" })); +});