-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.js
139 lines (115 loc) · 4.44 KB
/
build.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
const fs = require('fs').promises
const camelcase = require('camelcase')
const { promisify } = require('util')
const rimraf = promisify(require('rimraf'))
const svgr = require('@svgr/core').default
const babel = require('@babel/core')
const { compile: compileVue } = require('@vue/compiler-dom')
const { dirname } = require('path')
let transform = {
react: async (svg, componentName, format) => {
let component = await svgr(svg, { ref: true, titleProp: true }, { componentName })
let { code } = await babel.transformAsync(component, {
plugins: [[require('@babel/plugin-transform-react-jsx'), { useBuiltIns: true }]],
})
if (format === 'esm') {
return code
}
return code
.replace('import * as React from "react"', 'const React = require("react")')
.replace('export default', 'module.exports =')
},
vue: (svg, componentName, format) => {
let { code } = compileVue(svg, {
mode: 'module',
})
if (format === 'esm') {
return code.replace('export function', 'export default function')
}
return code
.replace(
/import\s+\{\s*([^}]+)\s*\}\s+from\s+(['"])(.*?)\2/,
(_match, imports, _quote, mod) => {
let newImports = imports
.split(',')
.map((i) => i.trim().replace(/\s+as\s+/, ': '))
.join(', ')
return `const { ${newImports} } = require("${mod}")`
}
)
.replace('export function render', 'module.exports = function render')
},
}
async function getIcons(style) {
let files = await fs.readdir(`./src/${style}`)
return Promise.all(
files.map(async (file) => ({
svg: await fs.readFile(`./src/${style}/${file}`, 'utf8'),
componentName: `${camelcase(file.replace(/\.svg$/, ''), {
pascalCase: true,
})}Icon`,
}))
)
}
function exportAll(icons, format, includeExtension = true) {
return icons
.map(({ componentName }) => {
let extension = includeExtension ? '.js' : ''
if (format === 'esm') {
return `export { default as ${componentName} } from './${componentName}${extension}'`
}
return `module.exports.${componentName} = require("./${componentName}${extension}")`
})
.join('\n')
}
async function ensureWrite(file, text) {
await fs.mkdir(dirname(file), { recursive: true })
await fs.writeFile(file, text, 'utf8')
}
async function ensureWriteJson(file, json) {
await ensureWrite(file, JSON.stringify(json, null, 2))
}
async function buildIcons(package, style, format) {
let outDir = `./${package}/${style}`
if (format === 'esm') {
outDir += '/esm'
}
let icons = await getIcons(style)
await Promise.all(
icons.flatMap(async ({ componentName, svg }) => {
let content = await transform[package](svg, componentName, format)
let types =
package === 'react'
? `import * as React from 'react';\ndeclare function ${componentName}(props: React.ComponentProps<'svg'>): JSX.Element;\nexport default ${componentName};\n`
: `import type { FunctionalComponent, HTMLAttributes, VNodeProps } from 'vue';\ndeclare const ${componentName}: FunctionalComponent<HTMLAttributes & VNodeProps>;\nexport default ${componentName};\n`
return [
ensureWrite(`${outDir}/${componentName}.js`, content),
...(types ? [ensureWrite(`${outDir}/${componentName}.d.ts`, types)] : []),
]
})
)
await ensureWrite(`${outDir}/index.js`, exportAll(icons, format))
await ensureWrite(`${outDir}/index.d.ts`, exportAll(icons, 'esm', false))
}
async function main(package) {
const cjsPackageJson = { module: './esm/index.js', sideEffects: false }
const esmPackageJson = { type: 'module', sideEffects: false }
console.log(`Building ${package} package...`)
await Promise.all([rimraf(`./${package}/jam/*`), rimraf(`./${package}/humble/*`)])
await Promise.all([
buildIcons(package, 'jam', 'cjs'),
buildIcons(package, 'jam', 'esm'),
buildIcons(package, 'humble', 'cjs'),
buildIcons(package, 'humble', 'esm'),
ensureWriteJson(`./${package}/jam/esm/package.json`, esmPackageJson),
ensureWriteJson(`./${package}/jam/package.json`, cjsPackageJson),
ensureWriteJson(`./${package}/humble/esm/package.json`, esmPackageJson),
ensureWriteJson(`./${package}/humble/package.json`, cjsPackageJson),
])
return console.log(`Finished building ${package} package.`)
}
let [package] = process.argv.slice(2)
if (!package) {
throw new Error('Please specify a package')
}
main(package)