css-loader 3.4.0 → 3.5.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,38 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [3.5.1](https://github.com/webpack-contrib/css-loader/compare/v3.5.0...v3.5.1) (2020-04-07)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * don't generate an invalid code for `locals` ([#1072](https://github.com/webpack-contrib/css-loader/issues/1072)) ([866b84a](https://github.com/webpack-contrib/css-loader/commit/866b84acd7fd47651f741ca1e6cf7081c2bbe357))
11
+
12
+ ## [3.5.0](https://github.com/webpack-contrib/css-loader/compare/v3.4.2...v3.5.0) (2020-04-06)
13
+
14
+
15
+ ### Features
16
+
17
+ * accept semver compatible postcss AST ([#1049](https://github.com/webpack-contrib/css-loader/issues/1049)) ([14c4faa](https://github.com/webpack-contrib/css-loader/commit/14c4faae87305c9b965de4f468bb1e118f6b84cc))
18
+ * allow to determinate css modules using the `modules.auto` option, please look at an [example](https://github.com/webpack-contrib/css-loader#pure-css-css-modules-and-postcss) of how you can simplify the configuration. ([#1067](https://github.com/webpack-contrib/css-loader/issues/1067)) ([c673cf4](https://github.com/webpack-contrib/css-loader/commit/c673cf418e901c5050bc697eb45401dc9a42c477))
19
+ * the `modules.exportGlobals` option for export global classes and ids ([#1069](https://github.com/webpack-contrib/css-loader/issues/1069)) ([519e5f4](https://github.com/webpack-contrib/css-loader/commit/519e5f41539f4c87ec96db0a908aaadecc284a6c))
20
+ * the `modules.mode` option may be a function ([#1065](https://github.com/webpack-contrib/css-loader/issues/1065)) ([0d8ac3b](https://github.com/webpack-contrib/css-loader/commit/0d8ac3bcb831bc747657c914aba106b93840737e))
21
+
22
+ ### [3.4.2](https://github.com/webpack-contrib/css-loader/compare/v3.4.1...v3.4.2) (2020-01-10)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * do not duplicate css on `composes` ([#1040](https://github.com/webpack-contrib/css-loader/issues/1040)) ([df79602](https://github.com/webpack-contrib/css-loader/commit/df7960277be20ec80e9be1a41ac53baf69847fa0))
28
+
29
+ ### [3.4.1](https://github.com/webpack-contrib/css-loader/compare/v3.4.0...v3.4.1) (2020-01-03)
30
+
31
+
32
+ ### Bug Fixes
33
+
34
+ * do not output `undefined` when sourceRoot is unavailable ([#1036](https://github.com/webpack-contrib/css-loader/issues/1036)) ([ded2a79](https://github.com/webpack-contrib/css-loader/commit/ded2a797271f2adf864bf92300621c024974bc79))
35
+ * don't output invalid es5 code when locals do not exists ([#1035](https://github.com/webpack-contrib/css-loader/issues/1035)) ([b60e62a](https://github.com/webpack-contrib/css-loader/commit/b60e62a655719cc1779fae7d577af6ad6cf42135))
36
+
5
37
  ## [3.4.0](https://github.com/webpack-contrib/css-loader/compare/v3.3.1...v3.4.0) (2019-12-17)
6
38
 
7
39
 
package/README.md CHANGED
@@ -528,6 +528,7 @@ module.exports = {
528
528
  options: {
529
529
  modules: {
530
530
  mode: 'local',
531
+ exportGlobals: true,
531
532
  localIdentName: '[path][name]__[local]--[hash:base64:5]',
532
533
  context: path.resolve(__dirname, 'src'),
533
534
  hashPrefix: 'my-custom-hash',
@@ -539,13 +540,75 @@ module.exports = {
539
540
  };
540
541
  ```
541
542
 
543
+ ##### `auto`
544
+
545
+ Type: `Boolean|RegExp`
546
+ Default: `'undefined'`
547
+
548
+ Allows auto enable css modules based on filename.
549
+
550
+ ###### `Boolean`
551
+
552
+ Possible values:
553
+
554
+ - `true` - enable css modules for all files for which `/\.module\.\w+$/i.test(filename)` return true
555
+ - `false` - disable css modules
556
+
557
+ **webpack.config.js**
558
+
559
+ ```js
560
+ module.exports = {
561
+ module: {
562
+ rules: [
563
+ {
564
+ test: /\.css$/i,
565
+ loader: 'css-loader',
566
+ options: {
567
+ modules: {
568
+ auto: true,
569
+ },
570
+ },
571
+ },
572
+ ],
573
+ },
574
+ };
575
+ ```
576
+
577
+ ###### `RegExp`
578
+
579
+ Enable css modules for files based on a filename and satisfying your regex.
580
+
581
+ **webpack.config.js**
582
+
583
+ ```js
584
+ module.exports = {
585
+ module: {
586
+ rules: [
587
+ {
588
+ test: /\.css$/i,
589
+ loader: 'css-loader',
590
+ options: {
591
+ modules: {
592
+ auto: /\.custom-module\.\w+$/i,
593
+ },
594
+ },
595
+ },
596
+ ],
597
+ },
598
+ };
599
+ ```
600
+
542
601
  ##### `mode`
543
602
 
544
- Type: `String`
603
+ Type: `String|Function`
545
604
  Default: `'local'`
546
605
 
547
606
  Setup `mode` option. You can omit the value when you want `local` mode.
548
607
 
608
+ ###### `String`
609
+
610
+ Possible values - `local`, `global`, and `pure`.
611
+
549
612
  **webpack.config.js**
550
613
 
551
614
  ```js
@@ -566,6 +629,70 @@ module.exports = {
566
629
  };
567
630
  ```
568
631
 
632
+ ###### `Function`
633
+
634
+ Allows set different values for the `mode` option based on a filename
635
+
636
+ Possible return values - `local`, `global`, and `pure`.
637
+
638
+ **webpack.config.js**
639
+
640
+ ```js
641
+ module.exports = {
642
+ module: {
643
+ rules: [
644
+ {
645
+ test: /\.css$/i,
646
+ loader: 'css-loader',
647
+ options: {
648
+ modules: {
649
+ // Callback must return "local", "global", or "pure" values
650
+ mode: (resourcePath) => {
651
+ if (/pure.css$/i.test(resourcePath)) {
652
+ return 'pure';
653
+ }
654
+
655
+ if (/global.css$/i.test(resourcePath)) {
656
+ return 'global';
657
+ }
658
+
659
+ return 'local';
660
+ },
661
+ },
662
+ },
663
+ },
664
+ ],
665
+ },
666
+ };
667
+ ```
668
+
669
+ ##### `exportGlobals`
670
+
671
+ Type: `Boolean`
672
+ Default: `false`
673
+
674
+ Allow `css-loader` to export names from global class or id, so you can use that as local name.
675
+
676
+ **webpack.config.js**
677
+
678
+ ```js
679
+ module.exports = {
680
+ module: {
681
+ rules: [
682
+ {
683
+ test: /\.css$/i,
684
+ loader: 'css-loader',
685
+ options: {
686
+ modules: {
687
+ exportGlobals: true,
688
+ },
689
+ },
690
+ },
691
+ ],
692
+ },
693
+ };
694
+ ```
695
+
569
696
  ##### `localIdentName`
570
697
 
571
698
  Type: `String`
@@ -922,9 +1049,9 @@ For production builds it's recommended to extract the CSS from your bundle being
922
1049
 
923
1050
  - As an alternative, if seeking better development performance and css outputs that mimic production. [extract-css-chunks-webpack-plugin](https://github.com/faceyspacey/extract-css-chunks-webpack-plugin) offers a hot module reload friendly, extended version of mini-css-extract-plugin. HMR real CSS files in dev, works like mini-css in non-dev
924
1051
 
925
- ### CSS modules and pure CSS
1052
+ ### Pure CSS, CSS modules and PostCSS
926
1053
 
927
- When you have pure CSS (without CSS modules) and CSS modules in project you can use this setup:
1054
+ When you have pure CSS (without CSS modules), CSS modules and PostCSS in your project you can use this setup:
928
1055
 
929
1056
  **webpack.config.js**
930
1057
 
@@ -932,23 +1059,34 @@ When you have pure CSS (without CSS modules) and CSS modules in project you can
932
1059
  module.exports = {
933
1060
  module: {
934
1061
  rules: [
935
- {
936
- // For pure CSS (without CSS modules)
937
- test: /\.css$/i,
938
- exclude: /\.module\.css$/i,
939
- use: ['style-loader', 'css-loader'],
940
- },
941
1062
  {
942
1063
  // For CSS modules
943
- test: /\.module\.css$/i,
1064
+ // For pure CSS - /\.css$/i,
1065
+ // For Sass/SCSS - /\.((c|sa|sc)ss)$/i,
1066
+ // For Less - /\.((c|le)ss)$/i,
1067
+ test: /\.((c|sa|sc)ss)$/i,
944
1068
  use: [
945
1069
  'style-loader',
946
1070
  {
947
1071
  loader: 'css-loader',
948
1072
  options: {
949
- modules: true,
1073
+ // Run `postcss-loader` on each CSS `@import`, do not forget that `sass-loader` compile non CSS `@import`'s into a single file
1074
+ // If you need run `sass-loader` and `postcss-loader` on each CSS `@import` please set it to `2`
1075
+ importLoaders: 1,
1076
+ // Automatically enable css modules for files satisfying `/\.module\.\w+$/i` RegExp.
1077
+ modules: { auto: true },
950
1078
  },
951
1079
  },
1080
+ {
1081
+ loader: 'postcss-loader',
1082
+ options: { plugins: () => [postcssPresetEnv({ stage: 0 })] },
1083
+ },
1084
+ // Can be `less-loader`
1085
+ // The `test` property should be `\.less/i`
1086
+ {
1087
+ test: /\.s[ac]ss$/i,
1088
+ loader: 'sass-loader',
1089
+ },
952
1090
  ],
953
1091
  },
954
1092
  {
package/dist/index.js CHANGED
@@ -5,13 +5,19 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = loader;
7
7
 
8
- var _schemaUtils = _interopRequireDefault(require("schema-utils"));
8
+ var _loaderUtils = require("loader-utils");
9
9
 
10
10
  var _postcss = _interopRequireDefault(require("postcss"));
11
11
 
12
12
  var _package = _interopRequireDefault(require("postcss/package.json"));
13
13
 
14
- var _loaderUtils = require("loader-utils");
14
+ var _schemaUtils = _interopRequireDefault(require("schema-utils"));
15
+
16
+ var _semver = require("semver");
17
+
18
+ var _CssSyntaxError = _interopRequireDefault(require("./CssSyntaxError"));
19
+
20
+ var _Warning = _interopRequireDefault(require("./Warning"));
15
21
 
16
22
  var _options = _interopRequireDefault(require("./options.json"));
17
23
 
@@ -19,10 +25,6 @@ var _plugins = require("./plugins");
19
25
 
20
26
  var _utils = require("./utils");
21
27
 
22
- var _Warning = _interopRequireDefault(require("./Warning"));
23
-
24
- var _CssSyntaxError = _interopRequireDefault(require("./CssSyntaxError"));
25
-
26
28
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
29
 
28
30
  /*
@@ -39,22 +41,30 @@ function loader(content, map, meta) {
39
41
  const sourceMap = options.sourceMap || false;
40
42
  const plugins = [];
41
43
 
42
- if (options.modules) {
44
+ if ((0, _utils.shouldUseModulesPlugins)(options.modules, this.resourcePath)) {
43
45
  plugins.push(...(0, _utils.getModulesPlugins)(options, this));
44
46
  }
45
47
 
46
48
  const exportType = options.onlyLocals ? 'locals' : 'full';
47
- plugins.push((0, _plugins.icssParser)());
49
+ const preRequester = (0, _utils.getPreRequester)(this);
50
+
51
+ const urlHandler = url => (0, _loaderUtils.stringifyRequest)(this, preRequester(options.importLoaders) + url);
52
+
53
+ plugins.push((0, _plugins.icssParser)({
54
+ urlHandler
55
+ }));
48
56
 
49
57
  if (options.import !== false && exportType === 'full') {
50
58
  plugins.push((0, _plugins.importParser)({
51
- filter: (0, _utils.getFilter)(options.import, this.resourcePath)
59
+ filter: (0, _utils.getFilter)(options.import, this.resourcePath),
60
+ urlHandler
52
61
  }));
53
62
  }
54
63
 
55
64
  if (options.url !== false && exportType === 'full') {
56
65
  plugins.push((0, _plugins.urlParser)({
57
- filter: (0, _utils.getFilter)(options.url, this.resourcePath, value => (0, _loaderUtils.isUrlRequest)(value))
66
+ filter: (0, _utils.getFilter)(options.url, this.resourcePath, value => (0, _loaderUtils.isUrlRequest)(value)),
67
+ urlHandler: url => (0, _loaderUtils.stringifyRequest)(this, url)
58
68
  }));
59
69
  } // Reuse CSS AST (PostCSS AST e.g 'postcss-loader') to avoid reparsing
60
70
 
@@ -64,7 +74,7 @@ function loader(content, map, meta) {
64
74
  ast
65
75
  } = meta;
66
76
 
67
- if (ast && ast.type === 'postcss' && ast.version === _package.default.version) {
77
+ if (ast && ast.type === 'postcss' && (0, _semver.satisfies)(ast.version, `^${_package.default.version}`)) {
68
78
  // eslint-disable-next-line no-param-reassign
69
79
  content = ast.root;
70
80
  }
@@ -80,10 +90,15 @@ function loader(content, map, meta) {
80
90
  annotation: false
81
91
  } : false
82
92
  }).then(result => {
83
- result.warnings().forEach(warning => this.emitWarning(new _Warning.default(warning)));
93
+ for (const warning of result.warnings()) {
94
+ this.emitWarning(new _Warning.default(warning));
95
+ }
96
+
84
97
  const imports = [];
98
+ const apiImports = [];
99
+ const urlReplacements = [];
100
+ const icssReplacements = [];
85
101
  const exports = [];
86
- const replacers = [];
87
102
 
88
103
  for (const message of result.messages) {
89
104
  // eslint-disable-next-line default-case
@@ -92,25 +107,32 @@ function loader(content, map, meta) {
92
107
  imports.push(message.value);
93
108
  break;
94
109
 
95
- case 'export':
96
- exports.push(message.value);
110
+ case 'api-import':
111
+ apiImports.push(message.value);
97
112
  break;
98
113
 
99
- case 'replacer':
100
- replacers.push(message.value);
114
+ case 'url-replacement':
115
+ urlReplacements.push(message.value);
116
+ break;
117
+
118
+ case 'icss-replacement':
119
+ icssReplacements.push(message.value);
120
+ break;
121
+
122
+ case 'export':
123
+ exports.push(message.value);
101
124
  break;
102
125
  }
103
126
  }
104
127
 
105
128
  const {
106
- importLoaders,
107
129
  localsConvention
108
130
  } = options;
109
131
  const esModule = typeof options.esModule !== 'undefined' ? options.esModule : false;
110
- const importCode = (0, _utils.getImportCode)(this, imports, exportType, sourceMap, importLoaders, esModule);
111
- const moduleCode = (0, _utils.getModuleCode)(this, result, exportType, sourceMap, replacers);
112
- const exportCode = (0, _utils.getExportCode)(this, exports, exportType, replacers, localsConvention, esModule);
113
- return callback(null, [importCode, moduleCode, exportCode].join(''));
132
+ const importCode = (0, _utils.getImportCode)(this, exportType, imports, esModule);
133
+ const moduleCode = (0, _utils.getModuleCode)(result, exportType, sourceMap, apiImports, urlReplacements, icssReplacements, esModule);
134
+ const exportCode = (0, _utils.getExportCode)(exports, exportType, localsConvention, icssReplacements, esModule);
135
+ return callback(null, `${importCode}${moduleCode}${exportCode}`);
114
136
  }).catch(error => {
115
137
  callback(error.name === 'CssSyntaxError' ? new _CssSyntaxError.default(error) : error);
116
138
  });
package/dist/options.json CHANGED
@@ -36,8 +36,28 @@
36
36
  "type": "object",
37
37
  "additionalProperties": false,
38
38
  "properties": {
39
+ "auto": {
40
+ "anyOf": [
41
+ {
42
+ "type": "object"
43
+ },
44
+ {
45
+ "type": "boolean"
46
+ }
47
+ ]
48
+ },
39
49
  "mode": {
40
- "enum": ["local", "global", "pure"]
50
+ "anyOf": [
51
+ {
52
+ "enum": ["local", "global", "pure"]
53
+ },
54
+ {
55
+ "instanceof": "Function"
56
+ }
57
+ ]
58
+ },
59
+ "exportGlobals": {
60
+ "type": "boolean"
41
61
  },
42
62
  "localIdentName": {
43
63
  "type": "string"
@@ -83,7 +103,7 @@
83
103
  "type": "boolean"
84
104
  },
85
105
  {
86
- "type": "number"
106
+ "type": "integer"
87
107
  }
88
108
  ]
89
109
  },
@@ -13,9 +13,7 @@ var _loaderUtils = require("loader-utils");
13
13
 
14
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
15
 
16
- const pluginName = 'postcss-icss-parser';
17
-
18
- function normalizeIcssImports(icssImports) {
16
+ function makeRequestableIcssImports(icssImports) {
19
17
  return Object.keys(icssImports).reduce((accumulator, url) => {
20
18
  const tokensMap = icssImports[url];
21
19
  const tokens = Object.keys(tokensMap);
@@ -40,58 +38,63 @@ function normalizeIcssImports(icssImports) {
40
38
  }, {});
41
39
  }
42
40
 
43
- var _default = _postcss.default.plugin(pluginName, () => function process(css, result) {
41
+ var _default = _postcss.default.plugin('postcss-icss-parser', options => (css, result) => {
44
42
  const importReplacements = Object.create(null);
45
- const {
46
- icssImports,
47
- icssExports
48
- } = (0, _icssUtils.extractICSS)(css);
49
- const normalizedIcssImports = normalizeIcssImports(icssImports);
50
- Object.keys(normalizedIcssImports).forEach((url, importIndex) => {
43
+ const extractedICSS = (0, _icssUtils.extractICSS)(css);
44
+ const icssImports = makeRequestableIcssImports(extractedICSS.icssImports);
45
+
46
+ for (const [importIndex, url] of Object.keys(icssImports).entries()) {
51
47
  const importName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}___`;
52
48
  result.messages.push({
53
- pluginName,
54
49
  type: 'import',
55
50
  value: {
56
- type: 'icss-import',
57
51
  importName,
58
- url
52
+ url: options.urlHandler ? options.urlHandler(url) : url
53
+ }
54
+ }, {
55
+ type: 'api-import',
56
+ value: {
57
+ type: 'internal',
58
+ importName,
59
+ dedupe: true
59
60
  }
60
61
  });
61
- const tokenMap = normalizedIcssImports[url];
62
+ const tokenMap = icssImports[url];
62
63
  const tokens = Object.keys(tokenMap);
63
- tokens.forEach((token, replacementIndex) => {
64
+
65
+ for (const [replacementIndex, token] of tokens.entries()) {
64
66
  const replacementName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}_REPLACEMENT_${replacementIndex}___`;
65
67
  const localName = tokenMap[token];
66
68
  importReplacements[token] = replacementName;
67
69
  result.messages.push({
68
- pluginName,
69
- type: 'replacer',
70
+ type: 'icss-replacement',
70
71
  value: {
71
- type: 'icss-import',
72
- importName,
73
72
  replacementName,
73
+ importName,
74
74
  localName
75
75
  }
76
76
  });
77
- });
78
- });
77
+ }
78
+ }
79
79
 
80
80
  if (Object.keys(importReplacements).length > 0) {
81
81
  (0, _icssUtils.replaceSymbols)(css, importReplacements);
82
82
  }
83
83
 
84
- Object.keys(icssExports).forEach(name => {
84
+ const {
85
+ icssExports
86
+ } = extractedICSS;
87
+
88
+ for (const name of Object.keys(icssExports)) {
85
89
  const value = (0, _icssUtils.replaceValueSymbols)(icssExports[name], importReplacements);
86
90
  result.messages.push({
87
- pluginName,
88
91
  type: 'export',
89
92
  value: {
90
93
  name,
91
94
  value
92
95
  }
93
96
  });
94
- });
97
+ }
95
98
  });
96
99
 
97
100
  exports.default = _default;