Skip to content

Commit d9517fc

Browse files
committed
Merge pull request #46 from css-modules/long-and-short-scoped-names
update to allow passing a generateScopedName func directly
2 parents 8465246 + 50f3a4f commit d9517fc

File tree

3 files changed

+61
-8
lines changed

3 files changed

+61
-8
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ b.bundle();
5151
- `output`: path to write the generated css.
5252
- `jsonOutput`: optional path to write a json manifest of classnames.
5353
- `use`: optional array of postcss plugins (by default we use the css-modules core plugins).
54+
- `generateScopedName`: (API only) a function to override the default behaviour of creating locally scoped classnames.
5455

5556
## Using CSS Modules on the backend
5657

@@ -89,6 +90,20 @@ browserify -p [css-modulesify \
8990
[postcss-modules-extract-imports]: https://github.com/css-modules/postcss-modules-extract-imports
9091
[postcss-modules-scope]: https://github.com/css-modules/postcss-modules-scope
9192

93+
## Building for production
94+
95+
If you set `NODE_ENV=production` then `css-modulesify` will generate shorter (though less useful) classnames.
96+
97+
You can also manually switch to short names by setting the `generateScopedName` option. Eg:
98+
99+
```
100+
browserify.plugin(cssModulesify, {
101+
rootDir: __dirname,
102+
output: './dist/main.css',
103+
generateScopedName: cssModulesify.generateShortName
104+
})
105+
```
106+
92107
## Example
93108

94109
An example implementation can be found [here](https://github.com/css-modules/browserify-demo).

index.js

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,50 @@ var FileSystemLoader = require('css-modules-loader-core/lib/file-system-loader')
66
var assign = require('object-assign');
77
var stringHash = require('string-hash');
88

9+
10+
/*
11+
Custom `generateScopedName` function for `postcss-modules-scope`.
12+
Short names consisting of source hash and line number.
13+
*/
14+
function generateShortName (name, filename, css) {
15+
// first occurrence of the name
16+
// TOOD: better match with regex
17+
var i = css.indexOf('.' + name);
18+
var numLines = css.substr(0, i).split(/[\r\n]/).length;
19+
20+
var hash = stringHash(css).toString(36).substr(0, 5);
21+
return '_' + name + '_' + hash + '_' + numLines;
22+
}
23+
924
/*
1025
Custom `generateScopedName` function for `postcss-modules-scope`.
1126
Appends a hash of the css source.
1227
*/
13-
function createScopedNameFunc (plugin) {
14-
var orig = plugin.generateScopedName;
15-
return function (name, filename, css) {
16-
var hash = stringHash(css).toString(36).substr(0, 5);
17-
return orig.apply(plugin, arguments) + '___' + hash;
18-
};
28+
function generateLongName (name, filename) {
29+
var sanitisedPath = filename.replace(/\.[^\.\/\\]+$/, '')
30+
.replace(/[\W_]+/g, '_')
31+
.replace(/^_|_$/g, '');
32+
33+
return '_' + sanitisedPath + '__' + name;
34+
}
35+
36+
/*
37+
Get the default plugins and apply options.
38+
*/
39+
function getDefaultPlugins (options) {
40+
var scope = Core.scope;
41+
var customNameFunc = options.generateScopedName;
42+
var defaultNameFunc = process.env.NODE_ENV === 'production' ?
43+
generateShortName :
44+
generateLongName;
45+
46+
scope.generateScopedName = customNameFunc || defaultNameFunc;
47+
48+
return [
49+
Core.localByDefault
50+
, Core.extractImports
51+
, scope
52+
];
1953
}
2054

2155
/*
@@ -71,7 +105,7 @@ module.exports = function (browserify, options) {
71105
// PostCSS plugins passed to FileSystemLoader
72106
var plugins = options.use || options.u;
73107
if (!plugins) {
74-
plugins = Core.defaultPlugins;
108+
plugins = getDefaultPlugins(options);
75109
}
76110
else {
77111
if (typeof plugins === 'string') {
@@ -95,7 +129,7 @@ module.exports = function (browserify, options) {
95129
if (name === 'postcss-modules-scope') {
96130
options[name] = options[name] || {};
97131
if (!options[name].generateScopedName) {
98-
options[name].generateScopedName = createScopedNameFunc(plugin);
132+
options[name].generateScopedName = generateLongName;
99133
}
100134
}
101135

@@ -174,3 +208,6 @@ module.exports = function (browserify, options) {
174208

175209
return browserify;
176210
};
211+
212+
module.exports.generateShortName = generateShortName;
213+
module.exports.generateLongName = generateLongName;

tests/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ function runTestCase (dir) {
2929
b.plugin(cssModulesify, {
3030
rootDir: path.join(casesDir, dir)
3131
, output: cssOutFilename
32+
, generateScopedName: cssModulesify.generateLongName
3233
});
3334

3435
b.bundle(function (err) {

0 commit comments

Comments
 (0)