-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathdist.js
executable file
·107 lines (90 loc) · 3.37 KB
/
dist.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
#!/usr/bin/env node
import {globby} from 'globby'
import compiler from './primer-css-compiler.js'
import cssstats from 'cssstats'
import {dirname, join} from 'path'
import analyzeVariables from './analyze-variables.js'
import fsExtra from 'fs-extra'
const {copy, remove, mkdirp, readFile, writeFile} = fsExtra
const inDir = 'src'
const outDir = 'dist'
const statsDir = join(outDir, 'stats')
const encoding = 'utf8'
// Bundle paths are normalized in getPathName() using dirname() and then
// replacing any slashes with hyphens, but some bundles need to be
// special-cased. Keys in this object are the path minus the "src/" prefix,
// and values are the bundle file base name. ("primer" produces
// "dist/primer.css", etc.)
const bundleNames = {
'index.scss': 'primer'
}
async function dist() {
try {
const bundles = {}
await remove(outDir)
await mkdirp(statsDir)
const files = await globby([`${inDir}/**/index.scss`])
const inPattern = new RegExp(`^${inDir}/`)
const tasks = files.map(async from => {
const path = from.replace(inPattern, '')
const name = bundleNames[path] || getPathName(dirname(path))
const to = join(outDir, `${name}.css`)
const meta = {
name,
source: from,
sass: `@primer/css/${path}`,
css: to,
map: `${to}.map`,
js: join(outDir, `${name}.js`),
stats: join(statsDir, `${name}.json`),
legacy: `primer-${name}/index.scss`
}
const scss = await readFile(from, encoding)
meta.imports = getExternalImports(scss, path).map(getPathName)
const result = await compiler(scss, {from, to})
const warnings = result.warnings()
// We don't want to release changes that cause warnings with postcss. Fail the dist build if any warnings are detected.
if (warnings.length) {
for (const warning of warnings) {
console.warn(warning.toString())
}
throw new Error(`Warnings while compiling ${from}. See output above.`)
}
await Promise.all([
writeFile(to, result.css, encoding),
writeFile(meta.stats, JSON.stringify(cssstats(result.css)), encoding),
writeFile(meta.js, `export {cssstats: require('./stats/${name}.json')}`, encoding),
result.map ? writeFile(meta.map, result.map.toString(), encoding) : null
])
bundles[name] = meta
})
await Promise.all(tasks)
const meta = {bundles}
await writeFile(join(outDir, 'meta.json'), JSON.stringify(meta, null, 2), encoding)
await writeVariableData()
await copy(join(inDir, 'deprecations.json'), join(outDir, 'deprecations.json'))
} catch (error) {
console.error(error)
process.exitCode = 1
}
}
function getExternalImports(scss, relativeTo) {
const imports = []
const dir = dirname(relativeTo)
// XXX: this might *seem* fragile, but since we enforce double quotes via
// stylelint, I think it's kosher.
scss.replace(/@import "(.+)\/index\.scss";/g, (_, dep) => {
imports.push(join(dir, dep))
})
return imports
}
function getPathName(path) {
return path.replace(/\//g, '-')
}
dist()
async function writeVariableData() {
const support = await analyzeVariables('src/support/index.scss')
const marketing = await analyzeVariables('src/marketing/support/index.scss')
const data = Object.assign({}, support, marketing)
writeFile(join(outDir, 'variables.json'), JSON.stringify(data, null, 2))
}