@parcel/transformer-css 2.0.0-nightly.85 → 2.0.0-nightly.852

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,15 +5,75 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _plugin = require("@parcel/plugin");
8
+ function _sourceMap() {
9
+ const data = _interopRequireDefault(require("@parcel/source-map"));
9
10
 
10
- var _utils = require("@parcel/utils");
11
+ _sourceMap = function () {
12
+ return data;
13
+ };
11
14
 
12
- var _postcss = _interopRequireDefault(require("postcss"));
15
+ return data;
16
+ }
17
+
18
+ function _plugin() {
19
+ const data = require("@parcel/plugin");
20
+
21
+ _plugin = function () {
22
+ return data;
23
+ };
24
+
25
+ return data;
26
+ }
27
+
28
+ function _utils() {
29
+ const data = require("@parcel/utils");
13
30
 
14
- var _postcssValueParser = _interopRequireDefault(require("postcss-value-parser"));
31
+ _utils = function () {
32
+ return data;
33
+ };
34
+
35
+ return data;
36
+ }
37
+
38
+ function _postcss() {
39
+ const data = _interopRequireDefault(require("postcss"));
40
+
41
+ _postcss = function () {
42
+ return data;
43
+ };
44
+
45
+ return data;
46
+ }
15
47
 
16
- var _semver = _interopRequireDefault(require("semver"));
48
+ function _nullthrows() {
49
+ const data = _interopRequireDefault(require("nullthrows"));
50
+
51
+ _nullthrows = function () {
52
+ return data;
53
+ };
54
+
55
+ return data;
56
+ }
57
+
58
+ function _postcssValueParser() {
59
+ const data = _interopRequireDefault(require("postcss-value-parser"));
60
+
61
+ _postcssValueParser = function () {
62
+ return data;
63
+ };
64
+
65
+ return data;
66
+ }
67
+
68
+ function _semver() {
69
+ const data = _interopRequireDefault(require("semver"));
70
+
71
+ _semver = function () {
72
+ return data;
73
+ };
74
+
75
+ return data;
76
+ }
17
77
 
18
78
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
79
 
@@ -24,11 +84,11 @@ function canHaveDependencies(filePath, code) {
24
84
  return !/\.css$/.test(filePath) || IMPORT_RE.test(code) || URL_RE.test(code);
25
85
  }
26
86
 
