@parcel/transformer-postcss 2.0.0-nightly.107 → 2.0.0-nightly.1070

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.
@@ -5,205 +5,354 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _utils = require("@parcel/utils");
8
+ function _hash() {
9
+ const data = require("@parcel/hash");
9
10
 
10
- var _plugin = require("@parcel/plugin");
11
+ _hash = function () {
12
+ return data;
13
+ };
11
14
 
12
- var _fileSystemLoader = _interopRequireDefault(require("css-modules-loader-core/lib/file-system-loader"));
15
+ return data;
16
+ }
13
17
 
14
- var _nullthrows = _interopRequireDefault(require("nullthrows"));
18
+ function _utils() {
19
+ const data = require("@parcel/utils");
15
20
 
16
- var _path = _interopRequireDefault(require("path"));
21
+ _utils = function () {
22
+ return data;
23
+ };
17
24
 
18
- var _postcss = _interopRequireDefault(require("postcss"));
25
+ return data;
26
+ }
19
27
 
20
- var _semver = _interopRequireDefault(require("semver"));
28
+ function _plugin() {
29
+ const data = require("@parcel/plugin");
21
30
 
22
- var _postcssValueParser = _interopRequireDefault(require("postcss-value-parser"));
31
+ _plugin = function () {
32
+ return data;
33
+ };
23
34
 
24
- var _loadPlugins = _interopRequireDefault(require("./loadPlugins"));
35
+ return data;
36
+ }
25
37
 
26
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
38
+ function _nullthrows() {
39
+ const data = _interopRequireDefault(require("nullthrows"));
27
40
 
28
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
41
+ _nullthrows = function () {
42
+ return data;
43
+ };
29
44
 
30
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
45
+ return data;
46
+ }
31
47
 
