@parcel/transformer-postcss 2.1.1 → 2.3.1

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.
@@ -35,16 +35,6 @@ function _plugin() {
35
35
  return data;
36
36
  }
37
37
 
38
- function _fileSystemLoader() {
39
- const data = _interopRequireDefault(require("css-modules-loader-core/lib/file-system-loader"));
40
-
41
- _fileSystemLoader = function () {
42
- return data;
43
- };
44
-
45
- return data;
46
- }
47
-
48
38
  function _nullthrows() {
49
39
  const data = _interopRequireDefault(require("nullthrows"));
50
40
 
@@ -85,16 +75,6 @@ function _postcssValueParser() {
85
75
  return data;
86
76
  }
87
77
 
88
- function _postcssModules() {
89
- const data = _interopRequireDefault(require("postcss-modules"));
90
-
91
- _postcssModules = function () {
92
- return data;
93
- };
94
-
95
- return data;
96
- }
97
-
98
78
  var _loadConfig = require("./loadConfig");
99
79
 
100
80
  var _constants = require("./constants");
@@ -103,6 +83,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
103
83
 
104
84
  const COMPOSES_RE = /composes:.+from\s*("|').*("|')\s*;?/;
105
85
  const FROM_IMPORT_RE = /.+from\s*(?:"|')(.*)(?:"|')\s*;?/;
86
+ const LEGACY_MODULE_RE = /@value|(:global|:local)(?!\s*\()/i;
87
+ const MODULE_BY_NAME_RE = /\.module\./;
106
88
 
107
89
  var _default = new (_plugin().Transformer)({
108
90
  loadConfig({
@@ -128,7 +110,9 @@ var _default = new (_plugin().Transformer)({
128
110
  config,
129
111
  options
130
112
  }) {
131
- if (!config) {
113
+ let isLegacy = await isLegacyCssModule(asset);
114
+
115
+ if (!config && !isLegacy) {
132
116
  return;
133
117
  }
134
118
 
@@ -149,52 +133,70 @@ var _default = new (_plugin().Transformer)({
149
133
  resolve
150
134
  }) {
151
135
  asset.type = 'css';
136
+ let isLegacy = await isLegacyCssModule(asset);
137
+
138
+ if (isLegacy && !config) {
139
+ config = {
140
+ hydrated: {
141
+ plugins: [],
142
+ from: asset.filePath,
143
+ to: asset.filePath,
144
+ modules: {}
145
+ }
146
+ }; // TODO: warning?
147
+ }
152
148
 
153
149
  if (!config) {
154
150
  return [asset];
155
151
  }
156
152
 
157
153
  const postcss = await loadPostcss(options, asset.filePath);
154
+ let ast = (0, _nullthrows().default)(await asset.getAST());
155
+ let program = postcss.fromJSON(ast.program);
158
156
  let plugins = [...config.hydrated.plugins];
159
157
  let cssModules = null;
160
158
 
161
159
  if (config.hydrated.modules) {
162
- plugins.push((0, _postcssModules().default)({
160
+ asset.meta.cssModulesCompiled = true; // TODO: should this be resolved from the project root?
161
+
162
+ let postcssModules = await options.packageManager.require('postcss-modules', asset.filePath, {
163
+ range: '^4.3.0',
164
+ saveDev: true,
165
+ shouldAutoInstall: options.shouldAutoInstall
166
+ });
167
+ plugins.push(postcssModules({
163
168
  getJSON: (filename, json) => cssModules = json,
164
- Loader: createLoader(asset, resolve),
165
- generateScopedName: (name, filename) => `_${name}_${(0, _hash().hashString)(_path().default.relative(options.projectRoot, filename)).substr(0, 6)}`,
169
+ Loader: await createLoader(asset, resolve, options),
170
+ generateScopedName: (name, filename) => `${name}_${(0, _hash().hashString)(_path().default.relative(options.projectRoot, filename)).substr(0, 6)}`,
166
171
  ...config.hydrated.modules
167
172
  }));
168
- }
169
-
170
- let ast = (0, _nullthrows().default)(await asset.getAST());
171
- let program = postcss.fromJSON(ast.program);
172
- let code = asset.isASTDirty() ? null : await asset.getCode();
173
-
174
- if (code == null || COMPOSES_RE.test(code)) {
175
- program.walkDecls(decl => {
176
- let [, importPath] = FROM_IMPORT_RE.exec(decl.value) || [];
177
-
178
- if (decl.prop === 'composes' && importPath != null) {
179
- let parsed = (0, _postcssValueParser().default)(decl.value);
180
- parsed.walk(node => {
181
- if (node.type === 'string') {
182
- asset.addDependency({
183
- specifier: importPath,
184
- specifierType: 'url',
185
- loc: {
186
- filePath: asset.filePath,
187
- start: decl.source.start,
188
- end: {
189
- line: decl.source.start.line,
190
- column: decl.source.start.column + importPath.length
173
+ let code = asset.isASTDirty() ? null : await asset.getCode();
174
+
175
+ if (code == null || COMPOSES_RE.test(code)) {
176
+ program.walkDecls(decl => {
177
+ let [, importPath] = FROM_IMPORT_RE.exec(decl.value) || [];
178
+
179
+ if (decl.prop === 'composes' && importPath != null) {
180
+ let parsed = (0, _postcssValueParser().default)(decl.value);
181
+ parsed.walk(node => {
182
+ if (node.type === 'string') {
183
+ asset.addDependency({
184
+ specifier: importPath,
185
+ specifierType: 'url',
186
+ loc: {
187
+ filePath: asset.filePath,
188
+ start: decl.source.start,
189
+ end: {
190
+ line: decl.source.start.line,
191
+ column: decl.source.start.column + importPath.length
192
+ }
191
193
  }
192
- }
193
- });
194
- }
195
- });
196
- }
197
- });
194
+ });
195
+ }
196
+ });
197
+ }
198
+ });
199
+ }
198
200
  } // $FlowFixMe Added in Flow 0.121.0 upgrade in #4381
199
201
 
200
202
 
@@ -281,8 +283,11 @@ var _default = new (_plugin().Transformer)({
281
283
 
282
284
  exports.default = _default;
283
285
 
284
- function createLoader(asset, resolve) {
285
- return class extends _fileSystemLoader().default {
286
+ async function createLoader(asset, resolve, options) {
287
+ let {
288
+ default: FileSystemLoader
289
+ } = await options.packageManager.require('postcss-modules/build/css-loader-core/loader', asset.filePath);
290
+ return class extends FileSystemLoader {
286
291
  async fetch(composesPath, relativeTo) {
287
292
  let importPath = composesPath.replace(/^["']|["']$/g, '');
288
293
  let resolved = await resolve(relativeTo, importPath);
@@ -318,4 +323,13 @@ function loadPostcss(options, from) {
318
323
  saveDev: true,
319
324
  shouldAutoInstall: options.shouldAutoInstall
320
325
  });
326
+ }
327
+
328
+ async function isLegacyCssModule(asset) {
329
+ if (!MODULE_BY_NAME_RE.test(asset.filePath)) {
330
+ return false;
331
+ }
332
+
333
+ let code = await asset.getCode();
334
+ return LEGACY_MODULE_RE.test(code);
321
335
  }
package/lib/loadConfig.js CHANGED
@@ -51,20 +51,7 @@ var _loadPlugins = _interopRequireDefault(require("./loadPlugins"));
51
51
 
52
52
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
53
53
 
54
- const MODULE_BY_NAME_RE = /\.module\./;
55
-
56
54
  async function configHydrator(configFile, config, resolveFrom, options) {
57
- // Use a basic, modules-only PostCSS config if the file opts in by a name
58
- // like foo.module.css
59
- if (configFile == null && config.searchPath.match(MODULE_BY_NAME_RE)) {
60
- configFile = {
61
- plugins: {
62
- 'postcss-modules': {}
63
- }
64
- };
65
- resolveFrom = __filename;
66
- }
67
-
68
55
  if (configFile == null) {
69
56
  return;
70
57
  } // Load the custom config...
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parcel/transformer-postcss",
3
- "version": "2.1.1",
3
+ "version": "2.3.1",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -17,21 +17,19 @@
17
17
  "source": "src/PostCSSTransformer.js",
18
18
  "engines": {
19
19
  "node": ">= 12.0.0",
20
- "parcel": "^2.1.1"
20
+ "parcel": "^2.3.1"
21
21
  },
22
22
  "dependencies": {
23
- "@parcel/hash": "^2.1.1",
24
- "@parcel/plugin": "^2.1.1",
25
- "@parcel/utils": "^2.1.1",
23
+ "@parcel/hash": "2.3.1",
24
+ "@parcel/plugin": "2.3.1",
25
+ "@parcel/utils": "2.3.1",
26
26
  "clone": "^2.1.1",
27
- "css-modules-loader-core": "^1.1.0",
28
27
  "nullthrows": "^1.1.1",
29
- "postcss-modules": "^3.2.2",
30
- "postcss-value-parser": "^4.1.0",
28
+ "postcss-value-parser": "^4.2.0",
31
29
  "semver": "^5.7.1"
32
30
  },
33
31
  "devDependencies": {
34
- "postcss": "^8.3.0"
32
+ "postcss": "^8.4.5"
35
33
  },
36
- "gitHead": "f53ffe772a8259d94ca2937d02fde149454112f3"
34
+ "gitHead": "699f0b24c38eabcdad0960c62c03bd2f2902b19e"
37
35
  }
@@ -1,16 +1,14 @@
1
1
  // @flow
2
2
 
3
- import type {FilePath, MutableAsset, PluginOptions} from '@parcel/types';
3
+ import type {FilePath, Asset, MutableAsset, PluginOptions} from '@parcel/types';
4
4
 
5
5
  import {hashString} from '@parcel/hash';
6
6
  import {glob} from '@parcel/utils';
7
7
  import {Transformer} from '@parcel/plugin';
8
- import FileSystemLoader from 'css-modules-loader-core/lib/file-system-loader';
9
8
  import nullthrows from 'nullthrows';
10
9
  import path from 'path';
11
10
  import semver from 'semver';
12
11
  import valueParser from 'postcss-value-parser';
13
- import postcssModules from 'postcss-modules';
14
12
  import typeof * as Postcss from 'postcss';
15
13
 
16
14
  import {load} from './loadConfig';
@@ -18,6 +16,8 @@ import {POSTCSS_RANGE} from './constants';
18
16
 
19
17
  const COMPOSES_RE = /composes:.+from\s*("|').*("|')\s*;?/;
20
18
  const FROM_IMPORT_RE = /.+from\s*(?:"|')(.*)(?:"|')\s*;?/;
19
+ const LEGACY_MODULE_RE = /@value|(:global|:local)(?!\s*\()/i;
20
+ const MODULE_BY_NAME_RE = /\.module\./;
21
21
 
22
22
  export default (new Transformer({
23
23
  loadConfig({config, options, logger}) {
@@ -31,7 +31,8 @@ export default (new Transformer({
31
31
  },
32
32
 
33
33
  async parse({asset, config, options}) {
34
- if (!config) {
34
+ let isLegacy = await isLegacyCssModule(asset);
35
+ if (!config && !isLegacy) {
35
36
  return;
36
37
  }
37
38
 
@@ -50,55 +51,82 @@ export default (new Transformer({
50
51
 
51
52
  async transform({asset, config, options, resolve}) {
52
53
  asset.type = 'css';
54
+ let isLegacy = await isLegacyCssModule(asset);
55
+ if (isLegacy && !config) {
56
+ config = {
57
+ hydrated: {
58
+ plugins: [],
59
+ from: asset.filePath,
60
+ to: asset.filePath,
61
+ modules: {},
62
+ },
63
+ };
64
+
65
+ // TODO: warning?
66
+ }
67
+
53
68
  if (!config) {
54
69
  return [asset];
55
70
  }
56
71
 
57
72
  const postcss: Postcss = await loadPostcss(options, asset.filePath);
73
+ let ast = nullthrows(await asset.getAST());
74
+ let program = postcss.fromJSON(ast.program);
58
75
 
59
76
  let plugins = [...config.hydrated.plugins];
60
77
  let cssModules: ?{|[string]: string|} = null;
61
78
  if (config.hydrated.modules) {
79
+ asset.meta.cssModulesCompiled = true;
80
+
81
+ // TODO: should this be resolved from the project root?
82
+ let postcssModules = await options.packageManager.require(
83
+ 'postcss-modules',
84
+ asset.filePath,
85
+ {
86
+ range: '^4.3.0',
87
+ saveDev: true,
88
+ shouldAutoInstall: options.shouldAutoInstall,
89
+ },
90
+ );
91
+
62
92
  plugins.push(
63
93
  postcssModules({
64
94
  getJSON: (filename, json) => (cssModules = json),
65
- Loader: createLoader(asset, resolve),
95
+ Loader: await createLoader(asset, resolve, options),
66
96
  generateScopedName: (name, filename) =>
67
- `_${name}_${hashString(
97
+ `${name}_${hashString(
68
98
  path.relative(options.projectRoot, filename),
69
99
  ).substr(0, 6)}`,
70
100
  ...config.hydrated.modules,
71
101
  }),
72
102
  );
73
- }
74
103
 
75
- let ast = nullthrows(await asset.getAST());
76
- let program = postcss.fromJSON(ast.program);
77
- let code = asset.isASTDirty() ? null : await asset.getCode();
78
- if (code == null || COMPOSES_RE.test(code)) {
79
- program.walkDecls(decl => {
80
- let [, importPath] = FROM_IMPORT_RE.exec(decl.value) || [];
81
- if (decl.prop === 'composes' && importPath != null) {
82
- let parsed = valueParser(decl.value);
83
-
84
- parsed.walk(node => {
85
- if (node.type === 'string') {
86
- asset.addDependency({
87
- specifier: importPath,
88
- specifierType: 'url',
89
- loc: {
90
- filePath: asset.filePath,
91
- start: decl.source.start,
92
- end: {
93
- line: decl.source.start.line,
94
- column: decl.source.start.column + importPath.length,
104
+ let code = asset.isASTDirty() ? null : await asset.getCode();
105
+ if (code == null || COMPOSES_RE.test(code)) {
106
+ program.walkDecls(decl => {
107
+ let [, importPath] = FROM_IMPORT_RE.exec(decl.value) || [];
108
+ if (decl.prop === 'composes' && importPath != null) {
109
+ let parsed = valueParser(decl.value);
110
+
111
+ parsed.walk(node => {
112
+ if (node.type === 'string') {
113
+ asset.addDependency({
114
+ specifier: importPath,
115
+ specifierType: 'url',
116
+ loc: {
117
+ filePath: asset.filePath,
118
+ start: decl.source.start,
119
+ end: {
120
+ line: decl.source.start.line,
121
+ column: decl.source.start.column + importPath.length,
122
+ },
95
123
  },
96
- },
97
- });
98
- }
99
- });
100
- }
101
- });
124
+ });
125
+ }
126
+ });
127
+ }
128
+ });
129
+ }
102
130
  }
103
131
 
104
132
  // $FlowFixMe Added in Flow 0.121.0 upgrade in #4381
@@ -178,10 +206,15 @@ export default (new Transformer({
178
206
  },
179
207
  }): Transformer);
180
208
 
181
- function createLoader(
209
+ async function createLoader(
182
210
  asset: MutableAsset,
183
211
  resolve: (from: FilePath, to: string) => Promise<FilePath>,
212
+ options: PluginOptions,
184
213
  ) {
214
+ let {default: FileSystemLoader} = await options.packageManager.require(
215
+ 'postcss-modules/build/css-loader-core/loader',
216
+ asset.filePath,
217
+ );
185
218
  return class ParcelFileSystemLoader extends FileSystemLoader {
186
219
  async fetch(composesPath, relativeTo) {
187
220
  let importPath = composesPath.replace(/^["']|["']$/g, '');
@@ -218,3 +251,12 @@ function loadPostcss(options: PluginOptions, from: FilePath): Promise<Postcss> {
218
251
  shouldAutoInstall: options.shouldAutoInstall,
219
252
  });
220
253
  }
254
+
255
+ async function isLegacyCssModule(asset: Asset | MutableAsset) {
256
+ if (!MODULE_BY_NAME_RE.test(asset.filePath)) {
257
+ return false;
258
+ }
259
+
260
+ let code = await asset.getCode();
261
+ return LEGACY_MODULE_RE.test(code);
262
+ }
package/src/loadConfig.js CHANGED
@@ -13,8 +13,6 @@ import {POSTCSS_RANGE} from './constants';
13
13
 
14
14
  import loadExternalPlugins from './loadPlugins';
15
15
 
16
- const MODULE_BY_NAME_RE = /\.module\./;
17
-
18
16
  type ConfigResult = {|
19
17
  raw: any,
20
18
  hydrated: {|
@@ -31,17 +29,6 @@ async function configHydrator(
31
29
  resolveFrom: ?FilePath,
32
30
  options: PluginOptions,
33
31
  ): Promise<?ConfigResult> {
34
- // Use a basic, modules-only PostCSS config if the file opts in by a name
35
- // like foo.module.css
36
- if (configFile == null && config.searchPath.match(MODULE_BY_NAME_RE)) {
37
- configFile = {
38
- plugins: {
39
- 'postcss-modules': {},
40
- },
41
- };
42
- resolveFrom = __filename;
43
- }
44
-
45
32
  if (configFile == null) {
46
33
  return;
47
34
  }