summaryrefslogtreecommitdiff
path: root/node_modules/cssnano/src/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/cssnano/src/index.js')
-rw-r--r--node_modules/cssnano/src/index.js164
1 files changed, 164 insertions, 0 deletions
diff --git a/node_modules/cssnano/src/index.js b/node_modules/cssnano/src/index.js
new file mode 100644
index 00000000..50fb2148
--- /dev/null
+++ b/node_modules/cssnano/src/index.js
@@ -0,0 +1,164 @@
+'use strict';
+const path = require('path');
+/** @type {any} */
+const postcss = require('postcss');
+const { lilconfigSync } = require('lilconfig');
+
+const cssnano = 'cssnano';
+
+/** @typedef {{preset?: any, plugins?: any[], configFile?: string}} Options */
+/**
+ * @param {string} moduleId
+ * @returns {boolean}
+ */
+function isResolvable(moduleId) {
+ try {
+ require.resolve(moduleId);
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
+
+/**
+ * preset can be one of four possibilities:
+ * preset = 'default'
+ * preset = ['default', {}]
+ * preset = function <- to be invoked
+ * preset = {plugins: []} <- already invoked function
+ *
+ * @param {any} preset
+ * @return {[import('postcss').PluginCreator<any>, boolean | Record<string, any> | undefined][]}}
+ */
+function resolvePreset(preset) {
+ let fn, options;
+
+ if (Array.isArray(preset)) {
+ fn = preset[0];
+ options = preset[1];
+ } else {
+ fn = preset;
+ options = {};
+ }
+
+ // For JS setups where we invoked the preset already
+ if (preset.plugins) {
+ return preset.plugins;
+ }
+
+ // Provide an alias for the default preset, as it is built-in.
+ if (fn === 'default') {
+ return require('cssnano-preset-default')(options).plugins;
+ }
+
+ // For non-JS setups; we'll need to invoke the preset ourselves.
+ if (typeof fn === 'function') {
+ return fn(options).plugins;
+ }
+
+ // Try loading a preset from node_modules
+ if (isResolvable(fn)) {
+ return require(fn)(options).plugins;
+ }
+
+ const sugar = `cssnano-preset-${fn}`;
+
+ // Try loading a preset from node_modules (sugar)
+ if (isResolvable(sugar)) {
+ return require(sugar)(options).plugins;
+ }
+
+ // If all else fails, we probably have a typo in the config somewhere
+ throw new Error(
+ `Cannot load preset "${fn}". Please check your configuration for errors and try again.`
+ );
+}
+
+/**
+ * cssnano will look for configuration firstly as options passed
+ * directly to it, and failing this it will use lilconfig to
+ * load an external file.
+
+ * @param {Options} options
+ */
+function resolveConfig(options) {
+ if (options.preset) {
+ return resolvePreset(options.preset);
+ }
+
+ /** @type {string | undefined} */
+ let searchPath = process.cwd();
+ let configPath = undefined;
+
+ if (options.configFile) {
+ searchPath = undefined;
+ configPath = path.resolve(process.cwd(), options.configFile);
+ }
+
+ const configExplorer = lilconfigSync(cssnano, {
+ searchPlaces: [
+ 'package.json',
+ '.cssnanorc',
+ '.cssnanorc.json',
+ '.cssnanorc.js',
+ 'cssnano.config.js',
+ ],
+ });
+ const config = configPath
+ ? configExplorer.load(configPath)
+ : configExplorer.search(searchPath);
+
+ if (config === null) {
+ return resolvePreset('default');
+ }
+
+ return resolvePreset(config.config.preset || config.config);
+}
+
+/**
+ * @type {import('postcss').PluginCreator<Options>}
+ * @param {Options=} options
+ * @return {import('postcss').Processor}
+ */
+function cssnanoPlugin(options = {}) {
+ if (Array.isArray(options.plugins)) {
+ if (!options.preset || !options.preset.plugins) {
+ options.preset = { plugins: [] };
+ }
+
+ options.plugins.forEach((plugin) => {
+ if (Array.isArray(plugin)) {
+ const [pluginDef, opts = {}] = plugin;
+ if (typeof pluginDef === 'string' && isResolvable(pluginDef)) {
+ options.preset.plugins.push([require(pluginDef), opts]);
+ } else {
+ options.preset.plugins.push([pluginDef, opts]);
+ }
+ } else if (typeof plugin === 'string' && isResolvable(plugin)) {
+ options.preset.plugins.push([require(plugin), {}]);
+ } else {
+ options.preset.plugins.push([plugin, {}]);
+ }
+ });
+ }
+ const plugins = [];
+ const nanoPlugins = resolveConfig(options);
+ for (const nanoPlugin of nanoPlugins) {
+ if (Array.isArray(nanoPlugin)) {
+ const [processor, opts] = nanoPlugin;
+ if (
+ typeof opts === 'undefined' ||
+ (typeof opts === 'object' && !opts.exclude) ||
+ (typeof opts === 'boolean' && opts === true)
+ ) {
+ plugins.push(processor(opts));
+ }
+ } else {
+ plugins.push(nanoPlugin);
+ }
+ }
+ return postcss(plugins);
+}
+
+cssnanoPlugin.postcss = true;
+module.exports = cssnanoPlugin;