32
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
48
+ function _path() {
49
+ const data = _interopRequireDefault(require("path"));
33
50
 
34
- const COMPOSES_RE = /composes:.+from\s*("|').*("|')\s*;?/;
35
- const FROM_IMPORT_RE = /.+from\s*(?:"|')(.*)(?:"|')\s*;?/;
36
- const MODULE_BY_NAME_RE = /\.module\./;
51
+ _path = function () {
52
+ return data;
53
+ };
37
54
 
38
- var _default = new _plugin.Transformer({
39
- async getConfig({
40
- asset,
41
- resolve,
42
- options
43
- }) {
44
- let configFile = await asset.getConfig(['.postcssrc', '.postcssrc.json', '.postcssrc.js', 'postcss.config.js'], {
45
- packageKey: 'postcss'
46
- }); // Use a basic, modules-only PostCSS config if the file opts in by a name
47
- // like foo.module.css
48
-
49
- if (configFile == null && asset.filePath.match(MODULE_BY_NAME_RE)) {
50
- configFile = {
51
- plugins: {
52
- 'postcss-modules': {}
53
- }
54
- };
55
- }
55
+ return data;
56
+ }
56
57
 
57
- if (configFile == null) {
58
- return;
59
- }
58
+ function _semver() {
59
+ const data = _interopRequireDefault(require("semver"));
60
60
 
61
- if (typeof configFile !== 'object') {
62
- throw new Error('PostCSS config should be an object.');
63
- }
61
+ _semver = function () {
62
+ return data;
63
+ };
64
64
 
65
- if (configFile.plugins == null || typeof configFile.plugins !== 'object' || Object.keys(configFile.plugins) === 0) {
66
- throw new Error('PostCSS config must have plugins');
67
- }
65
+ return data;
66
+ }
68
67
 
69
- let originalModulesConfig;
70
- let configFilePlugins = configFile.plugins;
68
+ function _postcssValueParser() {
69
+ const data = _interopRequireDefault(require("postcss-value-parser"));
71
70
 
72
- if (configFilePlugins != null && typeof configFilePlugins === 'object' && configFilePlugins['postcss-modules'] != null) {
73
- originalModulesConfig = configFilePlugins['postcss-modules']; // $FlowFixMe
71
+ _postcssValueParser = function () {
72
+ return data;
73
+ };
74
74
 
75
- delete configFilePlugins['postcss-modules'];
76
- }
75
+ return data;
76
+ }
77
77
 
78
- let plugins = await (0, _loadPlugins.default)(configFilePlugins, asset.filePath, options);
78
+ var _loadConfig = require("./loadConfig");
79
79
 
80
- if (originalModulesConfig || configFile.modules) {
81
- let postcssModules = await options.packageManager.require('postcss-modules', asset.filePath);
82
- plugins.push(postcssModules(_objectSpread({
83
- getJSON: (filename, json) => asset.meta.cssModules = json,
84
- Loader: createLoader(asset, resolve),
85
- generateScopedName: (name, filename, css) => `_${name}_${(0, _utils.md5FromString)(filename + css).substr(0, 5)}`
86
- }, originalModulesConfig)));
87
- }
80
+ var _constants = require("./constants");
88
81
 
89
- return {
90
- plugins,
91
- from: asset.filePath,
92
- to: asset.filePath
93
- };
82
+ function _diagnostic() {
83
+ const data = require("@parcel/diagnostic");
84
+
85
+ _diagnostic = function () {
86
+ return data;
87
+ };
88
+
89
+ return data;
90
+ }
91
+
92
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
93
+
94
+ const COMPOSES_RE = /composes:.+from\s*("|').*("|')\s*;?/;
95
+ const FROM_IMPORT_RE = /.+from\s*(?:"|')(.*)(?:"|')\s*;?/;
96
+ const LEGACY_MODULE_RE = /@value|:export|(:global|:local|:import)(?!\s*\()/i;
97
+ const MODULE_BY_NAME_RE = /\.module\./;
98
+
99
+ var _default = new (_plugin().Transformer)({
100
+ loadConfig({
101
+ config,
102
+ options,
103
+ logger
104
+ }) {
105
+ return (0, _loadConfig.load)({
106
+ config,
107
+ options,
108
+ logger
109
+ });
94
110
  },
95
111
 
96
112
  canReuseAST({
97
113
  ast
98
114
  }) {
99
- return ast.type === 'postcss' && _semver.default.satisfies(ast.version, '^7.0.0');
115
+ return ast.type === 'postcss' && _semver().default.satisfies(ast.version, _constants.POSTCSS_RANGE);
100
116
  },
101
117
 
102
118
  async parse({
103
119
  asset,
104
- config
120
+ config,
121
+ options
105
122
  }) {
106
- if (!config) {
123
+ let isLegacy = await isLegacyCssModule(asset);
124
+
125
+ if (!config && !isLegacy) {
107
126
  return;
108
127
  }
109
128
 
129
+ const postcss = await loadPostcss(options, asset.filePath);
110
130
  return {
111
131
  type: 'postcss',
112
- version: '7.0.0',
113
- program: _postcss.default.parse((await asset.getCode()), {
132
+ version: '8.2.1',
133
+ program: postcss.parse(await asset.getCode(), {
114
134
  from: asset.filePath
115
- })
135
+ }).toJSON()
116
136
  };
117
137
  },
118
138
 
119
139
  async transform({
120
140
  asset,
121
- config
141
+ config,
142
+ options,
143
+ resolve,
144
+ logger
122
145
  }) {
146
+ asset.type = 'css';
147
+ let isLegacy = await isLegacyCssModule(asset);
148
+
149
+ if (isLegacy && !config) {
150
+ config = {
151
+ raw: {},
152
+ filePath: '',
153
+ hydrated: {
154
+ plugins: [],
155
+ from: asset.filePath,
156
+ to: asset.filePath,
157
+ modules: {}
158
+ }
159
+ }; // TODO: warning?
160
+ }
161
+
123
162
  if (!config) {
124
163
  return [asset];
125
164
  }
126
165
 
127
- let ast = (0, _nullthrows.default)(asset.ast);
128
-
129
- if (COMPOSES_RE.test((await asset.getCode()))) {
130
- ast.program.walkDecls(decl => {
131
- let [, importPath] = FROM_IMPORT_RE.exec(decl.value) || [];
132
-
133
- if (decl.prop === 'composes' && importPath != null) {
134
- let parsed = (0, _postcssValueParser.default)(decl.value);
135
- parsed.walk(node => {
136
- if (node.type === 'string') {
137
- asset.addDependency({
138
- moduleSpecifier: importPath,
139
- loc: {
140
- filePath: importPath,
141
- start: decl.source.start,
142
- end: {
143
- line: decl.source.start.line,
144
- column: decl.source.start.column + importPath.length
145
- }
146
- }
147
- });
148
- }
149
- });
166
+ const postcss = await loadPostcss(options, asset.filePath);
167
+ let ast = (0, _nullthrows().default)(await asset.getAST());
168
+ let program = postcss.fromJSON(ast.program);
169
+ let plugins = [...config.hydrated.plugins];
170
+ let cssModules = null;
171
+
172
+ if (config.hydrated.modules) {
173
+ asset.meta.cssModulesCompiled = 'postcss';
174
+ let code = asset.isASTDirty() ? null : await asset.getCode();
175
+
176
+ if (Object.keys(config.hydrated.modules).length === 0 && code && !isLegacy && !LEGACY_MODULE_RE.test(code)) {
177
+ let filename = _path().default.basename(config.filePath);
178
+
179
+ let message;
180
+ let configKey;
181
+ let hint;
182
+
183
+ if (config.raw.modules) {
184
+ message = (0, _diagnostic().md)`The "modules" option in __${filename}__ can be replaced with configuration for @parcel/transformer-css to improve build performance.`;
185
+ configKey = '/modules';
186
+ hint = (0, _diagnostic().md)`Remove the "modules" option from __${filename}__`;
187
+ } else {
188
+ message = (0, _diagnostic().md)`The "postcss-modules" plugin in __${filename}__ can be replaced with configuration for @parcel/transformer-css to improve build performance.`;
189
+ configKey = '/plugins/postcss-modules';
190
+ hint = (0, _diagnostic().md)`Remove the "postcss-modules" plugin from __${filename}__`;
191
+ }
192
+
193
+ let hints = ['Enable the "cssModules" option for "@parcel/transformer-css" in your package.json'];
194
+
195
+ if (plugins.length === 0) {
196
+ message += (0, _diagnostic().md)` Since there are no other plugins, __${filename}__ can be deleted safely.`;
197
+ hints.push((0, _diagnostic().md)`Delete __${filename}__`);
198
+ } else {
199
+ hints.push(hint);
150
200
  }
201
+
202
+ let codeFrames;
203
+
204
+ if (_path().default.extname(filename) !== '.js') {
205
+ let contents = await asset.fs.readFile(config.filePath, 'utf8');
206
+ codeFrames = [{
207
+ language: 'json',
208
+ filePath: config.filePath,
209
+ code: contents,
210
+ codeHighlights: (0, _diagnostic().generateJSONCodeHighlights)(contents, [{
211
+ key: configKey,
212
+ type: 'key'
213
+ }])
214
+ }];
215
+ } else {
216
+ codeFrames = [{
217
+ filePath: config.filePath,
218
+ codeHighlights: [{
219
+ start: {
220
+ line: 1,
221
+ column: 1
222
+ },
223
+ end: {
224
+ line: 1,
225
+ column: 1
226
+ }
227
+ }]
228
+ }];
229
+ }
230
+
231
+ logger.warn({
232
+ message,
233
+ hints,
234
+ documentationURL: 'https://parceljs.org/languages/css/#enabling-css-modules-globally',
235
+ codeFrames
236
+ });
237
+ } // TODO: should this be resolved from the project root?
238
+
239
+
240
+ let postcssModules = await options.packageManager.require('postcss-modules', asset.filePath, {
241
+ range: '^4.3.0',
242
+ saveDev: true,
243
+ shouldAutoInstall: options.shouldAutoInstall
151
244
  });
152
- }
245
+ plugins.push(postcssModules({
246
+ getJSON: (filename, json) => cssModules = json,
247
+ Loader: await createLoader(asset, resolve, options),
248
+ generateScopedName: (name, filename) => `${name}_${(0, _hash().hashString)(_path().default.relative(options.projectRoot, filename)).substr(0, 6)}`,
249
+ ...config.hydrated.modules
250
+ }));
251
+
252
+ if (code == null || COMPOSES_RE.test(code)) {
253
+ program.walkDecls(decl => {
254
+ let [, importPath] = FROM_IMPORT_RE.exec(decl.value) || [];
255
+
256
+ if (decl.prop === 'composes' && importPath != null) {
257
+ let parsed = (0, _postcssValueParser().default)(decl.value);
258
+ parsed.walk(node => {
259
+ if (node.type === 'string') {
260
+ asset.addDependency({
261
+ specifier: importPath,
262
+ specifierType: 'url',
263
+ loc: {
264
+ filePath: asset.filePath,
265
+ start: decl.source.start,
266
+ end: {
267
+ line: decl.source.start.line,
268
+ column: decl.source.start.column + importPath.length
269
+ }
270
+ }
271
+ });
272
+ }
273
+ });
274
+ }
275
+ });
276
+ }
277
+ } // $FlowFixMe Added in Flow 0.121.0 upgrade in #4381
278
+
153
279
 
154
280
  let {
155
281
  messages,
156
282
  root
157
- } = await (0, _postcss.default)(config.plugins).process(ast.program, config);
158
- ast.program = root;
159
- ast.isDirty = true;
283
+ } = await postcss(plugins).process(program, config.hydrated);
284
+ asset.setAST({
285
+ type: 'postcss',
286
+ version: '8.2.1',
287
+ program: root.toJSON()
288
+ });
160
289
 
161
290
  for (let msg of messages) {
162
291
  if (msg.type === 'dependency') {
163
- // $FlowFixMe merely a convention
164
- msg = msg;
165
- asset.addIncludedFile({
166
- filePath: msg.file
292
+ asset.invalidateOnFileChange(msg.file);
293
+ } else if (msg.type === 'dir-dependency') {
294
+ var _msg$glob;
295
+
296
+ let pattern = `${msg.dir}/${(_msg$glob = msg.glob) !== null && _msg$glob !== void 0 ? _msg$glob : '**/*'}`;
297
+ let files = await (0, _utils().glob)(pattern, asset.fs, {
298
+ onlyFiles: true
299
+ });
300
+
301
+ for (let file of files) {
302
+ asset.invalidateOnFileChange(_path().default.normalize(file));
303
+ }
304
+
305
+ asset.invalidateOnFileCreate({
306
+ glob: pattern
167
307
  });
168
308
  }
169
309
  }
170
310
 
171
311
  let assets = [asset];
172
312
 
173
- if (asset.meta.cssModules) {
174
- let code = JSON.stringify(asset.meta.cssModules, null, 2);
175
- let deps = asset.getDependencies().filter(dep => !dep.isURL);
313
+ if (cssModules) {
314
+ // $FlowFixMe
315
+ let cssModulesList = Object.entries(cssModules);
316
+ let deps = asset.getDependencies().filter(dep => dep.priority === 'sync');
317
+ let code;
176
318
 
177
319
  if (deps.length > 0) {
178
320
  code = `
179
- module.exports = Object.assign({}, ${deps.map(dep => `require(${JSON.stringify(dep.moduleSpecifier)})`).join(', ')}, ${code});
321
+ module.exports = Object.assign({}, ${deps.map(dep => `require(${JSON.stringify(dep.specifier)})`).join(', ')}, ${JSON.stringify(cssModules, null, 2)});
180
322
  `;
181
323
  } else {
182
- code = `module.exports = ${code};`;
324
+ code = cssModulesList.map( // This syntax enables shaking the invidual statements, so that unused classes don't even exist in JS.
325
+ ([className, classNameHashed]) => `module.exports[${JSON.stringify(className)}] = ${JSON.stringify(classNameHashed)};`).join('\n');
183
326
  }
184
327
 
328
+ asset.symbols.ensure();
329
+
330
+ for (let [k, v] of cssModulesList) {
331
+ asset.symbols.set(k, v);
332
+ }
333
+
334
+ asset.symbols.set('default', 'default');
185
335
  assets.push({
186
336
  type: 'js',
187
- filePath: asset.filePath + '.js',
188
- code
337
+ content: code
189
338
  });
190
339
  }
191
340
 
192
341
  return assets;
193
342
  },
194
343
 
195
- generate({
196
- asset
344
+ async generate({
345
+ asset,
346
+ ast,
347
+ options
197
348
  }) {
198
- let ast = (0, _nullthrows.default)(asset.ast);
349
+ const postcss = await loadPostcss(options, asset.filePath);
199
350
  let code = '';
200
-
201
- _postcss.default.stringify(ast.program, c => {
351
+ postcss.stringify(postcss.fromJSON(ast.program), c => {
202
352
  code += c;
203
353
  });
204
-
205
354
  return {
206
- code
355
+ content: code
207
356
  };
208
357
  }
209
358
 
@@ -211,15 +360,18 @@ var _default = new _plugin.Transformer({
211
360
 
212
361
  exports.default = _default;
213
362
 
214
- function createLoader(asset, resolve) {
215
- return class extends _fileSystemLoader.default {
363
+ async function createLoader(asset, resolve, options) {
364
+ let {
365
+ default: FileSystemLoader
366
+ } = await options.packageManager.require('postcss-modules/build/css-loader-core/loader', asset.filePath);
367
+ return class extends FileSystemLoader {
216
368
  async fetch(composesPath, relativeTo) {
217
369
  let importPath = composesPath.replace(/^["']|["']$/g, '');
218
370
  let resolved = await resolve(relativeTo, importPath);
219
371
 
220
- let rootRelativePath = _path.default.resolve(_path.default.dirname(relativeTo), resolved);
372
+ let rootRelativePath = _path().default.resolve(_path().default.dirname(relativeTo), resolved);
221
373
 
222
- let root = _path.default.resolve('/'); // fixes an issue on windows which is part of the css-modules-loader-core
374
+ let root = _path().default.resolve('/'); // fixes an issue on windows which is part of the css-modules-loader-core
223
375
  // see https://github.com/css-modules/css-modules-loader-core/issues/230
224
376
 
225
377
 
@@ -230,7 +382,8 @@ function createLoader(asset, resolve) {
230
382
  let source = await asset.fs.readFile(resolved, 'utf-8');
231
383
  let {
232
384
  exportTokens
233
- } = await this.core.load(source, rootRelativePath, undefined, this.fetch.bind(this));
385
+ } = await this.core.load(source, rootRelativePath, undefined, // $FlowFixMe[method-unbinding]
386
+ this.fetch.bind(this));
234
387
  return exportTokens;
235
388
  }
236
389
 
@@ -239,4 +392,21 @@ function createLoader(asset, resolve) {
239
392
  }
240
393
 
241
394
  };
395
+ }
396
+
397
+ function loadPostcss(options, from) {
398
+ return options.packageManager.require('postcss', from, {
399
+ range: _constants.POSTCSS_RANGE,
400
+ saveDev: true,
401
+ shouldAutoInstall: options.shouldAutoInstall
402
+ });
403
+ }
404
+
405
+ async function isLegacyCssModule(asset) {
406
+ if (!MODULE_BY_NAME_RE.test(asset.filePath)) {
407
+ return false;
408
+ }
409
+
410
+ let code = await asset.getCode();
411
+ return LEGACY_MODULE_RE.test(code);
242
412
  }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.POSTCSS_RANGE = void 0;
7
+ const POSTCSS_RANGE = '^8.2.1';
8
+ exports.POSTCSS_RANGE = POSTCSS_RANGE;