@parcel/transformer-css 2.3.2 → 2.4.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 +210 -309
- package/package.json +9 -13
- package/src/CSSTransformer.js +213 -332
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,396 +35,297 @@ 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"));
|
|
90
|
-
|
|
91
|
-
_path = function () {
|
|
92
|
-
return data;
|
|
93
|
-
};
|
|
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); }
|
|
94
89
|
|
|
95
|
-
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
let
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
110
|
+
let [code, originalMap] = await Promise.all([asset.getBuffer(), asset.getMap()]);
|
|
111
|
+
let targets = getTargets(asset.env.engines.browsers);
|
|
112
|
+
let res;
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
if (asset.meta.type === 'attr') {
|
|
116
|
+
res = (0, _css().transformStyleAttribute)({
|
|
117
|
+
code,
|
|
118
|
+
analyzeDependencies: true,
|
|
119
|
+
targets
|
|
120
|
+
});
|
|
121
|
+
} else {
|
|
122
|
+
var _config$cssModules;
|
|
123
|
+
|
|
124
|
+
res = (0, _css().transform)({
|
|
125
|
+
filename: _path().default.relative(options.projectRoot, asset.filePath),
|
|
126
|
+
code,
|
|
127
|
+
cssModules: (_config$cssModules = config === null || config === void 0 ? void 0 : config.cssModules) !== null && _config$cssModules !== void 0 ? _config$cssModules : asset.meta.cssModulesCompiled !== true && /\.module\./.test(asset.filePath),
|
|
128
|
+
analyzeDependencies: asset.meta.hasDependencies !== false,
|
|
129
|
+
sourceMap: !!asset.env.sourceMap,
|
|
130
|
+
drafts: config === null || config === void 0 ? void 0 : config.drafts,
|
|
131
|
+
pseudoClasses: config === null || config === void 0 ? void 0 : config.pseudoClasses,
|
|
132
|
+
targets
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
} catch (err) {
|
|
136
|
+
var _err$data;
|
|
166
137
|
|
|
167
|
-
|
|
138
|
+
err.filePath = asset.filePath;
|
|
139
|
+
let diagnostic = (0, _diagnostic().errorToDiagnostic)(err, {
|
|
140
|
+
origin: '@parcel/transformer-css'
|
|
141
|
+
});
|
|
168
142
|
|
|
169
|
-
|
|
170
|
-
|
|
143
|
+
if (((_err$data = err.data) === null || _err$data === void 0 ? void 0 : _err$data.type) === 'AmbiguousUrlInCustomProperty' && err.data.url) {
|
|
144
|
+
let p = '/' + (0, _utils().relativePath)(options.projectRoot, _path().default.resolve(_path().default.dirname(asset.filePath), err.data.url), false);
|
|
145
|
+
diagnostic[0].hints = [`Replace with: url(${p})`];
|
|
146
|
+
diagnostic[0].documentationURL = 'https://parceljs.org/languages/css/#url()';
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
throw new (_diagnostic().default)({
|
|
150
|
+
diagnostic
|
|
151
|
+
});
|
|
171
152
|
}
|
|
172
153
|
|
|
173
|
-
|
|
154
|
+
asset.setBuffer(res.code);
|
|
174
155
|
|
|
175
|
-
|
|
156
|
+
if (res.map != null) {
|
|
157
|
+
let vlqMap = JSON.parse(res.map.toString());
|
|
158
|
+
let map = new (_sourceMap().default)(options.projectRoot);
|
|
159
|
+
map.addVLQMap(vlqMap);
|
|
176
160
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
161
|
+
if (originalMap) {
|
|
162
|
+
map.extends(originalMap);
|
|
163
|
+
}
|
|
180
164
|
|
|
181
|
-
|
|
182
|
-
return assets;
|
|
165
|
+
asset.setMap(map);
|
|
183
166
|
}
|
|
184
167
|
|
|
185
|
-
|
|
168
|
+
if (res.dependencies) {
|
|
169
|
+
for (let dep of res.dependencies) {
|
|
170
|
+
let loc = dep.loc;
|
|
186
171
|
|
|
187
|
-
|
|
188
|
-
|
|
172
|
+
if (originalMap) {
|
|
173
|
+
loc = (0, _utils().remapSourceLocation)(loc, originalMap);
|
|
174
|
+
}
|
|
189
175
|
|
|
190
|
-
|
|
191
|
-
|
|
176
|
+
if (dep.type === 'import') {
|
|
177
|
+
asset.addDependency({
|
|
178
|
+
specifier: dep.url,
|
|
179
|
+
specifierType: 'url',
|
|
180
|
+
loc,
|
|
181
|
+
meta: {
|
|
182
|
+
// For the glob resolver to distinguish between `@import` and other URL dependencies.
|
|
183
|
+
isCSSImport: true,
|
|
184
|
+
media: dep.media
|
|
185
|
+
},
|
|
186
|
+
symbols: new Map([['*', {
|
|
187
|
+
local: '*',
|
|
188
|
+
isWeak: true,
|
|
189
|
+
loc
|
|
190
|
+
}]])
|
|
191
|
+
});
|
|
192
|
+
} else if (dep.type === 'url') {
|
|
193
|
+
asset.addURLDependency(dep.url, {
|
|
194
|
+
loc,
|
|
195
|
+
meta: {
|
|
196
|
+
placeholder: dep.placeholder
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
192
200
|
}
|
|
201
|
+
}
|
|
193
202
|
|
|
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;
|
|
203
|
+
let assets = [asset];
|
|
202
204
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
+
if (res.exports != null) {
|
|
206
|
+
let exports = res.exports;
|
|
207
|
+
asset.symbols.ensure();
|
|
208
|
+
asset.symbols.set('default', 'default');
|
|
209
|
+
let dependencies = new Map();
|
|
210
|
+
let selfReferences = new Set();
|
|
211
|
+
let locals = new Map();
|
|
212
|
+
let c = 0;
|
|
213
|
+
let depjs = '';
|
|
214
|
+
let js = '';
|
|
215
|
+
|
|
216
|
+
for (let key in exports) {
|
|
217
|
+
locals.set(exports[key].name, key);
|
|
205
218
|
}
|
|
206
219
|
|
|
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(); // }
|
|
235
|
-
|
|
236
|
-
isDirty = true;
|
|
237
|
-
});
|
|
238
|
-
program.walkDecls(decl => {
|
|
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
|
-
});
|
|
220
|
+
let seen = new Set();
|
|
255
221
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
222
|
+
let add = key => {
|
|
223
|
+
if (seen.has(key)) {
|
|
224
|
+
return;
|
|
259
225
|
}
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
226
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
});
|
|
267
|
-
}
|
|
227
|
+
seen.add(key);
|
|
228
|
+
let e = exports[key];
|
|
229
|
+
let s = `module.exports[${JSON.stringify(key)}] = \`${e.name}`;
|
|
268
230
|
|
|
269
|
-
|
|
270
|
-
|
|
231
|
+
if (e.isReferenced) {
|
|
232
|
+
selfReferences.add(e.name);
|
|
233
|
+
}
|
|
271
234
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
235
|
+
for (let ref of e.composes) {
|
|
236
|
+
s += ' ';
|
|
237
|
+
|
|
238
|
+
if (ref.type === 'local') {
|
|
239
|
+
add((0, _nullthrows().default)(locals.get(ref.name)));
|
|
240
|
+
s += '${' + `module.exports[${JSON.stringify((0, _nullthrows().default)(locals.get(ref.name)))}]` + '}';
|
|
241
|
+
} else if (ref.type === 'global') {
|
|
242
|
+
s += ref.name;
|
|
243
|
+
} else if (ref.type === 'dependency') {
|
|
244
|
+
let d = dependencies.get(ref.specifier);
|
|
245
|
+
|
|
246
|
+
if (d == null) {
|
|
247
|
+
d = `dep_${c++}`;
|
|
248
|
+
depjs += `import * as ${d} from ${JSON.stringify(ref.specifier)};\n`;
|
|
249
|
+
dependencies.set(ref.specifier, d);
|
|
250
|
+
asset.addDependency({
|
|
251
|
+
specifier: ref.specifier,
|
|
252
|
+
specifierType: 'url'
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
s += '${' + `${d}[${JSON.stringify(ref.name)}]` + '}';
|
|
257
|
+
}
|
|
258
|
+
}
|
|
291
259
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
260
|
+
s += '`;\n';
|
|
261
|
+
js += s;
|
|
262
|
+
};
|
|
295
263
|
|
|
296
|
-
|
|
297
|
-
|
|
264
|
+
for (let key in exports) {
|
|
265
|
+
asset.symbols.set(key, exports[key].name);
|
|
266
|
+
add(key);
|
|
298
267
|
}
|
|
299
|
-
} else {
|
|
300
|
-
map = originalSourceMap;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
return {
|
|
304
|
-
content: result.css,
|
|
305
|
-
map
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
268
|
|
|
309
|
-
|
|
269
|
+
for (let dep of asset.getDependencies()) {
|
|
270
|
+
if (dep.priority === 'sync') {
|
|
271
|
+
// TODO: Figure out how to treeshake this
|
|
272
|
+
let d = `dep_$${c++}`;
|
|
273
|
+
depjs += `import * as ${d} from ${JSON.stringify(dep.specifier)};\n`;
|
|
274
|
+
depjs += `for (let key in ${d}) { if (key in module.exports) module.exports[key] += ' ' + ${d}[key]; else module.exports[key] = ${d}[key]; }\n`;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
310
277
|
|
|
311
|
-
|
|
278
|
+
assets.push({
|
|
279
|
+
type: 'js',
|
|
280
|
+
content: depjs + js,
|
|
281
|
+
dependencies: [],
|
|
282
|
+
env: asset.env
|
|
283
|
+
});
|
|
312
284
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
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
|
-
}
|
|
285
|
+
if (selfReferences.size > 0) {
|
|
286
|
+
asset.addDependency({
|
|
287
|
+
specifier: `./${_path().default.basename(asset.filePath)}`,
|
|
288
|
+
specifierType: 'url',
|
|
289
|
+
symbols: new Map([...locals].filter(([local]) => selfReferences.has(local)).map(([local, exported]) => [exported, {
|
|
290
|
+
local,
|
|
291
|
+
isWeak: false,
|
|
292
|
+
loc: null
|
|
293
|
+
}]))
|
|
339
294
|
});
|
|
340
295
|
}
|
|
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
|
-
}
|
|
296
|
+
} // Normalize the asset's environment so that properties that only affect JS don't cause CSS to be duplicated.
|
|
297
|
+
// For example, with ESModule and CommonJS targets, only a single shared CSS bundle should be produced.
|
|
380
298
|
|
|
381
|
-
asset.symbols.ensure();
|
|
382
299
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
env
|
|
300
|
+
asset.setEnvironment({
|
|
301
|
+
context: 'browser',
|
|
302
|
+
engines: {
|
|
303
|
+
browsers: asset.env.engines.browsers
|
|
304
|
+
},
|
|
305
|
+
shouldOptimize: asset.env.shouldOptimize,
|
|
306
|
+
shouldScopeHoist: asset.env.shouldScopeHoist,
|
|
307
|
+
sourceMap: asset.env.sourceMap
|
|
392
308
|
});
|
|
309
|
+
return assets;
|
|
393
310
|
}
|
|
394
311
|
|
|
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
|
|
312
|
+
});
|
|
411
313
|
|
|
314
|
+
exports.default = _default;
|
|
315
|
+
let cache = new Map();
|
|
412
316
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
317
|
+
function getTargets(browsers) {
|
|
318
|
+
if (browsers == null) {
|
|
319
|
+
return undefined;
|
|
320
|
+
}
|
|
416
321
|
|
|
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
|
-
}
|
|
322
|
+
let cached = cache.get(browsers);
|
|
424
323
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
324
|
+
if (cached != null) {
|
|
325
|
+
return cached;
|
|
326
|
+
}
|
|
428
327
|
|
|
429
|
-
|
|
328
|
+
let targets = (0, _css().browserslistToTargets)((0, _browserslist().default)(browsers));
|
|
329
|
+
cache.set(browsers, targets);
|
|
330
|
+
return targets;
|
|
430
331
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parcel/transformer-css",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.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.4.0"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@parcel/
|
|
24
|
-
"@parcel/
|
|
23
|
+
"@parcel/css": "^1.7.2",
|
|
24
|
+
"@parcel/diagnostic": "2.4.0",
|
|
25
|
+
"@parcel/plugin": "2.4.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.4.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": "b1bbfdab2e902d33c0b6ff75bfba2d22283a8de6"
|
|
36
32
|
}
|
package/src/CSSTransformer.js
CHANGED
|
@@ -1,376 +1,257 @@
|
|
|
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
|
-
|
|
17
|
+
async loadConfig({config, options}) {
|
|
18
|
+
let conf = await config.getConfigFrom(options.projectRoot + '/index', [], {
|
|
19
|
+
packageKey: '@parcel/transformer-css',
|
|
20
|
+
});
|
|
21
|
+
return conf?.contents;
|
|
29
22
|
},
|
|
23
|
+
async transform({asset, config, options}) {
|
|
24
|
+
let [code, originalMap] = await Promise.all([
|
|
25
|
+
asset.getBuffer(),
|
|
26
|
+
asset.getMap(),
|
|
27
|
+
]);
|
|
28
|
+
|
|
29
|
+
let targets = getTargets(asset.env.engines.browsers);
|
|
30
|
+
let res;
|
|
31
|
+
try {
|
|
32
|
+
if (asset.meta.type === 'attr') {
|
|
33
|
+
res = transformStyleAttribute({
|
|
34
|
+
code,
|
|
35
|
+
analyzeDependencies: true,
|
|
36
|
+
targets,
|
|
37
|
+
});
|
|
38
|
+
} else {
|
|
39
|
+
res = transform({
|
|
40
|
+
filename: path.relative(options.projectRoot, asset.filePath),
|
|
41
|
+
code,
|
|
42
|
+
cssModules:
|
|
43
|
+
config?.cssModules ??
|
|
44
|
+
(asset.meta.cssModulesCompiled !== true &&
|
|
45
|
+
/\.module\./.test(asset.filePath)),
|
|
46
|
+
analyzeDependencies: asset.meta.hasDependencies !== false,
|
|
47
|
+
sourceMap: !!asset.env.sourceMap,
|
|
48
|
+
drafts: config?.drafts,
|
|
49
|
+
pseudoClasses: config?.pseudoClasses,
|
|
50
|
+
targets,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
} catch (err) {
|
|
54
|
+
err.filePath = asset.filePath;
|
|
55
|
+
let diagnostic = errorToDiagnostic(err, {
|
|
56
|
+
origin: '@parcel/transformer-css',
|
|
57
|
+
});
|
|
58
|
+
if (err.data?.type === 'AmbiguousUrlInCustomProperty' && err.data.url) {
|
|
59
|
+
let p =
|
|
60
|
+
'/' +
|
|
61
|
+
relativePath(
|
|
62
|
+
options.projectRoot,
|
|
63
|
+
path.resolve(path.dirname(asset.filePath), err.data.url),
|
|
64
|
+
false,
|
|
65
|
+
);
|
|
66
|
+
diagnostic[0].hints = [`Replace with: url(${p})`];
|
|
67
|
+
diagnostic[0].documentationURL =
|
|
68
|
+
'https://parceljs.org/languages/css/#url()';
|
|
69
|
+
}
|
|
30
70
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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;
|
|
71
|
+
throw new ThrowableDiagnostic({
|
|
72
|
+
diagnostic,
|
|
73
|
+
});
|
|
43
74
|
}
|
|
44
75
|
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
code != null &&
|
|
48
|
-
!canHaveDependencies(asset.filePath, code) &&
|
|
49
|
-
!isCSSModule
|
|
50
|
-
) {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
76
|
+
asset.setBuffer(res.code);
|
|
53
77
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
.parse(code, {
|
|
59
|
-
from: asset.filePath,
|
|
60
|
-
})
|
|
61
|
-
.toJSON(),
|
|
62
|
-
};
|
|
63
|
-
},
|
|
78
|
+
if (res.map != null) {
|
|
79
|
+
let vlqMap = JSON.parse(res.map.toString());
|
|
80
|
+
let map = new SourceMap(options.projectRoot);
|
|
81
|
+
map.addVLQMap(vlqMap);
|
|
64
82
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
let env = asset.env;
|
|
69
|
-
asset.setEnvironment({
|
|
70
|
-
context: 'browser',
|
|
71
|
-
engines: {
|
|
72
|
-
browsers: asset.env.engines.browsers,
|
|
73
|
-
},
|
|
74
|
-
shouldOptimize: asset.env.shouldOptimize,
|
|
75
|
-
sourceMap: asset.env.sourceMap,
|
|
76
|
-
});
|
|
83
|
+
if (originalMap) {
|
|
84
|
+
map.extends(originalMap);
|
|
85
|
+
}
|
|
77
86
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
87
|
+
asset.setMap(map);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (res.dependencies) {
|
|
91
|
+
for (let dep of res.dependencies) {
|
|
92
|
+
let loc = dep.loc;
|
|
93
|
+
if (originalMap) {
|
|
94
|
+
loc = remapSourceLocation(loc, originalMap);
|
|
95
|
+
}
|
|
81
96
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
97
|
+
if (dep.type === 'import') {
|
|
98
|
+
asset.addDependency({
|
|
99
|
+
specifier: dep.url,
|
|
100
|
+
specifierType: 'url',
|
|
101
|
+
loc,
|
|
102
|
+
meta: {
|
|
103
|
+
// For the glob resolver to distinguish between `@import` and other URL dependencies.
|
|
104
|
+
isCSSImport: true,
|
|
105
|
+
media: dep.media,
|
|
106
|
+
},
|
|
107
|
+
symbols: new Map([['*', {local: '*', isWeak: true, loc}]]),
|
|
108
|
+
});
|
|
109
|
+
} else if (dep.type === 'url') {
|
|
110
|
+
asset.addURLDependency(dep.url, {
|
|
111
|
+
loc,
|
|
112
|
+
meta: {
|
|
113
|
+
placeholder: dep.placeholder,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
88
118
|
}
|
|
89
119
|
|
|
90
|
-
let program: Root = postcss.fromJSON(ast.program);
|
|
91
120
|
let assets = [asset];
|
|
92
|
-
if (isCSSModule) {
|
|
93
|
-
assets = await compileCSSModules(asset, env, program, resolve, options);
|
|
94
|
-
}
|
|
95
121
|
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
|
|
122
|
+
if (res.exports != null) {
|
|
123
|
+
let exports = res.exports;
|
|
124
|
+
asset.symbols.ensure();
|
|
125
|
+
asset.symbols.set('default', 'default');
|
|
99
126
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
let
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
colOffset,
|
|
107
|
-
o,
|
|
108
|
-
);
|
|
109
|
-
if (originalSourceMap) {
|
|
110
|
-
loc = remapSourceLocation(loc, originalSourceMap);
|
|
111
|
-
}
|
|
112
|
-
return loc;
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
let isDirty = false;
|
|
116
|
-
program.walkAtRules('import', rule => {
|
|
117
|
-
let params = valueParser(rule.params);
|
|
118
|
-
let [name, ...media] = params.nodes;
|
|
119
|
-
let specifier;
|
|
120
|
-
if (
|
|
121
|
-
name.type === 'function' &&
|
|
122
|
-
name.value === 'url' &&
|
|
123
|
-
name.nodes.length
|
|
124
|
-
) {
|
|
125
|
-
name = name.nodes[0];
|
|
126
|
-
}
|
|
127
|
+
let dependencies = new Map();
|
|
128
|
+
let selfReferences = new Set();
|
|
129
|
+
let locals = new Map();
|
|
130
|
+
let c = 0;
|
|
131
|
+
let depjs = '';
|
|
132
|
+
let js = '';
|
|
127
133
|
|
|
128
|
-
|
|
134
|
+
let jsDeps = [];
|
|
129
135
|
|
|
130
|
-
|
|
131
|
-
|
|
136
|
+
for (let key in exports) {
|
|
137
|
+
locals.set(exports[key].name, key);
|
|
132
138
|
}
|
|
133
139
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
// rule.params = params.toString();
|
|
141
|
-
// } else {
|
|
142
|
-
media = valueParser.stringify(media).trim();
|
|
143
|
-
let dep = {
|
|
144
|
-
specifier,
|
|
145
|
-
specifierType: 'url',
|
|
146
|
-
// Offset by 8 as it does not include `@import `
|
|
147
|
-
loc: createLoc(nullthrows(rule.source.start), specifier, 0, 8),
|
|
148
|
-
meta: {
|
|
149
|
-
// For the glob resolver to distinguish between `@import` and other URL dependencies.
|
|
150
|
-
isCSSImport: true,
|
|
151
|
-
media,
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
asset.addDependency(dep);
|
|
155
|
-
rule.remove();
|
|
156
|
-
// }
|
|
157
|
-
isDirty = true;
|
|
158
|
-
});
|
|
140
|
+
let seen = new Set();
|
|
141
|
+
let add = key => {
|
|
142
|
+
if (seen.has(key)) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
seen.add(key);
|
|
159
146
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
let parsed = valueParser(decl.value);
|
|
163
|
-
let isDeclDirty = false;
|
|
164
|
-
|
|
165
|
-
parsed.walk(node => {
|
|
166
|
-
if (
|
|
167
|
-
node.type === 'function' &&
|
|
168
|
-
node.value === 'url' &&
|
|
169
|
-
node.nodes.length > 0 &&
|
|
170
|
-
!node.nodes[0].value.startsWith('#') // IE's `behavior: url(#default#VML)`
|
|
171
|
-
) {
|
|
172
|
-
let urlNode = node.nodes[0];
|
|
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;
|
|
189
|
-
}
|
|
190
|
-
});
|
|
147
|
+
let e = exports[key];
|
|
148
|
+
let s = `module.exports[${JSON.stringify(key)}] = \`${e.name}`;
|
|
191
149
|
|
|
192
|
-
if (
|
|
193
|
-
|
|
194
|
-
isDirty = true;
|
|
150
|
+
if (e.isReferenced) {
|
|
151
|
+
selfReferences.add(e.name);
|
|
195
152
|
}
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
153
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
154
|
+
for (let ref of e.composes) {
|
|
155
|
+
s += ' ';
|
|
156
|
+
if (ref.type === 'local') {
|
|
157
|
+
add(nullthrows(locals.get(ref.name)));
|
|
158
|
+
s +=
|
|
159
|
+
'${' +
|
|
160
|
+
`module.exports[${JSON.stringify(
|
|
161
|
+
nullthrows(locals.get(ref.name)),
|
|
162
|
+
)}]` +
|
|
163
|
+
'}';
|
|
164
|
+
} else if (ref.type === 'global') {
|
|
165
|
+
s += ref.name;
|
|
166
|
+
} else if (ref.type === 'dependency') {
|
|
167
|
+
let d = dependencies.get(ref.specifier);
|
|
168
|
+
if (d == null) {
|
|
169
|
+
d = `dep_${c++}`;
|
|
170
|
+
depjs += `import * as ${d} from ${JSON.stringify(
|
|
171
|
+
ref.specifier,
|
|
172
|
+
)};\n`;
|
|
173
|
+
dependencies.set(ref.specifier, d);
|
|
174
|
+
|
|
175
|
+
asset.addDependency({
|
|
176
|
+
specifier: ref.specifier,
|
|
177
|
+
specifierType: 'url',
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
s += '${' + `${d}[${JSON.stringify(ref.name)}]` + '}';
|
|
181
|
+
}
|
|
182
|
+
}
|
|
205
183
|
|
|
206
|
-
|
|
207
|
-
|
|
184
|
+
s += '`;\n';
|
|
185
|
+
js += s;
|
|
186
|
+
};
|
|
208
187
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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
|
-
});
|
|
188
|
+
for (let key in exports) {
|
|
189
|
+
asset.symbols.set(key, exports[key].name);
|
|
190
|
+
add(key);
|
|
191
|
+
}
|
|
222
192
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
193
|
+
for (let dep of asset.getDependencies()) {
|
|
194
|
+
if (dep.priority === 'sync') {
|
|
195
|
+
// TODO: Figure out how to treeshake this
|
|
196
|
+
let d = `dep_$${c++}`;
|
|
197
|
+
depjs += `import * as ${d} from ${JSON.stringify(dep.specifier)};\n`;
|
|
198
|
+
depjs += `for (let key in ${d}) { if (key in module.exports) module.exports[key] += ' ' + ${d}[key]; else module.exports[key] = ${d}[key]; }\n`;
|
|
199
|
+
}
|
|
230
200
|
}
|
|
231
|
-
} else {
|
|
232
|
-
map = originalSourceMap;
|
|
233
|
-
}
|
|
234
201
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
})
|
|
202
|
+
assets.push({
|
|
203
|
+
type: 'js',
|
|
204
|
+
content: depjs + js,
|
|
205
|
+
dependencies: jsDeps,
|
|
206
|
+
env: asset.env,
|
|
207
|
+
});
|
|
241
208
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
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
|
-
}
|
|
209
|
+
if (selfReferences.size > 0) {
|
|
210
|
+
asset.addDependency({
|
|
211
|
+
specifier: `./${path.basename(asset.filePath)}`,
|
|
212
|
+
specifierType: 'url',
|
|
213
|
+
symbols: new Map(
|
|
214
|
+
[...locals]
|
|
215
|
+
.filter(([local]) => selfReferences.has(local))
|
|
216
|
+
.map(([local, exported]) => [
|
|
217
|
+
exported,
|
|
218
|
+
{local, isWeak: false, loc: null},
|
|
219
|
+
]),
|
|
220
|
+
),
|
|
270
221
|
});
|
|
271
222
|
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Normalize the asset's environment so that properties that only affect JS don't cause CSS to be duplicated.
|
|
226
|
+
// For example, with ESModule and CommonJS targets, only a single shared CSS bundle should be produced.
|
|
227
|
+
asset.setEnvironment({
|
|
228
|
+
context: 'browser',
|
|
229
|
+
engines: {
|
|
230
|
+
browsers: asset.env.engines.browsers,
|
|
231
|
+
},
|
|
232
|
+
shouldOptimize: asset.env.shouldOptimize,
|
|
233
|
+
shouldScopeHoist: asset.env.shouldScopeHoist,
|
|
234
|
+
sourceMap: asset.env.sourceMap,
|
|
272
235
|
});
|
|
273
|
-
}
|
|
274
236
|
|
|
275
|
-
|
|
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
|
-
}
|
|
237
|
+
return assets;
|
|
238
|
+
},
|
|
239
|
+
}): Transformer);
|
|
324
240
|
|
|
325
|
-
|
|
326
|
-
for (let [k, v] of cssModulesList) {
|
|
327
|
-
asset.symbols.set(k, v);
|
|
328
|
-
}
|
|
329
|
-
asset.symbols.set('default', 'default');
|
|
241
|
+
let cache = new Map();
|
|
330
242
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
env,
|
|
335
|
-
});
|
|
243
|
+
function getTargets(browsers) {
|
|
244
|
+
if (browsers == null) {
|
|
245
|
+
return undefined;
|
|
336
246
|
}
|
|
337
|
-
return assets;
|
|
338
|
-
}
|
|
339
247
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
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
|
-
}
|
|
248
|
+
let cached = cache.get(browsers);
|
|
249
|
+
if (cached != null) {
|
|
250
|
+
return cached;
|
|
251
|
+
}
|
|
360
252
|
|
|
361
|
-
|
|
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
|
-
}
|
|
253
|
+
let targets = browserslistToTargets(browserslist(browsers));
|
|
371
254
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
}
|
|
375
|
-
};
|
|
255
|
+
cache.set(browsers, targets);
|
|
256
|
+
return targets;
|
|
376
257
|
}
|