css-loader 0.28.0 → 0.28.4

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,57 @@
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
+ <a name="0.28.4"></a>
6
+ ## [0.28.4](https://github.com/webpack/css-loader/compare/v0.28.3...v0.28.4) (2017-05-30)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * preserve leading underscore in class names ([#543](https://github.com/webpack/css-loader/issues/543)) ([f6673c8](https://github.com/webpack/css-loader/commit/f6673c8))
12
+
13
+
14
+
15
+ <a name="0.28.3"></a>
16
+ ## [0.28.3](https://github.com/webpack/css-loader/compare/v0.28.2...v0.28.3) (2017-05-25)
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * correct plugin order for CSS Modules ([#534](https://github.com/webpack/css-loader/issues/534)) ([b90f492](https://github.com/webpack/css-loader/commit/b90f492))
22
+
23
+
24
+
25
+ <a name="0.28.2"></a>
26
+ ## [0.28.2](https://github.com/webpack/css-loader/compare/v0.28.1...v0.28.2) (2017-05-22)
27
+
28
+
29
+ ### Bug Fixes
30
+
31
+ * source maps path on `windows` ([#532](https://github.com/webpack/css-loader/issues/532)) ([c3d0d91](https://github.com/webpack/css-loader/commit/c3d0d91))
32
+
33
+
34
+
35
+ <a name="0.28.1"></a>
36
+ ## [0.28.1](https://github.com/webpack/css-loader/compare/v0.28.0...v0.28.1) (2017-05-02)
37
+
38
+
39
+ ### Bug Fixes
40
+
41
+ * allow to specify a full hostname as a root URL ([#521](https://github.com/webpack/css-loader/issues/521)) ([06d27a1](https://github.com/webpack/css-loader/commit/06d27a1))
42
+ * case insensitivity of [@import](https://github.com/import) ([#514](https://github.com/webpack/css-loader/issues/514)) ([de4356b](https://github.com/webpack/css-loader/commit/de4356b))
43
+ * don't handle empty [@import](https://github.com/import) and url() ([#513](https://github.com/webpack/css-loader/issues/513)) ([868fc94](https://github.com/webpack/css-loader/commit/868fc94))
44
+ * imported variables are replaced in exports if followed by a comma ([#504](https://github.com/webpack/css-loader/issues/504)) ([956bad7](https://github.com/webpack/css-loader/commit/956bad7))
45
+ * loader now correctly handles `url` with space(s) ([#495](https://github.com/webpack/css-loader/issues/495)) ([534ea55](https://github.com/webpack/css-loader/commit/534ea55))
46
+ * url with a trailing space is now handled correctly ([#494](https://github.com/webpack/css-loader/issues/494)) ([e1ec4f2](https://github.com/webpack/css-loader/commit/e1ec4f2))
47
+ * use `btoa` instead `Buffer` ([#501](https://github.com/webpack/css-loader/issues/501)) ([fbb0714](https://github.com/webpack/css-loader/commit/fbb0714))
48
+
49
+
50
+ ### Performance Improvements
51
+
52
+ * generate source maps only when explicitly set ([#478](https://github.com/webpack/css-loader/issues/478)) ([b8f5c8f](https://github.com/webpack/css-loader/commit/b8f5c8f))
53
+
54
+
55
+
5
56
  <a name="0.28.0"></a>
6
57
  # [0.28.0](https://github.com/webpack/css-loader/compare/v0.27.3...v0.28.0) (2017-03-30)
7
58
 
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![chat][chat]][chat-url]
7
7
 
8
8
  <div align="center">
9
- <img width="200" height="200"
9
+ <img width="180" height="180" vspace="20"
10
10
  src="https://cdn.worldvectorlogo.com/logos/css-3.svg">
11
11
  <a href="https://github.com/webpack/webpack">
12
12
  <img width="200" height="200"
@@ -23,11 +23,16 @@ npm install --save-dev css-loader
23
23
 
24
24
  <h2 align="center">Usage</h2>
25
25
 
26
- The `css-loader` interprets `@import` and `url()` like `requires`.
26
+ The `css-loader` interprets `@import` and `url()` like `import/require()`
27
+ and will resolve them.
27
28
 
28
- Use the loader either via your webpack config, CLI or inline.
29
+ Good loaders for requiring your assets are the [file-loader](https://github.com/webpack/file-loader)
30
+ and the [url-loader](https://github.com/webpack/url-loader) which you should specify in your config (see [below](https://github.com/michael-ciniawsky/css-loader#assets)).
29
31
 
30
- ### Via webpack config (recommended)
32
+ **file.js**
33
+ ```js
34
+ import css from 'file.css';
35
+ ```
31
36
 
32
37
  **webpack.config.js**
33
38
  ```js
@@ -43,109 +48,155 @@ module.exports = {
43
48
  }
44
49
  ```
45
50
 
46
- **In your application**
47
- ```js
48
- import css from 'file.css';
49
- ```
51
+ ### `toString`
50
52
 
51
- ### CLI
53
+ You can also use the css-loader results directly as string, such as in Angular's component style.
52
54
 
53
- ```bash
54
- webpack --module-bind 'css=style-loader!css-loader'
55
+ **webpack.config.js**
56
+ ```js
57
+ {
58
+    test: /\.css$/,
59
+    use: [
60
+      'to-string-loader',
61
+ 'css-loader'
62
+    ]
63
+ }
55
64
  ```
56
65
 
57
- **In your application**
66
+ or
67
+
58
68
  ```js
59
- import css from 'file.css';
69
+ const css = require('./test.css').toString();
70
+
71
+ console.log(css); // {String}
60
72
  ```
61
73
 
62
- ### Inline
74
+ If there are SourceMaps, they will also be included in the result string.
75
+
76
+ If, for one reason or another, you need to extract CSS as a
77
+ plain string resource (i.e. not wrapped in a JS module) you
78
+ might want to check out the [extract-loader](https://github.com/peerigon/extract-loader).
79
+ It's useful when you, for instance, need to post process the CSS as a string.
63
80
 
64
- **In your application**
81
+ **webpack.config.js**
65
82
  ```js
66
- import css from 'style-loader!css-loader!./file.css';
83
+ {
84
+    test: /\.css$/,
85
+    use: [
86
+ 'handlebars-loader', // handlebars loader expects raw resource string
87
+      'extract-loader',
88
+ 'css-loader'
89
+    ]
90
+ }
67
91
  ```
68
92
 
69
93
  <h2 align="center">Options</h2>
70
94
 
71
- `@import` and `url()` are interpreted like `import` and will be resolved by the css-loader.
72
- Good loaders for requiring your assets are the [file-loader](https://github.com/webpack/file-loader)
73
- and the [url-loader](https://github.com/webpack/url-loader) which you should specify in your config (see below).
74
-
75
- To be compatible with existing css files (if not in CSS Module mode):
95
+ |Name|Type|Default|Description|
96
+ |:--:|:--:|:-----:|:----------|
97
+ |**`root`**|`{String}`|`/`|Path to resolve URLs, URLs starting with `/` will not be translated|
98
+ |**`url`**|`{Boolean}`|`true`| Enable/Disable `url()` handling|
99
+ |**`alias`**|`{Object}`|`{}`|Create aliases to import certain modules more easily|
100
+ |**`import`** |`{Boolean}`|`true`| Enable/Disable @import handling|
101
+ |**`modules`**|`{Boolean}`|`false`|Enable/Disable CSS Modules|
102
+ |**`minimize`**|`{Boolean\|Object}`|`false`|Enable/Disable minification|
103
+ |**`sourceMap`**|`{Boolean}`|`false`|Enable/Disable Sourcemaps|
104
+ |**`camelCase`**|`{Boolean\|String}`|`false`|Export Classnames in CamelCase|
105
+ |**`importLoaders`**|`{Number}`|`0`|Number of loaders applied before CSS loader|
76
106
 
77
- * `url(image.png)` => `require('./image.png')`
78
- * `url(~module/image.png)` => `require('module/image.png')`
107
+ ### `root`
79
108
 
80
- <h2 align="center">Options</h2>
109
+ For URLs that start with a `/`, the default behavior is to not translate them.
81
110
 
82
- |Name|Default|Description|
83
- |:--:|:-----:|:----------|
84
- |**`root`**|`/`|Path to resolve URLs, URLs starting with `/` will not be translated|
85
- |**`modules`**|`false`|Enable/Disable CSS Modules|
86
- |**`import`** |`true`| Enable/Disable @import handling|
87
- |**`url`**|`true`| Enable/Disable `url()` handling|
88
- |**`minimize`**|`false`|Enable/Disable minification|
89
- |**`sourceMap`**|`false`|Enable/Disable Sourcemaps|
90
- |**`camelCase`**|`false`|Export Classnames in CamelCase|
91
- |**`importLoaders`**|`0`|Number of loaders applied before CSS loader|
92
- |**`alias`**|`{}`|Create aliases to import certain modules more easily|
111
+ `url(/image.png) => url(/image.png)`
93
112
 
94
- The following webpack config can load CSS files, embed small PNG/JPG/GIF/SVG images as well as fonts as [Data URLs](https://tools.ietf.org/html/rfc2397) and copy larger files to the output directory.
113
+ If a `root` query parameter is set, however, it will be prepended to the URL
114
+ and then translated.
95
115
 
96
116
  **webpack.config.js**
97
117
  ```js
98
- module.exports = {
99
- module: {
100
- rules: [
101
- {
102
- test: /\.css$/,
103
- use: [ 'style-loader', 'css-loader' ]
104
- },
105
- {
106
- test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
107
- loader: 'url-loader',
108
- options: {
109
- limit: 10000
110
- }
111
- }
112
- ]
113
- }
114
- };
118
+ {
119
+ loader: 'css-loader',
120
+ options: { root: '.' }
121
+ }
115
122
  ```
116
123
 
117
- ### Root
124
+ `url(/image.png)` => `require('./image.png')`
118
125
 
119
- For URLs that start with a `/`, the default behavior is to not translate them:
126
+ Using 'Root-relative' urls is not recommended. You should only use it for legacy CSS files.
120
127
 
121
- * `url(/image.png)` => `url(/image.png)`
128
+ ### `url`
122
129
 
123
- If a `root` query parameter is set, however, it will be prepended to the URL
124
- and then translated:
130
+ To disable `url()` resolving by `css-loader` set the option to `false`.
131
+
132
+ To be compatible with existing css files (if not in CSS Module mode).
133
+
134
+ ```
135
+ url(image.png) => require('./image.png')
136
+ url(~module/image.png) => require('module/image.png')
137
+ ```
138
+
139
+ ### `alias`
140
+
141
+ Rewrite your urls with alias, this is useful when it's hard to change url paths of your input files, for example, when you're using some css / sass files in another package (bootstrap, ratchet, font-awesome, etc.).
142
+
143
+ `css-loader`'s `alias` follows the same syntax as webpack's `resolve.alias`, you can see the details at the [resolve docs] (https://webpack.js.org/configuration/resolve/#resolve-alias)
144
+
145
+ **file.scss**
146
+ ```css
147
+ @charset "UTF-8";
148
+ @import "bootstrap";
149
+ ```
125
150
 
126
151
  **webpack.config.js**
127
152
  ```js
128
- rules: [
129
- {
130
- test: /\.css$/,
131
- use: [
132
- 'style-loader',
133
- {
134
- loader: 'css-loader',
135
- options: { root: '.' }
153
+ {
154
+ test: /\.scss$/,
155
+ use: [
156
+ {
157
+ loader: "style-loader"
158
+ },
159
+ {
160
+ loader: "css-loader",
161
+ options: {
162
+ alias: {
163
+ "../fonts/bootstrap": "bootstrap-sass/assets/fonts/bootstrap"
164
+ }
136
165
  }
137
- ]
138
- }
139
- ]
166
+ },
167
+ {
168
+ loader: "sass-loader",
169
+ options: {
170
+ includePaths: [
171
+ path.resolve("./node_modules/bootstrap-sass/assets/stylesheets")
172
+ ]
173
+ }
174
+ }
175
+ ]
176
+ }
140
177
  ```
141
178
 
142
- * `url(/image.png)` => `require('./image.png')`
179
+ Check out this [working bootstrap example](https://github.com/bbtfr/webpack2-bootstrap-sass-sample).
143
180
 
144
- Using 'Root-relative' urls is not recommended. You should only use it for legacy CSS files.
181
+ ### `import`
145
182
 
146
- ### CSS Scope
183
+ To disable `@import` resolving by `css-loader` set the option to `false`
184
+
185
+ ```css
186
+ @import url('https://fonts.googleapis.com/css?family=Roboto');
187
+ ```
188
+
189
+ > _⚠️ Use with caution, since this disables resolving for **all** `@import`s, including css modules `composes: xxx from 'path/to/file.css'` feature._
190
+
191
+ ### [`modules`](https://github.com/css-modules/css-modules)
192
+
193
+ The query parameter `modules` enables the **CSS Modules** spec.
147
194
 
148
- By default CSS exports all class names into a global selector scope. Styles can be locally scoped to avoid globally scoping styles.
195
+ This enables local scoped CSS by default. (You can switch it off with `:global(...)` or `:global` for selectors and/or rules.).
196
+
197
+ #### `Scope`
198
+
199
+ By default CSS exports all classnames into a global selector scope. Styles can be locally scoped to avoid globally scoping styles.
149
200
 
150
201
  The syntax `:local(.className)` can be used to declare `className` in the local scope. The local identifiers are exported by the module.
151
202
 
@@ -153,7 +204,6 @@ With `:local` (without brackets) local mode can be switched on for this selector
153
204
 
154
205
  The loader replaces local selectors with unique identifiers. The choosen unique identifiers are exported by the module.
155
206
 
156
- **app.css**
157
207
  ```css
158
208
  :local(.className) { background: red; }
159
209
  :local .className { color: green; }
@@ -161,17 +211,16 @@ The loader replaces local selectors with unique identifiers. The choosen unique
161
211
  :local .className .subClass :global(.global-class-name) { color: blue; }
162
212
  ```
163
213
 
164
- **app.bundle.css**
165
- ``` css
214
+ ```css
166
215
  ._23_aKvs-b8bW2Vg3fwHozO { background: red; }
167
216
  ._23_aKvs-b8bW2Vg3fwHozO { color: green; }
168
217
  ._23_aKvs-b8bW2Vg3fwHozO ._13LGdX8RMStbBE9w-t0gZ1 { color: green; }
169
218
  ._23_aKvs-b8bW2Vg3fwHozO ._13LGdX8RMStbBE9w-t0gZ1 .global-class-name { color: blue; }
170
219
  ```
171
220
 
172
- > Note: Identifiers are exported
221
+ > :information_source: Identifiers are exported
173
222
 
174
- ``` js
223
+ ```js
175
224
  exports.locals = {
176
225
  className: '_23_aKvs-b8bW2Vg3fwHozO',
177
226
  subClass: '_13LGdX8RMStbBE9w-t0gZ1'
@@ -180,13 +229,14 @@ exports.locals = {
180
229
 
181
230
  CamelCase is recommended for local selectors. They are easier to use in the within the imported JS module.
182
231
 
183
- `url()` URLs in block scoped (`:local .abc`) rules behave like requests in modules:
232
+ `url()` URLs in block scoped (`:local .abc`) rules behave like requests in modules.
184
233
 
185
- * `./file.png` instead of `file.png`
186
- * `module/file.png` instead of `~module/file.png`
234
+ ```
235
+ file.png => ./file.png
236
+ ~module/file.png => module/file.png
237
+ ```
187
238
 
188
239
  You can use `:local(#someId)`, but this is not recommended. Use classes instead of ids.
189
-
190
240
  You can configure the generated ident with the `localIdentName` query parameter (default `[hash:base64]`).
191
241
 
192
242
  **webpack.config.js**
@@ -205,39 +255,29 @@ You can configure the generated ident with the `localIdentName` query parameter
205
255
  }
206
256
  ```
207
257
 
208
- You can also specify the absolute path to your custom `getLocalIdent` function to generate classname based on a different schema. Note that this requires `webpack >= v2.x.` since to be able to pass function in. For example:
258
+ You can also specify the absolute path to your custom `getLocalIdent` function to generate classname based on a different schema. This requires `webpack >= 2.2.1` (it supports functions in the `options` object).
209
259
 
260
+ **webpack.config.js**
210
261
  ```js
211
262
  {
212
- test: /\.css$/,
213
- use: [
214
- {
215
- loader: 'css-loader',
216
- options: {
217
- modules: true,
218
- localIdentName: '[path][name]__[local]--[hash:base64:5]',
219
- getLocalIdent: (context, localIdentName, localName, options) => {
220
- return 'whatever_random_class_name'
221
- }
222
- }
263
+ loader: 'css-loader',
264
+ options: {
265
+ modules: true,
266
+ localIdentName: '[path][name]__[local]--[hash:base64:5]',
267
+ getLocalIdent: (context, localIdentName, localName, options) => {
268
+ return 'whatever_random_class_name'
223
269
  }
224
- ]
270
+ }
225
271
  }
226
272
  ```
227
273
 
228
- Note: For prerendering with extract-text-webpack-plugin you should use `css-loader/locals` instead of `style-loader!css-loader` **in the prerendering bundle**. It doesn't embed CSS but only exports the identifier mappings.
229
-
230
- ### [CSS Modules](https://github.com/css-modules/css-modules)
231
-
232
- The query parameter `modules` enables the **CSS Modules** spec.
233
-
234
- This enables local scoped CSS by default. (You can switch it off with `:global(...)` or `:global` for selectors and/or rules.)
274
+ > :information_source: For prerendering with extract-text-webpack-plugin you should use `css-loader/locals` instead of `style-loader!css-loader` **in the prerendering bundle**. It doesn't embed CSS but only exports the identifier mappings.
235
275
 
236
- ### CSS Composing
276
+ #### `Composing`
237
277
 
238
- When declaring a local class name you can compose a local class from another local class name.
278
+ When declaring a local classname you can compose a local class from another local classname.
239
279
 
240
- ``` css
280
+ ```css
241
281
  :local(.className) {
242
282
  background: red;
243
283
  color: yellow;
@@ -249,7 +289,7 @@ When declaring a local class name you can compose a local class from another loc
249
289
  }
250
290
  ```
251
291
 
252
- This doesn't result in any change to the CSS itself but exports multiple class names:
292
+ This doesn't result in any change to the CSS itself but exports multiple classnames.
253
293
 
254
294
  ```js
255
295
  exports.locals = {
@@ -269,18 +309,18 @@ exports.locals = {
269
309
  }
270
310
  ```
271
311
 
272
- ### Importing CSS Locals
312
+ #### `Importing`
273
313
 
274
- To import a local class name from another module:
314
+ To import a local classname from another module.
275
315
 
276
- ``` css
316
+ ```css
277
317
  :local(.continueButton) {
278
318
  composes: button from 'library/button.css';
279
319
  background: red;
280
320
  }
281
321
  ```
282
322
 
283
- ``` css
323
+ ```css
284
324
  :local(.nameEdit) {
285
325
  composes: edit highlight from './edit.css';
286
326
  background: red;
@@ -289,7 +329,7 @@ To import a local class name from another module:
289
329
 
290
330
  To import from multiple modules use multiple `composes:` rules.
291
331
 
292
- ``` css
332
+ ```css
293
333
  :local(.className) {
294
334
  composes: edit hightlight from './edit.css';
295
335
  composes: button from 'module/button.css';
@@ -298,177 +338,159 @@ To import from multiple modules use multiple `composes:` rules.
298
338
  }
299
339
  ```
300
340
 
301
- ### SourceMaps
341
+ ### `minimize`
302
342
 
303
- To include Sourcemaps set the `sourceMap` query param.
343
+ By default the css-loader minimizes the css if specified by the module system.
304
344
 
305
- I. e. the extract-text-webpack-plugin can handle them.
345
+ In some cases the minification is destructive to the css, so you can provide your own options to the minifier if needed. cssnano is used for minification and you find a [list of options here](http://cssnano.co/options/).
306
346
 
307
- They are not enabled by default because they expose a runtime overhead and increase in bundle size (JS SourceMap do not). In addition to that relative paths are buggy and you need to use an absolute public path which include the server URL.
347
+ You can also disable or enforce minification with the `minimize` query parameter.
308
348
 
309
349
  **webpack.config.js**
310
350
  ```js
311
351
  {
312
- test: /\.css$/,
313
- use: [
314
- {
315
- loader: 'css-loader',
316
- options: {
317
- sourceMap: true
318
- }
319
- }
320
- ]
352
+ loader: 'css-loader',
353
+ options: {
354
+ minimize: true || {/* CSSNano Options */}
355
+ }
321
356
  }
322
357
  ```
323
358
 
324
- ### toString
359
+ ### `sourceMap`
325
360
 
326
- You can also use the css-loader results directly as string, such as in Angular's component style.
361
+ To include source maps set the `sourceMap` option.
327
362
 
328
- **webpack.config.js**
363
+ I. e. the extract-text-webpack-plugin can handle them.
329
364
 
365
+ They are not enabled by default because they expose a runtime overhead and increase in bundle size (JS source maps do not). In addition to that relative paths are buggy and you need to use an absolute public path which include the server URL.
366
+
367
+ **webpack.config.js**
330
368
  ```js
331
369
  {
332
-    test: /\.css$/,
333
-    use: [
334
-      {
335
-        loaders: ['to-string-loader', 'css-loader']
336
-      }
337
-    ]
370
+ loader: 'css-loader',
371
+ options: {
372
+ sourceMap: true
373
+ }
338
374
  }
339
375
  ```
340
376
 
341
- or
377
+ ### `camelCase`
342
378
 
343
- ```js
344
- const cssText = require('./test.css').toString();
345
-
346
- console.log(cssText);
347
- ```
348
-
349
- If there are SourceMaps, they will also be included in the result string.
379
+ By default, the exported JSON keys mirror the class names. If you want to camelize class names (useful in JS), pass the query parameter `camelCase` to css-loader.
350
380
 
351
- ### ImportLoaders
381
+ |Name|Type|Description|
382
+ |:--:|:--:|:----------|
383
+ |**`true`**|`{Boolean}`|Class names will be camelized|
384
+ |**`'dashes'`**|`{String}`|Only dashes in class names will be camelized|
385
+ |**`'only'`** |`{String}`|Introduced in `0.27.1`. Class names will be camelized, the original class name will be removed from the locals|
386
+ |**`'dashesOnly'`**|`{String}`|Introduced in `0.27.1`. Dashes in class names will be camelized, the original class name will be removed from the locals|
352
387
 
353
- The query parameter `importLoaders` allow to configure which loaders should be applied to `@import`ed resources.
388
+ **file.css**
389
+ ```css
390
+ .class-name {}
391
+ ```
354
392
 
355
- `importLoaders`: That many loaders after the css-loader are used to import resources.
393
+ **file.js**
394
+ ```js
395
+ import { className } from 'file.css';
396
+ ```
356
397
 
357
398
  **webpack.config.js**
358
399
  ```js
359
400
  {
360
- test: /\.css$/,
361
- use: [
362
- {
363
- loader: 'css-loader',
364
- options: {
365
- importLoaders: 1
366
- }
367
- },
368
- 'postcss-loader'
369
- ]
401
+ loader: 'css-loader',
402
+ options: {
403
+ camelCase: true
404
+ }
370
405
  }
371
406
  ```
372
407
 
373
- This may change in the future, when the module system (i. e. webpack) supports loader matching by origin.
374
-
375
- ### Minification
408
+ ### `importLoaders`
376
409
 
377
- By default the css-loader minimizes the css if specified by the module system.
378
-
379
- In some cases the minification is destructive to the css, so you can provide some options to it. cssnano is used for minification and you find a [list of options here](http://cssnano.co/options/).
380
-
381
- You can also disable or enforce minification with the `minimize` query parameter.
410
+ The query parameter `importLoaders` allows to configure how many loaders before `css-loader` should be applied to `@import`ed resources.
382
411
 
383
412
  **webpack.config.js**
384
413
  ```js
385
414
  {
386
415
  test: /\.css$/,
387
416
  use: [
417
+ 'style-loader',
388
418
  {
389
419
  loader: 'css-loader',
390
420
  options: {
391
- minimize: true || {/* CSSNano Options */}
421
+ importLoaders: 1 // 0 => no loaders (default); 1 => postcss-loader; 2 => postcss-loader, sass-loader
392
422
  }
393
- }
423
+ },
424
+ 'postcss-loader',
425
+ 'sass-loader'
394
426
  ]
395
427
  }
396
428
  ```
397
429
 
398
- ### CamelCase
430
+ This may change in the future, when the module system (i. e. webpack) supports loader matching by origin.
399
431
 
400
- By default, the exported JSON keys mirror the class names. If you want to camelize class names (useful in JS), pass the query parameter `camelCase` to css-loader.
432
+ <h2 align="center">Examples</h2>
401
433
 
402
- #### Possible Options
434
+ ### Assets
403
435
 
404
- |Option|Description|
405
- |:----:|:--------|
406
- |**`true`**|Class names will be camelized|
407
- |**`'dashes'`**|Only dashes in class names will be camelized|
408
- |**`'only'`** |Introduced in `0.27.1`. Class names will be camelized, the original class name will be removed from the locals|
409
- |**`'dashesOnly'`**|Introduced in `0.27.1`. Dashes in class names will be camelized, the original class name will be removed from the locals|
436
+ The following `webpack.config.js` can load CSS files, embed small PNG/JPG/GIF/SVG images as well as fonts as [Data URLs](https://tools.ietf.org/html/rfc2397) and copy larger files to the output directory.
410
437
 
411
438
  **webpack.config.js**
412
439
  ```js
413
- {
414
- test: /\.css$/,
415
- use: [
416
- {
417
- loader: 'css-loader',
418
- options: {
419
- camelCase: true
440
+ module.exports = {
441
+ module: {
442
+ rules: [
443
+ {
444
+ test: /\.css$/,
445
+ use: [ 'style-loader', 'css-loader' ]
446
+ },
447
+ {
448
+ test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
449
+ loader: 'url-loader',
450
+ options: {
451
+ limit: 10000
452
+ }
420
453
  }
421
- }
422
- ]
454
+ ]
455
+ }
423
456
  }
424
457
  ```
425
458
 
426
- ```css
427
- .class-name {}
428
- ```
429
-
430
- ```js
431
- import { className } from 'file.css';
432
- ```
459
+ ### Extract
433
460
 
434
- ### Alias
435
-
436
- Rewrite your urls with alias, this is useful when it's hard to change url paths of your input files, for example, when you're using some css / sass files in another package (bootstrap, ratchet, font-awesome, etc.).
437
-
438
- #### Possible Options
439
-
440
- css-loader's `alias` follows the same syntax as webpack's `resolve.alias`, you can see the details at: https://webpack.js.org/configuration/resolve/#resolve-alias
461
+ For production builds it's recommended to extract the CSS from your bundle being able to use parallel loading of CSS/JS resources later on. This can be achieved by using the [extract-text-webpack-plugin](https://github.com/webpack-contrib/extract-text-webpack-plugin) to extract the CSS when running in production mode.
441
462
 
442
463
  **webpack.config.js**
443
464
  ```js
444
- {
445
- test: /\.scss$/,
446
- use: [{
447
- loader: "style-loader"
448
- }, {
449
- loader: "css-loader",
450
- options: {
451
- alias: {
452
- "../fonts/bootstrap": "bootstrap-sass/assets/fonts/bootstrap"
453
- }
454
- }
455
- }, {
456
- loader: "sass-loader",
457
- options: {
458
- includePaths: [
459
- path.resolve("./node_modules/bootstrap-sass/assets/stylesheets")
465
+ const env = process.env.NODE_ENV
466
+
467
+ const ExtractTextPlugin = require('extract-text-webpack-plugin')
468
+
469
+ module.exports = {
470
+ module: {
471
+ rules: [
472
+ {
473
+ test: /\.css$/,
474
+ use: env === 'production'
475
+ ? ExtractTextPlugin.extract({
476
+ fallback: 'style-loader',
477
+ use: [ 'css-loader' ]
478
+ })
479
+ : [ 'style-loader', 'css-loader' ]
480
+ },
481
+ ]
482
+ },
483
+ plugins: env === 'production'
484
+ ? [
485
+ new ExtractTextPlugin({
486
+ filename: '[name].css'
487
+ })
460
488
  ]
461
- }
462
- }]
489
+ : []
490
+ ]
463
491
  }
464
492
  ```
465
493
 
466
- ```scss
467
- @charset "UTF-8";
468
- @import "bootstrap";
469
- ```
470
- Check out this [working bootstrap example](https://github.com/bbtfr/webpack2-bootstrap-sass-sample).
471
-
472
494
  <h2 align="center">Maintainers</h2>
473
495
 
474
496
  <table>
@@ -476,29 +498,49 @@ Check out this [working bootstrap example](https://github.com/bbtfr/webpack2-boo
476
498
  <tr>
477
499
  <td align="center">
478
500
  <img width="150" height="150"
479
- src="https://avatars3.githubusercontent.com/u/166921?v=3&s=150">
501
+ src="https://github.com/bebraw.png?v=3&s=150">
480
502
  </br>
481
503
  <a href="https://github.com/bebraw">Juho Vepsäläinen</a>
482
504
  </td>
483
505
  <td align="center">
484
506
  <img width="150" height="150"
485
- src="https://avatars2.githubusercontent.com/u/8420490?v=3&s=150">
507
+ src="https://github.com/d3viant0ne.png?v=3&s=150">
486
508
  </br>
487
509
  <a href="https://github.com/d3viant0ne">Joshua Wiens</a>
488
510
  </td>
489
511
  <td align="center">
490
512
  <img width="150" height="150"
491
- src="https://avatars3.githubusercontent.com/u/533616?v=3&s=150">
513
+ src="https://github.com/SpaceK33z.png?v=3&s=150">
492
514
  </br>
493
515
  <a href="https://github.com/SpaceK33z">Kees Kluskens</a>
494
516
  </td>
495
517
  <td align="center">
496
518
  <img width="150" height="150"
497
- src="https://avatars3.githubusercontent.com/u/3408176?v=3&s=150">
519
+ src="https://github.com/TheLarkInn.png?v=3&s=150">
498
520
  </br>
499
521
  <a href="https://github.com/TheLarkInn">Sean Larkin</a>
500
522
  </td>
501
523
  </tr>
524
+ <tr>
525
+ <td align="center">
526
+ <img width="150" height="150"
527
+ src="https://github.com/michael-ciniawsky.png?v=3&s=150">
528
+ </br>
529
+ <a href="https://github.com/michael-ciniawsky">Michael Ciniawsky</a>
530
+ </td>
531
+ <td align="center">
532
+ <img width="150" height="150"
533
+ src="https://github.com/evilebottnawi.png?v=3&s=150">
534
+ </br>
535
+ <a href="https://github.com/evilebottnawi">Evilebot Tnawi</a>
536
+ </td>
537
+ <td align="center">
538
+ <img width="150" height="150"
539
+ src="https://github.com/joscha.png?v=3&s=150">
540
+ </br>
541
+ <a href="https://github.com/joscha">Joscha Feth</a>
542
+ </td>
543
+ </tr>
502
544
  <tbody>
503
545
  </table>
504
546
 
package/lib/css-base.js CHANGED
@@ -54,7 +54,7 @@ function cssWithMappingToString(item, useSourceMap) {
54
54
  return content;
55
55
  }
56
56
 
57
- if (useSourceMap) {
57
+ if (useSourceMap && typeof btoa === 'function') {
58
58
  var sourceMapping = toComment(cssMapping);
59
59
  var sourceURLs = cssMapping.sources.map(function (source) {
60
60
  return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'
@@ -68,8 +68,9 @@ function cssWithMappingToString(item, useSourceMap) {
68
68
 
69
69
  // Adapted from convert-source-map (MIT)
70
70
  function toComment(sourceMap) {
71
- var base64 = new Buffer(JSON.stringify(sourceMap)).toString('base64');
72
- var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;
71
+ // eslint-disable-next-line no-undef
72
+ var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
73
+ var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;
73
74
 
74
- return '/*# ' + data + ' */';
75
+ return '/*# ' + data + ' */';
75
76
  }
package/lib/loader.js CHANGED
@@ -16,19 +16,35 @@ module.exports = function(content, map) {
16
16
  var root = query.root;
17
17
  var moduleMode = query.modules || query.module;
18
18
  var camelCaseKeys = query.camelCase || query.camelcase;
19
+ var sourceMap = query.sourceMap || false;
19
20
  var resolve = createResolver(query.alias);
20
21
 
21
- if(map !== null && typeof map !== "string") {
22
- map = JSON.stringify(map);
22
+ if(sourceMap) {
23
+ if (map) {
24
+ if (typeof map === "string") {
25
+ map = JSON.stringify(map);
26
+ }
27
+
28
+ if (map.sources) {
29
+ map.sources = map.sources.map(function (source) {
30
+ return source.replace(/\\/g, '/');
31
+ });
32
+ map.sourceRoot = '';
33
+ }
34
+ }
35
+ } else {
36
+ // Some loaders (example `"postcss-loader": "1.x.x"`) always generates source map, we should remove it
37
+ map = null;
23
38
  }
24
39
 
25
40
  processCss(content, map, {
26
41
  mode: moduleMode ? "local" : "global",
27
- from: loaderUtils.getRemainingRequest(this),
28
- to: loaderUtils.getCurrentRequest(this),
42
+ from: loaderUtils.getRemainingRequest(this).split("!").pop(),
43
+ to: loaderUtils.getCurrentRequest(this).split("!").pop(),
29
44
  query: query,
30
45
  minimize: this.minimize,
31
- loaderContext: this
46
+ loaderContext: this,
47
+ sourceMap: sourceMap
32
48
  }, function(err, result) {
33
49
  if(err) return callback(err);
34
50
 
@@ -98,11 +114,11 @@ module.exports = function(content, map) {
98
114
  map = result.map;
99
115
  if(map.sources) {
100
116
  map.sources = map.sources.map(function(source) {
101
- return source.split("!").pop();
117
+ return source.split("!").pop().replace(/\\/g, '/');
102
118
  }, this);
103
119
  map.sourceRoot = "";
104
120
  }
105
- map.file = map.file.split("!").pop();
121
+ map.file = map.file.split("!").pop().replace(/\\/g, '/');
106
122
  map = JSON.stringify(map);
107
123
  moduleJs = "exports.push([module.id, " + cssAsString + ", \"\", " + map + "]);";
108
124
  } else {
package/lib/processCss.js CHANGED
@@ -9,10 +9,12 @@ var loaderUtils = require("loader-utils");
9
9
  var assign = require("object-assign");
10
10
  var getLocalIdent = require("./getLocalIdent");
11
11
 
12
+ var icssUtils = require('icss-utils');
12
13
  var localByDefault = require("postcss-modules-local-by-default");
13
14
  var extractImports = require("postcss-modules-extract-imports");
14
15
  var modulesScope = require("postcss-modules-scope");
15
16
  var modulesValues = require("postcss-modules-values");
17
+ var valueParser = require('postcss-value-parser');
16
18
 
17
19
  var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
18
20
  return function(css) {
@@ -23,28 +25,34 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
23
25
 
24
26
  function replaceImportsInString(str) {
25
27
  if(options.import) {
26
- var tokens = str.split(/(\S+)/);
27
- tokens = tokens.map(function (token) {
28
+ var tokens = valueParser(str);
29
+ tokens.walk(function (node) {
30
+ if (node.type !== 'word') {
31
+ return;
32
+ }
33
+ var token = node.value;
28
34
  var importIndex = imports["$" + token];
29
35
  if(typeof importIndex === "number") {
30
- return "___CSS_LOADER_IMPORT___" + importIndex + "___";
36
+ node.value = "___CSS_LOADER_IMPORT___" + importIndex + "___";
31
37
  }
32
- return token;
33
- });
34
- return tokens.join("");
38
+ })
39
+ return tokens.toString();
35
40
  }
36
41
  return str;
37
42
  }
38
43
 
39
44
  if(options.import) {
40
- css.walkAtRules("import", function(rule) {
45
+ css.walkAtRules(/import/i, function(rule) {
41
46
  var values = Tokenizer.parseValues(rule.params);
42
47
  var url = values.nodes[0].nodes[0];
43
48
  if(url.type === "url") {
44
49
  url = url.url;
45
50
  } else if(url.type === "string") {
46
51
  url = url.value;
47
- } else throw rule.error("Unexpected format" + rule.params);
52
+ } else throw rule.error("Unexpected format " + rule.params);
53
+ if (!url.replace(/\s/g, '').length) {
54
+ return;
55
+ }
48
56
  values.nodes[0].nodes.shift();
49
57
  var mediaQuery = Tokenizer.stringifyValues(values);
50
58
  if(loaderUtils.isUrlRequest(url, options.root) && options.mode === "global") {
@@ -58,24 +66,17 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
58
66
  });
59
67
  }
60
68
 
61
- css.walkRules(function(rule) {
62
- if(rule.selector === ":export") {
63
- rule.walkDecls(function(decl) {
64
- exports[decl.prop] = decl.value;
65
- });
66
- rule.remove();
67
- } else if(/^:import\(.+\)$/.test(rule.selector)) {
68
- var match = /^:import\((.+)\)$/.exec(rule.selector);
69
- var url = loaderUtils.parseString(match[1]);
70
- rule.walkDecls(function(decl) {
71
- imports["$" + decl.prop] = importItems.length;
72
- importItems.push({
73
- url: url,
74
- export: decl.value
75
- });
69
+ var icss = icssUtils.extractICSS(css);
70
+ exports = icss.icssExports;
71
+ Object.keys(icss.icssImports).forEach(function(key) {
72
+ var url = loaderUtils.parseString(key);
73
+ Object.keys(icss.icssImports[key]).forEach(function(prop) {
74
+ imports["$" + prop] = importItems.length;
75
+ importItems.push({
76
+ url: url,
77
+ export: icss.icssImports[key][prop]
76
78
  });
77
- rule.remove();
78
- }
79
+ })
79
80
  });
80
81
 
81
82
  Object.keys(exports).forEach(function(exportName) {
@@ -97,8 +98,11 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
97
98
  }
98
99
  break;
99
100
  case "url":
100
- if (options.url && !/^#/.test(item.url) && loaderUtils.isUrlRequest(item.url, options.root)) {
101
- item.stringType = "";
101
+ if (options.url && item.url.replace(/\s/g, '').length && !/^#/.test(item.url) && loaderUtils.isUrlRequest(item.url, options.root)) {
102
+ // Don't remove quotes around url when contain space
103
+ if (item.url.indexOf(" ") === -1) {
104
+ item.stringType = "";
105
+ }
102
106
  delete item.innerSpacingBefore;
103
107
  delete item.innerSpacingAfter;
104
108
  var url = item.url;
@@ -132,7 +136,7 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
132
136
 
133
137
  module.exports = function processCss(inputSource, inputMap, options, callback) {
134
138
  var query = options.query;
135
- var root = query.root;
139
+ var root = query.root && query.root.length > 0 ? query.root.replace(/\/$/, "") : query.root;
136
140
  var context = query.context;
137
141
  var localIdentName = query.localIdentName || "[hash:base64]";
138
142
  var localIdentRegExp = query.localIdentRegExp;
@@ -149,11 +153,14 @@ module.exports = function processCss(inputSource, inputMap, options, callback) {
149
153
  };
150
154
 
151
155
  var pipeline = postcss([
156
+ modulesValues,
152
157
  localByDefault({
153
158
  mode: options.mode,
154
159
  rewriteUrl: function(global, url) {
155
160
  if(parserOptions.url){
156
- if(!loaderUtils.isUrlRequest(url, root)) {
161
+ url = url.trim();
162
+
163
+ if(!url.replace(/\s/g, '').length || !loaderUtils.isUrlRequest(url, root)) {
157
164
  return url;
158
165
  }
159
166
  if(global) {
@@ -164,7 +171,6 @@ module.exports = function processCss(inputSource, inputMap, options, callback) {
164
171
  }
165
172
  }),
166
173
  extractImports(),
167
- modulesValues,
168
174
  modulesScope({
169
175
  generateScopedName: function generateScopedName (exportName) {
170
176
  return customGetLocalIdent(options.loaderContext, localIdentName, exportName, {
@@ -191,12 +197,12 @@ module.exports = function processCss(inputSource, inputMap, options, callback) {
191
197
  // we need a prefix to avoid path rewriting of PostCSS
192
198
  from: "/css-loader!" + options.from,
193
199
  to: options.to,
194
- map: {
200
+ map: options.sourceMap ? {
195
201
  prev: inputMap,
196
202
  sourcesContent: true,
197
203
  inline: false,
198
204
  annotation: false
199
- }
205
+ } : null
200
206
  }).then(function(result) {
201
207
  callback(null, {
202
208
  source: result.css,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "css-loader",
3
- "version": "0.28.0",
3
+ "version": "0.28.4",
4
4
  "author": "Tobias Koppers @sokra",
5
5
  "description": "css loader module for webpack",
6
6
  "engines": {
@@ -15,6 +15,7 @@
15
15
  "babel-code-frame": "^6.11.0",
16
16
  "css-selector-tokenizer": "^0.7.0",
17
17
  "cssnano": ">=2.6.1 <4",
18
+ "icss-utils": "^2.1.0",
18
19
  "loader-utils": "^1.0.2",
19
20
  "lodash.camelcase": "^4.3.0",
20
21
  "object-assign": "^4.0.1",
@@ -23,6 +24,7 @@
23
24
  "postcss-modules-local-by-default": "^1.0.1",
24
25
  "postcss-modules-scope": "^1.0.0",
25
26
  "postcss-modules-values": "^1.1.0",
27
+ "postcss-value-parser": "^3.3.0",
26
28
  "source-list-map": "^0.1.7"
27
29
  },
28
30
  "devDependencies": {