|
1 | 1 | var loaderUtils = require('loader-utils'); |
| 2 | +var loadConfig = require('postcss-load-config'); |
2 | 3 | var postcss = require('postcss'); |
| 4 | +var assign = require('object-assign'); |
3 | 5 |
|
4 | | -function PostCSSLoaderError(error) { |
5 | | - Error.call(this); |
6 | | - Error.captureStackTrace(this, PostCSSLoaderError); |
7 | | - this.name = 'Syntax Error'; |
8 | | - this.error = error.input.source; |
9 | | - this.message = error.reason; |
10 | | - if ( error.line ) { |
11 | | - this.message += ' (' + error.line + ':' + error.column + ')'; |
12 | | - } |
13 | | - if ( error.line && error.input.source ) { |
14 | | - this.message += '\n\n' + error.showSourceCode() + '\n'; |
15 | | - } |
16 | | - this.hideStack = true; |
17 | | -} |
18 | | - |
19 | | -PostCSSLoaderError.prototype = Object.create(Error.prototype); |
20 | | -PostCSSLoaderError.prototype.constructor = PostCSSLoaderError; |
21 | | - |
22 | | -module.exports = function (source, map) { |
23 | | - if ( this.cacheable ) this.cacheable(); |
24 | | - |
25 | | - var file = this.resourcePath; |
26 | | - var params = loaderUtils.parseQuery(this.query); |
27 | | - |
28 | | - var opts = { |
29 | | - from: file, |
30 | | - to: file, |
31 | | - map: { |
32 | | - inline: params.sourceMap === 'inline', |
33 | | - annotation: false |
34 | | - } |
35 | | - }; |
36 | | - |
37 | | - if ( typeof map === 'string' ) map = JSON.parse(map); |
38 | | - if ( map && map.mappings ) opts.map.prev = map; |
| 6 | +var PostCSSLoaderError = require('./error'); |
39 | 7 |
|
40 | | - var options = params.plugins || this.options.postcss; |
| 8 | +function parseOptions(options, pack) { |
41 | 9 | if ( typeof options === 'function' ) { |
42 | 10 | options = options.call(this, this); |
43 | 11 | } |
44 | 12 |
|
45 | 13 | var plugins; |
46 | | - var exec; |
47 | | - if ( typeof options === 'undefined' ) { |
| 14 | + if ( typeof options === 'undefined') { |
48 | 15 | plugins = []; |
49 | 16 | } else if ( Array.isArray(options) ) { |
50 | 17 | plugins = options; |
51 | 18 | } else { |
52 | 19 | plugins = options.plugins || options.defaults; |
53 | | - opts.stringifier = options.stringifier; |
54 | | - opts.parser = options.parser; |
55 | | - opts.syntax = options.syntax; |
56 | | - exec = options.exec; |
57 | 20 | } |
58 | | - if ( params.pack ) { |
59 | | - plugins = options[params.pack]; |
| 21 | + |
| 22 | + if ( pack ) { |
| 23 | + plugins = options[pack]; |
60 | 24 | if ( !plugins ) { |
61 | 25 | throw new Error('PostCSS plugin pack is not defined in options'); |
62 | 26 | } |
63 | 27 | } |
64 | 28 |
|
65 | | - if ( params.syntax ) { |
66 | | - opts.syntax = require(params.syntax); |
67 | | - } |
68 | | - if ( params.parser ) { |
69 | | - opts.parser = require(params.parser); |
70 | | - } |
71 | | - if ( params.stringifier ) { |
72 | | - opts.stringifier = require(params.stringifier); |
73 | | - } |
74 | | - if ( params.exec ) { |
75 | | - exec = params.exec; |
| 29 | + var opts = { }; |
| 30 | + if ( typeof options !== 'undefined' ) { |
| 31 | + opts.stringifier = options.stringifier; |
| 32 | + opts.parser = options.parser; |
| 33 | + opts.syntax = options.syntax; |
76 | 34 | } |
77 | 35 |
|
| 36 | + var exec = options && options.exec; |
| 37 | + return Promise.resolve({ options: opts, plugins: plugins, exec: exec }); |
| 38 | +} |
| 39 | + |
| 40 | +module.exports = function (source, map) { |
| 41 | + if ( this.cacheable ) this.cacheable(); |
| 42 | + |
| 43 | + var file = this.resourcePath; |
| 44 | + var params = loaderUtils.parseQuery(this.query); |
| 45 | + |
| 46 | + var options = params.plugins || this.options.postcss; |
| 47 | + var pack = params.pack; |
78 | 48 | var loader = this; |
79 | 49 | var callback = this.async(); |
80 | 50 |
|
81 | | - if ( params.parser === 'postcss-js' || exec ) { |
82 | | - source = this.exec(source, this.resource); |
83 | | - } |
| 51 | + Promise.resolve().then(function () { |
| 52 | + if ( typeof options !== 'undefined' ) { |
| 53 | + return parseOptions(options, pack); |
| 54 | + } else { |
| 55 | + if ( pack ) { |
| 56 | + throw new Error('PostCSS plugin pack is supported ' + |
| 57 | + 'only when config is passed explicitly'); |
| 58 | + } |
| 59 | + return loadConfig(pack); |
| 60 | + } |
| 61 | + }).then(function (config) { |
| 62 | + var plugins = config.plugins; |
84 | 63 |
|
85 | | - // Allow plugins to add or remove postcss plugins |
86 | | - if ( this._compilation ) { |
87 | | - plugins = this._compilation.applyPluginsWaterfall( |
88 | | - 'postcss-loader-before-processing', |
89 | | - [].concat(plugins), |
90 | | - params |
91 | | - ); |
92 | | - } else { |
93 | | - loader.emitWarning( |
94 | | - 'this._compilation is not available thus ' + |
95 | | - '`postcss-loader-before-processing` is not supported' |
96 | | - ); |
97 | | - } |
| 64 | + var opts = assign({}, config.options, { |
| 65 | + from: file, |
| 66 | + to: file, |
| 67 | + map: { |
| 68 | + inline: params.sourceMap === 'inline', |
| 69 | + annotation: false |
| 70 | + } |
| 71 | + }); |
98 | 72 |
|
99 | | - postcss(plugins).process(source, opts) |
100 | | - .then(function (result) { |
| 73 | + if ( typeof map === 'string' ) map = JSON.parse(map); |
| 74 | + if ( map && map.mappings ) opts.map.prev = map; |
| 75 | + |
| 76 | + if ( params.syntax ) { |
| 77 | + opts.syntax = require(params.syntax); |
| 78 | + } |
| 79 | + if ( params.parser ) { |
| 80 | + opts.parser = require(params.parser); |
| 81 | + } |
| 82 | + if ( params.stringifier ) { |
| 83 | + opts.stringifier = require(params.stringifier); |
| 84 | + } |
| 85 | + |
| 86 | + var exec = params.exec || config.exec; |
| 87 | + if ( params.parser === 'postcss-js' || exec ) { |
| 88 | + source = loader.exec(source, loader.resource); |
| 89 | + } |
| 90 | + |
| 91 | + // Allow plugins to add or remove postcss plugins |
| 92 | + if ( loader._compilation ) { |
| 93 | + plugins = loader._compilation.applyPluginsWaterfall( |
| 94 | + 'postcss-loader-before-processing', |
| 95 | + [].concat(plugins), |
| 96 | + params |
| 97 | + ); |
| 98 | + } else { |
| 99 | + loader.emitWarning( |
| 100 | + 'this._compilation is not available thus ' + |
| 101 | + '`postcss-loader-before-processing` is not supported' |
| 102 | + ); |
| 103 | + } |
| 104 | + |
| 105 | + return postcss(plugins).process(source, opts).then(function (result) { |
101 | 106 | result.warnings().forEach(function (msg) { |
102 | 107 | loader.emitWarning(msg.toString()); |
103 | 108 | }); |
104 | | - callback(null, result.css, result.map ? result.map.toJSON() : null); |
| 109 | + |
| 110 | + var resultMap = result.map ? result.map.toJSON() : null; |
| 111 | + callback(null, result.css, resultMap); |
105 | 112 | return null; |
106 | | - }) |
107 | | - .catch(function (error) { |
108 | | - if ( error.name === 'CssSyntaxError' ) { |
109 | | - callback(new PostCSSLoaderError(error)); |
110 | | - } else { |
111 | | - callback(error); |
112 | | - } |
113 | 113 | }); |
| 114 | + }).catch(function (error) { |
| 115 | + if ( error.name === 'CssSyntaxError' ) { |
| 116 | + callback(new PostCSSLoaderError(error)); |
| 117 | + } else { |
| 118 | + callback(error); |
| 119 | + } |
| 120 | + }); |
114 | 121 | }; |
0 commit comments