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

src/index.ts   A

Complexity

Total Complexity 13
Complexity/F 6.5

Size

Lines of Code 83
Function Count 2

Duplication

Duplicated Lines 0
Ratio 0 %

Test Coverage

Coverage 91.46%

Importance

Changes 0
Metric Value
wmc 13
eloc 55
mnd 11
bc 11
fnc 2
dl 0
loc 83
ccs 75
cts 82
cp 0.9146
rs 10
bpm 5.5
cpm 6.5
noi 0
c 0
b 0
f 0

1 Function

Rating   Name   Duplication   Size   Complexity  
D index.ts ➔ PluginCritical 0 56 13
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