You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
5.4 KiB
198 lines
5.4 KiB
"use strict"; |
|
|
|
Object.defineProperty(exports, "__esModule", { |
|
value: true |
|
}); |
|
exports.default = loader; |
|
|
|
var _path = _interopRequireDefault(require("path")); |
|
|
|
var _semver = require("semver"); |
|
|
|
var _package = _interopRequireDefault(require("postcss/package.json")); |
|
|
|
var _Warning = _interopRequireDefault(require("./Warning")); |
|
|
|
var _Error = _interopRequireDefault(require("./Error")); |
|
|
|
var _options = _interopRequireDefault(require("./options.json")); |
|
|
|
var _utils = require("./utils"); |
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
|
|
|
let hasExplicitDependencyOnPostCSS = false; |
|
/** |
|
* **PostCSS Loader** |
|
* |
|
* Loads && processes CSS with [PostCSS](https://github.com/postcss/postcss) |
|
* |
|
* @method loader |
|
* |
|
* @param {String} content Source |
|
* @param {Object} sourceMap Source Map |
|
* @param {Object} meta Meta |
|
* |
|
* @return {callback} callback Result |
|
*/ |
|
|
|
async function loader(content, sourceMap, meta) { |
|
const options = this.getOptions(_options.default); |
|
const callback = this.async(); |
|
const configOption = typeof options.postcssOptions === "undefined" || typeof options.postcssOptions.config === "undefined" ? true : options.postcssOptions.config; |
|
const postcssFactory = (0, _utils.getPostcssImplementation)(this, options.implementation); |
|
|
|
if (!postcssFactory) { |
|
callback(new Error(`The Postcss implementation "${options.implementation}" not found`)); |
|
return; |
|
} |
|
|
|
let loadedConfig; |
|
|
|
if (configOption) { |
|
try { |
|
loadedConfig = await (0, _utils.loadConfig)(this, configOption, options.postcssOptions); |
|
} catch (error) { |
|
callback(error); |
|
return; |
|
} |
|
} |
|
|
|
const useSourceMap = typeof options.sourceMap !== "undefined" ? options.sourceMap : this.sourceMap; |
|
const { |
|
plugins, |
|
processOptions |
|
} = await (0, _utils.getPostcssOptions)(this, loadedConfig, options.postcssOptions); |
|
|
|
if (useSourceMap) { |
|
processOptions.map = { |
|
inline: false, |
|
annotation: false, |
|
...processOptions.map |
|
}; |
|
} |
|
|
|
if (sourceMap && processOptions.map) { |
|
processOptions.map.prev = (0, _utils.normalizeSourceMap)(sourceMap, this.context); |
|
} |
|
|
|
let root; // Reuse PostCSS AST from other loaders |
|
|
|
if (meta && meta.ast && meta.ast.type === "postcss" && (0, _semver.satisfies)(meta.ast.version, `^${_package.default.version}`)) { |
|
({ |
|
root |
|
} = meta.ast); |
|
} |
|
|
|
if (!root && options.execute) { |
|
// eslint-disable-next-line no-param-reassign |
|
content = (0, _utils.exec)(content, this); |
|
} |
|
|
|
let result; |
|
let processor; |
|
|
|
try { |
|
processor = postcssFactory(plugins); |
|
result = await processor.process(root || content, processOptions); |
|
} catch (error) { |
|
// Check postcss versions to avoid using PostCSS 7. |
|
// For caching reasons, we use the readFileSync and existsSync functions from the context, |
|
// not the functions from the `fs` module. |
|
if (!hasExplicitDependencyOnPostCSS && processor && processor.version && processor.version.startsWith("7.")) { |
|
// The `findPackageJsonDir` function returns `string` or `null`. |
|
// This is used to do for caching, that is, an explicit comparison with `undefined` |
|
// is used to make the condition body run once. |
|
const packageJSONDir = (0, _utils.findPackageJSONDir)(process.cwd(), this.fs.statSync); |
|
|
|
if (packageJSONDir) { |
|
let bufferOfPackageJSON; |
|
|
|
try { |
|
bufferOfPackageJSON = this.fs.readFileSync(_path.default.resolve(packageJSONDir, "package.json"), "utf8"); |
|
} catch (_error) {// Nothing |
|
} |
|
|
|
if (bufferOfPackageJSON) { |
|
let pkg; |
|
|
|
try { |
|
pkg = JSON.parse(bufferOfPackageJSON); |
|
} catch (_error) {// Nothing |
|
} |
|
|
|
if (pkg) { |
|
if (!pkg.dependencies.postcss && !pkg.devDependencies.postcss) { |
|
this.emitWarning(new Error("Add postcss as project dependency. postcss is not a peer dependency for postcss-loader. " + "Use `npm install postcss` or `yarn add postcss`")); |
|
} else { |
|
hasExplicitDependencyOnPostCSS = true; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
if (error.file) { |
|
this.addDependency(error.file); |
|
} |
|
|
|
if (error.name === "CssSyntaxError") { |
|
callback(new _Error.default(error)); |
|
} else { |
|
callback(error); |
|
} |
|
|
|
return; |
|
} |
|
|
|
for (const warning of result.warnings()) { |
|
this.emitWarning(new _Warning.default(warning)); |
|
} |
|
|
|
for (const message of result.messages) { |
|
// eslint-disable-next-line default-case |
|
switch (message.type) { |
|
case "dependency": |
|
this.addDependency(message.file); |
|
break; |
|
|
|
case "build-dependency": |
|
this.addBuildDependency(message.file); |
|
break; |
|
|
|
case "missing-dependency": |
|
this.addMissingDependency(message.file); |
|
break; |
|
|
|
case "context-dependency": |
|
this.addContextDependency(message.file); |
|
break; |
|
|
|
case "dir-dependency": |
|
this.addContextDependency(message.dir); |
|
break; |
|
|
|
case "asset": |
|
if (message.content && message.file) { |
|
this.emitFile(message.file, message.content, message.sourceMap, message.info); |
|
} |
|
|
|
} |
|
} // eslint-disable-next-line no-undefined |
|
|
|
|
|
let map = result.map ? result.map.toJSON() : undefined; |
|
|
|
if (map && useSourceMap) { |
|
map = (0, _utils.normalizeSourceMapAfterPostcss)(map, this.context); |
|
} |
|
|
|
const ast = { |
|
type: "postcss", |
|
version: result.processor.version, |
|
root: result.root |
|
}; |
|
callback(null, result.css, map, { |
|
ast |
|
}); |
|
} |