-
Notifications
You must be signed in to change notification settings - Fork 47
Expand file tree
/
Copy pathindex.js
More file actions
136 lines (109 loc) · 3.64 KB
/
Copy pathindex.js
File metadata and controls
136 lines (109 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
var fs = require('fs');
var path = require('path');
var through = require('through');
var Core = require('css-modules-loader-core');
var FileSystemLoader = require('css-modules-loader-core/lib/file-system-loader');
var assign = require('object-assign');
var stringHash = require('string-hash');
/*
Custom `generateScopedName` function for `postcss-modules-scope`.
Appends a hash of the css source.
*/
function createScopedNameFunc (plugin) {
var orig = plugin.generateScopedName;
return function (name, path, css) {
var hash = stringHash(css).toString(36).substr(0, 5);
return orig.apply(plugin, arguments) + '___' + hash;
}
};
var cssExt = /\.css$/;
module.exports = function (browserify, options) {
options = options || {};
var cssOutFilename = options.output || options.o;
if (!cssOutFilename) {
throw new Error('css-modulesify needs the --output / -o option (path to output css file)');
}
// PostCSS plugins passed to FileSystemLoader
var plugins = options.use || options.u;
if (!plugins) {
plugins = Core.defaultPlugins;
} else {
if (typeof plugins === 'string') {
plugins = [ plugins ];
}
plugins = plugins.map(function requirePlugin (name) {
// assume functions are already required plugins
if (typeof name === 'function') {
return name;
}
var plugin = require(require.resolve(name));
// custom scoped name generation
if (name === 'postcss-modules-scope') {
options[name] = options[name] || {};
if (!options[name].generateScopedName) {
options[name].generateScopedName = createScopedNameFunc(plugin);
}
}
if (name in options) {
plugin = plugin(options[name]);
} else {
plugin = plugin.postcss || plugin();
}
return plugin;
});
}
// keep track of css files visited
var filenames = [];
// keep track of all tokens so we can avoid duplicates
var tokensByFile = {};
// keep track of all source files for later builds: when
// using watchify, not all files will be caught on subsequent
// bundles
var sourceByFile = {};
function transform (filename) {
// only handle .css files
if (!cssExt.test(filename)) {
return through();
}
// collect visited filenames
filenames.push(filename);
return through(function noop () {}, function end () {
var self = this;
var loader = new FileSystemLoader(path.dirname(filename), plugins);
// pre-populate the loader's tokensByFile
loader.tokensByFile = tokensByFile;
loader.fetch(path.basename(filename), '/').then(function (tokens) {
var output = "module.exports = " + JSON.stringify(tokens);
assign(tokensByFile, loader.tokensByFile);
// store this file's source to be written out to disk later
sourceByFile[filename] = loader.finalSource;
self.queue(output);
self.queue(null);
}, function (err) {
console.error(err);
});
});
}
browserify.transform(transform, {
global: true
});
// wrap the `bundle` function
var bundle = browserify.bundle;
browserify.bundle = function (cb) {
// reset the `tokensByFile` cache
tokensByFile = {};
// call the original
var stream = bundle.call(browserify, function () {
// Combine the collected sources into a single CSS file
var css = Object.keys(sourceByFile).map(function(file) {
return sourceByFile[file];
}).join('\n');
var args = arguments;
fs.writeFile(cssOutFilename, css, function () {
if (typeof cb === 'function') cb.apply(null, args);
});
});
return stream;
};
return browserify;
};