Skip to content

Commit e3c6b6a

Browse files
committed
Merge pull request #39 from css-modules/feature/opts
added opportunity to easier extend the pipeline
2 parents cc377d8 + 54f4dd4 commit e3c6b6a

File tree

5 files changed

+261
-110
lines changed

5 files changed

+261
-110
lines changed

README.md

Lines changed: 98 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ A **CSS Module** is a CSS file in which all class names and animation names are
1111

1212
Compiling in runtime, [universal](https://medium.com/@mjackson/universal-javascript-4761051b7ae9) usage.
1313

14-
## Usage
1514

16-
### Requirements
15+
## Requirements
1716

1817
To use this tool we require [Node.js v0.12.x](https://github.com/nodejs/node) (or higher) and several modules to be installed.
1918

@@ -22,76 +21,133 @@ To use this tool we require [Node.js v0.12.x](https://github.com/nodejs/node) (o
2221
- [postcss-modules-local-by-default](https://github.com/css-modules/postcss-modules-local-by-default)
2322
- [postcss-modules-scope](https://github.com/css-modules/postcss-modules-scope)
2423

25-
### Installation
24+
## Installation
2625

2726
```bash
2827
$ npm i css-modules-require-hook
2928
```
3029

31-
### Tuning (options)
32-
33-
* `function` **createImportedName** — short alias for the [postcss-modules-extract-imports](https://github.com/css-modules/postcss-modules-extract-imports) plugin's `createImportedName` option.
34-
* `function` **generateScopedName** — short alias for the [postcss-modules-scope](https://github.com/css-modules/postcss-modules-scope) plugin's option. Helps you to specify the custom way to build generic names for the class selectors.
35-
* `function` **preprocessCss** — in rare cases you may want to precompile styles, before they will be passed to the postcss pipeline. You should use **synchronous** transformations, since `require` function is synchronous.
36-
* `function` **processCss** — in rare cases you may want to get compiled styles in runtime, so providing this option helps.
37-
* `string` **rootDir** — absolute path to the project directory. Providing this will result in better generated class names. It can be obligatory, if you run require hook and build tools (like [css-modulesify](https://github.com/css-modules/css-modulesify)) from different working directories.
38-
* `string` **to** — provides `to` option to the [LazyResult instance](https://github.com/postcss/postcss/blob/master/docs/api.md#processorprocesscss-opts).
39-
* `array` **use** — custom subset of postcss plugins.
40-
* `array` **extensions** — attach the hook to additional file extensions (for example `['.scss']`).
30+
## Usage
4131

42-
### Examples
32+
In this section I've tried to cover the common cases of usage.
4333

44-
Basically you need to load this module before you start loading css-modules. Otherwise you'll get an exception. For example:
34+
### Basic example
4535

46-
*icon.css*
47-
```css
48-
.icon
49-
{
50-
composes: fa fa-hand-peace-o from 'font-awesome/css/font-awesome.css';
51-
}
52-
```
36+
Basically to attach the require hook you need to require this module. If you need to adjust it see the tuning section below.
5337

54-
*server.js*
5538
```javascript
5639
require('css-modules-require-hook');
5740

58-
var styles = require('./icon.css');
59-
var html = '<i class="' + styles.icon + '"></i>';
60-
// send it somehow :)
41+
// var styles = require('./icon.css');
6142
```
6243

63-
You'll get:
44+
### Adding custom PostCSS plugins
45+
46+
```javascript
47+
var hook = require('css-modules-require-hook');
48+
var cssnext = require('cssnext');
6449

65-
```html
66-
<i class="_icon_font-awesome-css-font-awesome__fa _icon_font-awesome-css-font-awesome__fa-hand-peace-o"></i>'
50+
hook({
51+
prepend: [
52+
// adding CSS Next plugin
53+
cssnext(),
54+
],
55+
});
6756
```
6857

69-
In rare cases you may want to tune the require hook for better experience.
58+
### Specify custom function to build generic names
7059

7160
```javascript
7261
var hook = require('css-modules-require-hook');
73-
var path = require('path');
62+
63+
// specify your custom function
64+
function generateScopedName(exportedName, path) {/* your code here */}
7465

7566
hook({
76-
// setting root to the parent directory
77-
rootDir: path.join(__dirname, '..')
67+
generateScopedName: generateScopedName,
7868
});
7969
```
8070

81-
If you want to add any postcss plugins to the pipeline - you should use the `use` option.
71+
### Using Stylus as a preprocessor
8272

8373
```javascript
8474
var hook = require('css-modules-require-hook');
75+
var stylus = require('stylus');
8576

8677
hook({
87-
use: [
88-
// adding CSS Next plugin
89-
require('cssnext')(),
78+
extensions: ['.styl'],
79+
preprocessCss: function (css, filename) {
80+
return stylus(css)
81+
.set('filename', filename)
82+
.render();
83+
},
84+
});
85+
86+
// var styles = require('./demo.styl');
87+
```
9088

91-
// adding basic css-modules plugins
92-
require('postcss-modules-extract-imports'),
93-
require('postcss-modules-local-by-default'),
94-
require('postcss-modules-scope')
95-
]
89+
## Tuning (options)
90+
91+
To adjust the require hook you need to provide params to the exported function.
92+
93+
```javascript
94+
var hook = require('css-modules-require-hook');
95+
96+
hook({
97+
// append: [],
98+
// generateScopedName: function () {},
99+
// or any other options
100+
// see the list below
96101
});
97102
```
103+
104+
### `append` array
105+
106+
Appends custom plugins to the end of the PostCSS pipeline.
107+
108+
### `prepend` array
109+
110+
Prepends custom plugins to the beginning of the PostCSS pipeline.
111+
112+
### `use` array
113+
114+
Provides the full list of PostCSS plugins to the pipeline. Providing this cancels `append`, `prepend`, `createImportedName`, `generateScopedName` options.
115+
116+
### `preprocessCss` function
117+
118+
In rare cases you may want to precompile styles, before they will be passed to the PostCSS pipeline. You should use **synchronous** transformations, since `require` function is synchronous.
119+
120+
### `processCss` function
121+
122+
In rare cases you may want to get compiled styles in runtime, so providing this option helps.
123+
124+
### `extensions` array
125+
126+
Attach the require hook to additional file extensions (for example `['.scss']`).
127+
128+
### `rootDir` string
129+
130+
Provides absolute path to the project directory. Providing this will result in better generated class names. It can be obligatory, if you run require hook and build tools (like [css-modulesify](https://github.com/css-modules/css-modulesify)) from different working directories.
131+
132+
### `to` string
133+
134+
Provides `to` option to the [LazyResult instance](https://github.com/postcss/postcss/blob/master/docs/api.md#processorprocesscss-opts).
135+
136+
### `createImportedName` function
137+
138+
Short alias for the [postcss-modules-extract-imports](https://github.com/css-modules/postcss-modules-extract-imports) plugin's `createImportedName` option.
139+
140+
### `generateScopedName` function
141+
142+
Short alias for the [postcss-modules-scope](https://github.com/css-modules/postcss-modules-scope) plugin's option. Helps you to specify the custom way to build generic names for the class selectors.
143+
144+
### `mode` string
145+
146+
Short alias for the [postcss-modules-local-by-default](https://github.com/css-modules/postcss-modules-local-by-default) plugin's option.
147+
148+
## Debugging
149+
150+
[debug](https://www.npmjs.com/package/debug) package is used for debugging. So to turn it on simply specify the **DEBUG** environment variable:
151+
- `DEBUG=css-modules:fetch` &mdash; to see resolved paths to the files.
152+
- `DEBUG=css-modules:setup` &mdash; to see the new options list.
153+
- `DEBUG=css-modules:*` &mdash; to see everything.

src/index.js

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,25 @@ export default function setup(opts = {}) {
6363
return void (plugins = customPlugins);
6464
}
6565

66-
plugins = [];
67-
66+
const prepend = get('prepend', null, 'array', opts) || [];
67+
const append = get('append', null, 'array', opts) || [];
6868
const mode = get('mode', null, 'string', opts);
69-
plugins.push(mode
70-
? new LocalByDefault({mode: opts.mode})
71-
: LocalByDefault);
72-
7369
const createImportedName = get('createImportedName', null, 'function', opts);
74-
plugins.push(createImportedName
75-
? new ExtractImports({createImportedName: opts.createImportedName})
76-
: ExtractImports);
77-
7870
const generateScopedName = get('generateScopedName', null, 'function', opts);
79-
plugins.push(generateScopedName
80-
? new Scope({generateScopedName: opts.generateScopedName})
81-
: Scope);
71+
72+
plugins = [
73+
...prepend,
74+
mode
75+
? new LocalByDefault({mode: opts.mode})
76+
: LocalByDefault,
77+
createImportedName
78+
? new ExtractImports({createImportedName: opts.createImportedName})
79+
: ExtractImports,
80+
generateScopedName
81+
? new Scope({generateScopedName: opts.generateScopedName})
82+
: Scope,
83+
...append,
84+
];
8285
}
8386

8487
/**
@@ -98,10 +101,11 @@ function fetch(_to, _from, _trace) {
98101
// checking cache
99102
let tokens = tokensByFile[filename];
100103
if (tokens) {
104+
debugFetch({cache: true, filename});
101105
return tokens;
102106
}
103107

104-
debugFetch(filename);
108+
debugFetch({cache: false, filename});
105109
const rootRelativePath = sep + relative(rootDir, filename);
106110
const CSSSource = preProcess(readFileSync(filename, 'utf8'), filename);
107111

test/plugins.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
import { equal } from 'assert';
22
import { identity } from 'lodash';
3+
import { dropCache } from '../utils/sugar';
34
import hook from '../src';
45

56
import ExtractImports from 'postcss-modules-extract-imports';
67
import LocalByDefault from 'postcss-modules-local-by-default';
78
import Scope from 'postcss-modules-scope';
89

910
describe('plugins', () => {
10-
beforeEach(() => {
11-
// clearing cache
12-
delete require.cache[require.resolve('awesome-theme/oceanic.css')];
13-
});
11+
afterEach(() => dropCache('awesome-theme/oceanic.css'));
1412

1513
describe('custom generateScopedName() function', () => {
1614
before(() => hook({generateScopedName: identity}));

0 commit comments

Comments
 (0)