source: frontend/node_modules/cssnano/src/index.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 4.3 KB
Line 
1'use strict';
2const path = require('path');
3/** @type {any} */
4const postcss = require('postcss');
5const yaml = require('yaml');
6const { lilconfigSync } = require('lilconfig');
7
8const cssnano = 'cssnano';
9
10/** @typedef {{preset?: any, plugins?: any[], configFile?: string}} Options */
11/**
12 * @param {string} moduleId
13 * @returns {boolean}
14 */
15function isResolvable(moduleId) {
16 try {
17 require.resolve(moduleId);
18 return true;
19 } catch (e) {
20 return false;
21 }
22}
23
24/**
25 * preset can be one of four possibilities:
26 * preset = 'default'
27 * preset = ['default', {}]
28 * preset = function <- to be invoked
29 * preset = {plugins: []} <- already invoked function
30 *
31 * @param {any} preset
32 * @return {[import('postcss').PluginCreator<any>, boolean | Record<string, any> | undefined][]}}
33 */
34function resolvePreset(preset) {
35 let fn, options;
36
37 if (Array.isArray(preset)) {
38 fn = preset[0];
39 options = preset[1];
40 } else {
41 fn = preset;
42 options = {};
43 }
44
45 // For JS setups where we invoked the preset already
46 if (preset.plugins) {
47 return preset.plugins;
48 }
49
50 // Provide an alias for the default preset, as it is built-in.
51 if (fn === 'default') {
52 return require('cssnano-preset-default')(options).plugins;
53 }
54
55 // For non-JS setups; we'll need to invoke the preset ourselves.
56 if (typeof fn === 'function') {
57 return fn(options).plugins;
58 }
59
60 // Try loading a preset from node_modules
61 if (isResolvable(fn)) {
62 return require(fn)(options).plugins;
63 }
64
65 const sugar = `cssnano-preset-${fn}`;
66
67 // Try loading a preset from node_modules (sugar)
68 if (isResolvable(sugar)) {
69 return require(sugar)(options).plugins;
70 }
71
72 // If all else fails, we probably have a typo in the config somewhere
73 throw new Error(
74 `Cannot load preset "${fn}". Please check your configuration for errors and try again.`
75 );
76}
77
78/**
79 * cssnano will look for configuration firstly as options passed
80 * directly to it, and failing this it will use lilconfig to
81 * load an external file.
82
83 * @param {Options} options
84 */
85function resolveConfig(options) {
86 if (options.preset) {
87 return resolvePreset(options.preset);
88 }
89
90 /** @type {string | undefined} */
91 let searchPath = process.cwd();
92 let configPath = undefined;
93
94 if (options.configFile) {
95 searchPath = undefined;
96 configPath = path.resolve(process.cwd(), options.configFile);
97 }
98
99 const configExplorer = lilconfigSync(cssnano, {
100 searchPlaces: [
101 'package.json',
102 '.cssnanorc',
103 '.cssnanorc.json',
104 '.cssnanorc.yaml',
105 '.cssnanorc.yml',
106 '.cssnanorc.js',
107 'cssnano.config.js',
108 ],
109 loaders: {
110 '.yaml': (filepath, content) => yaml.parse(content),
111 '.yml': (filepath, content) => yaml.parse(content),
112 },
113 });
114 const config = configPath
115 ? configExplorer.load(configPath)
116 : configExplorer.search(searchPath);
117
118 if (config === null) {
119 return resolvePreset('default');
120 }
121
122 return resolvePreset(config.config.preset || config.config);
123}
124
125/**
126 * @type {import('postcss').PluginCreator<Options>}
127 * @param {Options=} options
128 * @return {import('postcss').Processor}
129 */
130function cssnanoPlugin(options = {}) {
131 if (Array.isArray(options.plugins)) {
132 if (!options.preset || !options.preset.plugins) {
133 options.preset = { plugins: [] };
134 }
135
136 options.plugins.forEach((plugin) => {
137 if (Array.isArray(plugin)) {
138 const [pluginDef, opts = {}] = plugin;
139 if (typeof pluginDef === 'string' && isResolvable(pluginDef)) {
140 options.preset.plugins.push([require(pluginDef), opts]);
141 } else {
142 options.preset.plugins.push([pluginDef, opts]);
143 }
144 } else if (typeof plugin === 'string' && isResolvable(plugin)) {
145 options.preset.plugins.push([require(plugin), {}]);
146 } else {
147 options.preset.plugins.push([plugin, {}]);
148 }
149 });
150 }
151 const plugins = [];
152 const nanoPlugins = resolveConfig(options);
153 for (const nanoPlugin of nanoPlugins) {
154 if (Array.isArray(nanoPlugin)) {
155 const [processor, opts] = nanoPlugin;
156 if (
157 typeof opts === 'undefined' ||
158 (typeof opts === 'object' && !opts.exclude) ||
159 (typeof opts === 'boolean' && opts === true)
160 ) {
161 plugins.push(processor(opts));
162 }
163 } else {
164 plugins.push(nanoPlugin);
165 }
166 }
167 return postcss(plugins);
168}
169
170cssnanoPlugin.postcss = true;
171module.exports = cssnanoPlugin;
Note: See TracBrowser for help on using the repository browser.