-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
73 lines (63 loc) · 2.01 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
const path = require('path');
const fs = require('fs');
const { JSDOM } = require('jsdom');
const webpack = require('webpack');
const MemoryFS = require('memory-fs');
async function build(input, output) {
const fs = new MemoryFS();
const compiler = webpack({
mode: 'development',
entry: { bundle: input },
output: {
path: output,
},
});
compiler.outputFileSystem = fs;
return new Promise((resolve, reject) => {
compiler.run((err, stats) => {
if (err) {
reject();
}
const content = fs.readFileSync(path.resolve(output, 'bundle.js'), 'utf8');
resolve(content);
});
});
}
function writeFile(file, data) {
return new Promise((resolve, reject) => {
fs.writeFile(file, data, (err) => {
if (err) reject(err);
resolve();
});
});
}
function removeHash(css, replacement) {
return css.replace(/(css-).*?(-)/gm, replacement ? `${replacement}-` : '');
}
function runBrowser(code) {
const dom = new JSDOM(``, { runScripts: 'dangerously' });
Object.defineProperty(dom.window.URL, 'createObjectURL', { value: (x) => x, configurable: true });
const scriptEl = dom.window.document.createElement('script');
scriptEl.textContent = code;
dom.window.document.body.appendChild(scriptEl);
const styles = Object.values(
dom.window.document.querySelectorAll('[data-emotion]') || {},
).map((element) => element.sheet.cssRules.map((rules) => rules.cssText));
const stylesList = styles.reduce(
(memo, list) => [...memo, ...list.reduce((memo, rule) => [...memo, rule], [])],
[],
);
return stylesList.join('');
}
async function extractEmotion(options) {
const { inputFile, output, filename = 'styles.css', prefix } = options;
const fileSource = await build(inputFile, output);
const extractedCSS = runBrowser(fileSource);
const pruned = removeHash(extractedCSS, prefix);
if (!fs.existsSync(output)) {
fs.mkdirSync(output);
}
await writeFile(path.resolve(output, filename), pruned);
return pruned;
}
module.exports = extractEmotion;