|
1 |
| -import postcss from 'postcss' |
2 |
| -import replaceSymbols, {replaceAll} from 'icss-replace-symbols' |
| 1 | +'use strict'; |
3 | 2 |
|
4 |
| -const matchImports = /^(.+?|\([\s\S]+?\))\s+from\s+("[^"]*"|'[^']*'|[\w-]+)$/ |
5 |
| -const matchValueDefinition = /(?:\s+|^)([\w-]+):?\s+(.+?)\s*$/g |
6 |
| -const matchImport = /^([\w-]+)(?:\s+as\s+([\w-]+))?/ |
7 |
| -let options = {} |
8 |
| -let importIndex = 0 |
9 |
| -let createImportedName = options && options.createImportedName || ((importName/*, path*/) => `i__const_${importName.replace(/\W/g, '_')}_${importIndex++}`) |
| 3 | +const postcss = require('postcss'); |
| 4 | +const ICSSReplaceSymbols = require('icss-replace-symbols'); |
| 5 | +const replaceSymbols = require('icss-replace-symbols'); |
10 | 6 |
|
11 |
| -export default postcss.plugin('postcss-modules-values', () => (css, result) => { |
12 |
| - let importAliases = [] |
13 |
| - let definitions = {} |
| 7 | +const matchImports = /^(.+?|\([\s\S]+?\))\s+from\s+("[^"]*"|'[^']*'|[\w-]+)$/; |
| 8 | +const matchValueDefinition = /(?:\s+|^)([\w-]+):?\s+(.+?)\s*$/g; |
| 9 | +const matchImport = /^([\w-]+)(?:\s+as\s+([\w-]+))?/; |
14 | 10 |
|
15 |
| - const addDefinition = atRule => { |
16 |
| - let matches |
17 |
| - while (matches = matchValueDefinition.exec(atRule.params)) { |
18 |
| - let [/*match*/, key, value] = matches |
19 |
| - // Add to the definitions, knowing that values can refer to each other |
20 |
| - definitions[key] = replaceAll(definitions, value) |
21 |
| - atRule.remove() |
22 |
| - } |
23 |
| - } |
| 11 | +let options = {}; |
| 12 | +let importIndex = 0; |
| 13 | +let createImportedName = |
| 14 | + (options && options.createImportedName) || |
| 15 | + ((importName /*, path*/) => |
| 16 | + `i__const_${importName.replace(/\W/g, '_')}_${importIndex++}`); |
24 | 17 |
|
25 |
| - const addImport = atRule => { |
26 |
| - let matches = matchImports.exec(atRule.params) |
27 |
| - if (matches) { |
28 |
| - let [/*match*/, aliases, path] = matches |
29 |
| - // We can use constants for path names |
30 |
| - if (definitions[path]) path = definitions[path] |
31 |
| - let imports = aliases.replace(/^\(\s*([\s\S]+)\s*\)$/, '$1').split(/\s*,\s*/).map(alias => { |
32 |
| - let tokens = matchImport.exec(alias) |
33 |
| - if (tokens) { |
34 |
| - let [/*match*/, theirName, myName = theirName] = tokens |
35 |
| - let importedName = createImportedName(myName) |
36 |
| - definitions[myName] = importedName |
37 |
| - return { theirName, importedName } |
38 |
| - } else { |
39 |
| - throw new Error(`@import statement "${alias}" is invalid!`) |
40 |
| - } |
41 |
| - }) |
42 |
| - importAliases.push({ path, imports }) |
43 |
| - atRule.remove() |
44 |
| - } |
45 |
| - } |
| 18 | +module.exports = postcss.plugin( |
| 19 | + 'postcss-modules-values', |
| 20 | + () => (css, result) => { |
| 21 | + const importAliases = []; |
| 22 | + const definitions = {}; |
46 | 23 |
|
47 |
| - /* Look at all the @value statements and treat them as locals or as imports */ |
48 |
| - css.walkAtRules('value', atRule => { |
49 |
| - if (matchImports.exec(atRule.params)) { |
50 |
| - addImport(atRule) |
51 |
| - } else { |
52 |
| - if (atRule.params.indexOf('@value') !== -1) { |
53 |
| - result.warn('Invalid value definition: ' + atRule.params) |
| 24 | + const addDefinition = atRule => { |
| 25 | + let matches; |
| 26 | + while ((matches = matchValueDefinition.exec(atRule.params))) { |
| 27 | + let [, /*match*/ key, value] = matches; |
| 28 | + // Add to the definitions, knowing that values can refer to each other |
| 29 | + definitions[key] = replaceSymbols.replaceAll(definitions, value); |
| 30 | + atRule.remove(); |
54 | 31 | }
|
| 32 | + }; |
55 | 33 |
|
56 |
| - addDefinition(atRule) |
57 |
| - } |
58 |
| - }) |
| 34 | + const addImport = atRule => { |
| 35 | + const matches = matchImports.exec(atRule.params); |
| 36 | + if (matches) { |
| 37 | + let [, /*match*/ aliases, path] = matches; |
| 38 | + // We can use constants for path names |
| 39 | + if (definitions[path]) { |
| 40 | + path = definitions[path]; |
| 41 | + } |
| 42 | + const imports = aliases |
| 43 | + .replace(/^\(\s*([\s\S]+)\s*\)$/, '$1') |
| 44 | + .split(/\s*,\s*/) |
| 45 | + .map(alias => { |
| 46 | + const tokens = matchImport.exec(alias); |
| 47 | + if (tokens) { |
| 48 | + const [, /*match*/ theirName, myName = theirName] = tokens; |
| 49 | + const importedName = createImportedName(myName); |
| 50 | + definitions[myName] = importedName; |
| 51 | + return { theirName, importedName }; |
| 52 | + } else { |
| 53 | + throw new Error(`@import statement "${alias}" is invalid!`); |
| 54 | + } |
| 55 | + }); |
| 56 | + importAliases.push({ path, imports }); |
| 57 | + atRule.remove(); |
| 58 | + } |
| 59 | + }; |
59 | 60 |
|
60 |
| - /* We want to export anything defined by now, but don't add it to the CSS yet or |
| 61 | + /* Look at all the @value statements and treat them as locals or as imports */ |
| 62 | + css.walkAtRules('value', atRule => { |
| 63 | + if (matchImports.exec(atRule.params)) { |
| 64 | + addImport(atRule); |
| 65 | + } else { |
| 66 | + if (atRule.params.indexOf('@value') !== -1) { |
| 67 | + result.warn('Invalid value definition: ' + atRule.params); |
| 68 | + } |
| 69 | + |
| 70 | + addDefinition(atRule); |
| 71 | + } |
| 72 | + }); |
| 73 | + |
| 74 | + /* We want to export anything defined by now, but don't add it to the CSS yet or |
61 | 75 | it well get picked up by the replacement stuff */
|
62 |
| - let exportDeclarations = Object.keys(definitions).map(key => postcss.decl({ |
63 |
| - value: definitions[key], |
64 |
| - prop: key, |
65 |
| - raws: { before: "\n " } |
66 |
| - })) |
| 76 | + const exportDeclarations = Object.keys(definitions).map(key => |
| 77 | + postcss.decl({ |
| 78 | + value: definitions[key], |
| 79 | + prop: key, |
| 80 | + raws: { before: '\n ' } |
| 81 | + }) |
| 82 | + ); |
67 | 83 |
|
68 |
| - /* If we have no definitions, don't continue */ |
69 |
| - if (!Object.keys(definitions).length) return |
| 84 | + /* If we have no definitions, don't continue */ |
| 85 | + if (!Object.keys(definitions).length) { |
| 86 | + return; |
| 87 | + } |
70 | 88 |
|
71 |
| - /* Perform replacements */ |
72 |
| - replaceSymbols(css, definitions) |
| 89 | + /* Perform replacements */ |
| 90 | + ICSSReplaceSymbols.default(css, definitions); |
73 | 91 |
|
74 |
| - /* Add export rules if any */ |
75 |
| - if (exportDeclarations.length > 0) { |
76 |
| - let exportRule = postcss.rule({ |
77 |
| - selector: `:export`, |
78 |
| - raws: { after: "\n" } |
79 |
| - }) |
80 |
| - exportRule.append(exportDeclarations) |
81 |
| - css.prepend(exportRule) |
82 |
| - } |
| 92 | + /* Add export rules if any */ |
| 93 | + if (exportDeclarations.length > 0) { |
| 94 | + const exportRule = postcss.rule({ |
| 95 | + selector: ':export', |
| 96 | + raws: { after: '\n' } |
| 97 | + }); |
| 98 | + exportRule.append(exportDeclarations); |
| 99 | + css.prepend(exportRule); |
| 100 | + } |
83 | 101 |
|
84 |
| - /* Add import rules */ |
85 |
| - importAliases.reverse().forEach(({ path, imports }) => { |
86 |
| - let importRule = postcss.rule({ |
87 |
| - selector: `:import(${path})`, |
88 |
| - raws: { after: "\n" } |
89 |
| - }) |
90 |
| - imports.forEach(({ theirName, importedName }) => { |
91 |
| - importRule.append({ |
92 |
| - value: theirName, |
93 |
| - prop: importedName, |
94 |
| - raws: { before: "\n " } |
95 |
| - }) |
96 |
| - }) |
| 102 | + /* Add import rules */ |
| 103 | + importAliases.reverse().forEach(({ path, imports }) => { |
| 104 | + const importRule = postcss.rule({ |
| 105 | + selector: `:import(${path})`, |
| 106 | + raws: { after: '\n' } |
| 107 | + }); |
| 108 | + imports.forEach(({ theirName, importedName }) => { |
| 109 | + importRule.append({ |
| 110 | + value: theirName, |
| 111 | + prop: importedName, |
| 112 | + raws: { before: '\n ' } |
| 113 | + }); |
| 114 | + }); |
97 | 115 |
|
98 |
| - css.prepend(importRule) |
99 |
| - }) |
100 |
| -}) |
| 116 | + css.prepend(importRule); |
| 117 | + }); |
| 118 | + } |
| 119 | +); |
0 commit comments