/
index.js
93 lines (67 loc) · 2.8 KB
/
index.js
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
import postcss from 'postcss';
import camelCase from 'lodash.camelcase';
import Parser from 'css-modules-loader-core/lib/parser';
import FileSystemLoader from 'css-modules-loader-core/lib/file-system-loader';
import genericNames from 'generic-names';
import generateScopedName from './generateScopedName';
import saveJSON from './saveJSON';
import {
getDefaultPlugins,
isValidBehaviour,
behaviours,
} from './behaviours';
const PLUGIN_NAME = 'postcss-modules';
function getDefaultScopeBehaviour(opts) {
if (opts.scopeBehaviour && isValidBehaviour(opts.scopeBehaviour)) {
return opts.scopeBehaviour;
}
return behaviours.LOCAL;
}
function getScopedNameGenerator(opts) {
const scopedNameGenerator = opts.generateScopedName || generateScopedName;
if (typeof scopedNameGenerator === 'function') return scopedNameGenerator;
return genericNames(scopedNameGenerator, { context: process.cwd() });
}
function getLoader(opts, plugins) {
const root = typeof opts.root === 'undefined' ? '/' : opts.root;
return typeof opts.Loader === 'function'
? new opts.Loader(root, plugins)
: new FileSystemLoader(root, plugins);
}
function isGlobalModule(globalModules, inputFile) {
return globalModules.some(regex => inputFile.match(regex));
}
function getDefaultPluginsList(opts, inputFile) {
const globalModulesList = opts.globalModulePaths || null;
const defaultBehaviour = getDefaultScopeBehaviour(opts);
const generateName = getScopedNameGenerator(opts);
if (globalModulesList && isGlobalModule(globalModulesList, inputFile)) {
return getDefaultPlugins(behaviours.GLOBAL, generateName);
}
return getDefaultPlugins(defaultBehaviour, generateName);
}
function isResultPlugin(plugin) {
return plugin.postcssPlugin !== PLUGIN_NAME;
}
module.exports = postcss.plugin(PLUGIN_NAME, (opts = {}) => {
const getJSON = opts.getJSON || saveJSON;
return async (css, result) => {
const inputFile = css.source.input.file;
const resultPlugins = result.processor.plugins.filter(isResultPlugin);
const pluginList = getDefaultPluginsList(opts, inputFile);
const plugins = [...pluginList, ...resultPlugins];
const loader = getLoader(opts, plugins);
const parser = new Parser(loader.fetch.bind(loader));
await postcss([...plugins, parser.plugin]).process(css, { from: inputFile });
const out = loader.finalSource;
if (out) css.prepend(out);
if (opts.camelCase === true) {
Object.keys(parser.exportTokens).forEach((token) => {
const camelCaseToken = camelCase(token);
parser.exportTokens[camelCaseToken] = parser.exportTokens[token];
});
}
// getJSON may return a promise
return getJSON(css.source.input.file, parser.exportTokens, result.opts.to);
};
});