|
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 | | -exportdefaultpostcss.plugin('postcss-modules-values',()=>(css,result)=>{ |
12 | | -letimportAliases=[] |
13 | | -letdefinitions={} |
| 7 | +constmatchImports=/^(.+?|\([\s\S]+?\))\s+from\s+("[^"]*"|'[^']*'|[\w-]+)$/; |
| 8 | +constmatchValueDefinition=/(?:\s+|^)([\w-]+):?\s+(.+?)\s*$/g; |
| 9 | +constmatchImport=/^([\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 | + constaddDefinition=atRule=>{ |
| 25 | + letmatches; |
| 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