/
index.js
91 lines (73 loc) · 2.86 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
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(),
hashPrefix: opts.hashPrefix
});
}
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) {
Object.keys(parser.exportTokens).forEach(token => {
const camelCaseToken = camelCase(token);
parser.exportTokens[camelCaseToken] = parser.exportTokens[token];
});
}
result.messages.push({
type: "export",
plugin: "postcss-modules",
exportTokens: parser.exportTokens
});
// getJSON may return a promise
return getJSON(css.source.input.file, parser.exportTokens, result.opts.to);
};
});