|
2 | 2 | MIT License http://www.opensource.org/licenses/mit-license.php |
3 | 3 | Author Tobias Koppers @sokra |
4 | 4 | */ |
5 | | -const Tokenizer = require('css-selector-tokenizer'); |
6 | 5 | const postcss = require('postcss'); |
7 | 6 | const loaderUtils = require('loader-utils'); |
8 | 7 |
|
9 | | -const icssUtils = require('icss-utils'); |
10 | 8 | const localByDefault = require('postcss-modules-local-by-default'); |
11 | 9 | const extractImports = require('postcss-modules-extract-imports'); |
12 | 10 | const modulesScope = require('postcss-modules-scope'); |
13 | 11 | const modulesValues = require('postcss-modules-values'); |
14 | | -const valueParser = require('postcss-value-parser'); |
| 12 | + |
| 13 | +const cssLoaderParser = require('./postcss-css-loader-parser'); |
15 | 14 |
|
16 | 15 | const CssSyntaxError = require('./CssSyntaxError'); |
17 | 16 | const getLocalIdent = require('./getLocalIdent'); |
18 | 17 |
|
19 | | -const parserPlugin = postcss.plugin('css-loader-parser', (options) => (css) => { |
20 | | - const imports = {}; |
21 | | - let exports = {}; |
22 | | - const importItems = []; |
23 | | - const urlItems = []; |
24 | | - |
25 | | - function replaceImportsInString(str) { |
26 | | - if (options.import) { |
27 | | - const tokens = valueParser(str); |
28 | | - tokens.walk((node) => { |
29 | | - if (node.type !== 'word') { |
30 | | - return; |
31 | | - } |
32 | | - const token = node.value; |
33 | | - const importIndex = imports[`$${token}`]; |
34 | | - if (typeof importIndex === 'number') { |
35 | | - // eslint-disable-next-line no-param-reassign |
36 | | - node.value = `___CSS_LOADER_IMPORT___${importIndex}___`; |
37 | | - } |
38 | | - }); |
39 | | - return tokens.toString(); |
40 | | - } |
41 | | - return str; |
42 | | - } |
43 | | - |
44 | | - if (options.import) { |
45 | | - css.walkAtRules(/^import$/i, (rule) => { |
46 | | - const values = Tokenizer.parseValues(rule.params); |
47 | | - let [url] = values.nodes[0].nodes; |
48 | | - if (url && url.type === 'url') { |
49 | | - ({ url } = url); |
50 | | - } else if (url && url.type === 'string') { |
51 | | - url = url.value; |
52 | | - } else throw rule.error(`Unexpected format ${rule.params}`); |
53 | | - if (!url.replace(/\s/g, '').length) { |
54 | | - return; |
55 | | - } |
56 | | - values.nodes[0].nodes.shift(); |
57 | | - const mediaQuery = Tokenizer.stringifyValues(values); |
58 | | - |
59 | | - if (loaderUtils.isUrlRequest(url)) { |
60 | | - url = loaderUtils.urlToRequest(url); |
61 | | - } |
62 | | - |
63 | | - importItems.push({ |
64 | | - url, |
65 | | - mediaQuery, |
66 | | - }); |
67 | | - rule.remove(); |
68 | | - }); |
69 | | - } |
70 | | - |
71 | | - const icss = icssUtils.extractICSS(css); |
72 | | - exports = icss.icssExports; |
73 | | - Object.keys(icss.icssImports).forEach((key) => { |
74 | | - const url = loaderUtils.parseString(key); |
75 | | - Object.keys(icss.icssImports[key]).forEach((prop) => { |
76 | | - imports[`$${prop}`] = importItems.length; |
77 | | - importItems.push({ |
78 | | - url, |
79 | | - export: icss.icssImports[key][prop], |
80 | | - }); |
81 | | - }); |
82 | | - }); |
83 | | - |
84 | | - Object.keys(exports).forEach((exportName) => { |
85 | | - exports[exportName] = replaceImportsInString(exports[exportName]); |
86 | | - }); |
87 | | - |
88 | | - function processNode(item) { |
89 | | - switch (item.type) { |
90 | | - case 'value': |
91 | | - item.nodes.forEach(processNode); |
92 | | - break; |
93 | | - case 'nested-item': |
94 | | - item.nodes.forEach(processNode); |
95 | | - break; |
96 | | - case 'item': { |
97 | | - const importIndex = imports[`$${item.name}`]; |
98 | | - if (typeof importIndex === 'number') { |
99 | | - // eslint-disable-next-line no-param-reassign |
100 | | - item.name = `___CSS_LOADER_IMPORT___${importIndex}___`; |
101 | | - } |
102 | | - break; |
103 | | - } |
104 | | - case 'url': |
105 | | - if ( |
106 | | - options.url && |
107 | | - item.url.replace(/\s/g, '').length && |
108 | | - !/^#/.test(item.url) && |
109 | | - loaderUtils.isUrlRequest(item.url) |
110 | | - ) { |
111 | | - // Strip quotes, they will be re-added if the module needs them |
112 | | - /* eslint-disable no-param-reassign */ |
113 | | - item.stringType = ''; |
114 | | - delete item.innerSpacingBefore; |
115 | | - delete item.innerSpacingAfter; |
116 | | - const { url } = item; |
117 | | - item.url = `___CSS_LOADER_URL___${urlItems.length}___`; |
118 | | - /* eslint-enable no-param-reassign */ |
119 | | - urlItems.push({ |
120 | | - url, |
121 | | - }); |
122 | | - } |
123 | | - break; |
124 | | - // no default |
125 | | - } |
126 | | - } |
127 | | - |
128 | | - css.walkDecls((decl) => { |
129 | | - const values = Tokenizer.parseValues(decl.value); |
130 | | - values.nodes.forEach((value) => { |
131 | | - value.nodes.forEach(processNode); |
132 | | - }); |
133 | | - // eslint-disable-next-line no-param-reassign |
134 | | - decl.value = Tokenizer.stringifyValues(values); |
135 | | - }); |
136 | | - css.walkAtRules((atrule) => { |
137 | | - if (typeof atrule.params === 'string') { |
138 | | - // eslint-disable-next-line no-param-reassign |
139 | | - atrule.params = replaceImportsInString(atrule.params); |
140 | | - } |
141 | | - }); |
142 | | - |
143 | | - /* eslint-disable no-param-reassign */ |
144 | | - options.importItems = importItems; |
145 | | - options.urlItems = urlItems; |
146 | | - options.exports = exports; |
147 | | - /* eslint-enable no-param-reassign */ |
148 | | -}); |
149 | | - |
150 | 18 | module.exports = function processCss(inputSource, inputMap, options, callback) { |
151 | 19 | const { query } = options; |
152 | 20 | const { context, localIdentRegExp } = query; |
@@ -197,7 +65,7 @@ module.exports = function processCss(inputSource, inputMap, options, callback) { |
197 | 65 | ); |
198 | 66 | }, |
199 | 67 | }), |
200 | | - parserPlugin(parserOptions), |
| 68 | + cssLoaderParser(parserOptions), |
201 | 69 | ]); |
202 | 70 |
|
203 | 71 | pipeline |
|
0 commit comments