2019-02-12 06:49:13 +03:00
|
|
|
#!/usr/bin/env node
|
2019-09-05 22:38:06 +03:00
|
|
|
/* eslint-disable no-console */
|
2019-02-12 06:49:13 +03:00
|
|
|
const globby = require('globby')
|
|
|
|
const cssstats = require('cssstats')
|
|
|
|
const postcss = require('postcss')
|
|
|
|
const loadConfig = require('postcss-load-config')
|
2019-02-12 08:03:20 +03:00
|
|
|
const {remove, mkdirp, readFile, writeFile} = require('fs-extra')
|
2019-09-05 21:13:45 +03:00
|
|
|
const {dirname, join} = require('path')
|
2019-01-29 01:52:45 +03:00
|
|
|
|
2019-02-12 06:49:13 +03:00
|
|
|
const inDir = 'src'
|
|
|
|
const outDir = 'dist'
|
2019-02-12 08:03:20 +03:00
|
|
|
const statsDir = join(outDir, 'stats')
|
2019-02-12 08:28:25 +03:00
|
|
|
const encoding = 'utf8'
|
2019-01-29 01:52:45 +03:00
|
|
|
|
2019-02-12 21:30:54 +03:00
|
|
|
// 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'
|
|
|
|
}
|
|
|
|
|
2019-10-21 23:24:26 +03:00
|
|
|
async function dist() {
|
|
|
|
try {
|
|
|
|
const bundles = {}
|
|
|
|
const {plugins, options} = await loadConfig()
|
|
|
|
const processor = postcss(plugins)
|
2019-02-12 09:33:03 +03:00
|
|
|
|
2019-10-21 23:24:26 +03:00
|
|
|
await remove(outDir)
|
|
|
|
await mkdirp(statsDir)
|
|
|
|
const files = await globby([`${inDir}/**/index.scss`])
|
2019-02-12 09:33:03 +03:00
|
|
|
|
2019-10-21 23:24:26 +03:00
|
|
|
const inPattern = new RegExp(`^${inDir}/`)
|
|
|
|
const tasks = files.map(async from => {
|
|
|
|
const path = from.replace(inPattern, '')
|
|
|
|
const name = bundleNames[path] || getPathName(dirname(path))
|
2019-02-12 08:03:20 +03:00
|
|
|
|
2019-10-21 23:24:26 +03:00
|
|
|
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`
|
|
|
|
}
|
2019-02-12 08:03:20 +03:00
|
|
|
|
2019-10-21 23:24:26 +03:00
|
|
|
const scss = await readFile(from, encoding)
|
|
|
|
meta.imports = getExternalImports(scss, path).map(getPathName)
|
|
|
|
const result = await processor.process(scss, Object.assign({from, to}, options))
|
|
|
|
await Promise.all([
|
|
|
|
writeFile(to, result.css, encoding),
|
|
|
|
writeFile(meta.stats, JSON.stringify(cssstats(result.css)), encoding),
|
|
|
|
writeFile(meta.js, `module.exports = {cssstats: require('./stats/${name}.json')}`, encoding),
|
2020-12-15 00:54:36 +03:00
|
|
|
result.map ? writeFile(meta.map, result.map.toString(), encoding) : null
|
2019-10-21 23:24:26 +03:00
|
|
|
])
|
|
|
|
bundles[name] = meta
|
|
|
|
})
|
|
|
|
|
|
|
|
await Promise.all(tasks)
|
|
|
|
|
|
|
|
const meta = {bundles}
|
|
|
|
await writeFile(join(outDir, 'meta.json'), JSON.stringify(meta, null, 2), encoding)
|
2019-10-31 14:37:36 +03:00
|
|
|
await writeVariableData()
|
2019-10-21 23:24:26 +03:00
|
|
|
await writeDeprecationData()
|
|
|
|
} catch (error) {
|
2019-02-12 06:49:13 +03:00
|
|
|
console.error(error)
|
|
|
|
process.exitCode = 1
|
2019-10-21 23:24:26 +03:00
|
|
|
}
|
|
|
|
}
|
2019-02-12 09:33:03 +03:00
|
|
|
|
|
|
|
function getExternalImports(scss, relativeTo) {
|
|
|
|
const imports = []
|
2019-02-12 21:30:54 +03:00
|
|
|
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))
|
2019-02-12 09:33:03 +03:00
|
|
|
})
|
|
|
|
return imports
|
|
|
|
}
|
2019-02-12 21:30:54 +03:00
|
|
|
|
|
|
|
function getPathName(path) {
|
|
|
|
return path.replace(/\//g, '-')
|
|
|
|
}
|
|
|
|
|
2019-09-05 21:13:45 +03:00
|
|
|
function writeDeprecationData() {
|
2019-11-01 21:05:46 +03:00
|
|
|
const {versionDeprecations, selectorDeprecations, variableDeprecations} = require('../deprecations')
|
2019-09-05 21:55:10 +03:00
|
|
|
const data = {
|
|
|
|
versions: versionDeprecations,
|
2019-11-01 21:05:46 +03:00
|
|
|
selectors: mapToObject(selectorDeprecations),
|
|
|
|
variables: mapToObject(variableDeprecations)
|
|
|
|
}
|
|
|
|
return writeFile(join(outDir, 'deprecations.json'), JSON.stringify(data, null, 2))
|
|
|
|
|
|
|
|
function mapToObject(map) {
|
|
|
|
return Array.from(map.entries()).reduce((obj, [key, value]) => {
|
|
|
|
obj[key] = value
|
2019-09-05 21:55:10 +03:00
|
|
|
return obj
|
|
|
|
}, {})
|
|
|
|
}
|
2019-09-05 21:13:45 +03:00
|
|
|
}
|
2019-10-19 02:21:14 +03:00
|
|
|
|
2019-10-21 23:24:26 +03:00
|
|
|
if (require.main === module) {
|
|
|
|
dist()
|
2019-10-19 02:21:14 +03:00
|
|
|
}
|
2019-10-31 14:37:36 +03:00
|
|
|
|
|
|
|
function writeVariableData() {
|
2020-08-10 20:39:07 +03:00
|
|
|
// const analyzeVariables = require('./analyze-variables')
|
|
|
|
// return Promise.all([
|
|
|
|
// analyzeVariables('src/support/index.scss'),
|
|
|
|
// analyzeVariables('src/marketing/support/index.scss')
|
|
|
|
// ]).then(([support, marketing]) => {
|
|
|
|
// const data = Object.assign({}, support, marketing)
|
|
|
|
// writeFile(join(outDir, 'variables.json'), JSON.stringify(data, null, 2))
|
|
|
|
// })
|
2019-10-31 14:37:36 +03:00
|
|
|
}
|