@parcel/transformer-css 2.0.0-nightly.130 → 2.0.0-nightly.1303
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 +320 -119
- package/package.json +15 -9
- package/src/CSSTransformer.js +276 -143
package/lib/CSSTransformer.js
CHANGED
|
@@ -5,173 +5,374 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
function _path() {
|
|
9
|
+
const data = _interopRequireDefault(require("path"));
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
_path = function () {
|
|
12
|
+
return data;
|
|
13
|
+
};
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
13
17
|
|
|
14
|
-
|
|
18
|
+
function _sourceMap() {
|
|
19
|
+
const data = _interopRequireDefault(require("@parcel/source-map"));
|
|
15
20
|
|
|
16
|
-
|
|
21
|
+
_sourceMap = function () {
|
|
22
|
+
return data;
|
|
23
|
+
};
|
|
17
24
|
|
|
18
|
-
|
|
25
|
+
return data;
|
|
26
|
+
}
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
const
|
|
28
|
+
function _plugin() {
|
|
29
|
+
const data = require("@parcel/plugin");
|
|
22
30
|
|
|
23
|
-
function
|
|
24
|
-
|
|
31
|
+
_plugin = function () {
|
|
32
|
+
return data;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return data;
|
|
25
36
|
}
|
|
26
37
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
ast
|
|
30
|
-
}) {
|
|
31
|
-
return ast.type === 'postcss' && _semver.default.satisfies(ast.version, '^7.0.0');
|
|
32
|
-
},
|
|
38
|
+
function _lightningcss() {
|
|
39
|
+
const data = require("lightningcss");
|
|
33
40
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// to be filled in later. When the CSS transformer runs, it would pick that up and try to
|
|
41
|
-
// resolve a dependency for the id which obviously doesn't exist. Also, it's faster to do
|
|
42
|
-
// it this way since the resulting CSS doesn't need to be re-parsed.
|
|
43
|
-
if (asset.meta.hasDependencies === false) {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
41
|
+
_lightningcss = function () {
|
|
42
|
+
return data;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return data;
|
|
46
|
+
}
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
function _utils() {
|
|
49
|
+
const data = require("@parcel/utils");
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
_utils = function () {
|
|
52
|
+
return data;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return data;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function _browserslist() {
|
|
59
|
+
const data = _interopRequireDefault(require("browserslist"));
|
|
60
|
+
|
|
61
|
+
_browserslist = function () {
|
|
62
|
+
return data;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
return data;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function _nullthrows() {
|
|
69
|
+
const data = _interopRequireDefault(require("nullthrows"));
|
|
70
|
+
|
|
71
|
+
_nullthrows = function () {
|
|
72
|
+
return data;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
return data;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function _diagnostic() {
|
|
79
|
+
const data = _interopRequireWildcard(require("@parcel/diagnostic"));
|
|
80
|
+
|
|
81
|
+
_diagnostic = function () {
|
|
82
|
+
return data;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return data;
|
|
86
|
+
}
|
|
87
|
+
|
|
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); }
|
|
89
|
+
|
|
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; }
|
|
52
91
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
92
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
93
|
+
|
|
94
|
+
var _default = new (_plugin().Transformer)({
|
|
95
|
+
async loadConfig({
|
|
96
|
+
config,
|
|
97
|
+
options
|
|
98
|
+
}) {
|
|
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;
|
|
61
103
|
},
|
|
62
104
|
|
|
63
|
-
transform({
|
|
64
|
-
asset
|
|
105
|
+
async transform({
|
|
106
|
+
asset,
|
|
107
|
+
config,
|
|
108
|
+
options,
|
|
109
|
+
logger
|
|
65
110
|
}) {
|
|
66
111
|
// Normalize the asset's environment so that properties that only affect JS don't cause CSS to be duplicated.
|
|
67
112
|
// For example, with ESModule and CommonJS targets, only a single shared CSS bundle should be produced.
|
|
113
|
+
let env = asset.env;
|
|
68
114
|
asset.setEnvironment({
|
|
69
115
|
context: 'browser',
|
|
70
116
|
engines: {
|
|
71
117
|
browsers: asset.env.engines.browsers
|
|
72
118
|
},
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
119
|
+
shouldOptimize: asset.env.shouldOptimize,
|
|
120
|
+
shouldScopeHoist: asset.env.shouldScopeHoist,
|
|
121
|
+
sourceMap: asset.env.sourceMap
|
|
122
|
+
});
|
|
123
|
+
let [code, originalMap] = await Promise.all([asset.getBuffer(), asset.getMap()]);
|
|
124
|
+
let targets = getTargets(asset.env.engines.browsers);
|
|
125
|
+
let res;
|
|
76
126
|
|
|
77
|
-
|
|
78
|
-
asset.
|
|
79
|
-
|
|
127
|
+
try {
|
|
128
|
+
if (asset.meta.type === 'attr') {
|
|
129
|
+
res = (0, _lightningcss().transformStyleAttribute)({
|
|
130
|
+
code,
|
|
131
|
+
analyzeDependencies: true,
|
|
132
|
+
errorRecovery: (config === null || config === void 0 ? void 0 : config.errorRecovery) || false,
|
|
133
|
+
targets
|
|
134
|
+
});
|
|
135
|
+
} else {
|
|
136
|
+
let cssModules = false;
|
|
80
137
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// ast and CSSTransformer's parse was never called.
|
|
138
|
+
if (asset.meta.type !== 'tag' && asset.meta.cssModulesCompiled == null) {
|
|
139
|
+
let cssModulesConfig = config === null || config === void 0 ? void 0 : config.cssModules;
|
|
84
140
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
141
|
+
if (asset.isSource && (typeof cssModulesConfig === 'boolean' || cssModulesConfig !== null && cssModulesConfig !== void 0 && cssModulesConfig.global) || /\.module\./.test(asset.filePath)) {
|
|
142
|
+
if (cssModulesConfig !== null && cssModulesConfig !== void 0 && cssModulesConfig.dashedIdents && !asset.isSource) {
|
|
143
|
+
cssModulesConfig.dashedIdents = false;
|
|
144
|
+
}
|
|
88
145
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
let moduleSpecifier;
|
|
146
|
+
cssModules = cssModulesConfig !== null && cssModulesConfig !== void 0 ? cssModulesConfig : true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
93
149
|
|
|
94
|
-
|
|
95
|
-
|
|
150
|
+
res = (0, _lightningcss().transform)({
|
|
151
|
+
filename: _path().default.relative(options.projectRoot, asset.filePath),
|
|
152
|
+
code,
|
|
153
|
+
cssModules,
|
|
154
|
+
analyzeDependencies: asset.meta.hasDependencies !== false,
|
|
155
|
+
sourceMap: !!asset.env.sourceMap,
|
|
156
|
+
drafts: config === null || config === void 0 ? void 0 : config.drafts,
|
|
157
|
+
pseudoClasses: config === null || config === void 0 ? void 0 : config.pseudoClasses,
|
|
158
|
+
errorRecovery: (config === null || config === void 0 ? void 0 : config.errorRecovery) || false,
|
|
159
|
+
targets
|
|
160
|
+
});
|
|
96
161
|
}
|
|
162
|
+
} catch (err) {
|
|
163
|
+
var _err$data;
|
|
97
164
|
|
|
98
|
-
|
|
165
|
+
err.filePath = asset.filePath;
|
|
166
|
+
let diagnostic = (0, _diagnostic().errorToDiagnostic)(err, {
|
|
167
|
+
origin: '@parcel/transformer-css'
|
|
168
|
+
});
|
|
99
169
|
|
|
100
|
-
if (
|
|
101
|
-
|
|
170
|
+
if (((_err$data = err.data) === null || _err$data === void 0 ? void 0 : _err$data.type) === 'AmbiguousUrlInCustomProperty' && err.data.url) {
|
|
171
|
+
let p = '/' + (0, _utils().relativePath)(options.projectRoot, _path().default.resolve(_path().default.dirname(asset.filePath), err.data.url), false);
|
|
172
|
+
diagnostic[0].hints = [`Replace with: url(${p})`];
|
|
173
|
+
diagnostic[0].documentationURL = 'https://parceljs.org/languages/css/#url()';
|
|
102
174
|
}
|
|
103
175
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
176
|
+
throw new (_diagnostic().default)({
|
|
177
|
+
diagnostic
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (res.warnings) {
|
|
182
|
+
for (let warning of res.warnings) {
|
|
183
|
+
logger.warn({
|
|
184
|
+
message: warning.message,
|
|
185
|
+
codeFrames: [{
|
|
186
|
+
filePath: asset.filePath,
|
|
187
|
+
codeHighlights: [{
|
|
188
|
+
start: {
|
|
189
|
+
line: warning.loc.line,
|
|
190
|
+
column: warning.loc.column
|
|
191
|
+
},
|
|
192
|
+
end: {
|
|
193
|
+
line: warning.loc.line,
|
|
194
|
+
column: warning.loc.column
|
|
195
|
+
}
|
|
196
|
+
}]
|
|
197
|
+
}]
|
|
107
198
|
});
|
|
108
|
-
} else {
|
|
109
|
-
// If this came from an inline <style> tag, don't inline the imported file. Replace with the correct URL instead.
|
|
110
|
-
// TODO: run CSSPackager on inline style tags.
|
|
111
|
-
// let inlineHTML =
|
|
112
|
-
// this.options.rendition && this.options.rendition.inlineHTML;
|
|
113
|
-
// if (inlineHTML) {
|
|
114
|
-
// name.value = asset.addURLDependency(dep, {loc: rule.source.start});
|
|
115
|
-
// rule.params = params.toString();
|
|
116
|
-
// } else {
|
|
117
|
-
media = _postcssValueParser.default.stringify(media).trim();
|
|
118
|
-
let dep = {
|
|
119
|
-
moduleSpecifier,
|
|
120
|
-
// Offset by 8 as it does not include `@import `
|
|
121
|
-
loc: (0, _utils.createDependencyLocation)(rule.source.start, moduleSpecifier, 0, 8),
|
|
122
|
-
meta: {
|
|
123
|
-
media
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
asset.addDependency(dep);
|
|
127
|
-
rule.remove(); // }
|
|
128
199
|
}
|
|
200
|
+
}
|
|
129
201
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
202
|
+
asset.setBuffer(res.code);
|
|
203
|
+
|
|
204
|
+
if (res.map != null) {
|
|
205
|
+
let vlqMap = JSON.parse(res.map.toString());
|
|
206
|
+
let map = new (_sourceMap().default)(options.projectRoot);
|
|
207
|
+
map.addVLQMap(vlqMap);
|
|
208
|
+
|
|
209
|
+
if (originalMap) {
|
|
210
|
+
map.extends(originalMap);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
asset.setMap(map);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (res.dependencies) {
|
|
217
|
+
for (let dep of res.dependencies) {
|
|
218
|
+
let loc = dep.loc;
|
|
219
|
+
|
|
220
|
+
if (originalMap) {
|
|
221
|
+
loc = (0, _utils().remapSourceLocation)(loc, originalMap);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (dep.type === 'import' && !res.exports) {
|
|
225
|
+
asset.addDependency({
|
|
226
|
+
specifier: dep.url,
|
|
227
|
+
specifierType: 'url',
|
|
228
|
+
loc,
|
|
229
|
+
packageConditions: ['style'],
|
|
230
|
+
meta: {
|
|
231
|
+
// For the glob resolver to distinguish between `@import` and other URL dependencies.
|
|
232
|
+
isCSSImport: true,
|
|
233
|
+
media: dep.media
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
} else if (dep.type === 'url') {
|
|
237
|
+
asset.addURLDependency(dep.url, {
|
|
238
|
+
loc,
|
|
239
|
+
meta: {
|
|
240
|
+
placeholder: dep.placeholder
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
let assets = [asset];
|
|
248
|
+
|
|
249
|
+
if (res.exports != null) {
|
|
250
|
+
let exports = res.exports;
|
|
251
|
+
asset.symbols.ensure();
|
|
252
|
+
asset.symbols.set('default', 'default');
|
|
253
|
+
let dependencies = new Map();
|
|
254
|
+
let locals = new Map();
|
|
255
|
+
let c = 0;
|
|
256
|
+
let depjs = '';
|
|
257
|
+
let js = '';
|
|
258
|
+
|
|
259
|
+
for (let key in exports) {
|
|
260
|
+
locals.set(exports[key].name, key);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
let seen = new Set();
|
|
264
|
+
|
|
265
|
+
let add = key => {
|
|
266
|
+
if (seen.has(key)) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
seen.add(key);
|
|
271
|
+
let e = exports[key];
|
|
272
|
+
let s = `module.exports[${JSON.stringify(key)}] = \`${e.name}`;
|
|
273
|
+
|
|
274
|
+
for (let ref of e.composes) {
|
|
275
|
+
s += ' ';
|
|
276
|
+
|
|
277
|
+
if (ref.type === 'local') {
|
|
278
|
+
add((0, _nullthrows().default)(locals.get(ref.name)));
|
|
279
|
+
s += '${' + `module.exports[${JSON.stringify((0, _nullthrows().default)(locals.get(ref.name)))}]` + '}';
|
|
280
|
+
} else if (ref.type === 'global') {
|
|
281
|
+
s += ref.name;
|
|
282
|
+
} else if (ref.type === 'dependency') {
|
|
283
|
+
let d = dependencies.get(ref.specifier);
|
|
284
|
+
|
|
285
|
+
if (d == null) {
|
|
286
|
+
d = `dep_${c++}`;
|
|
287
|
+
depjs += `import * as ${d} from ${JSON.stringify(ref.specifier)};\n`;
|
|
288
|
+
dependencies.set(ref.specifier, d);
|
|
289
|
+
asset.addDependency({
|
|
290
|
+
specifier: ref.specifier,
|
|
291
|
+
specifierType: 'esm',
|
|
292
|
+
packageConditions: ['style']
|
|
141
293
|
});
|
|
142
|
-
isDirty = true;
|
|
143
294
|
}
|
|
144
|
-
});
|
|
145
295
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
296
|
+
s += '${' + `${d}[${JSON.stringify(ref.name)}]` + '}';
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
s += '`;\n'; // If the export is referenced internally (e.g. used @keyframes), add a self-reference
|
|
301
|
+
// to the JS so the symbol is retained during tree-shaking.
|
|
302
|
+
|
|
303
|
+
if (e.isReferenced) {
|
|
304
|
+
s += `module.exports[${JSON.stringify(key)}];\n`;
|
|
149
305
|
}
|
|
306
|
+
|
|
307
|
+
js += s;
|
|
308
|
+
}; // It's possible that the exports can be ordered differently between builds.
|
|
309
|
+
// Sorting by key is safe as the order is irrelevant but needs to be deterministic.
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
for (let key of Object.keys(exports).sort()) {
|
|
313
|
+
asset.symbols.set(key, exports[key].name);
|
|
314
|
+
add(key);
|
|
150
315
|
}
|
|
151
|
-
});
|
|
152
|
-
return [asset];
|
|
153
|
-
},
|
|
154
316
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
317
|
+
if (res.dependencies) {
|
|
318
|
+
for (let dep of res.dependencies) {
|
|
319
|
+
if (dep.type === 'import') {
|
|
320
|
+
// TODO: Figure out how to treeshake this
|
|
321
|
+
let d = `dep_$${c++}`;
|
|
322
|
+
depjs += `import * as ${d} from ${JSON.stringify(dep.url)};\n`;
|
|
323
|
+
js += `for (let key in ${d}) { if (key in module.exports) module.exports[key] += ' ' + ${d}[key]; else module.exports[key] = ${d}[key]; }\n`;
|
|
324
|
+
asset.symbols.set('*', '*');
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
159
328
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
329
|
+
if (res.references != null) {
|
|
330
|
+
let references = res.references;
|
|
331
|
+
|
|
332
|
+
for (let symbol in references) {
|
|
333
|
+
let reference = references[symbol];
|
|
334
|
+
asset.addDependency({
|
|
335
|
+
specifier: reference.specifier,
|
|
336
|
+
specifierType: 'esm',
|
|
337
|
+
packageConditions: ['style'],
|
|
338
|
+
symbols: new Map([[reference.name, {
|
|
339
|
+
local: symbol,
|
|
340
|
+
isWeak: false,
|
|
341
|
+
loc: null
|
|
342
|
+
}]])
|
|
343
|
+
});
|
|
344
|
+
asset.meta.hasReferences = true;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
164
347
|
|
|
165
|
-
|
|
166
|
-
|
|
348
|
+
assets.push({
|
|
349
|
+
type: 'js',
|
|
350
|
+
content: depjs + js,
|
|
351
|
+
dependencies: [],
|
|
352
|
+
env
|
|
167
353
|
});
|
|
168
354
|
}
|
|
169
355
|
|
|
170
|
-
return
|
|
171
|
-
code
|
|
172
|
-
};
|
|
356
|
+
return assets;
|
|
173
357
|
}
|
|
174
358
|
|
|
175
359
|
});
|
|
176
360
|
|
|
177
|
-
exports.default = _default;
|
|
361
|
+
exports.default = _default;
|
|
362
|
+
let cache = new Map();
|
|
363
|
+
|
|
364
|
+
function getTargets(browsers) {
|
|
365
|
+
if (browsers == null) {
|
|
366
|
+
return undefined;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
let cached = cache.get(browsers);
|
|
370
|
+
|
|
371
|
+
if (cached != null) {
|
|
372
|
+
return cached;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
let targets = (0, _lightningcss().browserslistToTargets)((0, _browserslist().default)(browsers));
|
|
376
|
+
cache.set(browsers, targets);
|
|
377
|
+
return targets;
|
|
378
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parcel/transformer-css",
|
|
3
|
-
"version": "2.0.0-nightly.
|
|
3
|
+
"version": "2.0.0-nightly.1303+cd4336412",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
|
+
"funding": {
|
|
9
|
+
"type": "opencollective",
|
|
10
|
+
"url": "https://opencollective.com/parcel"
|
|
11
|
+
},
|
|
8
12
|
"repository": {
|
|
9
13
|
"type": "git",
|
|
10
14
|
"url": "https://github.com/parcel-bundler/parcel.git"
|
|
@@ -12,15 +16,17 @@
|
|
|
12
16
|
"main": "lib/CSSTransformer.js",
|
|
13
17
|
"source": "src/CSSTransformer.js",
|
|
14
18
|
"engines": {
|
|
15
|
-
"node": ">=
|
|
16
|
-
"parcel": "
|
|
19
|
+
"node": ">= 12.0.0",
|
|
20
|
+
"parcel": "2.0.0-nightly.1301+cd4336412"
|
|
17
21
|
},
|
|
18
22
|
"dependencies": {
|
|
19
|
-
"@parcel/
|
|
20
|
-
"@parcel/
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
23
|
+
"@parcel/diagnostic": "2.0.0-nightly.1303+cd4336412",
|
|
24
|
+
"@parcel/plugin": "2.0.0-nightly.1303+cd4336412",
|
|
25
|
+
"@parcel/source-map": "^2.1.1",
|
|
26
|
+
"@parcel/utils": "2.0.0-nightly.1303+cd4336412",
|
|
27
|
+
"browserslist": "^4.6.6",
|
|
28
|
+
"lightningcss": "^1.16.1",
|
|
29
|
+
"nullthrows": "^1.1.1"
|
|
24
30
|
},
|
|
25
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "cd4336412242b6d6da40ef6cba8e7ac99c72b090"
|
|
26
32
|
}
|
package/src/CSSTransformer.js
CHANGED
|
@@ -1,178 +1,311 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
|
-
import type {FilePath} from '@parcel/types';
|
|
1
|
+
// @flow strict-local
|
|
4
2
|
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import SourceMap from '@parcel/source-map';
|
|
5
5
|
import {Transformer} from '@parcel/plugin';
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
import {
|
|
7
|
+
transform,
|
|
8
|
+
transformStyleAttribute,
|
|
9
|
+
browserslistToTargets,
|
|
10
|
+
} from 'lightningcss';
|
|
11
|
+
import {remapSourceLocation, relativePath} from '@parcel/utils';
|
|
12
|
+
import browserslist from 'browserslist';
|
|
13
|
+
import nullthrows from 'nullthrows';
|
|
14
|
+
import ThrowableDiagnostic, {errorToDiagnostic} from '@parcel/diagnostic';
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return ast.type === 'postcss' && semver.satisfies(ast.version, '^7.0.0');
|
|
21
|
-
},
|
|
22
|
-
|
|
23
|
-
async parse({asset}) {
|
|
24
|
-
// This is set by other transformers (e.g. Stylus) to indicate that it has already processed
|
|
25
|
-
// all dependencies, and that the CSS transformer can skip this asset completely. This is
|
|
26
|
-
// required because when stylus processes e.g. url() it replaces them with a dependency id
|
|
27
|
-
// to be filled in later. When the CSS transformer runs, it would pick that up and try to
|
|
28
|
-
// resolve a dependency for the id which obviously doesn't exist. Also, it's faster to do
|
|
29
|
-
// it this way since the resulting CSS doesn't need to be re-parsed.
|
|
30
|
-
if (asset.meta.hasDependencies === false) {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let code = await asset.getCode();
|
|
35
|
-
if (!canHaveDependencies(asset.filePath, code)) {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return {
|
|
40
|
-
type: 'postcss',
|
|
41
|
-
version: '7.0.0',
|
|
42
|
-
isDirty: false,
|
|
43
|
-
program: postcss.parse(code, {
|
|
44
|
-
from: asset.filePath,
|
|
45
|
-
}),
|
|
46
|
-
};
|
|
16
|
+
export default (new Transformer({
|
|
17
|
+
async loadConfig({config, options}) {
|
|
18
|
+
let conf = await config.getConfigFrom(options.projectRoot + '/index', [], {
|
|
19
|
+
packageKey: '@parcel/transformer-css',
|
|
20
|
+
});
|
|
21
|
+
return conf?.contents;
|
|
47
22
|
},
|
|
48
|
-
|
|
49
|
-
transform({asset}) {
|
|
23
|
+
async transform({asset, config, options, logger}) {
|
|
50
24
|
// Normalize the asset's environment so that properties that only affect JS don't cause CSS to be duplicated.
|
|
51
25
|
// For example, with ESModule and CommonJS targets, only a single shared CSS bundle should be produced.
|
|
26
|
+
let env = asset.env;
|
|
52
27
|
asset.setEnvironment({
|
|
53
28
|
context: 'browser',
|
|
54
29
|
engines: {
|
|
55
30
|
browsers: asset.env.engines.browsers,
|
|
56
31
|
},
|
|
57
|
-
|
|
32
|
+
shouldOptimize: asset.env.shouldOptimize,
|
|
33
|
+
shouldScopeHoist: asset.env.shouldScopeHoist,
|
|
34
|
+
sourceMap: asset.env.sourceMap,
|
|
58
35
|
});
|
|
59
36
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
+
errorRecovery: config?.errorRecovery || false,
|
|
50
|
+
targets,
|
|
51
|
+
});
|
|
52
|
+
} else {
|
|
53
|
+
let cssModules = false;
|
|
54
|
+
if (
|
|
55
|
+
asset.meta.type !== 'tag' &&
|
|
56
|
+
asset.meta.cssModulesCompiled == null
|
|
57
|
+
) {
|
|
58
|
+
let cssModulesConfig = config?.cssModules;
|
|
59
|
+
if (
|
|
60
|
+
(asset.isSource &&
|
|
61
|
+
(typeof cssModulesConfig === 'boolean' ||
|
|
62
|
+
cssModulesConfig?.global)) ||
|
|
63
|
+
/\.module\./.test(asset.filePath)
|
|
64
|
+
) {
|
|
65
|
+
if (cssModulesConfig?.dashedIdents && !asset.isSource) {
|
|
66
|
+
cssModulesConfig.dashedIdents = false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
cssModules = cssModulesConfig ?? true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
res = transform({
|
|
74
|
+
filename: path.relative(options.projectRoot, asset.filePath),
|
|
75
|
+
code,
|
|
76
|
+
cssModules,
|
|
77
|
+
analyzeDependencies: asset.meta.hasDependencies !== false,
|
|
78
|
+
sourceMap: !!asset.env.sourceMap,
|
|
79
|
+
drafts: config?.drafts,
|
|
80
|
+
pseudoClasses: config?.pseudoClasses,
|
|
81
|
+
errorRecovery: config?.errorRecovery || false,
|
|
82
|
+
targets,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
} catch (err) {
|
|
86
|
+
err.filePath = asset.filePath;
|
|
87
|
+
let diagnostic = errorToDiagnostic(err, {
|
|
88
|
+
origin: '@parcel/transformer-css',
|
|
89
|
+
});
|
|
90
|
+
if (err.data?.type === 'AmbiguousUrlInCustomProperty' && err.data.url) {
|
|
91
|
+
let p =
|
|
92
|
+
'/' +
|
|
93
|
+
relativePath(
|
|
94
|
+
options.projectRoot,
|
|
95
|
+
path.resolve(path.dirname(asset.filePath), err.data.url),
|
|
96
|
+
false,
|
|
97
|
+
);
|
|
98
|
+
diagnostic[0].hints = [`Replace with: url(${p})`];
|
|
99
|
+
diagnostic[0].documentationURL =
|
|
100
|
+
'https://parceljs.org/languages/css/#url()';
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
throw new ThrowableDiagnostic({
|
|
104
|
+
diagnostic,
|
|
105
|
+
});
|
|
64
106
|
}
|
|
65
107
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
108
|
+
if (res.warnings) {
|
|
109
|
+
for (let warning of res.warnings) {
|
|
110
|
+
logger.warn({
|
|
111
|
+
message: warning.message,
|
|
112
|
+
codeFrames: [
|
|
113
|
+
{
|
|
114
|
+
filePath: asset.filePath,
|
|
115
|
+
codeHighlights: [
|
|
116
|
+
{
|
|
117
|
+
start: {
|
|
118
|
+
line: warning.loc.line,
|
|
119
|
+
column: warning.loc.column,
|
|
120
|
+
},
|
|
121
|
+
end: {
|
|
122
|
+
line: warning.loc.line,
|
|
123
|
+
column: warning.loc.column,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
});
|
|
130
|
+
}
|
|
72
131
|
}
|
|
73
132
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
let
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
name = name.nodes[0];
|
|
133
|
+
asset.setBuffer(res.code);
|
|
134
|
+
|
|
135
|
+
if (res.map != null) {
|
|
136
|
+
let vlqMap = JSON.parse(res.map.toString());
|
|
137
|
+
let map = new SourceMap(options.projectRoot);
|
|
138
|
+
map.addVLQMap(vlqMap);
|
|
139
|
+
|
|
140
|
+
if (originalMap) {
|
|
141
|
+
map.extends(originalMap);
|
|
84
142
|
}
|
|
85
143
|
|
|
86
|
-
|
|
144
|
+
asset.setMap(map);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (res.dependencies) {
|
|
148
|
+
for (let dep of res.dependencies) {
|
|
149
|
+
let loc = dep.loc;
|
|
150
|
+
if (originalMap) {
|
|
151
|
+
loc = remapSourceLocation(loc, originalMap);
|
|
152
|
+
}
|
|
87
153
|
|
|
88
|
-
|
|
89
|
-
|
|
154
|
+
if (dep.type === 'import' && !res.exports) {
|
|
155
|
+
asset.addDependency({
|
|
156
|
+
specifier: dep.url,
|
|
157
|
+
specifierType: 'url',
|
|
158
|
+
loc,
|
|
159
|
+
packageConditions: ['style'],
|
|
160
|
+
meta: {
|
|
161
|
+
// For the glob resolver to distinguish between `@import` and other URL dependencies.
|
|
162
|
+
isCSSImport: true,
|
|
163
|
+
media: dep.media,
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
} else if (dep.type === 'url') {
|
|
167
|
+
asset.addURLDependency(dep.url, {
|
|
168
|
+
loc,
|
|
169
|
+
meta: {
|
|
170
|
+
placeholder: dep.placeholder,
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
}
|
|
90
174
|
}
|
|
175
|
+
}
|
|
91
176
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
// } else {
|
|
110
|
-
media = valueParser.stringify(media).trim();
|
|
111
|
-
let dep = {
|
|
112
|
-
moduleSpecifier,
|
|
113
|
-
// Offset by 8 as it does not include `@import `
|
|
114
|
-
loc: createDependencyLocation(
|
|
115
|
-
rule.source.start,
|
|
116
|
-
moduleSpecifier,
|
|
117
|
-
0,
|
|
118
|
-
8,
|
|
119
|
-
),
|
|
120
|
-
meta: {
|
|
121
|
-
media,
|
|
122
|
-
},
|
|
123
|
-
};
|
|
124
|
-
asset.addDependency(dep);
|
|
125
|
-
rule.remove();
|
|
126
|
-
// }
|
|
177
|
+
let assets = [asset];
|
|
178
|
+
|
|
179
|
+
if (res.exports != null) {
|
|
180
|
+
let exports = res.exports;
|
|
181
|
+
asset.symbols.ensure();
|
|
182
|
+
asset.symbols.set('default', 'default');
|
|
183
|
+
|
|
184
|
+
let dependencies = new Map();
|
|
185
|
+
let locals = new Map();
|
|
186
|
+
let c = 0;
|
|
187
|
+
let depjs = '';
|
|
188
|
+
let js = '';
|
|
189
|
+
|
|
190
|
+
let jsDeps = [];
|
|
191
|
+
|
|
192
|
+
for (let key in exports) {
|
|
193
|
+
locals.set(exports[key].name, key);
|
|
127
194
|
}
|
|
128
|
-
ast.isDirty = true;
|
|
129
|
-
});
|
|
130
195
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
196
|
+
let seen = new Set();
|
|
197
|
+
let add = key => {
|
|
198
|
+
if (seen.has(key)) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
seen.add(key);
|
|
135
202
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
|
|
203
|
+
let e = exports[key];
|
|
204
|
+
let s = `module.exports[${JSON.stringify(key)}] = \`${e.name}`;
|
|
205
|
+
|
|
206
|
+
for (let ref of e.composes) {
|
|
207
|
+
s += ' ';
|
|
208
|
+
if (ref.type === 'local') {
|
|
209
|
+
add(nullthrows(locals.get(ref.name)));
|
|
210
|
+
s +=
|
|
211
|
+
'${' +
|
|
212
|
+
`module.exports[${JSON.stringify(
|
|
213
|
+
nullthrows(locals.get(ref.name)),
|
|
214
|
+
)}]` +
|
|
215
|
+
'}';
|
|
216
|
+
} else if (ref.type === 'global') {
|
|
217
|
+
s += ref.name;
|
|
218
|
+
} else if (ref.type === 'dependency') {
|
|
219
|
+
let d = dependencies.get(ref.specifier);
|
|
220
|
+
if (d == null) {
|
|
221
|
+
d = `dep_${c++}`;
|
|
222
|
+
depjs += `import * as ${d} from ${JSON.stringify(
|
|
223
|
+
ref.specifier,
|
|
224
|
+
)};\n`;
|
|
225
|
+
dependencies.set(ref.specifier, d);
|
|
226
|
+
asset.addDependency({
|
|
227
|
+
specifier: ref.specifier,
|
|
228
|
+
specifierType: 'esm',
|
|
229
|
+
packageConditions: ['style'],
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
s += '${' + `${d}[${JSON.stringify(ref.name)}]` + '}';
|
|
150
233
|
}
|
|
151
|
-
}
|
|
234
|
+
}
|
|
152
235
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
236
|
+
s += '`;\n';
|
|
237
|
+
|
|
238
|
+
// If the export is referenced internally (e.g. used @keyframes), add a self-reference
|
|
239
|
+
// to the JS so the symbol is retained during tree-shaking.
|
|
240
|
+
if (e.isReferenced) {
|
|
241
|
+
s += `module.exports[${JSON.stringify(key)}];\n`;
|
|
156
242
|
}
|
|
243
|
+
|
|
244
|
+
js += s;
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
// It's possible that the exports can be ordered differently between builds.
|
|
248
|
+
// Sorting by key is safe as the order is irrelevant but needs to be deterministic.
|
|
249
|
+
for (let key of Object.keys(exports).sort()) {
|
|
250
|
+
asset.symbols.set(key, exports[key].name);
|
|
251
|
+
add(key);
|
|
157
252
|
}
|
|
158
|
-
});
|
|
159
253
|
|
|
160
|
-
|
|
161
|
-
|
|
254
|
+
if (res.dependencies) {
|
|
255
|
+
for (let dep of res.dependencies) {
|
|
256
|
+
if (dep.type === 'import') {
|
|
257
|
+
// TODO: Figure out how to treeshake this
|
|
258
|
+
let d = `dep_$${c++}`;
|
|
259
|
+
depjs += `import * as ${d} from ${JSON.stringify(dep.url)};\n`;
|
|
260
|
+
js += `for (let key in ${d}) { if (key in module.exports) module.exports[key] += ' ' + ${d}[key]; else module.exports[key] = ${d}[key]; }\n`;
|
|
261
|
+
asset.symbols.set('*', '*');
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (res.references != null) {
|
|
267
|
+
let references = res.references;
|
|
268
|
+
for (let symbol in references) {
|
|
269
|
+
let reference = references[symbol];
|
|
270
|
+
asset.addDependency({
|
|
271
|
+
specifier: reference.specifier,
|
|
272
|
+
specifierType: 'esm',
|
|
273
|
+
packageConditions: ['style'],
|
|
274
|
+
symbols: new Map([
|
|
275
|
+
[reference.name, {local: symbol, isWeak: false, loc: null}],
|
|
276
|
+
]),
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
asset.meta.hasReferences = true;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
162
282
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
code = '';
|
|
169
|
-
postcss.stringify(asset.ast.program, c => {
|
|
170
|
-
code += c;
|
|
283
|
+
assets.push({
|
|
284
|
+
type: 'js',
|
|
285
|
+
content: depjs + js,
|
|
286
|
+
dependencies: jsDeps,
|
|
287
|
+
env,
|
|
171
288
|
});
|
|
172
289
|
}
|
|
173
290
|
|
|
174
|
-
return
|
|
175
|
-
code,
|
|
176
|
-
};
|
|
291
|
+
return assets;
|
|
177
292
|
},
|
|
178
|
-
});
|
|
293
|
+
}): Transformer);
|
|
294
|
+
|
|
295
|
+
let cache = new Map();
|
|
296
|
+
|
|
297
|
+
function getTargets(browsers) {
|
|
298
|
+
if (browsers == null) {
|
|
299
|
+
return undefined;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
let cached = cache.get(browsers);
|
|
303
|
+
if (cached != null) {
|
|
304
|
+
return cached;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
let targets = browserslistToTargets(browserslist(browsers));
|
|
308
|
+
|
|
309
|
+
cache.set(browsers, targets);
|
|
310
|
+
return targets;
|
|
311
|
+
}
|