@parcel/transformer-css 2.3.2 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/CSSTransformer.js +183 -298
- package/package.json +9 -13
- package/src/CSSTransformer.js +191 -324
package/lib/CSSTransformer.js
CHANGED
|
@@ -5,10 +5,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
-
function
|
|
9
|
-
const data = require("
|
|
8
|
+
function _path() {
|
|
9
|
+
const data = _interopRequireDefault(require("path"));
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
_path = function () {
|
|
12
12
|
return data;
|
|
13
13
|
};
|
|
14
14
|
|
|
@@ -35,118 +35,76 @@ function _plugin() {
|
|
|
35
35
|
return data;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
function
|
|
39
|
-
const data = require("@parcel/
|
|
38
|
+
function _css() {
|
|
39
|
+
const data = require("@parcel/css");
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
_css = function () {
|
|
42
42
|
return data;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
return data;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
function
|
|
49
|
-
const data =
|
|
48
|
+
function _utils() {
|
|
49
|
+
const data = require("@parcel/utils");
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
_utils = function () {
|
|
52
52
|
return data;
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
return data;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
function
|
|
59
|
-
const data = _interopRequireDefault(require("
|
|
58
|
+
function _browserslist() {
|
|
59
|
+
const data = _interopRequireDefault(require("browserslist"));
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
_browserslist = function () {
|
|
62
62
|
return data;
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
return data;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
function
|
|
69
|
-
const data = _interopRequireDefault(require("
|
|
68
|
+
function _nullthrows() {
|
|
69
|
+
const data = _interopRequireDefault(require("nullthrows"));
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
_nullthrows = function () {
|
|
72
72
|
return data;
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
return data;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
function
|
|
79
|
-
const data =
|
|
78
|
+
function _diagnostic() {
|
|
79
|
+
const data = _interopRequireWildcard(require("@parcel/diagnostic"));
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
_diagnostic = function () {
|
|
82
82
|
return data;
|
|
83
83
|
};
|
|
84
84
|
|
|
85
85
|
return data;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
function
|
|
89
|
-
const data = _interopRequireDefault(require("path"));
|
|
88
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
90
89
|
|
|
91
|
-
|
|
92
|
-
return data;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
return data;
|
|
96
|
-
}
|
|
90
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
97
91
|
|
|
98
92
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
99
93
|
|
|
100
|
-
const URL_RE = /url\s*\(/;
|
|
101
|
-
const IMPORT_RE = /@import/;
|
|
102
|
-
const COMPOSES_RE = /composes:.+from\s*("|').*("|')\s*;?/;
|
|
103
|
-
const FROM_IMPORT_RE = /.+from\s*(?:"|')(.*)(?:"|')\s*;?/;
|
|
104
|
-
const MODULE_BY_NAME_RE = /\.module\./;
|
|
105
|
-
|
|
106
|
-
function canHaveDependencies(filePath, code) {
|
|
107
|
-
return !/\.css$/.test(filePath) || IMPORT_RE.test(code) || URL_RE.test(code);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
94
|
var _default = new (_plugin().Transformer)({
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return ast.type === 'postcss' && _semver().default.satisfies(ast.version, '^8.2.1');
|
|
115
|
-
},
|
|
116
|
-
|
|
117
|
-
async parse({
|
|
118
|
-
asset
|
|
95
|
+
async loadConfig({
|
|
96
|
+
config,
|
|
97
|
+
options
|
|
119
98
|
}) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
// resolve a dependency for the id which obviously doesn't exist. Also, it's faster to do
|
|
125
|
-
// it this way since the resulting CSS doesn't need to be re-parsed.
|
|
126
|
-
let isCSSModule = asset.meta.cssModulesCompiled !== true && MODULE_BY_NAME_RE.test(asset.filePath);
|
|
127
|
-
|
|
128
|
-
if (asset.meta.hasDependencies === false && !isCSSModule) {
|
|
129
|
-
return null;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
let code = await asset.getCode();
|
|
133
|
-
|
|
134
|
-
if (code != null && !canHaveDependencies(asset.filePath, code) && !isCSSModule) {
|
|
135
|
-
return null;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
type: 'postcss',
|
|
140
|
-
version: '8.2.1',
|
|
141
|
-
program: _postcss().default.parse(code, {
|
|
142
|
-
from: asset.filePath
|
|
143
|
-
}).toJSON()
|
|
144
|
-
};
|
|
99
|
+
let conf = await config.getConfigFrom(options.projectRoot + '/index', [], {
|
|
100
|
+
packageKey: '@parcel/transformer-css'
|
|
101
|
+
});
|
|
102
|
+
return conf === null || conf === void 0 ? void 0 : conf.contents;
|
|
145
103
|
},
|
|
146
104
|
|
|
147
105
|
async transform({
|
|
148
106
|
asset,
|
|
149
|
-
|
|
107
|
+
config,
|
|
150
108
|
options
|
|
151
109
|
}) {
|
|
152
110
|
// Normalize the asset's environment so that properties that only affect JS don't cause CSS to be duplicated.
|
|
@@ -158,273 +116,200 @@ var _default = new (_plugin().Transformer)({
|
|
|
158
116
|
browsers: asset.env.engines.browsers
|
|
159
117
|
},
|
|
160
118
|
shouldOptimize: asset.env.shouldOptimize,
|
|
119
|
+
shouldScopeHoist: asset.env.shouldScopeHoist,
|
|
161
120
|
sourceMap: asset.env.sourceMap
|
|
162
121
|
});
|
|
163
|
-
let
|
|
164
|
-
|
|
165
|
-
|
|
122
|
+
let [code, originalMap] = await Promise.all([asset.getBuffer(), asset.getMap()]);
|
|
123
|
+
let targets = getTargets(asset.env.engines.browsers);
|
|
124
|
+
let res;
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
if (asset.meta.type === 'attr') {
|
|
128
|
+
res = (0, _css().transformStyleAttribute)({
|
|
129
|
+
code,
|
|
130
|
+
analyzeDependencies: true,
|
|
131
|
+
targets
|
|
132
|
+
});
|
|
133
|
+
} else {
|
|
134
|
+
var _config$cssModules;
|
|
135
|
+
|
|
136
|
+
res = (0, _css().transform)({
|
|
137
|
+
filename: _path().default.relative(options.projectRoot, asset.filePath),
|
|
138
|
+
code,
|
|
139
|
+
cssModules: asset.meta.type !== 'tag' && ((_config$cssModules = config === null || config === void 0 ? void 0 : config.cssModules) !== null && _config$cssModules !== void 0 ? _config$cssModules : asset.meta.cssModulesCompiled == null && /\.module\./.test(asset.filePath)),
|
|
140
|
+
analyzeDependencies: asset.meta.hasDependencies !== false,
|
|
141
|
+
sourceMap: !!asset.env.sourceMap,
|
|
142
|
+
drafts: config === null || config === void 0 ? void 0 : config.drafts,
|
|
143
|
+
pseudoClasses: config === null || config === void 0 ? void 0 : config.pseudoClasses,
|
|
144
|
+
targets
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
} catch (err) {
|
|
148
|
+
var _err$data;
|
|
166
149
|
|
|
167
|
-
|
|
150
|
+
err.filePath = asset.filePath;
|
|
151
|
+
let diagnostic = (0, _diagnostic().errorToDiagnostic)(err, {
|
|
152
|
+
origin: '@parcel/transformer-css'
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
if (((_err$data = err.data) === null || _err$data === void 0 ? void 0 : _err$data.type) === 'AmbiguousUrlInCustomProperty' && err.data.url) {
|
|
156
|
+
let p = '/' + (0, _utils().relativePath)(options.projectRoot, _path().default.resolve(_path().default.dirname(asset.filePath), err.data.url), false);
|
|
157
|
+
diagnostic[0].hints = [`Replace with: url(${p})`];
|
|
158
|
+
diagnostic[0].documentationURL = 'https://parceljs.org/languages/css/#url()';
|
|
159
|
+
}
|
|
168
160
|
|
|
169
|
-
|
|
170
|
-
|
|
161
|
+
throw new (_diagnostic().default)({
|
|
162
|
+
diagnostic
|
|
163
|
+
});
|
|
171
164
|
}
|
|
172
165
|
|
|
173
|
-
|
|
166
|
+
asset.setBuffer(res.code);
|
|
174
167
|
|
|
175
|
-
|
|
168
|
+
if (res.map != null) {
|
|
169
|
+
let vlqMap = JSON.parse(res.map.toString());
|
|
170
|
+
let map = new (_sourceMap().default)(options.projectRoot);
|
|
171
|
+
map.addVLQMap(vlqMap);
|
|
176
172
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
173
|
+
if (originalMap) {
|
|
174
|
+
map.extends(originalMap);
|
|
175
|
+
}
|
|
180
176
|
|
|
181
|
-
|
|
182
|
-
return assets;
|
|
177
|
+
asset.setMap(map);
|
|
183
178
|
}
|
|
184
179
|
|
|
185
|
-
|
|
180
|
+
if (res.dependencies) {
|
|
181
|
+
for (let dep of res.dependencies) {
|
|
182
|
+
let loc = dep.loc;
|
|
186
183
|
|
|
187
|
-
|
|
188
|
-
|
|
184
|
+
if (originalMap) {
|
|
185
|
+
loc = (0, _utils().remapSourceLocation)(loc, originalMap);
|
|
186
|
+
}
|
|
189
187
|
|
|
190
|
-
|
|
191
|
-
|
|
188
|
+
if (dep.type === 'import' && !res.exports) {
|
|
189
|
+
asset.addDependency({
|
|
190
|
+
specifier: dep.url,
|
|
191
|
+
specifierType: 'url',
|
|
192
|
+
loc,
|
|
193
|
+
meta: {
|
|
194
|
+
// For the glob resolver to distinguish between `@import` and other URL dependencies.
|
|
195
|
+
isCSSImport: true,
|
|
196
|
+
media: dep.media
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
} else if (dep.type === 'url') {
|
|
200
|
+
asset.addURLDependency(dep.url, {
|
|
201
|
+
loc,
|
|
202
|
+
meta: {
|
|
203
|
+
placeholder: dep.placeholder
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
192
207
|
}
|
|
208
|
+
}
|
|
193
209
|
|
|
194
|
-
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
let isDirty = false;
|
|
198
|
-
program.walkAtRules('import', rule => {
|
|
199
|
-
let params = (0, _postcssValueParser().default)(rule.params);
|
|
200
|
-
let [name, ...media] = params.nodes;
|
|
201
|
-
let specifier;
|
|
210
|
+
let assets = [asset];
|
|
202
211
|
|
|
203
|
-
|
|
204
|
-
|
|
212
|
+
if (res.exports != null) {
|
|
213
|
+
let exports = res.exports;
|
|
214
|
+
asset.symbols.ensure();
|
|
215
|
+
asset.symbols.set('default', 'default');
|
|
216
|
+
let dependencies = new Map();
|
|
217
|
+
let locals = new Map();
|
|
218
|
+
let c = 0;
|
|
219
|
+
let depjs = '';
|
|
220
|
+
let js = '';
|
|
221
|
+
|
|
222
|
+
for (let key in exports) {
|
|
223
|
+
locals.set(exports[key].name, key);
|
|
205
224
|
}
|
|
206
225
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if (!specifier) {
|
|
210
|
-
throw new Error('Could not find import name for ' + String(rule));
|
|
211
|
-
} // If this came from an inline <style> tag, don't inline the imported file. Replace with the correct URL instead.
|
|
212
|
-
// TODO: run CSSPackager on inline style tags.
|
|
213
|
-
// let inlineHTML =
|
|
214
|
-
// this.options.rendition && this.options.rendition.inlineHTML;
|
|
215
|
-
// if (inlineHTML) {
|
|
216
|
-
// name.value = asset.addURLDependency(dep, {loc: rule.source.start});
|
|
217
|
-
// rule.params = params.toString();
|
|
218
|
-
// } else {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
media = _postcssValueParser().default.stringify(media).trim();
|
|
222
|
-
let dep = {
|
|
223
|
-
specifier,
|
|
224
|
-
specifierType: 'url',
|
|
225
|
-
// Offset by 8 as it does not include `@import `
|
|
226
|
-
loc: createLoc((0, _nullthrows().default)(rule.source.start), specifier, 0, 8),
|
|
227
|
-
meta: {
|
|
228
|
-
// For the glob resolver to distinguish between `@import` and other URL dependencies.
|
|
229
|
-
isCSSImport: true,
|
|
230
|
-
media
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
asset.addDependency(dep);
|
|
234
|
-
rule.remove(); // }
|
|
226
|
+
let seen = new Set();
|
|
235
227
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (URL_RE.test(decl.value)) {
|
|
240
|
-
let parsed = (0, _postcssValueParser().default)(decl.value);
|
|
241
|
-
let isDeclDirty = false;
|
|
242
|
-
parsed.walk(node => {
|
|
243
|
-
if (node.type === 'function' && node.value === 'url' && node.nodes.length > 0 && !node.nodes[0].value.startsWith('#') // IE's `behavior: url(#default#VML)`
|
|
244
|
-
) {
|
|
245
|
-
let urlNode = node.nodes[0];
|
|
246
|
-
let url = asset.addURLDependency(urlNode.value, {
|
|
247
|
-
loc: decl.source && decl.source.start && createLoc(decl.source.start, urlNode.value, 0, decl.source.start.offset + urlNode.sourceIndex + 1, 0)
|
|
248
|
-
});
|
|
249
|
-
isDeclDirty = urlNode.value !== url;
|
|
250
|
-
urlNode.type = 'string';
|
|
251
|
-
urlNode.quote = '"';
|
|
252
|
-
urlNode.value = url;
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
if (isDeclDirty) {
|
|
257
|
-
decl.value = parsed.toString();
|
|
258
|
-
isDirty = true;
|
|
228
|
+
let add = key => {
|
|
229
|
+
if (seen.has(key)) {
|
|
230
|
+
return;
|
|
259
231
|
}
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
232
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
});
|
|
267
|
-
}
|
|
233
|
+
seen.add(key);
|
|
234
|
+
let e = exports[key];
|
|
235
|
+
let s = `module.exports[${JSON.stringify(key)}] = \`${e.name}`;
|
|
268
236
|
|
|
269
|
-
|
|
270
|
-
|
|
237
|
+
for (let ref of e.composes) {
|
|
238
|
+
s += ' ';
|
|
271
239
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
to: options.projectRoot + '/index',
|
|
280
|
-
map: {
|
|
281
|
-
annotation: false,
|
|
282
|
-
inline: false,
|
|
283
|
-
sourcesContent: false
|
|
284
|
-
},
|
|
285
|
-
// Pass postcss's own stringifier to it to silence its warning
|
|
286
|
-
// as we don't want to perform any transformations -- only generate
|
|
287
|
-
stringifier: _postcss().default.stringify
|
|
288
|
-
});
|
|
289
|
-
let map = null;
|
|
290
|
-
let originalSourceMap = await asset.getMap();
|
|
240
|
+
if (ref.type === 'local') {
|
|
241
|
+
add((0, _nullthrows().default)(locals.get(ref.name)));
|
|
242
|
+
s += '${' + `module.exports[${JSON.stringify((0, _nullthrows().default)(locals.get(ref.name)))}]` + '}';
|
|
243
|
+
} else if (ref.type === 'global') {
|
|
244
|
+
s += ref.name;
|
|
245
|
+
} else if (ref.type === 'dependency') {
|
|
246
|
+
let d = dependencies.get(ref.specifier);
|
|
291
247
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
248
|
+
if (d == null) {
|
|
249
|
+
d = `dep_${c++}`;
|
|
250
|
+
depjs += `import * as ${d} from ${JSON.stringify(ref.specifier)};\n`;
|
|
251
|
+
dependencies.set(ref.specifier, d);
|
|
252
|
+
}
|
|
295
253
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
} else {
|
|
300
|
-
map = originalSourceMap;
|
|
301
|
-
}
|
|
254
|
+
s += '${' + `${d}[${JSON.stringify(ref.name)}]` + '}';
|
|
255
|
+
}
|
|
256
|
+
}
|
|
302
257
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
map
|
|
306
|
-
};
|
|
307
|
-
}
|
|
258
|
+
s += '`;\n'; // If the export is referenced internally (e.g. used @keyframes), add a self-reference
|
|
259
|
+
// to the JS so the symbol is retained during tree-shaking.
|
|
308
260
|
|
|
309
|
-
|
|
261
|
+
if (e.isReferenced) {
|
|
262
|
+
s += `module.exports[${JSON.stringify(key)}];\n`;
|
|
263
|
+
}
|
|
310
264
|
|
|
311
|
-
|
|
265
|
+
js += s;
|
|
266
|
+
};
|
|
312
267
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
if (code == null || COMPOSES_RE.test(code)) {
|
|
318
|
-
program.walkDecls(decl => {
|
|
319
|
-
let [, importPath] = FROM_IMPORT_RE.exec(decl.value) || [];
|
|
320
|
-
|
|
321
|
-
if (decl.prop === 'composes' && importPath != null) {
|
|
322
|
-
let parsed = (0, _postcssValueParser().default)(decl.value);
|
|
323
|
-
let start = decl.source.start;
|
|
324
|
-
parsed.walk(node => {
|
|
325
|
-
if (node.type === 'string') {
|
|
326
|
-
asset.addDependency({
|
|
327
|
-
specifier: importPath,
|
|
328
|
-
specifierType: 'url',
|
|
329
|
-
loc: start ? {
|
|
330
|
-
filePath: asset.filePath,
|
|
331
|
-
start,
|
|
332
|
-
end: {
|
|
333
|
-
line: start.line,
|
|
334
|
-
column: start.column + importPath.length
|
|
335
|
-
}
|
|
336
|
-
} : undefined
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
});
|
|
268
|
+
for (let key in exports) {
|
|
269
|
+
asset.symbols.set(key, exports[key].name);
|
|
270
|
+
add(key);
|
|
340
271
|
}
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
let postcssModules = await options.packageManager.require('postcss-modules', asset.filePath, {
|
|
345
|
-
range: '^4.3.0',
|
|
346
|
-
saveDev: true,
|
|
347
|
-
shouldAutoInstall: options.shouldAutoInstall
|
|
348
|
-
});
|
|
349
|
-
let {
|
|
350
|
-
root
|
|
351
|
-
} = await (0, _postcss().default)([postcssModules({
|
|
352
|
-
getJSON: (filename, json) => cssModules = json,
|
|
353
|
-
Loader: await createLoader(asset, resolve, options),
|
|
354
|
-
generateScopedName: (name, filename) => `${name}_${(0, _hash().hashString)(_path().default.relative(options.projectRoot, filename)).substr(0, 6)}`
|
|
355
|
-
})]).process(program, {
|
|
356
|
-
from: asset.filePath,
|
|
357
|
-
to: asset.filePath
|
|
358
|
-
});
|
|
359
|
-
asset.setAST({
|
|
360
|
-
type: 'postcss',
|
|
361
|
-
version: '8.2.1',
|
|
362
|
-
program: root.toJSON()
|
|
363
|
-
});
|
|
364
|
-
let assets = [asset];
|
|
365
|
-
|
|
366
|
-
if (cssModules) {
|
|
367
|
-
// $FlowFixMe
|
|
368
|
-
let cssModulesList = Object.entries(cssModules);
|
|
369
|
-
let deps = asset.getDependencies().filter(dep => dep.priority === 'sync');
|
|
370
|
-
let code;
|
|
371
|
-
|
|
372
|
-
if (deps.length > 0) {
|
|
373
|
-
code = `
|
|
374
|
-
module.exports = Object.assign({}, ${deps.map(dep => `require(${JSON.stringify(dep.specifier)})`).join(', ')}, ${JSON.stringify(cssModules, null, 2)});
|
|
375
|
-
`;
|
|
376
|
-
} else {
|
|
377
|
-
code = cssModulesList.map( // This syntax enables shaking the invidual statements, so that unused classes don't even exist in JS.
|
|
378
|
-
([className, classNameHashed]) => `module.exports[${JSON.stringify(className)}] = ${JSON.stringify(classNameHashed)};`).join('\n');
|
|
379
|
-
}
|
|
380
272
|
|
|
381
|
-
|
|
273
|
+
if (res.dependencies) {
|
|
274
|
+
for (let dep of res.dependencies) {
|
|
275
|
+
if (dep.type === 'import') {
|
|
276
|
+
// TODO: Figure out how to treeshake this
|
|
277
|
+
let d = `dep_$${c++}`;
|
|
278
|
+
depjs += `import * as ${d} from ${JSON.stringify(dep.url)};\n`;
|
|
279
|
+
js += `for (let key in ${d}) { if (key in module.exports) module.exports[key] += ' ' + ${d}[key]; else module.exports[key] = ${d}[key]; }\n`;
|
|
280
|
+
asset.symbols.set('*', '*');
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
382
284
|
|
|
383
|
-
|
|
384
|
-
|
|
285
|
+
assets.push({
|
|
286
|
+
type: 'js',
|
|
287
|
+
content: depjs + js,
|
|
288
|
+
dependencies: [],
|
|
289
|
+
env
|
|
290
|
+
});
|
|
385
291
|
}
|
|
386
292
|
|
|
387
|
-
|
|
388
|
-
assets.push({
|
|
389
|
-
type: 'js',
|
|
390
|
-
content: code,
|
|
391
|
-
env
|
|
392
|
-
});
|
|
293
|
+
return assets;
|
|
393
294
|
}
|
|
394
295
|
|
|
395
|
-
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
async function createLoader(asset, resolve, options) {
|
|
399
|
-
let {
|
|
400
|
-
default: FileSystemLoader
|
|
401
|
-
} = await options.packageManager.require('postcss-modules/build/css-loader-core/loader', asset.filePath);
|
|
402
|
-
return class extends FileSystemLoader {
|
|
403
|
-
async fetch(composesPath, relativeTo) {
|
|
404
|
-
let importPath = composesPath.replace(/^["']|["']$/g, '');
|
|
405
|
-
let resolved = await resolve(relativeTo, importPath);
|
|
406
|
-
|
|
407
|
-
let rootRelativePath = _path().default.resolve(_path().default.dirname(relativeTo), resolved);
|
|
408
|
-
|
|
409
|
-
let root = _path().default.resolve('/'); // fixes an issue on windows which is part of the css-modules-loader-core
|
|
410
|
-
// see https://github.com/css-modules/css-modules-loader-core/issues/230
|
|
296
|
+
});
|
|
411
297
|
|
|
298
|
+
exports.default = _default;
|
|
299
|
+
let cache = new Map();
|
|
412
300
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
301
|
+
function getTargets(browsers) {
|
|
302
|
+
if (browsers == null) {
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
416
305
|
|
|
417
|
-
|
|
418
|
-
let {
|
|
419
|
-
exportTokens
|
|
420
|
-
} = await this.core.load(source, rootRelativePath, undefined, // $FlowFixMe[method-unbinding]
|
|
421
|
-
this.fetch.bind(this));
|
|
422
|
-
return exportTokens;
|
|
423
|
-
}
|
|
306
|
+
let cached = cache.get(browsers);
|
|
424
307
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
308
|
+
if (cached != null) {
|
|
309
|
+
return cached;
|
|
310
|
+
}
|
|
428
311
|
|
|
429
|
-
|
|
312
|
+
let targets = (0, _css().browserslistToTargets)((0, _browserslist().default)(browsers));
|
|
313
|
+
cache.set(browsers, targets);
|
|
314
|
+
return targets;
|
|
430
315
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parcel/transformer-css",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -17,20 +17,16 @@
|
|
|
17
17
|
"source": "src/CSSTransformer.js",
|
|
18
18
|
"engines": {
|
|
19
19
|
"node": ">= 12.0.0",
|
|
20
|
-
"parcel": "^2.
|
|
20
|
+
"parcel": "^2.5.0"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@parcel/
|
|
24
|
-
"@parcel/
|
|
23
|
+
"@parcel/css": "^1.8.1",
|
|
24
|
+
"@parcel/diagnostic": "2.5.0",
|
|
25
|
+
"@parcel/plugin": "2.5.0",
|
|
25
26
|
"@parcel/source-map": "^2.0.0",
|
|
26
|
-
"@parcel/utils": "2.
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"postcss-value-parser": "^4.2.0",
|
|
30
|
-
"semver": "^5.7.1"
|
|
27
|
+
"@parcel/utils": "2.5.0",
|
|
28
|
+
"browserslist": "^4.6.6",
|
|
29
|
+
"nullthrows": "^1.1.1"
|
|
31
30
|
},
|
|
32
|
-
"
|
|
33
|
-
"postcss-modules": "^4.3.0"
|
|
34
|
-
},
|
|
35
|
-
"gitHead": "47379bf8fabeb2cfe03ade8802d942388b153e5b"
|
|
31
|
+
"gitHead": "5cfb846d742eb86b1232e531be6e0e513551d838"
|
|
36
32
|
}
|
package/src/CSSTransformer.js
CHANGED
|
@@ -1,68 +1,26 @@
|
|
|
1
|
-
// @flow
|
|
1
|
+
// @flow strict-local
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import type {FilePath, MutableAsset, PluginOptions} from '@parcel/types';
|
|
5
|
-
|
|
6
|
-
import {hashString} from '@parcel/hash';
|
|
3
|
+
import path from 'path';
|
|
7
4
|
import SourceMap from '@parcel/source-map';
|
|
8
5
|
import {Transformer} from '@parcel/plugin';
|
|
9
|
-
import {
|
|
10
|
-
|
|
6
|
+
import {
|
|
7
|
+
transform,
|
|
8
|
+
transformStyleAttribute,
|
|
9
|
+
browserslistToTargets,
|
|
10
|
+
} from '@parcel/css';
|
|
11
|
+
import {remapSourceLocation, relativePath} from '@parcel/utils';
|
|
12
|
+
import browserslist from 'browserslist';
|
|
11
13
|
import nullthrows from 'nullthrows';
|
|
12
|
-
import
|
|
13
|
-
import semver from 'semver';
|
|
14
|
-
import path from 'path';
|
|
15
|
-
|
|
16
|
-
const URL_RE = /url\s*\(/;
|
|
17
|
-
const IMPORT_RE = /@import/;
|
|
18
|
-
const COMPOSES_RE = /composes:.+from\s*("|').*("|')\s*;?/;
|
|
19
|
-
const FROM_IMPORT_RE = /.+from\s*(?:"|')(.*)(?:"|')\s*;?/;
|
|
20
|
-
const MODULE_BY_NAME_RE = /\.module\./;
|
|
21
|
-
|
|
22
|
-
function canHaveDependencies(filePath: FilePath, code: string) {
|
|
23
|
-
return !/\.css$/.test(filePath) || IMPORT_RE.test(code) || URL_RE.test(code);
|
|
24
|
-
}
|
|
14
|
+
import ThrowableDiagnostic, {errorToDiagnostic} from '@parcel/diagnostic';
|
|
25
15
|
|
|
26
16
|
export default (new Transformer({
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// This is set by other transformers (e.g. Stylus) to indicate that it has already processed
|
|
33
|
-
// all dependencies, and that the CSS transformer can skip this asset completely. This is
|
|
34
|
-
// required because when stylus processes e.g. url() it replaces them with a dependency id
|
|
35
|
-
// to be filled in later. When the CSS transformer runs, it would pick that up and try to
|
|
36
|
-
// resolve a dependency for the id which obviously doesn't exist. Also, it's faster to do
|
|
37
|
-
// it this way since the resulting CSS doesn't need to be re-parsed.
|
|
38
|
-
let isCSSModule =
|
|
39
|
-
asset.meta.cssModulesCompiled !== true &&
|
|
40
|
-
MODULE_BY_NAME_RE.test(asset.filePath);
|
|
41
|
-
if (asset.meta.hasDependencies === false && !isCSSModule) {
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
let code = await asset.getCode();
|
|
46
|
-
if (
|
|
47
|
-
code != null &&
|
|
48
|
-
!canHaveDependencies(asset.filePath, code) &&
|
|
49
|
-
!isCSSModule
|
|
50
|
-
) {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return {
|
|
55
|
-
type: 'postcss',
|
|
56
|
-
version: '8.2.1',
|
|
57
|
-
program: postcss
|
|
58
|
-
.parse(code, {
|
|
59
|
-
from: asset.filePath,
|
|
60
|
-
})
|
|
61
|
-
.toJSON(),
|
|
62
|
-
};
|
|
17
|
+
async loadConfig({config, options}) {
|
|
18
|
+
let conf = await config.getConfigFrom(options.projectRoot + '/index', [], {
|
|
19
|
+
packageKey: '@parcel/transformer-css',
|
|
20
|
+
});
|
|
21
|
+
return conf?.contents;
|
|
63
22
|
},
|
|
64
|
-
|
|
65
|
-
async transform({asset, resolve, options}) {
|
|
23
|
+
async transform({asset, config, options}) {
|
|
66
24
|
// Normalize the asset's environment so that properties that only affect JS don't cause CSS to be duplicated.
|
|
67
25
|
// For example, with ESModule and CommonJS targets, only a single shared CSS bundle should be produced.
|
|
68
26
|
let env = asset.env;
|
|
@@ -72,305 +30,214 @@ export default (new Transformer({
|
|
|
72
30
|
browsers: asset.env.engines.browsers,
|
|
73
31
|
},
|
|
74
32
|
shouldOptimize: asset.env.shouldOptimize,
|
|
33
|
+
shouldScopeHoist: asset.env.shouldScopeHoist,
|
|
75
34
|
sourceMap: asset.env.sourceMap,
|
|
76
35
|
});
|
|
77
36
|
|
|
78
|
-
let
|
|
79
|
-
asset.
|
|
80
|
-
|
|
37
|
+
let [code, originalMap] = await Promise.all([
|
|
38
|
+
asset.getBuffer(),
|
|
39
|
+
asset.getMap(),
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
let targets = getTargets(asset.env.engines.browsers);
|
|
43
|
+
let res;
|
|
44
|
+
try {
|
|
45
|
+
if (asset.meta.type === 'attr') {
|
|
46
|
+
res = transformStyleAttribute({
|
|
47
|
+
code,
|
|
48
|
+
analyzeDependencies: true,
|
|
49
|
+
targets,
|
|
50
|
+
});
|
|
51
|
+
} else {
|
|
52
|
+
res = transform({
|
|
53
|
+
filename: path.relative(options.projectRoot, asset.filePath),
|
|
54
|
+
code,
|
|
55
|
+
cssModules:
|
|
56
|
+
asset.meta.type !== 'tag' &&
|
|
57
|
+
(config?.cssModules ??
|
|
58
|
+
(asset.meta.cssModulesCompiled == null &&
|
|
59
|
+
/\.module\./.test(asset.filePath))),
|
|
60
|
+
analyzeDependencies: asset.meta.hasDependencies !== false,
|
|
61
|
+
sourceMap: !!asset.env.sourceMap,
|
|
62
|
+
drafts: config?.drafts,
|
|
63
|
+
pseudoClasses: config?.pseudoClasses,
|
|
64
|
+
targets,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
} catch (err) {
|
|
68
|
+
err.filePath = asset.filePath;
|
|
69
|
+
let diagnostic = errorToDiagnostic(err, {
|
|
70
|
+
origin: '@parcel/transformer-css',
|
|
71
|
+
});
|
|
72
|
+
if (err.data?.type === 'AmbiguousUrlInCustomProperty' && err.data.url) {
|
|
73
|
+
let p =
|
|
74
|
+
'/' +
|
|
75
|
+
relativePath(
|
|
76
|
+
options.projectRoot,
|
|
77
|
+
path.resolve(path.dirname(asset.filePath), err.data.url),
|
|
78
|
+
false,
|
|
79
|
+
);
|
|
80
|
+
diagnostic[0].hints = [`Replace with: url(${p})`];
|
|
81
|
+
diagnostic[0].documentationURL =
|
|
82
|
+
'https://parceljs.org/languages/css/#url()';
|
|
83
|
+
}
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
let ast = await asset.getAST();
|
|
86
|
-
if (!ast || (asset.meta.hasDependencies === false && !isCSSModule)) {
|
|
87
|
-
return [asset];
|
|
85
|
+
throw new ThrowableDiagnostic({
|
|
86
|
+
diagnostic,
|
|
87
|
+
});
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
let assets = [asset];
|
|
92
|
-
if (isCSSModule) {
|
|
93
|
-
assets = await compileCSSModules(asset, env, program, resolve, options);
|
|
94
|
-
}
|
|
90
|
+
asset.setBuffer(res.code);
|
|
95
91
|
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
|
|
92
|
+
if (res.map != null) {
|
|
93
|
+
let vlqMap = JSON.parse(res.map.toString());
|
|
94
|
+
let map = new SourceMap(options.projectRoot);
|
|
95
|
+
map.addVLQMap(vlqMap);
|
|
99
96
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
let loc = createDependencyLocation(
|
|
103
|
-
start,
|
|
104
|
-
specifier,
|
|
105
|
-
lineOffset,
|
|
106
|
-
colOffset,
|
|
107
|
-
o,
|
|
108
|
-
);
|
|
109
|
-
if (originalSourceMap) {
|
|
110
|
-
loc = remapSourceLocation(loc, originalSourceMap);
|
|
97
|
+
if (originalMap) {
|
|
98
|
+
map.extends(originalMap);
|
|
111
99
|
}
|
|
112
|
-
return loc;
|
|
113
|
-
};
|
|
114
100
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
let
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
101
|
+
asset.setMap(map);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (res.dependencies) {
|
|
105
|
+
for (let dep of res.dependencies) {
|
|
106
|
+
let loc = dep.loc;
|
|
107
|
+
if (originalMap) {
|
|
108
|
+
loc = remapSourceLocation(loc, originalMap);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (dep.type === 'import' && !res.exports) {
|
|
112
|
+
asset.addDependency({
|
|
113
|
+
specifier: dep.url,
|
|
114
|
+
specifierType: 'url',
|
|
115
|
+
loc,
|
|
116
|
+
meta: {
|
|
117
|
+
// For the glob resolver to distinguish between `@import` and other URL dependencies.
|
|
118
|
+
isCSSImport: true,
|
|
119
|
+
media: dep.media,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
} else if (dep.type === 'url') {
|
|
123
|
+
asset.addURLDependency(dep.url, {
|
|
124
|
+
loc,
|
|
125
|
+
meta: {
|
|
126
|
+
placeholder: dep.placeholder,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
126
130
|
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let assets = [asset];
|
|
127
134
|
|
|
128
|
-
|
|
135
|
+
if (res.exports != null) {
|
|
136
|
+
let exports = res.exports;
|
|
137
|
+
asset.symbols.ensure();
|
|
138
|
+
asset.symbols.set('default', 'default');
|
|
129
139
|
|
|
130
|
-
|
|
131
|
-
|
|
140
|
+
let dependencies = new Map();
|
|
141
|
+
let locals = new Map();
|
|
142
|
+
let c = 0;
|
|
143
|
+
let depjs = '';
|
|
144
|
+
let js = '';
|
|
145
|
+
|
|
146
|
+
let jsDeps = [];
|
|
147
|
+
|
|
148
|
+
for (let key in exports) {
|
|
149
|
+
locals.set(exports[key].name, key);
|
|
132
150
|
}
|
|
133
151
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
152
|
+
let seen = new Set();
|
|
153
|
+
let add = key => {
|
|
154
|
+
if (seen.has(key)) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
seen.add(key);
|
|
158
|
+
|
|
159
|
+
let e = exports[key];
|
|
160
|
+
let s = `module.exports[${JSON.stringify(key)}] = \`${e.name}`;
|
|
161
|
+
|
|
162
|
+
for (let ref of e.composes) {
|
|
163
|
+
s += ' ';
|
|
164
|
+
if (ref.type === 'local') {
|
|
165
|
+
add(nullthrows(locals.get(ref.name)));
|
|
166
|
+
s +=
|
|
167
|
+
'${' +
|
|
168
|
+
`module.exports[${JSON.stringify(
|
|
169
|
+
nullthrows(locals.get(ref.name)),
|
|
170
|
+
)}]` +
|
|
171
|
+
'}';
|
|
172
|
+
} else if (ref.type === 'global') {
|
|
173
|
+
s += ref.name;
|
|
174
|
+
} else if (ref.type === 'dependency') {
|
|
175
|
+
let d = dependencies.get(ref.specifier);
|
|
176
|
+
if (d == null) {
|
|
177
|
+
d = `dep_${c++}`;
|
|
178
|
+
depjs += `import * as ${d} from ${JSON.stringify(
|
|
179
|
+
ref.specifier,
|
|
180
|
+
)};\n`;
|
|
181
|
+
dependencies.set(ref.specifier, d);
|
|
182
|
+
}
|
|
183
|
+
s += '${' + `${d}[${JSON.stringify(ref.name)}]` + '}';
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
s += '`;\n';
|
|
188
|
+
|
|
189
|
+
// If the export is referenced internally (e.g. used @keyframes), add a self-reference
|
|
190
|
+
// to the JS so the symbol is retained during tree-shaking.
|
|
191
|
+
if (e.isReferenced) {
|
|
192
|
+
s += `module.exports[${JSON.stringify(key)}];\n`;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
js += s;
|
|
153
196
|
};
|
|
154
|
-
asset.addDependency(dep);
|
|
155
|
-
rule.remove();
|
|
156
|
-
// }
|
|
157
|
-
isDirty = true;
|
|
158
|
-
});
|
|
159
197
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
198
|
+
for (let key in exports) {
|
|
199
|
+
asset.symbols.set(key, exports[key].name);
|
|
200
|
+
add(key);
|
|
201
|
+
}
|
|
164
202
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
let url = asset.addURLDependency(urlNode.value, {
|
|
174
|
-
loc:
|
|
175
|
-
decl.source &&
|
|
176
|
-
decl.source.start &&
|
|
177
|
-
createLoc(
|
|
178
|
-
decl.source.start,
|
|
179
|
-
urlNode.value,
|
|
180
|
-
0,
|
|
181
|
-
decl.source.start.offset + urlNode.sourceIndex + 1,
|
|
182
|
-
0,
|
|
183
|
-
),
|
|
184
|
-
});
|
|
185
|
-
isDeclDirty = urlNode.value !== url;
|
|
186
|
-
urlNode.type = 'string';
|
|
187
|
-
urlNode.quote = '"';
|
|
188
|
-
urlNode.value = url;
|
|
203
|
+
if (res.dependencies) {
|
|
204
|
+
for (let dep of res.dependencies) {
|
|
205
|
+
if (dep.type === 'import') {
|
|
206
|
+
// TODO: Figure out how to treeshake this
|
|
207
|
+
let d = `dep_$${c++}`;
|
|
208
|
+
depjs += `import * as ${d} from ${JSON.stringify(dep.url)};\n`;
|
|
209
|
+
js += `for (let key in ${d}) { if (key in module.exports) module.exports[key] += ' ' + ${d}[key]; else module.exports[key] = ${d}[key]; }\n`;
|
|
210
|
+
asset.symbols.set('*', '*');
|
|
189
211
|
}
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
if (isDeclDirty) {
|
|
193
|
-
decl.value = parsed.toString();
|
|
194
|
-
isDirty = true;
|
|
195
212
|
}
|
|
196
213
|
}
|
|
197
|
-
});
|
|
198
214
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
215
|
+
assets.push({
|
|
216
|
+
type: 'js',
|
|
217
|
+
content: depjs + js,
|
|
218
|
+
dependencies: jsDeps,
|
|
219
|
+
env,
|
|
203
220
|
});
|
|
204
221
|
}
|
|
205
222
|
|
|
206
223
|
return assets;
|
|
207
224
|
},
|
|
208
|
-
|
|
209
|
-
async generate({asset, ast, options}) {
|
|
210
|
-
let result = await postcss().process(postcss.fromJSON(ast.program), {
|
|
211
|
-
from: undefined,
|
|
212
|
-
to: options.projectRoot + '/index',
|
|
213
|
-
map: {
|
|
214
|
-
annotation: false,
|
|
215
|
-
inline: false,
|
|
216
|
-
sourcesContent: false,
|
|
217
|
-
},
|
|
218
|
-
// Pass postcss's own stringifier to it to silence its warning
|
|
219
|
-
// as we don't want to perform any transformations -- only generate
|
|
220
|
-
stringifier: postcss.stringify,
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
let map = null;
|
|
224
|
-
let originalSourceMap = await asset.getMap();
|
|
225
|
-
if (result.map != null) {
|
|
226
|
-
map = new SourceMap(options.projectRoot);
|
|
227
|
-
map.addVLQMap(result.map.toJSON());
|
|
228
|
-
if (originalSourceMap) {
|
|
229
|
-
map.extends(originalSourceMap.toBuffer());
|
|
230
|
-
}
|
|
231
|
-
} else {
|
|
232
|
-
map = originalSourceMap;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return {
|
|
236
|
-
content: result.css,
|
|
237
|
-
map,
|
|
238
|
-
};
|
|
239
|
-
},
|
|
240
225
|
}): Transformer);
|
|
241
226
|
|
|
242
|
-
|
|
243
|
-
let cssModules;
|
|
227
|
+
let cache = new Map();
|
|
244
228
|
|
|
245
|
-
|
|
246
|
-
if (
|
|
247
|
-
|
|
248
|
-
let [, importPath] = FROM_IMPORT_RE.exec(decl.value) || [];
|
|
249
|
-
if (decl.prop === 'composes' && importPath != null) {
|
|
250
|
-
let parsed = valueParser(decl.value);
|
|
251
|
-
let start = (decl.source.start: any);
|
|
252
|
-
|
|
253
|
-
parsed.walk(node => {
|
|
254
|
-
if (node.type === 'string') {
|
|
255
|
-
asset.addDependency({
|
|
256
|
-
specifier: importPath,
|
|
257
|
-
specifierType: 'url',
|
|
258
|
-
loc: start
|
|
259
|
-
? {
|
|
260
|
-
filePath: asset.filePath,
|
|
261
|
-
start,
|
|
262
|
-
end: {
|
|
263
|
-
line: start.line,
|
|
264
|
-
column: start.column + importPath.length,
|
|
265
|
-
},
|
|
266
|
-
}
|
|
267
|
-
: undefined,
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
});
|
|
229
|
+
function getTargets(browsers) {
|
|
230
|
+
if (browsers == null) {
|
|
231
|
+
return undefined;
|
|
273
232
|
}
|
|
274
233
|
|
|
275
|
-
let
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
{
|
|
279
|
-
range: '^4.3.0',
|
|
280
|
-
saveDev: true,
|
|
281
|
-
shouldAutoInstall: options.shouldAutoInstall,
|
|
282
|
-
},
|
|
283
|
-
);
|
|
284
|
-
|
|
285
|
-
let {root} = await postcss([
|
|
286
|
-
postcssModules({
|
|
287
|
-
getJSON: (filename, json) => (cssModules = json),
|
|
288
|
-
Loader: await createLoader(asset, resolve, options),
|
|
289
|
-
generateScopedName: (name, filename) =>
|
|
290
|
-
`${name}_${hashString(
|
|
291
|
-
path.relative(options.projectRoot, filename),
|
|
292
|
-
).substr(0, 6)}`,
|
|
293
|
-
}),
|
|
294
|
-
]).process(program, {from: asset.filePath, to: asset.filePath});
|
|
295
|
-
asset.setAST({
|
|
296
|
-
type: 'postcss',
|
|
297
|
-
version: '8.2.1',
|
|
298
|
-
program: root.toJSON(),
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
let assets = [asset];
|
|
302
|
-
if (cssModules) {
|
|
303
|
-
// $FlowFixMe
|
|
304
|
-
let cssModulesList = (Object.entries(cssModules): Array<[string, string]>);
|
|
305
|
-
let deps = asset.getDependencies().filter(dep => dep.priority === 'sync');
|
|
306
|
-
let code: string;
|
|
307
|
-
if (deps.length > 0) {
|
|
308
|
-
code = `
|
|
309
|
-
module.exports = Object.assign({}, ${deps
|
|
310
|
-
.map(dep => `require(${JSON.stringify(dep.specifier)})`)
|
|
311
|
-
.join(', ')}, ${JSON.stringify(cssModules, null, 2)});
|
|
312
|
-
`;
|
|
313
|
-
} else {
|
|
314
|
-
code = cssModulesList
|
|
315
|
-
.map(
|
|
316
|
-
// This syntax enables shaking the invidual statements, so that unused classes don't even exist in JS.
|
|
317
|
-
([className, classNameHashed]) =>
|
|
318
|
-
`module.exports[${JSON.stringify(className)}] = ${JSON.stringify(
|
|
319
|
-
classNameHashed,
|
|
320
|
-
)};`,
|
|
321
|
-
)
|
|
322
|
-
.join('\n');
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
asset.symbols.ensure();
|
|
326
|
-
for (let [k, v] of cssModulesList) {
|
|
327
|
-
asset.symbols.set(k, v);
|
|
328
|
-
}
|
|
329
|
-
asset.symbols.set('default', 'default');
|
|
330
|
-
|
|
331
|
-
assets.push({
|
|
332
|
-
type: 'js',
|
|
333
|
-
content: code,
|
|
334
|
-
env,
|
|
335
|
-
});
|
|
234
|
+
let cached = cache.get(browsers);
|
|
235
|
+
if (cached != null) {
|
|
236
|
+
return cached;
|
|
336
237
|
}
|
|
337
|
-
return assets;
|
|
338
|
-
}
|
|
339
238
|
|
|
340
|
-
|
|
341
|
-
asset: MutableAsset,
|
|
342
|
-
resolve: (from: FilePath, to: string) => Promise<FilePath>,
|
|
343
|
-
options: PluginOptions,
|
|
344
|
-
) {
|
|
345
|
-
let {default: FileSystemLoader} = await options.packageManager.require(
|
|
346
|
-
'postcss-modules/build/css-loader-core/loader',
|
|
347
|
-
asset.filePath,
|
|
348
|
-
);
|
|
349
|
-
return class ParcelFileSystemLoader extends FileSystemLoader {
|
|
350
|
-
async fetch(composesPath, relativeTo) {
|
|
351
|
-
let importPath = composesPath.replace(/^["']|["']$/g, '');
|
|
352
|
-
let resolved = await resolve(relativeTo, importPath);
|
|
353
|
-
let rootRelativePath = path.resolve(path.dirname(relativeTo), resolved);
|
|
354
|
-
let root = path.resolve('/');
|
|
355
|
-
// fixes an issue on windows which is part of the css-modules-loader-core
|
|
356
|
-
// see https://github.com/css-modules/css-modules-loader-core/issues/230
|
|
357
|
-
if (rootRelativePath.startsWith(root)) {
|
|
358
|
-
rootRelativePath = rootRelativePath.substr(root.length);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
let source = await asset.fs.readFile(resolved, 'utf-8');
|
|
362
|
-
let {exportTokens} = await this.core.load(
|
|
363
|
-
source,
|
|
364
|
-
rootRelativePath,
|
|
365
|
-
undefined,
|
|
366
|
-
// $FlowFixMe[method-unbinding]
|
|
367
|
-
this.fetch.bind(this),
|
|
368
|
-
);
|
|
369
|
-
return exportTokens;
|
|
370
|
-
}
|
|
239
|
+
let targets = browserslistToTargets(browserslist(browsers));
|
|
371
240
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
}
|
|
375
|
-
};
|
|
241
|
+
cache.set(browsers, targets);
|
|
242
|
+
return targets;
|
|
376
243
|
}
|