Skip to content

Commit 0665e94

Browse files
committed
Allow aliases for directories and resolve aliased paths normally
This changes the `alias` option to apply to the directories of imported files (such as alias the `utils` directory in `@import "utils/other";`). It also allows aliased paths to be processed with the full resolve algorithm, for example importing an aliased directory will search for the `index.css` file in the directory. Also expanded the options documentation
1 parent d9388c6 commit 0665e94

File tree

3 files changed

+132
-23
lines changed

3 files changed

+132
-23
lines changed

README.md

+88-19
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,91 @@ console.log(output);
4949

5050
Creates a new plugin for rework that will import files from NPM.
5151

52-
Valid options:
53-
54-
* `root`: The root directory for the source files. This is used for source maps
55-
to make imported file names relative to this directory, and for finding the
56-
absolute path for the top level source file. Example: `root: 'src/client'`
57-
* `shim`: If you need to import packages that do not specify a `style`
58-
property in their `package.json` or provide their styles in `index.css`,
59-
you can provide a shim config option to access them. This is specified as a
60-
hash whose keys are the names of packages to shim and whose values are the
61-
path, relative to that package's `package.json` file, where styles can be
62-
found. Example: `shim: { 'leaflet': 'dist/leaflet.css' }`
63-
* `alias`: You can provide aliases for arbitrary file paths using the same
64-
format as the `shim` option. These files must be complete file paths,
65-
relative to the `root` directory. Example:
66-
`alias: { 'tree': './deep/tree/index.css' }`
67-
* `prefilter`: A function that will be called before an imported file is
68-
parsed. This function will be called with the file contents and the full file
69-
path. This option can be used to convert other languages such as SCSS to CSS
70-
before importing. Example: `prefilter: function(src, file) { return src; }`
52+
## Options
53+
54+
### root
55+
The root directory for the source files. This is used for source maps to make
56+
imported file names relative to this directory, and for finding the absolute
57+
path for the top level source file.
58+
59+
Example:
60+
61+
```js
62+
// Uses `<dir>/src/index.css` as the file path for the top level file. Also all
63+
// file paths in the source map will be relative to the `<dir>/src` folder.
64+
rework('@import "./abc";', { source: 'index.css' })
65+
.use(reworkNPM({ root: path.join(__dirname, 'src') }))
66+
.toString();
67+
```
68+
69+
### shim
70+
If you need to import packages that do not specify a `style` property in their
71+
`package.json` or provide their styles in `index.css`, you can provide a shim
72+
config option to access them. This is specified as a hash whose keys are the
73+
names of packages to shim and whose values are the path, relative to that
74+
package's `package.json` file, where styles can be found.
75+
76+
Example:
77+
78+
```js
79+
// Imports the `dist/leaflet.css` file from the `leaflet` package
80+
rework('@import "leaflet";', { source: 'index.css' })
81+
.use(reworkNPM({ shim: { 'leaflet': 'dist/leaflet.css' } }))
82+
.toString();
83+
```
84+
85+
### alias
86+
87+
You can provide aliases for arbitrary import paths, including files and
88+
directories. When importing a file, it will search all directories in the path
89+
for aliases also. Note that relative imports are never aliased.
90+
91+
This is specified as an object where the keys are the name of the import path to
92+
alias, and the values are the file or directory path for the destination,
93+
relative to the `root` option.
94+
95+
Example:
96+
97+
```js
98+
// Imports the `styles/util.css` file
99+
rework('@import "util";', { source: 'index.css' })
100+
.use(reworkNPM({ alias: { 'util': 'styles/util.css' } }))
101+
.toString();
102+
```
103+
104+
```js
105+
// Imports the `styles/index.css` file if there is a `styles` directory,
106+
// otherwise the `styles.css` file.
107+
rework('@import "util";', { source: 'index.css' })
108+
.use(reworkNPM({ alias: { 'util': 'styles' } }))
109+
.toString();
110+
```
111+
112+
```js
113+
// Imports the `styles/other.css` file
114+
rework('@import "util/other";', { source: 'index.css' })
115+
.use(reworkNPM({ alias: { 'util': 'styles' } }))
116+
.toString();
117+
```
118+
119+
### prefilter
120+
A function that will be called before an imported file is parsed. This function
121+
will be called with the file contents and the full file path. This option can be
122+
used to convert other languages such as SCSS to CSS before importing.
123+
124+
Example:
125+
126+
```js
127+
// Process SCSS files
128+
rework('@import "./some-file.scss";', { source: 'index.css' })
129+
.use(reworkNPM({ prefilter: compile }))
130+
.toString();
131+
132+
function compile(src, file) {
133+
if (path.extname(file) === '.scss') {
134+
return compileScss(src);
135+
}
136+
137+
return src;
138+
}
139+
```

index.js

+23-4
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ var path = require('path');
55
var parse = require('css').parse;
66
var fs = require('fs');
77

8-
var ABS_URL = /^url\(|:\/\//,
9-
QUOTED = /^['"]|['"]$/g;
8+
var ABS_URL = /^url\(|:\/\//;
9+
var QUOTED = /^['"]|['"]$/g;
10+
var RELATIVE = /^\./;
11+
var SEPARATOR = '/';
1012

1113
module.exports = reworkNPM;
1214

@@ -51,8 +53,8 @@ function reworkNPM(opts) {
5153
return null;
5254
}
5355

54-
if (hasOwn(alias, name)) {
55-
return path.resolve(root, alias[name]);
56+
if (!RELATIVE.test(name)) {
57+
name = resolveAlias(name) || name;
5658
}
5759

5860
var source = rule.position.source;
@@ -67,6 +69,23 @@ function reworkNPM(opts) {
6769
return path.normalize(file);
6870
}
6971

72+
function resolveAlias(name) {
73+
if (hasOwn(alias, name)) {
74+
return path.resolve(root, alias[name]);
75+
}
76+
77+
var segments = name.split(SEPARATOR);
78+
if (segments.length > 1) {
79+
var current = segments.pop();
80+
var parent = resolveAlias(segments.join(SEPARATOR));
81+
if (parent) {
82+
return path.join(parent, current);
83+
}
84+
}
85+
86+
return null;
87+
}
88+
7089
function processPackage(pkg) {
7190
pkg.main =
7291
(hasOwn(shim, pkg.name) && shim[pkg.name]) ||

test.js

+21
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,27 @@ test('Use alias config option', function(t) {
192192
t.end();
193193
});
194194

195+
test('Import index file in aliased directory', function(t) {
196+
var source = '@import "util";';
197+
var alias = { 'util': 'test/styles' };
198+
var output = rework(source, { source: 'test/index.css' })
199+
.use(reworkNPM({ alias: alias }))
200+
.toString();
201+
202+
t.equal(output, '.test {\n content: "Test file";\n}');
203+
t.end();
204+
});
205+
206+
test('Import file in aliased directory', function(t) {
207+
var source = '@import "util/index";';
208+
var alias = { 'util': 'test/styles' };
209+
var output = rework(source, { source: 'test/index.css' })
210+
.use(reworkNPM({ alias: alias }))
211+
.toString();
212+
t.equal(output, '.test {\n content: "Test file";\n}');
213+
t.end();
214+
});
215+
195216
test('Allow prefiltering input CSS (e.g. css-whitespace)', function(t) {
196217
var input = '@import "./styles/index-unfiltered.css";';
197218
var output = rework(input, { source: 'test/index.css' })

0 commit comments

Comments
 (0)