Passed
Pull Request — master (#11)
by
unknown
04:39
created

index.ts ➔ PluginCritical   D

Complexity

Conditions 13

Size

Total Lines 56
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 50
CRAP Score 13.2076

Importance

Changes 0
Metric Value
eloc 41
dl 0
loc 56
ccs 50
cts 56
cp 0.8929
rs 4.2
c 0
b 0
f 0
cc 13
crap 13.2076

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like index.ts ➔ PluginCritical often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1 1
import {Plugin} from 'rollup';
2 1
import * as path from 'path';
3 1
4 1
const criticalSuffix = '_critical.min.css';
5 1
6 1
/**
7 1
 * Default `criticalConfig` passed in to `critical`
8 1
 */
9 1
const defaultCriticalConfig: Partial<CriticalConfig> = {
10 1
  inline: false,
11 1
  extract: false,
12 1
  width: 1200,
13 1
  height: 1200,
14 1
  penthouse: {
15 1
    blockJSRequests: false
16 1
  }
17 1
};
18 1
19 1
/**
20 1
 * [Vite.js](https://vitejs.dev/) & [Rollup](https://rollupjs.org/) plugin for generating critical CSS
21 1
 * that uses the [critical](https://github.com/addyosmani/critical) generator under the hood.
22 1
 *
23 1
 * @param {CriticalPluginConfig} pluginConfig - the plugin configuration object
24 1
 * @param {Function} callback - callback upon completion of the critical CSS generation
25 1
 * @constructor
26 1
 */
27 2
function PluginCritical(pluginConfig: CriticalPluginConfig, callback?: CriticalPluginCallback): Plugin {
28 2
  return {
29 2
    name: 'critical',
30 2
    async writeBundle(outputOptions, bundle) {
31 2
      const css: Array<string> = [];
32 2
      // Find all of the generated CSS assets
33 2
      for (const chunk of Object.values(bundle)) {
34 2
        if (chunk.type === 'asset' && chunk.fileName.endsWith('.css')) {
35 2
          const cssFile = path.join(outputOptions.dir || '', chunk.fileName);
36 2
          css.push(cssFile);
37 2
        }
38 2
      }
39 2
      // If we have no CSS, skip bundle
40 2
      if (!css.length) {
41
        return;
42
      }
43
      // Iterate through the pages
44 2
      const sites = Array.isArray(pluginConfig.criticalUrl) ? pluginConfig.criticalUrl : [{ url: pluginConfig.criticalUrl, id: "" }];
45 2
      for (const {url, id = ""} of sites) {
46 2
        if (!url) throw new Error("Configuration is missing a criticalUrl property.");
47 2
        for (const page of pluginConfig.criticalPages) {
48 2
          const criticalBase = pluginConfig.criticalBase;
49 2
          const criticalSrc = url + page.uri;
50 2
          // If inline is set to true, use HTML as target, otherwise CSS with suffix
51 3
          const criticalTarget = (pluginConfig.criticalConfig && pluginConfig.criticalConfig.inline == true) ? page.template + ".html" : page.template + (id ? "_" + id : "") + criticalSuffix;
52 2
          // Merge in our options
53 2
          const options = Object.assign(
54 2
            { css },
55 2
            defaultCriticalConfig,
56 2
            {
57 2
              base: criticalBase,
58 2
              src: criticalSrc,
59 2
              target: criticalTarget,
60 2
            },
61 2
            pluginConfig.criticalConfig
62 2
          );
63 2
          // Horrible nonsense to import an ESM module into CJS
64 2
          // ref: https://adamcoster.com/blog/commonjs-and-esm-importexport-compatibility-examples
65 2
          const generate = (await import('critical')).generate;
66 2
          // Generate the Critical CSS
67 2
          console.log(`Generating critical CSS from ${criticalSrc} to ${criticalTarget}`);
68 2
          await generate(options, (err: string) => {
69 2
            if (err) {
70
              console.error(err);
71
            }
72 2
            if (callback) {
73
              callback(err);
74
            }
75 2
          });
76 2
        }
77 2
      }
78 2
    }
79 2
  }
80 2
}
81 2
82
export default PluginCritical;
83