123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.exec = exec;
- exports.findPackageJSONDir = findPackageJSONDir;
- exports.getPostcssImplementation = getPostcssImplementation;
- exports.getPostcssOptions = getPostcssOptions;
- exports.loadConfig = loadConfig;
- exports.normalizeSourceMap = normalizeSourceMap;
- exports.normalizeSourceMapAfterPostcss = normalizeSourceMapAfterPostcss;
- var _path = _interopRequireDefault(require("path"));
- var _module = _interopRequireDefault(require("module"));
- var _full = require("klona/full");
- var _cosmiconfig = require("cosmiconfig");
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
- const parentModule = module;
- const stat = (inputFileSystem, filePath) => new Promise((resolve, reject) => {
- inputFileSystem.stat(filePath, (err, stats) => {
- if (err) {
- reject(err);
- }
- resolve(stats);
- });
- });
- function exec(code, loaderContext) {
- const {
- resource,
- context
- } = loaderContext;
- const module = new _module.default(resource, parentModule); // eslint-disable-next-line no-underscore-dangle
- module.paths = _module.default._nodeModulePaths(context);
- module.filename = resource; // eslint-disable-next-line no-underscore-dangle
- module._compile(code, resource);
- return module.exports;
- }
- async function loadConfig(loaderContext, config, postcssOptions) {
- const searchPath = typeof config === "string" ? _path.default.resolve(config) : _path.default.dirname(loaderContext.resourcePath);
- let stats;
- try {
- stats = await stat(loaderContext.fs, searchPath);
- } catch (errorIgnore) {
- throw new Error(`No PostCSS config found in: ${searchPath}`);
- }
- const explorer = (0, _cosmiconfig.cosmiconfig)("postcss");
- let result;
- try {
- if (stats.isFile()) {
- result = await explorer.load(searchPath);
- } else {
- result = await explorer.search(searchPath);
- }
- } catch (error) {
- throw error;
- }
- if (!result) {
- return {};
- }
- loaderContext.addBuildDependency(result.filepath);
- loaderContext.addDependency(result.filepath);
- if (result.isEmpty) {
- return result;
- }
- if (typeof result.config === "function") {
- const api = {
- mode: loaderContext.mode,
- file: loaderContext.resourcePath,
- // For complex use
- webpackLoaderContext: loaderContext,
- // Partial compatibility with `postcss-cli`
- env: loaderContext.mode,
- options: postcssOptions || {}
- };
- result.config = result.config(api);
- }
- result = (0, _full.klona)(result);
- return result;
- }
- function loadPlugin(plugin, options, file) {
- try {
- if (!options || Object.keys(options).length === 0) {
- // eslint-disable-next-line global-require, import/no-dynamic-require
- const loadedPlugin = require(plugin);
- if (loadedPlugin.default) {
- return loadedPlugin.default;
- }
- return loadedPlugin;
- } // eslint-disable-next-line global-require, import/no-dynamic-require
- const loadedPlugin = require(plugin);
- if (loadedPlugin.default) {
- return loadedPlugin.default(options);
- }
- return loadedPlugin(options);
- } catch (error) {
- throw new Error(`Loading PostCSS "${plugin}" plugin failed: ${error.message}\n\n(@${file})`);
- }
- }
- function pluginFactory() {
- const listOfPlugins = new Map();
- return plugins => {
- if (typeof plugins === "undefined") {
- return listOfPlugins;
- }
- if (Array.isArray(plugins)) {
- for (const plugin of plugins) {
- if (Array.isArray(plugin)) {
- const [name, options] = plugin;
- listOfPlugins.set(name, options);
- } else if (plugin && typeof plugin === "function") {
- listOfPlugins.set(plugin);
- } else if (plugin && Object.keys(plugin).length === 1 && (typeof plugin[Object.keys(plugin)[0]] === "object" || typeof plugin[Object.keys(plugin)[0]] === "boolean") && plugin[Object.keys(plugin)[0]] !== null) {
- const [name] = Object.keys(plugin);
- const options = plugin[name];
- if (options === false) {
- listOfPlugins.delete(name);
- } else {
- listOfPlugins.set(name, options);
- }
- } else if (plugin) {
- listOfPlugins.set(plugin);
- }
- }
- } else {
- const objectPlugins = Object.entries(plugins);
- for (const [name, options] of objectPlugins) {
- if (options === false) {
- listOfPlugins.delete(name);
- } else {
- listOfPlugins.set(name, options);
- }
- }
- }
- return listOfPlugins;
- };
- }
- async function tryRequireThenImport(module) {
- let exports;
- try {
- // eslint-disable-next-line import/no-dynamic-require, global-require
- exports = require(module);
- return exports;
- } catch (requireError) {
- let importESM;
- try {
- // eslint-disable-next-line no-new-func
- importESM = new Function("id", "return import(id);");
- } catch (e) {
- importESM = null;
- }
- if (requireError.code === "ERR_REQUIRE_ESM" && importESM) {
- exports = await importESM(module);
- return exports.default;
- }
- throw requireError;
- }
- }
- async function getPostcssOptions(loaderContext, loadedConfig = {}, postcssOptions = {}) {
- const file = loaderContext.resourcePath;
- let normalizedPostcssOptions = postcssOptions;
- if (typeof normalizedPostcssOptions === "function") {
- normalizedPostcssOptions = normalizedPostcssOptions(loaderContext);
- }
- let plugins = [];
- try {
- const factory = pluginFactory();
- if (loadedConfig.config && loadedConfig.config.plugins) {
- factory(loadedConfig.config.plugins);
- }
- factory(normalizedPostcssOptions.plugins);
- plugins = [...factory()].map(item => {
- const [plugin, options] = item;
- if (typeof plugin === "string") {
- return loadPlugin(plugin, options, file);
- }
- return plugin;
- });
- } catch (error) {
- loaderContext.emitError(error);
- }
- const processOptionsFromConfig = loadedConfig.config || {};
- if (processOptionsFromConfig.from) {
- processOptionsFromConfig.from = _path.default.resolve(_path.default.dirname(loadedConfig.filepath), processOptionsFromConfig.from);
- }
- if (processOptionsFromConfig.to) {
- processOptionsFromConfig.to = _path.default.resolve(_path.default.dirname(loadedConfig.filepath), processOptionsFromConfig.to);
- } // No need them for processOptions
- delete processOptionsFromConfig.plugins;
- const processOptionsFromOptions = (0, _full.klona)(normalizedPostcssOptions);
- if (processOptionsFromOptions.from) {
- processOptionsFromOptions.from = _path.default.resolve(loaderContext.rootContext, processOptionsFromOptions.from);
- }
- if (processOptionsFromOptions.to) {
- processOptionsFromOptions.to = _path.default.resolve(loaderContext.rootContext, processOptionsFromOptions.to);
- } // No need them for processOptions
- delete processOptionsFromOptions.config;
- delete processOptionsFromOptions.plugins;
- const processOptions = {
- from: file,
- to: file,
- map: false,
- ...processOptionsFromConfig,
- ...processOptionsFromOptions
- };
- if (typeof processOptions.parser === "string") {
- try {
- processOptions.parser = await tryRequireThenImport(processOptions.parser);
- } catch (error) {
- loaderContext.emitError(new Error(`Loading PostCSS "${processOptions.parser}" parser failed: ${error.message}\n\n(@${file})`));
- }
- }
- if (typeof processOptions.stringifier === "string") {
- try {
- processOptions.stringifier = await tryRequireThenImport(processOptions.stringifier);
- } catch (error) {
- loaderContext.emitError(new Error(`Loading PostCSS "${processOptions.stringifier}" stringifier failed: ${error.message}\n\n(@${file})`));
- }
- }
- if (typeof processOptions.syntax === "string") {
- try {
- processOptions.syntax = await tryRequireThenImport(processOptions.syntax);
- } catch (error) {
- loaderContext.emitError(new Error(`Loading PostCSS "${processOptions.syntax}" syntax failed: ${error.message}\n\n(@${file})`));
- }
- }
- if (processOptions.map === true) {
- // https://github.com/postcss/postcss/blob/master/docs/source-maps.md
- processOptions.map = {
- inline: true
- };
- }
- return {
- plugins,
- processOptions
- };
- }
- const IS_NATIVE_WIN32_PATH = /^[a-z]:[/\\]|^\\\\/i;
- const ABSOLUTE_SCHEME = /^[a-z0-9+\-.]+:/i;
- function getURLType(source) {
- if (source[0] === "/") {
- if (source[1] === "/") {
- return "scheme-relative";
- }
- return "path-absolute";
- }
- if (IS_NATIVE_WIN32_PATH.test(source)) {
- return "path-absolute";
- }
- return ABSOLUTE_SCHEME.test(source) ? "absolute" : "path-relative";
- }
- function normalizeSourceMap(map, resourceContext) {
- let newMap = map; // Some loader emit source map as string
- // Strip any JSON XSSI avoidance prefix from the string (as documented in the source maps specification), and then parse the string as JSON.
- if (typeof newMap === "string") {
- newMap = JSON.parse(newMap);
- }
- delete newMap.file;
- const {
- sourceRoot
- } = newMap;
- delete newMap.sourceRoot;
- if (newMap.sources) {
- newMap.sources = newMap.sources.map(source => {
- const sourceType = getURLType(source); // Do no touch `scheme-relative` and `absolute` URLs
- if (sourceType === "path-relative" || sourceType === "path-absolute") {
- const absoluteSource = sourceType === "path-relative" && sourceRoot ? _path.default.resolve(sourceRoot, _path.default.normalize(source)) : _path.default.normalize(source);
- return _path.default.relative(resourceContext, absoluteSource);
- }
- return source;
- });
- }
- return newMap;
- }
- function normalizeSourceMapAfterPostcss(map, resourceContext) {
- const newMap = map; // result.map.file is an optional property that provides the output filename.
- // Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it.
- // eslint-disable-next-line no-param-reassign
- delete newMap.file; // eslint-disable-next-line no-param-reassign
- newMap.sourceRoot = ""; // eslint-disable-next-line no-param-reassign
- newMap.sources = newMap.sources.map(source => {
- if (source.indexOf("<") === 0) {
- return source;
- }
- const sourceType = getURLType(source); // Do no touch `scheme-relative`, `path-absolute` and `absolute` types
- if (sourceType === "path-relative") {
- return _path.default.resolve(resourceContext, source);
- }
- return source;
- });
- return newMap;
- }
- function findPackageJSONDir(cwd, statSync) {
- let dir = cwd;
- for (;;) {
- try {
- if (statSync(_path.default.join(dir, "package.json")).isFile()) {
- break;
- }
- } catch (error) {// Nothing
- }
- const parent = _path.default.dirname(dir);
- if (dir === parent) {
- dir = null;
- break;
- }
- dir = parent;
- }
- return dir;
- }
- function getPostcssImplementation(loaderContext, implementation) {
- let resolvedImplementation = implementation;
- if (!implementation || typeof implementation === "string") {
- const postcssImplPkg = implementation || "postcss";
- try {
- // eslint-disable-next-line import/no-dynamic-require, global-require
- resolvedImplementation = require(postcssImplPkg);
- } catch (error) {
- loaderContext.emitError(error); // eslint-disable-next-line consistent-return
- return;
- }
- } // eslint-disable-next-line consistent-return
- return resolvedImplementation;
- }
|