27
- var _default = new _plugin.Transformer({
87
+ var _default = new (_plugin().Transformer)({
28
88
  canReuseAST({
29
89
  ast
30
90
  }) {
31
- return ast.type === 'postcss' && _semver.default.satisfies(ast.version, '^7.0.0');
91
+ return ast.type === 'postcss' && _semver().default.satisfies(ast.version, '^8.2.1');
32
92
  },
33
93
 
34
94
  async parse({
@@ -46,114 +106,161 @@ var _default = new _plugin.Transformer({
46
106
 
47
107
  let code = await asset.getCode();
48
108
 
49
- if (!canHaveDependencies(asset.filePath, code)) {
109
+ if (code != null && !canHaveDependencies(asset.filePath, code)) {
50
110
  return null;
51
111
  }
52
112
 
53
113
  return {
54
114
  type: 'postcss',
55
- version: '7.0.0',
56
- isDirty: false,
57
- program: _postcss.default.parse(code, {
115
+ version: '8.2.1',
116
+ program: _postcss().default.parse(code, {
58
117
  from: asset.filePath
59
- })
118
+ }).toJSON()
60
119
  };
61
120
  },
62
121
 
63
- transform({
122
+ async transform({
64
123
  asset
65
124
  }) {
66
- let ast = asset.ast; // Check for `hasDependencies` being false here as well, as it's possible
125
+ // Normalize the asset's environment so that properties that only affect JS don't cause CSS to be duplicated.
126
+ // For example, with ESModule and CommonJS targets, only a single shared CSS bundle should be produced.
127
+ asset.setEnvironment({
128
+ context: 'browser',
129
+ engines: {
130
+ browsers: asset.env.engines.browsers
131
+ },
132
+ shouldOptimize: asset.env.shouldOptimize,
133
+ sourceMap: asset.env.sourceMap
134
+ }); // Check for `hasDependencies` being false here as well, as it's possible
67
135
  // another transformer (such as PostCSSTransformer) has already parsed an
68
136
  // ast and CSSTransformer's parse was never called.
69
137
 
138
+ let ast = await asset.getAST();
139
+
70
140
  if (!ast || asset.meta.hasDependencies === false) {
71
141
  return [asset];
72
142
  }
73
143
 
74
- ast.program.walkAtRules('import', rule => {
75
- let params = (0, _postcssValueParser.default)(rule.params);
144
+ let program = _postcss().default.fromJSON(ast.program);
145
+
146
+ let originalSourceMap = await asset.getMap();
147
+
148
+ let createLoc = (start, specifier, lineOffset, colOffset) => {
149
+ let loc = (0, _utils().createDependencyLocation)(start, specifier, lineOffset, colOffset);
150
+
151
+ if (originalSourceMap) {
152
+ loc = (0, _utils().remapSourceLocation)(loc, originalSourceMap);
153
+ }
154
+
155
+ return loc;
156
+ };
157
+
158
+ let isDirty = false;
159
+ program.walkAtRules('import', rule => {
160
+ let params = (0, _postcssValueParser().default)(rule.params);
76
161
  let [name, ...media] = params.nodes;
77
- let moduleSpecifier;
162
+ let specifier;
78
163
 
79
164
  if (name.type === 'function' && name.value === 'url' && name.nodes.length) {
80
165
  name = name.nodes[0];
81
166
  }
82
167
 
83
- moduleSpecifier = name.value;
168
+ specifier = name.value;
84
169
 
85
- if (!moduleSpecifier) {
86
- throw new Error('Could not find import name for ' + rule);
87
- }
170
+ if (!specifier) {
171
+ throw new Error('Could not find import name for ' + String(rule));
172
+ } // If this came from an inline <style> tag, don't inline the imported file. Replace with the correct URL instead.
173
+ // TODO: run CSSPackager on inline style tags.
174
+ // let inlineHTML =
175
+ // this.options.rendition && this.options.rendition.inlineHTML;
176
+ // if (inlineHTML) {
177
+ // name.value = asset.addURLDependency(dep, {loc: rule.source.start});
178
+ // rule.params = params.toString();
179
+ // } else {
88
180
 
89
- if ((0, _utils.isURL)(moduleSpecifier)) {
90
- name.value = asset.addURLDependency(moduleSpecifier, {
91
- loc: (0, _utils.createDependencyLocation)(rule.source.start, moduleSpecifier, 0, 8)
92
- });
93
- } else {
94
- // If this came from an inline <style> tag, don't inline the imported file. Replace with the correct URL instead.
95
- // TODO: run CSSPackager on inline style tags.
96
- // let inlineHTML =
97
- // this.options.rendition && this.options.rendition.inlineHTML;
98
- // if (inlineHTML) {
99
- // name.value = asset.addURLDependency(dep, {loc: rule.source.start});
100
- // rule.params = params.toString();
101
- // } else {
102
- media = _postcssValueParser.default.stringify(media).trim();
103
- let dep = {
104
- moduleSpecifier,
105
- // Offset by 8 as it does not include `@import `
106
- loc: (0, _utils.createDependencyLocation)(rule.source.start, moduleSpecifier, 0, 8),
107
- meta: {
108
- media
109
- }
110
- };
111
- asset.addDependency(dep);
112
- rule.remove(); // }
113
- }
114
181
 
115
- ast.isDirty = true;
182
+ media = _postcssValueParser().default.stringify(media).trim();
183
+ let dep = {
184
+ specifier,
185
+ specifierType: 'url',
186
+ // Offset by 8 as it does not include `@import `
187
+ loc: createLoc((0, _nullthrows().default)(rule.source.start), specifier, 0, 8),
188
+ meta: {
189
+ // For the glob resolver to distinguish between `@import` and other URL dependencies.
190
+ isCSSImport: true,
191
+ media
192
+ }
193
+ };
194
+ asset.addDependency(dep);
195
+ rule.remove(); // }
196
+
197
+ isDirty = true;
116
198
  });
117
- ast.program.walkDecls(decl => {
199
+ program.walkDecls(decl => {
118
200
  if (URL_RE.test(decl.value)) {
119
- let parsed = (0, _postcssValueParser.default)(decl.value);
120
- let isDirty = false;
201
+ let parsed = (0, _postcssValueParser().default)(decl.value);
202
+ let isDeclDirty = false;
121
203
  parsed.walk(node => {
122
204
  if (node.type === 'function' && node.value === 'url' && node.nodes.length > 0 && !node.nodes[0].value.startsWith('#') // IE's `behavior: url(#default#VML)`
123
205
  ) {
124
- node.nodes[0].value = asset.addURLDependency(node.nodes[0].value, {
125
- loc: (0, _utils.createDependencyLocation)(decl.source.start, node.nodes[0].value)
206
+ let url = asset.addURLDependency(node.nodes[0].value, {
207
+ loc: createLoc((0, _nullthrows().default)(decl.source.start), node.nodes[0].value, 0, node.nodes[0].sourceIndex)
126
208
  });
127
- isDirty = true;
209
+ isDeclDirty = node.nodes[0].value !== url;
210
+ node.nodes[0].value = url;
128
211
  }
129
212
  });
130
213
 
131
- if (isDirty) {
214
+ if (isDeclDirty) {
132
215
  decl.value = parsed.toString();
133
- ast.isDirty = true;
216
+ isDirty = true;
134
217
  }
135
218
  }
136
219
  });
220
+
221
+ if (isDirty) {
222
+ asset.setAST({ ...ast,
223
+ program: program.toJSON()
224
+ });
225
+ }
226
+
137
227
  return [asset];
138
228
  },
139
229
 
140
230
  async generate({
141
- asset
231
+ asset,
232
+ ast,
233
+ options
142
234
  }) {
143
- let code;
235
+ let result = await (0, _postcss().default)().process(_postcss().default.fromJSON(ast.program), {
236
+ from: undefined,
237
+ to: options.projectRoot + '/index',
238
+ map: {
239
+ annotation: false,
240
+ inline: false,
241
+ sourcesContent: false
242
+ },
243
+ // Pass postcss's own stringifier to it to silence its warning
244
+ // as we don't want to perform any transformations -- only generate
245
+ stringifier: _postcss().default.stringify
246
+ });
247
+ let map = null;
248
+ let originalSourceMap = await asset.getMap();
144
249
 
145
- if (!asset.ast || !asset.ast.isDirty) {
146
- code = await asset.getCode();
147
- } else {
148
- code = '';
250
+ if (result.map != null) {
251
+ map = new (_sourceMap().default)(options.projectRoot);
252
+ map.addVLQMap(result.map.toJSON());
149
253
 
150
- _postcss.default.stringify(asset.ast.program, c => {
151
- code += c;
152
- });
254
+ if (originalSourceMap) {
255
+ map.extends(originalSourceMap.toBuffer());
256
+ }
257
+ } else {
258
+ map = originalSourceMap;
153
259
  }
154
260
 
155
261
  return {
156
- code
262
+ content: result.css,
263
+ map
157
264
  };
158
265
  }
159
266
 
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "@parcel/transformer-css",
3
- "version": "2.0.0-nightly.85+e33d9161",
3
+ "version": "2.0.0-nightly.852+843eb50e",
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": ">= 10.0.0",
16
- "parcel": "^2.0.0-alpha.1.1"
19
+ "node": ">= 12.0.0",
20
+ "parcel": "^2.0.0-beta.1"
17
21
  },
18
22
  "dependencies": {
19
- "@parcel/plugin": "2.0.0-nightly.85+e33d9161",
20
- "@parcel/utils": "2.0.0-nightly.85+e33d9161",
21
- "postcss": "^7.0.5",
22
- "postcss-value-parser": "^3.3.1",
23
+ "@parcel/plugin": "2.0.0-nightly.852+843eb50e",
24
+ "@parcel/source-map": "2.0.0-rc.7",
25
+ "@parcel/utils": "2.0.0-nightly.852+843eb50e",
26
+ "nullthrows": "^1.1.1",
27
+ "postcss": "^8.3.0",
28
+ "postcss-value-parser": "^4.1.0",
23
29
  "semver": "^5.4.1"
24
30
  },
25
- "gitHead": "e33d91613d0ab9f600c93c5f8466f20fe9ca9dce"
31
+ "gitHead": "843eb50ef398f61acd07847bc12a9f72aef02c06"
26
32
  }
@@ -1,10 +1,13 @@
1
1
  // @flow
2
2
 
3
+ import type {Root} from 'postcss';
3
4
  import type {FilePath} from '@parcel/types';
4
5
 
6
+ import SourceMap from '@parcel/source-map';
5
7
  import {Transformer} from '@parcel/plugin';
6
- import {createDependencyLocation, isURL} from '@parcel/utils';
8
+ import {createDependencyLocation, remapSourceLocation} from '@parcel/utils';
7
9
  import postcss from 'postcss';
10
+ import nullthrows from 'nullthrows';
8
11
  import valueParser from 'postcss-value-parser';
9
12
  import semver from 'semver';
10
13
 
@@ -15,9 +18,9 @@ function canHaveDependencies(filePath: FilePath, code: string) {
15
18
  return !/\.css$/.test(filePath) || IMPORT_RE.test(code) || URL_RE.test(code);
16
19
  }
17
20
 
18
- export default new Transformer({
21
+ export default (new Transformer({
19
22
  canReuseAST({ast}) {
20
- return ast.type === 'postcss' && semver.satisfies(ast.version, '^7.0.0');
23
+ return ast.type === 'postcss' && semver.satisfies(ast.version, '^8.2.1');
21
24
  },
22
25
 
23
26
  async parse({asset}) {
@@ -32,33 +35,61 @@ export default new Transformer({
32
35
  }
33
36
 
34
37
  let code = await asset.getCode();
35
- if (!canHaveDependencies(asset.filePath, code)) {
38
+ if (code != null && !canHaveDependencies(asset.filePath, code)) {
36
39
  return null;
37
40
  }
38
41
 
39
42
  return {
40
43
  type: 'postcss',
41
- version: '7.0.0',
42
- isDirty: false,
43
- program: postcss.parse(code, {
44
- from: asset.filePath,
45
- }),
44
+ version: '8.2.1',
45
+ program: postcss
46
+ .parse(code, {
47
+ from: asset.filePath,
48
+ })
49
+ .toJSON(),
46
50
  };
47
51
  },
48
52
 
49
- transform({asset}) {
50
- let ast = asset.ast;
53
+ async transform({asset}) {
54
+ // Normalize the asset's environment so that properties that only affect JS don't cause CSS to be duplicated.
55
+ // For example, with ESModule and CommonJS targets, only a single shared CSS bundle should be produced.
56
+ asset.setEnvironment({
57
+ context: 'browser',
58
+ engines: {
59
+ browsers: asset.env.engines.browsers,
60
+ },
61
+ shouldOptimize: asset.env.shouldOptimize,
62
+ sourceMap: asset.env.sourceMap,
63
+ });
64
+
51
65
  // Check for `hasDependencies` being false here as well, as it's possible
52
66
  // another transformer (such as PostCSSTransformer) has already parsed an
53
67
  // ast and CSSTransformer's parse was never called.
68
+ let ast = await asset.getAST();
54
69
  if (!ast || asset.meta.hasDependencies === false) {
55
70
  return [asset];
56
71
  }
57
72
 
58
- ast.program.walkAtRules('import', rule => {
73
+ let program: Root = postcss.fromJSON(ast.program);
74
+ let originalSourceMap = await asset.getMap();
75
+ let createLoc = (start, specifier, lineOffset, colOffset) => {
76
+ let loc = createDependencyLocation(
77
+ start,
78
+ specifier,
79
+ lineOffset,
80
+ colOffset,
81
+ );
82
+ if (originalSourceMap) {
83
+ loc = remapSourceLocation(loc, originalSourceMap);
84
+ }
85
+ return loc;
86
+ };
87
+
88
+ let isDirty = false;
89
+ program.walkAtRules('import', rule => {
59
90
  let params = valueParser(rule.params);
60
91
  let [name, ...media] = params.nodes;
61
- let moduleSpecifier;
92
+ let specifier;
62
93
  if (
63
94
  name.type === 'function' &&
64
95
  name.value === 'url' &&
@@ -67,55 +98,42 @@ export default new Transformer({
67
98
  name = name.nodes[0];
68
99
  }
69
100
 
70
- moduleSpecifier = name.value;
101
+ specifier = name.value;
71
102
 
72
- if (!moduleSpecifier) {
73
- throw new Error('Could not find import name for ' + rule);
103
+ if (!specifier) {
104
+ throw new Error('Could not find import name for ' + String(rule));
74
105
  }
75
106
 
76
- if (isURL(moduleSpecifier)) {
77
- name.value = asset.addURLDependency(moduleSpecifier, {
78
- loc: createDependencyLocation(
79
- rule.source.start,
80
- moduleSpecifier,
81
- 0,
82
- 8,
83
- ),
84
- });
85
- } else {
86
- // If this came from an inline <style> tag, don't inline the imported file. Replace with the correct URL instead.
87
- // TODO: run CSSPackager on inline style tags.
88
- // let inlineHTML =
89
- // this.options.rendition && this.options.rendition.inlineHTML;
90
- // if (inlineHTML) {
91
- // name.value = asset.addURLDependency(dep, {loc: rule.source.start});
92
- // rule.params = params.toString();
93
- // } else {
94
- media = valueParser.stringify(media).trim();
95
- let dep = {
96
- moduleSpecifier,
97
- // Offset by 8 as it does not include `@import `
98
- loc: createDependencyLocation(
99
- rule.source.start,
100
- moduleSpecifier,
101
- 0,
102
- 8,
103
- ),
104
- meta: {
105
- media,
106
- },
107
- };
108
- asset.addDependency(dep);
109
- rule.remove();
110
- // }
111
- }
112
- ast.isDirty = true;
107
+ // If this came from an inline <style> tag, don't inline the imported file. Replace with the correct URL instead.
108
+ // TODO: run CSSPackager on inline style tags.
109
+ // let inlineHTML =
110
+ // this.options.rendition && this.options.rendition.inlineHTML;
111
+ // if (inlineHTML) {
112
+ // name.value = asset.addURLDependency(dep, {loc: rule.source.start});
113
+ // rule.params = params.toString();
114
+ // } else {
115
+ media = valueParser.stringify(media).trim();
116
+ let dep = {
117
+ specifier,
118
+ specifierType: 'url',
119
+ // Offset by 8 as it does not include `@import `
120
+ loc: createLoc(nullthrows(rule.source.start), specifier, 0, 8),
121
+ meta: {
122
+ // For the glob resolver to distinguish between `@import` and other URL dependencies.
123
+ isCSSImport: true,
124
+ media,
125
+ },
126
+ };
127
+ asset.addDependency(dep);
128
+ rule.remove();
129
+ // }
130
+ isDirty = true;
113
131
  });
114
132
 
115
- ast.program.walkDecls(decl => {
133
+ program.walkDecls(decl => {
116
134
  if (URL_RE.test(decl.value)) {
117
135
  let parsed = valueParser(decl.value);
118
- let isDirty = false;
136
+ let isDeclDirty = false;
119
137
 
120
138
  parsed.walk(node => {
121
139
  if (
@@ -124,39 +142,65 @@ export default new Transformer({
124
142
  node.nodes.length > 0 &&
125
143
  !node.nodes[0].value.startsWith('#') // IE's `behavior: url(#default#VML)`
126
144
  ) {
127
- node.nodes[0].value = asset.addURLDependency(node.nodes[0].value, {
128
- loc: createDependencyLocation(
129
- decl.source.start,
145
+ let url = asset.addURLDependency(node.nodes[0].value, {
146
+ loc: createLoc(
147
+ nullthrows(decl.source.start),
130
148
  node.nodes[0].value,
149
+ 0,
150
+ node.nodes[0].sourceIndex,
131
151
  ),
132
152
  });
133
- isDirty = true;
153
+ isDeclDirty = node.nodes[0].value !== url;
154
+ node.nodes[0].value = url;
134
155
  }
135
156
  });
136
157
 
137
- if (isDirty) {
158
+ if (isDeclDirty) {
138
159
  decl.value = parsed.toString();
139
- ast.isDirty = true;
160
+ isDirty = true;
140
161
  }
141
162
  }
142
163
  });
143
164
 
165
+ if (isDirty) {
166
+ asset.setAST({
167
+ ...ast,
168
+ program: program.toJSON(),
169
+ });
170
+ }
171
+
144
172
  return [asset];
145
173
  },
146
174
 
147
- async generate({asset}) {
148
- let code;
149
- if (!asset.ast || !asset.ast.isDirty) {
150
- code = await asset.getCode();
175
+ async generate({asset, ast, options}) {
176
+ let result = await postcss().process(postcss.fromJSON(ast.program), {
177
+ from: undefined,
178
+ to: options.projectRoot + '/index',
179
+ map: {
180
+ annotation: false,
181
+ inline: false,
182
+ sourcesContent: false,
183
+ },
184
+ // Pass postcss's own stringifier to it to silence its warning
185
+ // as we don't want to perform any transformations -- only generate
186
+ stringifier: postcss.stringify,
187
+ });
188
+
189
+ let map = null;
190
+ let originalSourceMap = await asset.getMap();
191
+ if (result.map != null) {
192
+ map = new SourceMap(options.projectRoot);
193
+ map.addVLQMap(result.map.toJSON());
194
+ if (originalSourceMap) {
195
+ map.extends(originalSourceMap.toBuffer());
196
+ }
151
197
  } else {
152
- code = '';
153
- postcss.stringify(asset.ast.program, c => {
154
- code += c;
155
- });
198
+ map = originalSourceMap;
156
199
  }
157
200
 
158
201
  return {
159
- code,
202
+ content: result.css,
203
+ map,
160
204
  };
161
205
  },
162
- });
206
+ }): Transformer);