postcss-loader
Advanced tools
Comparing version 0.13.0 to 1.0.0
@@ -0,1 +1,7 @@ | ||
## 1.0 | ||
* Add common PostCSS config support (by Mateusz Derks). | ||
* Add Webpack 2 support with `plugins` query option (by Izaak Schroeder). | ||
* Add `dependency` message support. | ||
* Rewite docs (by Michael Ciniawsky). | ||
## 0.13 | ||
@@ -2,0 +8,0 @@ * Add `exec` parameter (by Neal Granger). |
173
index.js
var loaderUtils = require('loader-utils'); | ||
var loadConfig = require('postcss-load-config'); | ||
var postcss = require('postcss'); | ||
var assign = require('object-assign'); | ||
function PostCSSLoaderError(error) { | ||
Error.call(this); | ||
Error.captureStackTrace(this, PostCSSLoaderError); | ||
this.name = 'Syntax Error'; | ||
this.error = error.input.source; | ||
this.message = error.reason; | ||
if ( error.line ) { | ||
this.message += ' (' + error.line + ':' + error.column + ')'; | ||
} | ||
if ( error.line && error.input.source ) { | ||
this.message += '\n\n' + error.showSourceCode() + '\n'; | ||
} | ||
this.hideStack = true; | ||
} | ||
var PostCSSLoaderError = require('./error'); | ||
PostCSSLoaderError.prototype = Object.create(Error.prototype); | ||
PostCSSLoaderError.prototype.constructor = PostCSSLoaderError; | ||
module.exports = function (source, map) { | ||
if ( this.cacheable ) this.cacheable(); | ||
var file = this.resourcePath; | ||
var params = loaderUtils.parseQuery(this.query); | ||
var opts = { | ||
from: file, | ||
to: file, | ||
map: { | ||
inline: params.sourceMap === 'inline', | ||
annotation: false | ||
} | ||
}; | ||
if ( typeof map === 'string' ) map = JSON.parse(map); | ||
if ( map && map.mappings ) opts.map.prev = map; | ||
var options = this.options.postcss; | ||
function parseOptions(options, pack) { | ||
if ( typeof options === 'function' ) { | ||
@@ -46,4 +14,3 @@ options = options.call(this, this); | ||
var plugins; | ||
var exec; | ||
if ( typeof options === 'undefined' ) { | ||
if ( typeof options === 'undefined') { | ||
plugins = []; | ||
@@ -54,9 +21,6 @@ } else if ( Array.isArray(options) ) { | ||
plugins = options.plugins || options.defaults; | ||
opts.stringifier = options.stringifier; | ||
opts.parser = options.parser; | ||
opts.syntax = options.syntax; | ||
exec = options.exec; | ||
} | ||
if ( params.pack ) { | ||
plugins = options[params.pack]; | ||
if ( pack ) { | ||
plugins = options[pack]; | ||
if ( !plugins ) { | ||
@@ -67,44 +31,101 @@ throw new Error('PostCSS plugin pack is not defined in options'); | ||
if ( params.syntax ) { | ||
opts.syntax = require(params.syntax); | ||
var opts = { }; | ||
if ( typeof options !== 'undefined' ) { | ||
opts.stringifier = options.stringifier; | ||
opts.parser = options.parser; | ||
opts.syntax = options.syntax; | ||
} | ||
if ( params.parser ) { | ||
opts.parser = require(params.parser); | ||
} | ||
if ( params.stringifier ) { | ||
opts.stringifier = require(params.stringifier); | ||
} | ||
if ( params.exec ) { | ||
exec = params.exec; | ||
} | ||
var loader = this; | ||
var callback = this.async(); | ||
var exec = options && options.exec; | ||
return Promise.resolve({ options: opts, plugins: plugins, exec: exec }); | ||
} | ||
if ( params.parser === 'postcss-js' || exec ) { | ||
source = this.exec(source, this.resource); | ||
} | ||
module.exports = function (source, map) { | ||
if ( this.cacheable ) this.cacheable(); | ||
// Allow plugins to add or remove postcss plugins | ||
plugins = this._compilation.applyPluginsWaterfall( | ||
'postcss-loader-before-processing', | ||
[].concat(plugins), | ||
params | ||
); | ||
var loader = this; | ||
var file = loader.resourcePath; | ||
var params = loaderUtils.parseQuery(loader.query); | ||
postcss(plugins).process(source, opts) | ||
.then(function (result) { | ||
var options = params.plugins || loader.options.postcss; | ||
var pack = params.pack; | ||
var callback = loader.async(); | ||
Promise.resolve().then(function () { | ||
if ( typeof options !== 'undefined' ) { | ||
return parseOptions(options, pack); | ||
} else { | ||
if ( pack ) { | ||
throw new Error('PostCSS plugin pack is supported ' + | ||
'only when use plugins in webpack config'); | ||
} | ||
return loadConfig(pack); | ||
} | ||
}).then(function (config) { | ||
if ( !config ) config = { }; | ||
var plugins = config.plugins || []; | ||
var opts = assign({}, config.options, { | ||
from: file, | ||
to: file, | ||
map: { | ||
inline: params.sourceMap === 'inline', | ||
annotation: false | ||
} | ||
}); | ||
if ( typeof map === 'string' ) map = JSON.parse(map); | ||
if ( map && map.mappings ) opts.map.prev = map; | ||
if ( params.syntax ) { | ||
opts.syntax = require(params.syntax); | ||
} | ||
if ( params.parser ) { | ||
opts.parser = require(params.parser); | ||
} | ||
if ( params.stringifier ) { | ||
opts.stringifier = require(params.stringifier); | ||
} | ||
var exec = params.exec || config.exec; | ||
if ( params.parser === 'postcss-js' || exec ) { | ||
source = loader.exec(source, loader.resource); | ||
} | ||
// Allow plugins to add or remove postcss plugins | ||
if ( loader._compilation ) { | ||
plugins = loader._compilation.applyPluginsWaterfall( | ||
'postcss-loader-before-processing', | ||
[].concat(plugins), | ||
params | ||
); | ||
} else { | ||
loader.emitWarning( | ||
'this._compilation is not available thus ' + | ||
'`postcss-loader-before-processing` is not supported' | ||
); | ||
} | ||
return postcss(plugins).process(source, opts).then(function (result) { | ||
result.warnings().forEach(function (msg) { | ||
loader.emitWarning(msg.toString()); | ||
}); | ||
callback(null, result.css, result.map ? result.map.toJSON() : null); | ||
result.messages.forEach(function (msg) { | ||
if ( msg.type === 'dependency' ) { | ||
loader.addDependency(msg.file); | ||
} | ||
}); | ||
var resultMap = result.map ? result.map.toJSON() : null; | ||
callback(null, result.css, resultMap); | ||
return null; | ||
}) | ||
.catch(function (error) { | ||
if ( error.name === 'CssSyntaxError' ) { | ||
callback(new PostCSSLoaderError(error)); | ||
} else { | ||
callback(error); | ||
} | ||
}); | ||
}).catch(function (error) { | ||
if ( error.name === 'CssSyntaxError' ) { | ||
callback(new PostCSSLoaderError(error)); | ||
} else { | ||
callback(error); | ||
} | ||
}); | ||
}; |
{ | ||
"name": "postcss-loader", | ||
"version": "0.13.0", | ||
"version": "1.0.0", | ||
"description": "PostCSS loader for webpack", | ||
@@ -10,4 +10,6 @@ "keywords": ["webpack", "loader", "css", "postcss", "postcss-runner"], | ||
"dependencies": { | ||
"loader-utils": "^0.2.15", | ||
"postcss": "^5.2.0" | ||
"postcss-load-config": "^1.0.0-rc", | ||
"object-assign": "^4.1.0", | ||
"loader-utils": "^0.2.16", | ||
"postcss": "^5.2.4" | ||
}, | ||
@@ -24,2 +26,3 @@ "devDependencies": { | ||
"fs-extra": "0.30.0", | ||
"sugarss": "0.2.0", | ||
"chai": "3.5.0", | ||
@@ -26,0 +29,0 @@ "gulp": "3.9.1" |
369
README.md
@@ -9,4 +9,5 @@ # PostCSS for Webpack [![Build Status][ci-img]][ci] | ||
<a href="https://evilmartians.com/?utm_source=postcss-loader"> | ||
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"> | ||
<a href="https://evilmartians.com/?utm_source=postcss"> | ||
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" | ||
alt="Sponsored by Evil Martians" width="236" height="54"> | ||
</a> | ||
@@ -20,106 +21,116 @@ | ||
## Usage | ||
## Install | ||
Install `postcss-loader`: | ||
```console | ||
```sh | ||
npm install postcss-loader --save-dev | ||
``` | ||
Set `postcss` section in webpack config: | ||
## Usage | ||
You can configure PostCSS Loader in common PostCSS config or directly | ||
in Webpack config. Common PostCSS config is recommended way, because | ||
many PostCSS tools will be able to share it. | ||
### PostCSS Config | ||
Add PostCSS Loader to `webpack.config.js`. Put it before `css-loader` | ||
and `style-loader`. But after `sass-loader`, if you use it. | ||
```js | ||
var precss = require('precss'); | ||
var autoprefixer = require('autoprefixer'); | ||
module.exports = { | ||
module: { | ||
loaders: [ | ||
{ | ||
test: /\.css$/, | ||
loader: "style-loader!css-loader!postcss-loader" | ||
} | ||
module: { | ||
loaders: [ | ||
{ | ||
test: /\.css$/, | ||
loader: [ | ||
'style-loader', | ||
'css-loader?importLoaders=1', | ||
'postcss-loader' | ||
] | ||
}, | ||
postcss: function () { | ||
return [precss, autoprefixer]; | ||
} | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
> This example implementation uses two plugins that may need to be installed: | ||
> | ||
> ```console | ||
> npm install precss --save-dev | ||
> npm install autoprefixer --save-dev | ||
> ``` | ||
Then create `postcss.config.js`: | ||
Now your CSS files requirements will be processed by selected PostCSS plugins: | ||
```js | ||
var css = require('./file.css'); | ||
// => CSS after PreCSS and Autoprefixer | ||
``` | ||
Note that the context of this function | ||
```js | ||
module.exports = { | ||
... | ||
postcss: function () { | ||
return [autoprefixer, precss]; | ||
} | ||
plugins: [ | ||
require('precss'), | ||
require('autoprefixer') | ||
] | ||
} | ||
``` | ||
will be set to the [webpack loader-context]. | ||
If there is the need, this will let you access to webpack loaders API. | ||
You could put different configs in different directories. For example, | ||
global config in `project/postcss.config.js` and override its plugins | ||
in `project/src/legacy/postcss.config.js`. | ||
[webpack loader-context]: http://webpack.github.io/docs/loaders.html#loader-context | ||
You can read more about common PostCSS config in [postcss-load-config]. | ||
## Source Maps | ||
[postcss-load-config]: https://github.com/michael-ciniawsky/postcss-load-config | ||
Loader will use source map settings from previous loader. | ||
### Webpack 2.x Config | ||
You can set this `sourceMap` parameter to `inline` value to put source maps | ||
into CSS annotation comment: | ||
```js | ||
module.exports = { | ||
module: { | ||
loader: "style-loader!css-loader!postcss-loader?sourceMap=inline" | ||
} | ||
module: { | ||
rules: [ | ||
{ | ||
test: /\.css$/, | ||
use: [ | ||
'style-loader', | ||
{ | ||
loader: 'css-loader', | ||
options: { importLoaders: 1 } | ||
}, | ||
{ | ||
loader: 'postcss-loader', | ||
options: { | ||
plugins: function () { | ||
return [ | ||
require('precss'), | ||
require('autoprefixer') | ||
]; | ||
} | ||
} | ||
} | ||
] | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
## Plugins Packs | ||
### Webpack 1.x Config | ||
If you want to process different styles by different PostCSS plugins you can | ||
define plugin packs in `postcss` section and use them by `?pack=name` parameter. | ||
```js | ||
module.exports = { | ||
module: { | ||
loaders: [ | ||
{ | ||
test: /\.docs\.css$/, | ||
loader: "style-loader!css-loader!postcss-loader?pack=cleaner" | ||
}, | ||
{ | ||
test: /\.css$/, | ||
loader: "style-loader!css-loader!postcss-loader" | ||
} | ||
module: { | ||
loaders: [ | ||
{ | ||
test: /\.css$/, | ||
loader: [ | ||
'style-loader', | ||
'css-loader?importLoaders=1', | ||
'postcss-loader' | ||
] | ||
}, | ||
postcss: function () { | ||
return { | ||
defaults: [precss, autoprefixer], | ||
cleaner: [autoprefixer({ browsers: [] })] | ||
}; | ||
} | ||
} | ||
] | ||
}, | ||
postcss: function () { | ||
return [ | ||
require('precss'), | ||
require('autoprefixer') | ||
]; | ||
} | ||
} | ||
``` | ||
## Custom Syntaxes | ||
## Options | ||
### Syntaxes | ||
PostCSS can transforms styles in any syntax, not only in CSS. | ||
@@ -132,128 +143,71 @@ There are 3 parameters to control syntax: | ||
For example, you can use [Safe Parser] to find and fix any CSS errors: | ||
```js | ||
var css = require('postcss?parser=postcss-safe-parser!./broken') | ||
``` | ||
[Safe Parser]: https://github.com/postcss/postcss-safe-parser | ||
If you need to pass the function directly instead of a module name, | ||
you can do so through the webpack postcss option, as such: | ||
```js | ||
var sugarss = require('sugarss') | ||
module.exports = { | ||
module: { | ||
loaders: [ | ||
{ | ||
test: /\.css$/, | ||
loader: "style-loader!css-loader!postcss-loader" | ||
} | ||
module: { | ||
loaders: [ | ||
{ | ||
test: /\.sss/, | ||
loader: [ | ||
'style-loader', | ||
'css-loader?importLoaders=1', | ||
'postcss-loader?parser=sugarss' | ||
] | ||
}, | ||
postcss: function () { | ||
return { | ||
plugins: [autoprefixer, precss], | ||
syntax: sugarss | ||
}; | ||
} | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
## Examples | ||
### SourceMaps | ||
### With postcss-import | ||
Loader will use source map settings from previous loader. | ||
When using [postcss-import] plugin, you may want to tell webpack about | ||
dependencies coming from your `@import` directives. | ||
For example: in watch mode, to enable recompile on change. | ||
You can set this `sourceMap` parameter to `inline` value to put source maps | ||
into CSS annotation comment: | ||
Here is a simple way to let know postcss-import to pass files to webpack: | ||
```js | ||
var postcssImport = require('postcss-import'); | ||
module.exports = { | ||
module: { | ||
loaders: [ | ||
{ | ||
test: /\.css$/, | ||
loader: "style-loader!css-loader!postcss-loader" | ||
} | ||
module: { | ||
loaders: [ | ||
{ | ||
test: '\/.css', | ||
loader: [ | ||
'style-loader', | ||
'css-loader?importLoaders=1', | ||
'postcss-loader?sourceMap=inline' | ||
] | ||
}, | ||
postcss: function (webpack) { | ||
return [ | ||
postcssImport({ | ||
addDependencyTo: webpack | ||
}) | ||
]; | ||
} | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
[webpack loader-context]: http://webpack.github.io/docs/loaders.html#loader-context | ||
[postcss-import]: https://github.com/postcss/postcss-import | ||
## Examples | ||
### With CSS Modules | ||
### CSS Modules | ||
`postcss-loader` [cannot be used] with [CSS Modules] out of the box due | ||
This loader [cannot be used] with [CSS Modules] out of the box due | ||
to the way `css-loader` processes file imports. To make them work properly, | ||
either add the css-loader’s [`importLoaders` option]: | ||
either add the css-loader’s [`importLoaders`] option | ||
```js | ||
{ | ||
test: /\.css$/, | ||
loader: "style-loader!css-loader?modules&importLoaders=1!postcss-loader" | ||
} | ||
… | ||
{ | ||
test: /\.css$/, | ||
loader: [ | ||
'style-loader', | ||
'css-loader?modules&importLoaders=1', | ||
'postcss-loader' | ||
] | ||
} | ||
… | ||
``` | ||
or use [postcss-modules] plugin instead of `css-loader`. | ||
[`importLoaders` option]: https://github.com/webpack/css-loader#importing-and-chained-loaders | ||
[postcss-modules]: https://github.com/outpunk/postcss-modules | ||
[cannot be used]: https://github.com/webpack/css-loader/issues/137 | ||
[CSS Modules]: https://github.com/webpack/css-loader#css-modules | ||
## Custom Syntaxes | ||
[`importLoaders`]: https://github.com/webpack/css-loader#importing-and-chained-loaders | ||
[postcss-modules]: https://github.com/outpunk/postcss-modules | ||
[cannot be used]: https://github.com/webpack/css-loader/issues/137 | ||
[CSS Modules]: https://github.com/webpack/css-loader#css-modules | ||
PostCSS can transforms styles in any syntax, not only in CSS. | ||
There are 3 parameters to control syntax: | ||
* `syntax` accepts module name with `parse` and `stringify` function. | ||
* `parser` accepts module name with input parser function. | ||
* `stringifier` accepts module name with output stringifier function. | ||
For example, you can use [Safe Parser] to find and fix any CSS errors: | ||
```js | ||
var css = require('postcss?parser=postcss-safe-parser!./broken') | ||
``` | ||
[Safe Parser]: https://github.com/postcss/postcss-safe-parser | ||
If you need to pass the function directly instead of a module name, | ||
you can do so through the webpack postcss option, as such: | ||
```js | ||
var sugarss = require('sugarss') | ||
module.exports = { | ||
module: { | ||
loaders: [ | ||
{ | ||
test: /\.css$/, | ||
loader: "style-loader!css-loader!postcss-loader" | ||
} | ||
] | ||
}, | ||
postcss: function () { | ||
return { | ||
plugins: [autoprefixer, precss], | ||
syntax: sugarss | ||
}; | ||
} | ||
} | ||
``` | ||
### JS Styles | ||
@@ -265,30 +219,28 @@ | ||
```js | ||
{ | ||
test: /\.style.js$/, | ||
loader: "style-loader!css-loader!postcss-loader?parser=postcss-js" | ||
} | ||
… | ||
{ | ||
test: /\.style.js$/, | ||
loader: [ | ||
'style-loader', | ||
'css-loader?modules&importLoaders=1', | ||
'postcss-loader?parser=postcss-js', | ||
'babel' | ||
] | ||
} | ||
… | ||
``` | ||
Or use can use even ES6 in JS styles by Babel: | ||
```js | ||
{ | ||
test: /\.style.js$/, | ||
loader: "style-loader!css-loader!postcss-loader?parser=postcss-js!babel" | ||
} | ||
``` | ||
As result you will be able to write styles as: | ||
```js | ||
import colors from '../config/colors'; | ||
import colors from './config/colors' | ||
export default { | ||
'.menu': { | ||
color: colors.main, | ||
height: 25, | ||
'&_link': { | ||
color: 'white' | ||
} | ||
'.menu': { | ||
color: colors.main, | ||
height: 25, | ||
'&_link': { | ||
color: 'white' | ||
} | ||
} | ||
} | ||
@@ -300,20 +252,27 @@ ``` | ||
```js | ||
{ | ||
test: /\.style.xyz$/, | ||
loader: "style-loader!css-loader!postcss-loader?parser=custom-parser&exec" | ||
} | ||
… | ||
{ | ||
test: /\.style.xyz$/, | ||
loader: [ | ||
'style-loader', | ||
'css-loader?modules&importLoaders=1', | ||
'postcss-loader?parser=custom-parser&exec' | ||
] | ||
} | ||
… | ||
``` | ||
## Webpack Events | ||
[postcss-js]: https://github.com/postcss/postcss-js | ||
Webpack provides webpack-plugin developers a convenient way | ||
to hook into the build pipeline. The postcss-loader makes us | ||
### Webpack Events | ||
Webpack provides webpack plugin developers a convenient way | ||
to hook into the build pipeline. The postcss-loader makes use | ||
of this event system to allow building integrated postcss-webpack tools. | ||
See the [example implementation]. | ||
See the [example] implementation. | ||
* `postcss-loader-before-processing` | ||
is fired before processing and allows to add or remove postcss plugins | ||
Event `postcss-loader-before-processing` is fired before processing and allows | ||
to add or remove postcss plugins. | ||
[example implementation]: https://github.com/postcss/postcss-loader/blob/master/test/webpack-plugins/rewrite.js | ||
[postcss-js]: https://github.com/postcss/postcss-js | ||
[example]: https://github.com/postcss/postcss-loader/blob/master/test/support/webpack-plugins/rewrite.js |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
127
1
14297
4
12
6
274
+ Addedobject-assign@^4.1.0
+ Addedargparse@1.0.10(transitive)
+ Addedcosmiconfig@2.2.2(transitive)
+ Addederror-ex@1.3.2(transitive)
+ Addedesprima@4.0.1(transitive)
+ Addedis-arrayish@0.2.1(transitive)
+ Addedis-directory@0.3.1(transitive)
+ Addedjs-yaml@3.14.1(transitive)
+ Addedminimist@1.2.8(transitive)
+ Addedos-homedir@1.0.2(transitive)
+ Addedparse-json@2.2.0(transitive)
+ Addedpostcss-load-config@1.2.0(transitive)
+ Addedpostcss-load-options@1.2.0(transitive)
+ Addedpostcss-load-plugins@2.3.0(transitive)
+ Addedrequire-from-string@1.2.1(transitive)
+ Addedsprintf-js@1.0.3(transitive)
Updatedloader-utils@^0.2.16
Updatedpostcss@^5.2.4