Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: webpack-contrib/css-loader
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 7b5295135302d5db9ef337a803ca76174f5af1f0
Choose a base ref
...
head repository: webpack-contrib/css-loader
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 43179a82c88532bf93ccfafb4f78c10cdb80cbf7
Choose a head ref

Commits on Sep 1, 2017

  1. Fix markdown for link to webpack resolve.alias doc (#595)

    Fixes:
    [link text] (link) ---> [link text](link)
    ahoym authored and evilebottnawi committed Sep 1, 2017
    Copy the full SHA
    0840c80 View commit details

Commits on Sep 12, 2017

  1. Verified

    This commit was signed with the committer’s verified signature.
    targos Michaël Zasso
    Copy the full SHA
    7039740 View commit details
  2. Copy the full SHA
    c45fa66 View commit details
  3. Copy the full SHA
    05c36db View commit details

Commits on Dec 14, 2017

  1. Copy the full SHA
    d999f4a View commit details

Commits on Jan 4, 2018

  1. Copy the full SHA
    0dccfa9 View commit details
  2. Copy the full SHA
    8897d44 View commit details

Commits on Jan 5, 2018

  1. Copy the full SHA
    39773aa View commit details
  2. Copy the full SHA
    333a2ce View commit details
  3. Copy the full SHA
    0fc46c7 View commit details

Commits on Jan 17, 2018

  1. Copy the full SHA
    d1d8221 View commit details
  2. Copy the full SHA
    604bd4b View commit details
  3. Copy the full SHA
    630579d View commit details

Commits on Feb 15, 2018

  1. Copy the full SHA
    0452f26 View commit details

Commits on Feb 22, 2018

  1. Copy the full SHA
    9f876d2 View commit details
  2. Copy the full SHA
    c35d8bd View commit details

Commits on Mar 16, 2018

  1. Copy the full SHA
    c788450 View commit details
  2. Copy the full SHA
    df497db View commit details

Commits on May 2, 2018

  1. Copy the full SHA
    3de8aa7 View commit details
  2. tests: css custom variables (#709)

    evilebottnawi authored and evilebottnawi committed May 2, 2018
    Copy the full SHA
    07444ad View commit details
  3. Merge remote-tracking branch 'origin/master'

    # Conflicts:
    #	test/simpleTest.js
    evilebottnawi committed May 2, 2018
    Copy the full SHA
    50f8ec0 View commit details

Commits on May 5, 2018

  1. docs(README): fix malformed emoji (#701)

    Mikhail Vasin authored and michael-ciniawsky committed May 5, 2018
    Copy the full SHA
    1c51265 View commit details
  2. Copy the full SHA
    1703721 View commit details

Commits on Jul 4, 2018

  1. Copy the full SHA
    1b7acf7 View commit details

Commits on Jul 6, 2018

  1. version 1.0 (#742)

    * tests: css custom variables (#709)
    
    * refactor: remove `minimize` option
    
    BREAKING CHANGE: remove `minimize` option
    
    * refactor: remove `module` option
    
    BREAKING CHANGE: remove `module` option, use `modules` option instead
    
    * refactor: remove `camelcase` option
    
    BREAKING CHANGE: remove `camelcase` option, use `camelCase` option instead
    
    * refactor: remove `root` option
    
    BREAKING CHANGE: remove `root` option, use `postcss-loader` with `postcss-url` plugin instead
    
    * refactor: remove other `minimizer` stuff
    
    * refactor: remove `alias` option
    
    BREAKING CHANGE: remove `alias` option, use `webpack` `resolve.alias` option
    
    * refactor: readme
    
    * refactor: remove unused `object-assign`
    
    * chore(deps): update `postcss` to latest version
    
    * refactor: minimum require `nodejs` version is `6.9`
    
    BREAKING CHANGE: minimum require `nodejs` version is `6.9`
    
    * refactor: minimum require `webpack` version is `4`
    
    BREAKING CHANGE: minimum require `webpack` version is `4`
    evilebottnawi authored Jul 6, 2018
    Copy the full SHA
    240db53 View commit details
  2. Merge remote-tracking branch 'origin/master'

    # Conflicts:
    #	package-lock.json
    alexander-akait committed Jul 6, 2018
    Copy the full SHA
    3d53968 View commit details
  3. Copy the full SHA
    43179a8 View commit details
23 changes: 10 additions & 13 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -7,26 +7,23 @@ matrix:
fast_finish: true
include:
- os: linux
node_js: "7"
env: WEBPACK_VERSION="2.2.0" JOB_PART=lint
node_js: "10"
env: WEBPACK_VERSION="4.15.0" JOB_PART=lint
- os: linux
node_js: "6"
env: WEBPACK_VERSION="2.2.0" JOB_PART=test
- os: linux
node_js: "4.3"
env: WEBPACK_VERSION="2.2.0" JOB_PART=test
node_js: "10"
env: WEBPACK_VERSION="4.15.0" JOB_PART=test
- os: linux
node_js: "7"
env: WEBPACK_VERSION="2.2.0" JOB_PART=test
node_js: "8"
env: WEBPACK_VERSION="4.15.0" JOB_PART=test
- os: linux
node_js: "4.3"
env: WEBPACK_VERSION="1.14.0" JOB_PART=test
node_js: "6"
env: WEBPACK_VERSION="4.15.0" JOB_PART=test
before_install:
- nvm --version
- node --version
before_script:
- 'if [ "$WEBPACK_VERSION" ]; then yarn add webpack@^$WEBPACK_VERSION; fi'
- 'if [ "$WEBPACK_VERSION" ]; then npm i webpack@^$WEBPACK_VERSION; fi'
script:
- yarn run travis:$JOB_PART
- npm run travis:$JOB_PART
after_success:
- bash <(curl -s https://codecov.io/bash)
56 changes: 56 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,62 @@

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.

<a name="1.0.0"></a>
# [1.0.0](https://github.com/webpack-contrib/css-loader/compare/v0.28.11...v1.0.0) (2018-07-06)

### BREAKING CHANGES

* remove `minimize` option, use [`postcss-loader`](https://github.com/postcss/postcss-loader) with [`cssnano`](https://github.com/cssnano/cssnano) or use [`optimize-cssnano-plugin`](https://github.com/intervolga/optimize-cssnano-plugin) plugin
* remove `module` option, use `modules` option instead
* remove `camelcase` option, use `camelCase` option instead
* remove `root` option, use [`postcss-loader`](https://github.com/postcss/postcss-loader) with [`postcss-url`](https://github.com/postcss/postcss-url) plugin
* remove `alias` option, use [`resolve.alias`](https://webpack.js.org/configuration/resolve/) feature or use [`postcss-loader`](https://github.com/postcss/postcss-loader) with [`postcss-url`](https://github.com/postcss/postcss-url) plugin
* update `postcss` to `6` version
* minimum require `nodejs` version is `6.9`
* minimum require `webpack` version is `4`


<a name="0.28.11"></a>
## [0.28.11](https://github.com/webpack-contrib/css-loader/compare/v0.28.10...v0.28.11) (2018-03-16)


### Bug Fixes

* **lib/processCss:** don't check `mode` for `url` handling (`options.modules`) ([#698](https://github.com/webpack-contrib/css-loader/issues/698)) ([c788450](https://github.com/webpack-contrib/css-loader/commit/c788450))



<a name="0.28.10"></a>
## [0.28.10](https://github.com/webpack-contrib/css-loader/compare/v0.28.9...v0.28.10) (2018-02-22)


### Bug Fixes

* **getLocalIdent:** add `rootContext` support (`webpack >= v4.0.0`) ([#681](https://github.com/webpack-contrib/css-loader/issues/681)) ([9f876d2](https://github.com/webpack-contrib/css-loader/commit/9f876d2))



<a name="0.28.9"></a>
## [0.28.9](https://github.com/webpack-contrib/css-loader/compare/v0.28.8...v0.28.9) (2018-01-17)


### Bug Fixes

* ignore invalid URLs (`url()`) ([#663](https://github.com/webpack-contrib/css-loader/issues/663)) ([d1d8221](https://github.com/webpack-contrib/css-loader/commit/d1d8221))



<a name="0.28.8"></a>
## [0.28.8](https://github.com/webpack-contrib/css-loader/compare/v0.28.7...v0.28.8) (2018-01-05)


### Bug Fixes

* **loader:** correctly check if source map is `undefined` ([#641](https://github.com/webpack-contrib/css-loader/issues/641)) ([0dccfa9](https://github.com/webpack-contrib/css-loader/commit/0dccfa9))
* proper URL escaping and wrapping (`url()`) ([#627](https://github.com/webpack-contrib/css-loader/issues/627)) ([8897d44](https://github.com/webpack-contrib/css-loader/commit/8897d44))



<a name="0.28.7"></a>
## [0.28.7](https://github.com/webpack/css-loader/compare/v0.28.6...v0.28.7) (2017-08-30)

182 changes: 36 additions & 146 deletions README.md
Original file line number Diff line number Diff line change
@@ -94,37 +94,13 @@ It's useful when you, for instance, need to post process the CSS as a string.

|Name|Type|Default|Description|
|:--:|:--:|:-----:|:----------|
|**`root`**|`{String}`|`/`|Path to resolve URLs, URLs starting with `/` will not be translated|
|**`url`**|`{Boolean}`|`true`| Enable/Disable `url()` handling|
|**`alias`**|`{Object}`|`{}`|Create aliases to import certain modules more easily|
|**`import`** |`{Boolean}`|`true`| Enable/Disable @import handling|
|**`modules`**|`{Boolean}`|`false`|Enable/Disable CSS Modules|
|**`minimize`**|`{Boolean\|Object}`|`false`|Enable/Disable minification|
|**`sourceMap`**|`{Boolean}`|`false`|Enable/Disable Sourcemaps|
|**`camelCase`**|`{Boolean\|String}`|`false`|Export Classnames in CamelCase|
|**`importLoaders`**|`{Number}`|`0`|Number of loaders applied before CSS loader|
|**`localIdentName`**|`{String}`|`[hash:base64]`|Configure the generated ident|

### `root`

For URLs that start with a `/`, the default behavior is to not translate them.

`url(/image.png) => url(/image.png)`

If a `root` query parameter is set, however, it will be prepended to the URL
and then translated.

**webpack.config.js**
```js
{
loader: 'css-loader',
options: { root: '.' }
}
```

`url(/image.png)` => `require('./image.png')`

Using 'Root-relative' urls is not recommended. You should only use it for legacy CSS files.
|**[`url`](#url)**|`{Boolean}`|`true`| Enable/Disable `url()` handling|
|**[`import`](#import)** |`{Boolean}`|`true`| Enable/Disable @import handling|
|**[`modules`](#modules)**|`{Boolean}`|`false`|Enable/Disable CSS Modules|
|**[`localIdentName`](#localidentname)**|`{String}`|`[hash:base64]`|Configure the generated ident|
|**[`sourceMap`](#sourcemap)**|`{Boolean}`|`false`|Enable/Disable Sourcemaps|
|**[`camelCase`](#camelcase)**|`{Boolean\|String}`|`false`|Export Classnames in CamelCase|
|**[`importLoaders`](#importloaders)**|`{Number}`|`0`|Number of loaders applied before CSS loader|

### `url`

@@ -137,48 +113,6 @@ url(image.png) => require('./image.png')
url(~module/image.png) => require('module/image.png')
```

### `alias`

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.).

`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)

**file.scss**
```css
@charset "UTF-8";
@import "bootstrap";
```

**webpack.config.js**
```js
{
test: /\.scss$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
alias: {
"../fonts/bootstrap": "bootstrap-sass/assets/fonts/bootstrap"
}
}
},
{
loader: "sass-loader",
options: {
includePaths: [
path.resolve("./node_modules/bootstrap-sass/assets/stylesheets")
]
}
}
]
}
```

Check out this [working bootstrap example](https://github.com/bbtfr/webpack2-bootstrap-sass-sample).

### `import`

To disable `@import` resolving by `css-loader` set the option to `false`
@@ -219,7 +153,7 @@ The loader replaces local selectors with unique identifiers. The choosen unique
._23_aKvs-b8bW2Vg3fwHozO ._13LGdX8RMStbBE9w-t0gZ1 .global-class-name { color: blue; }
```

> :information_source: Identifiers are exported
> ℹ️ Identifiers are exported
```js
exports.locals = {
@@ -238,41 +172,6 @@ file.png => ./file.png
```

You can use `:local(#someId)`, but this is not recommended. Use classes instead of ids.
You can configure the generated ident with the `localIdentName` query parameter (default `[hash:base64]`).

**webpack.config.js**
```js
{
test: /\.css$/,
use: [
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[path][name]__[local]--[hash:base64:5]'
}
}
]
}
```

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).

**webpack.config.js**
```js
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[path][name]__[local]--[hash:base64:5]',
getLocalIdent: (context, localIdentName, localName, options) => {
return 'whatever_random_class_name'
}
}
}
```

> :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.

#### `Composing`

@@ -339,24 +238,44 @@ To import from multiple modules use multiple `composes:` rules.
}
```

### `minimize`
### `localIdentName`

By default the css-loader minimizes the css if specified by the module system.
You can configure the generated ident with the `localIdentName` query parameter. See [loader-utils's documentation](https://github.com/webpack/loader-utils#interpolatename) for more information on options.

In some cases the minification is destructive to the css, so you can provide your own options to the cssnano-based minifier if needed. See [cssnano's documentation](http://cssnano.co/guides/) for more information on the available options.
**webpack.config.js**
```js
{
test: /\.css$/,
use: [
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[path][name]__[local]--[hash:base64:5]'
}
}
]
}
```

You can also disable or enforce minification with the `minimize` query parameter.
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).

**webpack.config.js**
```js
{
loader: 'css-loader',
options: {
minimize: true || {/* CSSNano Options */}
modules: true,
localIdentName: '[path][name]__[local]--[hash:base64:5]',
getLocalIdent: (context, localIdentName, localName, options) => {
return 'whatever_random_class_name'
}
}
}
```

> ℹ️ 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.
### `sourceMap`

To include source maps set the `sourceMap` option.
@@ -419,7 +338,7 @@ The query parameter `importLoaders` allows to configure how many loaders before
{
loader: 'css-loader',
options: {
importLoaders: 1 // 0 => no loaders (default); 1 => postcss-loader; 2 => postcss-loader, sass-loader
importLoaders: 2 // 0 => no loaders (default); 1 => postcss-loader; 2 => postcss-loader, sass-loader
}
},
'postcss-loader',
@@ -459,37 +378,8 @@ module.exports = {

### Extract

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.

**webpack.config.js**
```js
const env = process.env.NODE_ENV

const ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: env === 'production'
? ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [ 'css-loader' ]
})
: [ 'style-loader', 'css-loader' ]
},
]
},
plugins: env === 'production'
? [
new ExtractTextPlugin({
filename: '[name].css'
})
]
: []
}
```
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 [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) to extract the CSS when running in production mode.

<h2 align="center">Maintainers</h2>

36 changes: 0 additions & 36 deletions lib/createResolver.js

This file was deleted.

11 changes: 9 additions & 2 deletions lib/getLocalIdent.js
Original file line number Diff line number Diff line change
@@ -6,8 +6,15 @@ var loaderUtils = require("loader-utils");
var path = require("path");

module.exports = function getLocalIdent(loaderContext, localIdentName, localName, options) {
if(!options.context)
options.context = loaderContext.options && typeof loaderContext.options.context === "string" ? loaderContext.options.context : loaderContext.context;
if(!options.context) {
if (loaderContext.rootContext) {
options.context = loaderContext.rootContext;
} else if (loaderContext.options && typeof loaderContext.options.context === "string") {
options.context = loaderContext.options.context;
} else {
options.context = loaderContext.context;
}
}
var request = path.relative(options.context, loaderContext.resourcePath);
options.content = options.hashPrefix + request + "+" + localName;
localIdentName = localIdentName.replace(/\[local\]/gi, localName);
34 changes: 17 additions & 17 deletions lib/loader.js
Original file line number Diff line number Diff line change
@@ -6,18 +6,14 @@ var loaderUtils = require("loader-utils");
var processCss = require("./processCss");
var getImportPrefix = require("./getImportPrefix");
var compileExports = require("./compile-exports");
var createResolver = require("./createResolver");


module.exports = function(content, map) {
if(this.cacheable) this.cacheable();
var callback = this.async();
var query = loaderUtils.getOptions(this) || {};
var root = query.root;
var moduleMode = query.modules || query.module;
var camelCaseKeys = query.camelCase || query.camelcase;
var moduleMode = query.modules;
var camelCaseKeys = query.camelCase;
var sourceMap = query.sourceMap || false;
var resolve = createResolver(query.alias);

if(sourceMap) {
if (map) {
@@ -42,8 +38,6 @@ module.exports = function(content, map) {
from: loaderUtils.getRemainingRequest(this).split("!").pop(),
to: loaderUtils.getCurrentRequest(this).split("!").pop(),
query: query,
resolve: resolve,
minimize: this.minimize,
loaderContext: this,
sourceMap: sourceMap
}, function(err, result) {
@@ -63,7 +57,7 @@ module.exports = function(content, map) {
}
return true;
}).map(function(imp) {
if(!loaderUtils.isUrlRequest(imp.url, root)) {
if(!loaderUtils.isUrlRequest(imp.url)) {
return "exports.push([module.id, " +
JSON.stringify("@import url(" + imp.url + ");") + ", " +
JSON.stringify(imp.mediaQuery) + "]);";
@@ -83,34 +77,39 @@ module.exports = function(content, map) {
}

cssAsString = cssAsString.replace(result.importItemRegExpG, importItemMatcher.bind(this));
if(query.url !== false) {

// helper for ensuring valid CSS strings from requires
var urlEscapeHelper = "";

if(query.url !== false && result.urlItems.length > 0) {
urlEscapeHelper = "var escape = require(" + loaderUtils.stringifyRequest(this, require.resolve("./url/escape.js")) + ");\n";

cssAsString = cssAsString.replace(result.urlItemRegExpG, function(item) {
var match = result.urlItemRegExp.exec(item);
var idx = +match[1];
var urlItem = result.urlItems[idx];
var url = resolve(urlItem.url);
var url = urlItem.url;
idx = url.indexOf("?#");
if(idx < 0) idx = url.indexOf("#");
var urlRequest;
if(idx > 0) { // idx === 0 is catched by isUrlRequest
// in cases like url('webfont.eot?#iefix')
urlRequest = url.substr(0, idx);
return "\" + require(" + loaderUtils.stringifyRequest(this, urlRequest) + ") + \"" +
return "\" + escape(require(" + loaderUtils.stringifyRequest(this, urlRequest) + ")) + \"" +
url.substr(idx);
}
urlRequest = url;
return "\" + require(" + loaderUtils.stringifyRequest(this, urlRequest) + ") + \"";
return "\" + escape(require(" + loaderUtils.stringifyRequest(this, urlRequest) + ")) + \"";
}.bind(this));
}


var exportJs = compileExports(result, importItemMatcher.bind(this), camelCaseKeys);
if (exportJs) {
exportJs = "exports.locals = " + exportJs + ";";
}

var moduleJs;
if(query.sourceMap && result.map) {
if(sourceMap && result.map) {
// add a SourceMap
map = result.map;
if(map.sources) {
@@ -127,9 +126,10 @@ module.exports = function(content, map) {
}

// embed runtime
callback(null, "exports = module.exports = require(" +
callback(null, urlEscapeHelper +
"exports = module.exports = require(" +
loaderUtils.stringifyRequest(this, require.resolve("./css-base.js")) +
")(" + query.sourceMap + ");\n" +
")(" + sourceMap + ");\n" +
"// imports\n" +
importJs + "\n\n" +
"// module\n" +
9 changes: 2 additions & 7 deletions lib/localsLoader.js
Original file line number Diff line number Diff line change
@@ -6,23 +6,18 @@ var loaderUtils = require("loader-utils");
var processCss = require("./processCss");
var getImportPrefix = require("./getImportPrefix");
var compileExports = require("./compile-exports");
var createResolver = require("./createResolver");


module.exports = function(content) {
if(this.cacheable) this.cacheable();
var callback = this.async();
var query = loaderUtils.getOptions(this) || {};
var moduleMode = query.modules || query.module;
var camelCaseKeys = query.camelCase || query.camelcase;
var resolve = createResolver(query.alias);
var moduleMode = query.modules;
var camelCaseKeys = query.camelCase;

processCss(content, null, {
mode: moduleMode ? "local" : "global",
query: query,
minimize: this.minimize,
loaderContext: this,
resolve: resolve
}, function(err, result) {
if(err) return callback(err);

38 changes: 9 additions & 29 deletions lib/processCss.js
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@ var formatCodeFrame = require("babel-code-frame");
var Tokenizer = require("css-selector-tokenizer");
var postcss = require("postcss");
var loaderUtils = require("loader-utils");
var assign = require("object-assign");
var getLocalIdent = require("./getLocalIdent");

var icssUtils = require('icss-utils');
@@ -55,9 +54,11 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
}
values.nodes[0].nodes.shift();
var mediaQuery = Tokenizer.stringifyValues(values);
if(loaderUtils.isUrlRequest(url, options.root) && options.mode === "global") {
url = loaderUtils.urlToRequest(url, options.root);

if(loaderUtils.isUrlRequest(url)) {
url = loaderUtils.urlToRequest(url);
}

importItems.push({
url: url,
mediaQuery: mediaQuery
@@ -83,11 +84,6 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
exports[exportName] = replaceImportsInString(exports[exportName]);
});

function isAlias(url) {
// Handle alias starting by / and root disabled
return url !== options.resolve(url)
}

function processNode(item) {
switch (item.type) {
case "value":
@@ -103,11 +99,9 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
}
break;
case "url":
if (options.url && item.url.replace(/\s/g, '').length && !/^#/.test(item.url) && (isAlias(item.url) || loaderUtils.isUrlRequest(item.url, options.root))) {
// Don't remove quotes around url when contain space
if (item.url.indexOf(" ") === -1) {
item.stringType = "";
}
if (options.url && item.url.replace(/\s/g, '').length && !/^#/.test(item.url) && loaderUtils.isUrlRequest(item.url)) {
// Strip quotes, they will be re-added if the module needs them
item.stringType = "";
delete item.innerSpacingBefore;
delete item.innerSpacingAfter;
var url = item.url;
@@ -141,17 +135,13 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {

module.exports = function processCss(inputSource, inputMap, options, callback) {
var query = options.query;
var root = query.root && query.root.length > 0 ? query.root.replace(/\/$/, "") : query.root;
var context = query.context;
var localIdentName = query.localIdentName || "[hash:base64]";
var localIdentRegExp = query.localIdentRegExp;
var forceMinimize = query.minimize;
var minimize = typeof forceMinimize !== "undefined" ? !!forceMinimize : options.minimize;

var customGetLocalIdent = query.getLocalIdent || getLocalIdent;

var parserOptions = {
root: root,
mode: options.mode,
url: query.url !== false,
import: query.import !== false,
@@ -166,11 +156,11 @@ module.exports = function processCss(inputSource, inputMap, options, callback) {
if(parserOptions.url){
url = url.trim();

if(!url.replace(/\s/g, '').length || !loaderUtils.isUrlRequest(url, root)) {
if(!url.replace(/\s/g, '').length || !loaderUtils.isUrlRequest(url)) {
return url;
}
if(global) {
return loaderUtils.urlToRequest(url, root);
return loaderUtils.urlToRequest(url);
}
}
return url;
@@ -189,16 +179,6 @@ module.exports = function processCss(inputSource, inputMap, options, callback) {
parserPlugin(parserOptions)
]);

if(minimize) {
var cssnano = require("cssnano");
var minimizeOptions = assign({}, query.minimize);
["zindex", "normalizeUrl", "discardUnused", "mergeIdents", "reduceIdents", "autoprefixer"].forEach(function(name) {
if(typeof minimizeOptions[name] === "undefined")
minimizeOptions[name] = false;
});
pipeline.use(cssnano(minimizeOptions));
}

pipeline.process(inputSource, {
// we need a prefix to avoid path rewriting of PostCSS
from: "/css-loader!" + options.from,
16 changes: 16 additions & 0 deletions lib/url/escape.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module.exports = function escape(url) {
if (typeof url !== 'string') {
return url
}
// If url is already wrapped in quotes, remove them
if (/^['"].*['"]$/.test(url)) {
url = url.slice(1, -1);
}
// Should url be wrapped?
// See https://drafts.csswg.org/css-values-3/#urls
if (/["'() \t\n]/.test(url)) {
return '"' + url.replace(/"/g, '\\"').replace(/\n/g, '\\n') + '"'
}

return url
}
4,076 changes: 4,076 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

40 changes: 20 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
{
"name": "css-loader",
"version": "0.28.7",
"version": "1.0.0",
"author": "Tobias Koppers @sokra",
"license": "MIT",
"description": "css loader module for webpack",
"engines": {
"node": ">=0.12.0 || >=4.3.0 <5.0.0 || >=5.10"
"node": ">= 6.9.0 <7.0.0 || >= 8.9.0"
},
"files": [
"lib",
"index.js",
"locals.js",
"lib"
"locals.js"
],
"dependencies": {
"babel-code-frame": "^6.11.0",
"babel-code-frame": "^6.26.0",
"css-selector-tokenizer": "^0.7.0",
"cssnano": ">=2.6.1 <4",
"icss-utils": "^2.1.0",
"loader-utils": "^1.0.2",
"lodash.camelcase": "^4.3.0",
"object-assign": "^4.0.1",
"postcss": "^5.0.6",
"postcss-modules-extract-imports": "^1.0.0",
"postcss-modules-local-by-default": "^1.0.1",
"postcss-modules-scope": "^1.0.0",
"postcss-modules-values": "^1.1.0",
"postcss": "^6.0.23",
"postcss-modules-extract-imports": "^1.2.0",
"postcss-modules-local-by-default": "^1.2.0",
"postcss-modules-scope": "^1.1.0",
"postcss-modules-values": "^1.3.0",
"postcss-value-parser": "^3.3.0",
"source-list-map": "^2.0.0"
},
@@ -35,18 +34,19 @@
"should": "^11.1.2",
"standard-version": "^4.0.0"
},
"peerDependencies": {
"webpack": "^4.0.0"
},
"scripts": {
"lint": "eslint lib test",
"test": "mocha",
"cover": "istanbul cover node_modules/mocha/bin/_mocha",
"test:cover": "npm run cover -- --report lcovonly",
"lint": "eslint lib test",
"travis:test": "npm run cover",
"travis:lint": "npm run lint",
"cover": "istanbul cover node_modules/mocha/bin/_mocha",
"release": "yarn run standard-version"
},
"repository": {
"type": "git",
"url": "git@github.com:webpack/css-loader.git"
"release": "standard-version"
},
"license": "MIT"
"homepage": "https://github.com/webpack-contrib/css-loader",
"repository": "https://github.com/webpack-contrib/css-loader.git",
"bugs": "https://github.com/webpack-contrib/css-loader/issues"
}
57 changes: 0 additions & 57 deletions test/aliasTest.js

This file was deleted.

21 changes: 5 additions & 16 deletions test/helpers.js
Original file line number Diff line number Diff line change
@@ -12,9 +12,11 @@ function getEvaluated(output, modules) {
fn(m, m.exports, function(module) {
if(module.indexOf("css-base") >= 0)
return require("../lib/css-base");
if(module.indexOf("url/escape") >= 0)
return require("../lib/url/escape");
if(module.indexOf("-!/path/css-loader!") === 0)
module = module.substr(19);
if(modules && modules[module])
if(modules && module in modules)
return modules[module];
return "{" + module + "}";
});
@@ -73,13 +75,13 @@ exports.test = function test(name, input, result, query, modules) {
});
};

exports.testRaw = function testRaw(name, input, result, query, modules) {
exports.testRaw = function testRaw(name, input, result, query) {
it(name, function(done) {
runLoader(cssLoader, input, undefined, !query || typeof query === "string" ? {
query: query
} : query, function(err, output) {
if(err) return done(err);
assertRaw(output, result, modules);
assertRaw(output, result);
done();
});
});
@@ -153,16 +155,3 @@ exports.testSingleItem = function testSingleItem(name, input, result, query, mod
});
});
};

exports.testMinimize = function testMinimize(name, input, result, query, modules) {
it(name, function(done) {
runLoader(cssLoader, input, undefined, {
minimize: true,
query: query
}, function(err, output) {
if(err) return done(err);
assetEvaluated(output, result, modules);
done();
});
});
};
23 changes: 5 additions & 18 deletions test/localTest.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
/*globals describe */

var test = require("./helpers").test;
var testMinimize = require("./helpers").testMinimize;

function testLocal(name, input, result, localsResult, query, modules) {
result.locals = localsResult;
test(name, input, result, query, modules);
}

function testLocalMinimize(name, input, result, localsResult, query, modules) {
result.locals = localsResult;
testMinimize(name, input, result, query, modules);
}

describe("local", function() {
testLocal("locals-format", ":local(.test) { background: red; }", [
[1, ".test-2_pBx { background: red; }", ""]
@@ -28,13 +22,6 @@ describe("local", function() {
someId: "_3vpqN0v_IxlO3TzQjbpB33",
subClass: "_1s1VsToXFz17cPAltMg7jz"
});
testLocalMinimize("minimized plus local", ":local(.localClass) { background: red; }\n:local .otherClass { background: red; }\n:local(.empty) { }", [
[1, "._localClass,._otherClass{background:red}", ""]
], {
localClass: "_localClass",
otherClass: "_otherClass",
empty: "_empty"
}, "?localIdentName=_[local]");
testLocal("mode switching", ".c1 :local .c2 .c3 :global .c4 :local .c5, .c6 :local .c7 { background: red; }\n.c8 { background: red; }", [
[1, ".c1 ._c2 ._c3 .c4 ._c5, .c6 ._c7 { background: red; }\n.c8 { background: red; }", ""]
], {
@@ -44,13 +31,13 @@ describe("local", function() {
c7: "_c7"
}, "?localIdentName=_[local]");
testLocal("comment in local", ":local(.c1/*.c2*/.c3) { background: red; }", [
[1, "._c1._c3 { background: red; }", ""]
[1, "._c1/*.c2*/._c3 { background: red; }", ""]
], {
c1: "_c1",
c3: "_c3"
}, "?localIdentName=_[local]");
testLocal("comment in local", ":local(.c1/*.c2*/.c3) { background: red; }", [
[1, "._c1._c3 { background: red; }", ""]
[1, "._c1/*.c2*/._c3 { background: red; }", ""]
], {
c1: "_c1",
c3: "_c3"
@@ -152,18 +139,18 @@ describe("local", function() {
className: "_23J0282swY7bwvI2X4fHiV",
someId: "_3vpqN0v_IxlO3TzQjbpB33",
subClass: "_1s1VsToXFz17cPAltMg7jz"
}, "?module");
}, "?modules");
testLocal("class name parsing", ".-a0-34a___f { color: red; }", [
[1, "._3ZMCqVa1XidxdqbX65hZ5D { color: red; }", ""]
], {
"-a0-34a___f": "_3ZMCqVa1XidxdqbX65hZ5D"
}, "?module");
}, "?modules");
testLocal("imported values in decl", ".className { color: IMPORTED_NAME; }\n" +
":import(\"./vars.css\") { IMPORTED_NAME: primary-color; }", [
[1, "._className { color: red; }", ""]
], {
"className": "_className"
}, "?module&localIdentName=_[local]", {
}, "?modules&localIdentName=_[local]", {
"./vars.css": {
locals: {
"primary-color": "red"
7 changes: 7 additions & 0 deletions test/localsTest.js
Original file line number Diff line number Diff line change
@@ -49,4 +49,11 @@ describe("locals", function() {
}
}
);
testLocals("should not fail on processing a url",
":local(.abc) { background: url(http://example.com/image.jpg); }",
{
abc: "_abc"
},
"?localIdentName=_[local]"
);
});
24 changes: 0 additions & 24 deletions test/moduleMinimizeTest.js

This file was deleted.

This file was deleted.

28 changes: 0 additions & 28 deletions test/moduleMinimizeTestCases/keyframes-and-animation/source.css

This file was deleted.

2 changes: 1 addition & 1 deletion test/moduleTest.js
Original file line number Diff line number Diff line change
@@ -12,6 +12,6 @@ describe("module", function() {
var source = fs.readFileSync(path.join(testCasesPath, name, "source.css"), "utf-8");
var expected = fs.readFileSync(path.join(testCasesPath, name, "expected.css"), "utf-8");

test(name, source, expected, "?module&sourceMap&localIdentName=_[local]_");
test(name, source, expected, "?modules&sourceMap&localIdentName=_[local]_");
});
});
2 changes: 1 addition & 1 deletion test/moduleTestCases/urls/expected.css
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
background: url({./module});
background: url({./module});
background: url("{./module module}");
background: url('{./module module}');
background: url("{./module module}");
background: url({./module});
background: url({./module}#?iefix);
background: url("#hash");
10 changes: 3 additions & 7 deletions test/simpleTest.js
Original file line number Diff line number Diff line change
@@ -3,15 +3,11 @@
var assert = require('assert');
var test = require("./helpers").test;
var testError = require("./helpers").testError;
var testMinimize = require("./helpers").testMinimize;

describe("simple", function() {
test("empty", "", [
[1, "", ""]
]);
testMinimize("empty minimized", "", [
[1, "", ""]
]);
test("simple", ".class { a: b c d; }", [
[1, ".class { a: b c d; }", ""]
]);
@@ -32,12 +28,12 @@ describe("simple", function() {
/*test("escape characters (two)", ".class { content: \"\\F10C \\F10D\" }", [
[1, ".class { content: \"\\F10C \\F10D\" }", ""]
]);*/
testMinimize("minimized simple", ".class { a: b c d; }", [
[1, ".class{a:b c d}", ""]
]);
test("charset directive", "@charset \"UTF-8\";\n .class { a: b c d; }", [
[1, "@charset \"UTF-8\";\n .class { a: b c d; }", ""]
]);
test("custom variables", ":root {--foo: 1px;\n--bar: 2px;}", [
[1, ":root {--foo: 1px;\n--bar: 2px;}", ""]
]);
testError("error formatting", ".some {\n invalid css;\n}", function(err) {
assert.equal(err.message, [
'Unknown word (2:2)',
48 changes: 35 additions & 13 deletions test/urlTest.js
Original file line number Diff line number Diff line change
@@ -19,23 +19,11 @@ describe("url", function() {
[1, ".class { background: green url(\"{./img img.png}\") xyz }", ""]
]);
test("background 2 img contain space in name", ".class { background: green url( 'img img.png' ) xyz }", [
[1, ".class { background: green url('{./img img.png}') xyz }", ""]
[1, ".class { background: green url(\"{./img img.png}\") xyz }", ""]
]);
test("background img absolute", ".class { background: green url(/img.png) xyz }", [
[1, ".class { background: green url(/img.png) xyz }", ""]
]);
test("background img absolute with root", ".class { background: green url(/img.png) xyz }", [
[1, ".class { background: green url({./img.png}) xyz }", ""]
], "?root=.");
test("background img absolute with root", ".class { background: green url(/img.png) xyz }", [
[1, ".class { background: green url({./img.png}) xyz }", ""]
], "?root=./");
test("root with absolute url", ".class { background: green url(/img.png) xyz }", [
[1, ".class { background: green url(http://some.cdn.com/img.png) xyz }", ""]
], "?root=http://some.cdn.com");
test("root with absolute url with trailing slash", ".class { background: green url(/img.png) xyz }", [
[1, ".class { background: green url(http://some.cdn.com/img.png) xyz }", ""]
], "?root=http://some.cdn.com/");
test("background img external",
".class { background: green url(data:image/png;base64,AAA) url(http://example.com/image.jpg) url(//example.com/image.png) xyz }", [
[1, ".class { background: green url(data:image/png;base64,AAA) url(http://example.com/image.jpg) url(//example.com/image.png) xyz }", ""]
@@ -103,6 +91,34 @@ describe("url", function() {
test("external schema-less url", ".class { background: green url(//raw.githubusercontent.com/webpack/media/master/logo/icon.png) xyz }", [
[1, ".class { background: green url(//raw.githubusercontent.com/webpack/media/master/logo/icon.png) xyz }", ""]
]);

test("module wrapped in spaces", ".class { background: green url(module) xyz }", [
[1, ".class { background: green url(module-wrapped) xyz }", ""]
], "", { './module': "\"module-wrapped\"" });
test("module with space", ".class { background: green url(module) xyz }", [
[1, ".class { background: green url(\"module with space\") xyz }", ""]
], "", { './module': "module with space" });
test("module with quote", ".class { background: green url(module) xyz }", [
[1, ".class { background: green url(\"module\\\"with\\\"quote\") xyz }", ""]
], "", { './module': "module\"with\"quote" });
test("module with quote wrapped", ".class { background: green url(module) xyz }", [
[1, ".class { background: green url(\"module\\\"with\\\"quote\\\"wrapped\") xyz }", ""]
], "", { './module': "\"module\"with\"quote\"wrapped\"" });
test("module with parens", ".class { background: green url(module) xyz }", [
[1, ".class { background: green url(\"module(with-parens)\") xyz }", ""]
], "", { './module': 'module(with-parens)' });
test("module with newline", ".class { background: green url(module) xyz }", [
[1, ".class { background: green url(\"module\\nwith\\nnewline\") xyz }", ""]
], "", { './module': "module\nwith\nnewline" });
test("module from url-loader", ".class { background: green url(module) xyz }", [
[1, ".class { background: green url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA) xyz }", ""]
], "", { './module': "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA" });
test("module from null-loader (empty object from webpack)", ".class { background: green url(module) xyz }", [
[1, ".class { background: green url([object Object]) xyz }", ""]
], "", { './module': {} });
test("module is null", ".class { background: green url(module) xyz }", [
[1, ".class { background: green url(null) xyz }", ""]
], "", { './module': null });

test("background img with url", ".class { background: green url( \"img.png\" ) xyz }", [
[1, ".class { background: green url( \"img.png\" ) xyz }", ""]
@@ -156,6 +172,12 @@ describe("url", function() {
test("font face with url", "@font-face { src: url(regular.woff) format('woff'), url(~truetype/regular.ttf) format('truetype') }", [
[1, "@font-face { src: url(regular.woff) format('woff'), url(~truetype/regular.ttf) format('truetype') }", ""]
], "?-url");
test("font face with url", "@font-face { src: url(Mark Simonson - Proxima Nova Alt Regular-webfont.eot?#iefix) format('embedded-opentype'), url(~opentype/Mark Simonson - Proxima Nova Alt Regular-webfont.eot?#iefix) format('embedded-opentype') }", [
[1, "@font-face { src: url(Mark Simonson - Proxima Nova Alt Regular-webfont.eot?#iefix) format('embedded-opentype'), url(~opentype/Mark Simonson - Proxima Nova Alt Regular-webfont.eot?#iefix) format('embedded-opentype') }", ""]
], "?-url");
test("font face with url", "@font-face { src: url('Mark Simonson - Proxima Nova Alt Regular-webfont.eot?#iefix') format('embedded-opentype'), url(\"Mark Simonson - Proxima Nova Alt Regular-webfont.eot?#iefix\") format('embedded-opentype') }", [
[1, "@font-face { src: url('Mark Simonson - Proxima Nova Alt Regular-webfont.eot?#iefix') format('embedded-opentype'), url(\"Mark Simonson - Proxima Nova Alt Regular-webfont.eot?#iefix\") format('embedded-opentype') }", ""]
], "?-url");
test("media query with url", "@media (min-width: 500px) { body { background: url(image.png); } }", [
[1, "@media (min-width: 500px) { body { background: url(image.png); } }", ""]
], "?-url");
2,870 changes: 0 additions & 2,870 deletions yarn.lock

This file was deleted.