Skip to content

Commit

Permalink
feat: add alias feature to rewrite URLs (#274)
Browse files Browse the repository at this point in the history
  • Loading branch information
bbtfr authored and michael-ciniawsky committed Mar 18, 2017
1 parent 04dabca commit c8db489
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 2 deletions.
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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**

Expand Down Expand Up @@ -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).

<h2 align="center">Maintainers</h2>

<table>
Expand Down
36 changes: 36 additions & 0 deletions lib/createResolver.js
Original file line number Diff line number Diff line change
@@ -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;
}
}
4 changes: 3 additions & 1 deletion lib/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
30 changes: 30 additions & 0 deletions test/aliasTest.js
Original file line number Diff line number Diff line change
@@ -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" }));
});

0 comments on commit c8db489

Please sign in to comment.