-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
107 lines (91 loc) · 2.98 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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
const beginAt = Date.now();
const path = require("path");
const fs = require("fs");
const src = path.resolve(__dirname, "../../..", "src");
const { dependencies } = require(`${src}/../package.json`);
const styles = Object.keys(dependencies).reduce((acc, dependency) => {
if (!/^@fortawesome.*svg-icons$/.test(dependency)) return acc;
const [, license, name] = dependency.match(
/^@fortawesome\/([a-z]+)-([a-z]+)-svg-icons$/
);
return { ...acc, [`fa${name[0]}`]: { name, license, icons: new Map() } };
}, {});
const outputFolder = `${src}/plugins`;
const outputFile = `${outputFolder}/fontawesome-autoimport.js`;
const {
pattern = `\[['"](fa[a-z])['"], *['"]([a-z0-9-]+)['"]\]`
} = process.env;
const faRegex = new RegExp(pattern, "g");
const fileRegex = new RegExp(/\.(vue|js)$/);
const setIcons = file =>
[
...fs
.readFileSync(file)
.toString()
.matchAll(faRegex)
].forEach(([, style, name]) =>
styles[style]
? styles[style].icons.set(name)
: console.warn(`! Unknown icon: ${style}-${name} (in ${file})`)
);
const parse = path =>
fs.readdirSync(path).forEach(entry => {
const entryPath = `${path}/${entry}`;
fs.lstatSync(entryPath).isDirectory()
? parse(entryPath)
: fileRegex.test(entry) && setIcons(entryPath);
});
const pascalCase = str =>
str
.split("-")
.reduce(
(acc, str) => `${acc}${str[0].toUpperCase() + str.substring(1)}`,
""
);
const generate = () => {
const consolidatedIcons = [];
let output = Object.entries(styles).reduce(
(acc, [style, { name, license, icons }]) =>
icons.size
? `${acc}\n// ${style}\nimport {${[...icons.keys()]
.sort()
.reduce((acc, icon) => {
const pascalIcon = pascalCase(icon);
consolidatedIcons.push(`${style}${pascalIcon}`);
return `${acc}\n fa${pascalIcon} as ${style}${pascalIcon},`;
}, "")}\n} from "@fortawesome/${license}-${name}-svg-icons";\n`
: acc,
"// Auto generated by fontawesome-autoimport\n"
);
output += `\nimport { library } from "@fortawesome/fontawesome-svg-core";\n`;
output += `library.add(\n ${consolidatedIcons.join(",\n ")}\n);\n`;
// Update the output file only if necessary
const prevConsolidatedIcons = [
...new Set(
[
...(fs.existsSync(outputFile) && fs.readFileSync(outputFile))
.toString()
.matchAll(/fa[a-z][A-Z]\w+/g)
].map(([icon]) => icon)
)
].sort();
if (
JSON.stringify(prevConsolidatedIcons) === JSON.stringify(consolidatedIcons)
)
return console.log(
`- Fontawesome treeshaking list already up-to-date. (took ${Date.now() -
beginAt} ms)`
);
fs.mkdir(outputFolder, { recursive: true }, err => {
if (err) throw err;
fs.writeFile(outputFile, output, err =>
console.log(
err ||
`- Fontawesome treeshaking list generated. (took ${Date.now() -
beginAt} ms)`
)
);
});
};
parse(src);
generate();