Skip to content

Commit c8db489

Browse files
bbtfrmichael-ciniawsky
authored andcommitted
feat: add alias feature to rewrite URLs (#274)
1 parent 04dabca commit c8db489

File tree

4 files changed

+109
-2
lines changed

4 files changed

+109
-2
lines changed

README.md

+40-1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ To be compatible with existing css files (if not in CSS Module mode):
8989
|**`sourceMap`**|`false`|Enable/Disable Sourcemaps|
9090
|**`camelCase`**|`false`|Export Classnames in CamelCase|
9191
|**`importLoaders`**|`0`|Number of loaders applied before CSS loader|
92+
|**`alias`**|`{}`|Create aliases to import certain modules more easily|
9293

9394
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.
9495

@@ -322,7 +323,7 @@ They are not enabled by default because they expose a runtime overhead and incre
322323

323324
### toString
324325

325-
You can also use the css-loader results directly as string, such as in Angular's component style.
326+
You can also use the css-loader results directly as string, such as in Angular's component style.
326327

327328
**webpack.config.js**
328329

@@ -430,6 +431,44 @@ By default, the exported JSON keys mirror the class names. If you want to cameli
430431
import { className } from 'file.css';
431432
```
432433

434+
### Alias
435+
436+
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.).
437+
438+
#### Possible Options
439+
440+
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
441+
442+
**webpack.config.js**
443+
```js
444+
{
445+
test: /\.scss$/,
446+
use: [{
447+
loader: "style-loader"
448+
}, {
449+
loader: "css-loader",
450+
options: {
451+
alias: {
452+
"../fonts/bootstrap": "bootstrap-sass/assets/fonts/bootstrap"
453+
}
454+
}
455+
}, {
456+
loader: "sass-loader",
457+
options: {
458+
includePaths: [
459+
path.resolve("./node_modules/bootstrap-sass/assets/stylesheets")
460+
]
461+
}
462+
}]
463+
}
464+
```
465+
466+
```scss
467+
@charset "UTF-8";
468+
@import "bootstrap";
469+
```
470+
Check out this [working bootstrap example](https://github.com/bbtfr/webpack2-bootstrap-sass-sample).
471+
433472
<h2 align="center">Maintainers</h2>
434473

435474
<table>

lib/createResolver.js

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
module.exports = function createResolver(alias) {
2+
if(typeof alias !== "object" || Array.isArray(alias)) {
3+
return function(url) {
4+
return url
5+
};
6+
}
7+
8+
alias = Object.keys(alias).map(function(key) {
9+
var onlyModule = false;
10+
var obj = alias[key];
11+
if(/\$$/.test(key)) {
12+
onlyModule = true;
13+
key = key.substr(0, key.length - 1);
14+
}
15+
if(typeof obj === "string") {
16+
obj = {
17+
alias: obj
18+
};
19+
}
20+
obj = Object.assign({
21+
name: key,
22+
onlyModule: onlyModule
23+
}, obj);
24+
return obj;
25+
});
26+
27+
return function(url) {
28+
alias.forEach(function(obj) {
29+
var name = obj.name;
30+
if(url === name || (!obj.onlyModule && url.startsWith(name + "/"))) {
31+
url = obj.alias + url.substr(name.length);
32+
}
33+
});
34+
return url;
35+
}
36+
}

lib/loader.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ var loaderUtils = require("loader-utils");
66
var processCss = require("./processCss");
77
var getImportPrefix = require("./getImportPrefix");
88
var compileExports = require("./compile-exports");
9+
var createResolver = require("./createResolver");
910

1011

1112
module.exports = function(content, map) {
@@ -15,6 +16,7 @@ module.exports = function(content, map) {
1516
var root = query.root;
1617
var moduleMode = query.modules || query.module;
1718
var camelCaseKeys = query.camelCase || query.camelcase;
19+
var resolve = createResolver(query.alias);
1820

1921
if(map !== null && typeof map !== "string") {
2022
map = JSON.stringify(map);
@@ -69,7 +71,7 @@ module.exports = function(content, map) {
6971
var match = result.urlItemRegExp.exec(item);
7072
var idx = +match[1];
7173
var urlItem = result.urlItems[idx];
72-
var url = urlItem.url;
74+
var url = resolve(urlItem.url);
7375
idx = url.indexOf("?#");
7476
if(idx < 0) idx = url.indexOf("#");
7577
var urlRequest;

test/aliasTest.js

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*globals describe */
2+
3+
var test = require("./helpers").test;
4+
5+
describe("alias", function() {
6+
var css = ".className { background: url(./path/to/file.png); }";
7+
var exports = {
8+
without: [
9+
[1, ".className { background: url({./path/to/file.png}); }", ""]
10+
],
11+
onlyModule: [
12+
[1, ".className { background: url({module/file.png}); }", ""]
13+
],
14+
exactMatch: [
15+
[1, ".className { background: url({module/file.png}); }", ""]
16+
],
17+
notExactMatch: [
18+
[1, ".className { background: url({./path/to/file.png}); }", ""]
19+
]
20+
};
21+
22+
function aliasOptions(alias) {
23+
return { query: { alias: alias }}
24+
}
25+
26+
test("without", css, exports.without);
27+
test("onlyModule", css, exports.onlyModule, aliasOptions({ "./path/to": "module" }));
28+
test("exactMatch", css, exports.exactMatch, aliasOptions({ "./path/to/file.png$": "module/file.png" }));
29+
test("notExactMatch", css, exports.notExactMatch, aliasOptions({ "./path/to/file.jpg$": "module/file.jpg" }));
30+
});

0 commit comments

Comments
 (0)