Created
October 21, 2020 11:25
-
-
Save flaki/88e9d453304dc0f2e8d5390588b28ac7 to your computer and use it in GitHub Desktop.
Generate minified, source-mapped PostCSS output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const postcss = require('postcss'); | |
const sourcemapConcat = require('concat-with-sourcemaps'); | |
const fs = require('fs-extra'); | |
const { dirname, basename } = require('path'); | |
let CONFIG; | |
try { | |
// Throws if no config file | |
let configFile = require('./postcss.config'); | |
// Function callback | |
if (typeof configFile === 'function') { | |
CONFIG = configFile.call(null, { | |
options: {} | |
}); | |
// Config obejct | |
} else if (typeof configFile === 'object') { | |
CONFIG = configFile; | |
// Invalid config file | |
} else { | |
throw(new Error('Invalid config file!')); | |
} | |
} | |
catch(e) { | |
console.error(e); | |
console.error('Make sure you configure postcss-generate first!'); | |
console.error('Hint: use the "generate" property of postcss.config.js!'); | |
process.exit(1); | |
} | |
function mkProcessOpts(src) { | |
return ({ | |
map: { | |
// Disable inline source maps to ensure .map is populated | |
inline: false, | |
// Turn off annotations (not needed since we're concating) | |
annotation: false | |
}, | |
from: src, | |
to: `${CONFIG.generate.outdir}${src}` | |
}); | |
} | |
async function transform(processor, src) { | |
let pOpts = mkProcessOpts(src); | |
let sourceCss = await fs.readFile(pOpts.from); | |
// Make sure output dir exists | |
await fs.ensureDir(dirname(pOpts.to)); | |
// Transform source | |
let result = await processor.process(sourceCss, pOpts); | |
// Only write resulting files of not concatenating (no outfile specified) | |
if (!CONFIG.generate.outfile) { | |
await fs.writeFile(pOpts.to, result.css); | |
if (result.map) { | |
await fs.writeFile(`${pOpts.to}.map`, result.map.toString()); | |
} | |
} | |
// Return full processing results for further processing | |
return result; | |
} | |
async function concat(results, outfile) { | |
let out = new sourcemapConcat(true, outfile, '\n'); | |
// Add a header | |
out.add(null, "/* (c) RustFest Global 2020 | Brand by URA Design */"); | |
for (const { opts, css, map } of results) { | |
// NOTE: for some inputs stripping the entire file path | |
// might not be desirable | |
// TODO: make this optional/configurable? | |
const filename = basename(opts.from); | |
// Original source filename (with full path) | |
// TODO: this isn't strictly neccessary - maybe make it optional? | |
out.add(null, `/* ${opts.from} */`); | |
out.add(filename, css.toString(), map.toString()); | |
} | |
// Link generated source map | |
out.add(null, `/*# sourceMappingURL=${basename(outfile)}.map */`); | |
const concatenated = { | |
css: out.content, // note: is a buffer | |
map: out.sourceMap // note: is a string | |
} | |
// Make sure output dir exists | |
await fs.ensureDir(dirname(outfile)); | |
// Transform source and write resulting CSS | |
await fs.writeFile(outfile, concatenated.css); | |
await fs.writeFile(`${outfile}.map`, concatenated.map); | |
return concatenated; | |
} | |
async function run() { | |
// Create a processor by using the plugins from the config file | |
const processor = postcss(CONFIG.plugins); | |
// Process source files | |
let results = await Promise.all( | |
CONFIG.generate.from.map( | |
sourceFile => transform(processor, sourceFile) | |
) | |
); | |
// Concatenate all sources into a single source-mapped outfile | |
let concatresult = await concat(results, CONFIG.generate.outfile); | |
console.log(`Updated CSS build in ${CONFIG.generate.outfile}`); | |
} | |
if (require.main === module) { | |
run().catch(e => console.error(e)); | |
} else { | |
module.exports = run | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = (ctx) => ({ | |
map: ctx.options.map, | |
plugins: [ | |
require('postcss-nested'), | |
require('autoprefixer'), | |
require('cssnano')({ | |
preset: 'default', | |
}), | |
], | |
//TODO: check for the canonical postcss.config.js properties | |
//TODO: figure out how list sources by paty (in a way that accounts for ordering) | |
generate: { | |
from: [ | |
// Fonts | |
'assets/fonts/inter/inter.css', | |
'assets/fonts/quicksand.css', | |
// Defaults | |
'assets/css/brand-colors.css', | |
'assets/css/brand-fonts.css', | |
'assets/css/brand-base.css', | |
'assets/css/brand-translations.css', | |
// Skeleton | |
'assets/css/brand-header.css', | |
'assets/css/brand-footer.css', | |
// Homepage | |
'assets/css/pg-home-twinkles.css', | |
'assets/css/pg-home-hero.css', | |
'assets/css/pg-home-boxes.css', | |
'assets/css/pg-home-intouch.css', | |
'assets/css/pg-home-sponsors.css', | |
// Information page | |
'assets/css/pg-info.css', | |
'assets/css/pg-info-team.css', | |
// Registration | |
'assets/css/pg-registration.css', | |
], | |
outdir: '_site/', | |
// If no outfile don't concat into single file | |
outfile: '_site/css/style.css', | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment