@tylertech/forge-build-tools
Version:
Node utilities for building and packaging libraries.
66 lines • 10.3 kB
JavaScript
import { compile } from 'sass';
import autoprefixer from 'autoprefixer';
import postcss from 'postcss';
import CleanCSS from 'clean-css';
import cpath from 'canonical-path';
import { globFilesAsync, writeFileAsync, mkdirp } from '../fs/index.js';
import { isGlob, logWarn } from '../utils/index.js';
/**
* Compiles .scss files to .css files within a `rootDir` and outputs them to the `outputDir`.
* @param {string[] | string} files An array of filenames, or a glob pattern to find files.
* @param {string} rootDir The common root directory in which the input files live. This is used to build the structure within the output directory.
* @param {string} outputDir The output directory where the .css files will be written to.
*/
export async function compileSass(files, rootDir, outputDir, options = { minify: true, postCss: true }) {
if (typeof files === 'string') {
files = isGlob(files) ? await globFilesAsync(files, {}) : [files];
}
rootDir = cpath.resolve(rootDir).replace(/\/?$/, '/');
outputDir = cpath.resolve(outputDir);
let includedFiles = [];
for (const file of files) {
const result = compile(file, { loadPaths: ['node_modules'], sourceMap: false, ...options.sassOptions });
includedFiles = includedFiles.concat(result.loadedUrls.map(url => cpath.resolve(url.pathname)));
let cssContent = result.css;
if (options.postCss) {
cssContent = await runPostCss(file, cssContent);
}
if (options.minify) {
cssContent = minifyCss(cssContent);
}
const relativeFilePath = cpath.resolve(file).replace(rootDir, '').replace(/^\//, '').replace(/\.scss$/, '.css');
const outputFilePath = cpath.join(outputDir, relativeFilePath);
const outputPath = cpath.dirname(outputFilePath);
mkdirp(outputPath);
await writeFileAsync(outputFilePath, cssContent, 'utf-8');
}
return includedFiles;
}
/**
* Runs CSS transformers on the provided CSS content.
* @param filename The CSS filename.
* @param css The CSS content.
*/
export async function runPostCss(filename, css) {
const autoprefixerOptions = {
overrideBrowserslist: [
'last 2 versions',
'not ie <= 10',
'not ie_mob <= 10'
],
cascade: false
};
const postcssOptions = { from: filename };
const postCssPlugins = [autoprefixer(autoprefixerOptions)];
const postCssResult = await postcss(postCssPlugins).process(css, postcssOptions);
postCssResult.warnings().forEach(warning => logWarn(warning.text));
return postCssResult.css;
}
/**
* Minifies CSS content.
* @param css The CSS content.
*/
export function minifyCss(css) {
return new CleanCSS({ rebase: false }).minify(css).styles;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Fzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jc3Mvc2Fzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUM3QyxPQUFPLFlBQVksTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxPQUEyQixNQUFNLFNBQVMsQ0FBQztBQUNsRCxPQUFPLFFBQVEsTUFBTSxXQUFXLENBQUM7QUFDakMsT0FBTyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFFbkMsT0FBTyxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEUsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQVFwRDs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsV0FBVyxDQUFDLEtBQXdCLEVBQUUsT0FBZSxFQUFFLFNBQWlCLEVBQUUsVUFBOEIsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUU7SUFDM0osSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUM5QixLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLGNBQWMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEYsQ0FBQztJQUVELE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDdEQsU0FBUyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDckMsSUFBSSxhQUFhLEdBQWEsRUFBRSxDQUFDO0lBRWpDLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7UUFDekIsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsR0FBRyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUN4RyxhQUFhLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVoRyxJQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDO1FBRTVCLElBQUksT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3BCLFVBQVUsR0FBRyxNQUFNLFVBQVUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDbEQsQ0FBQztRQUVELElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ25CLFVBQVUsR0FBRyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNoSCxNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBQy9ELE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7UUFFakQsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ25CLE1BQU0sY0FBYyxDQUFDLGNBQWMsRUFBRSxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVELE9BQU8sYUFBYSxDQUFDO0FBQ3ZCLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxVQUFVLENBQUMsUUFBZ0IsRUFBRSxHQUFXO0lBQzVELE1BQU0sbUJBQW1CLEdBQXlCO1FBQ2hELG9CQUFvQixFQUFFO1lBQ3BCLGlCQUFpQjtZQUNqQixjQUFjO1lBQ2Qsa0JBQWtCO1NBQ25CO1FBQ0QsT0FBTyxFQUFFLEtBQUs7S0FDZixDQUFDO0lBQ0YsTUFBTSxjQUFjLEdBQW1CLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFDO0lBQzFELE1BQU0sY0FBYyxHQUFVLENBQUMsWUFBWSxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztJQUNsRSxNQUFNLGFBQWEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ2pGLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDbkUsT0FBTyxhQUFhLENBQUMsR0FBRyxDQUFDO0FBQzNCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsU0FBUyxDQUFDLEdBQVc7SUFDbkMsT0FBTyxJQUFJLFFBQVEsQ0FBQyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7QUFDNUQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNvbXBpbGUsIHR5cGUgT3B0aW9ucyB9IGZyb20gJ3Nhc3MnO1xuaW1wb3J0IGF1dG9wcmVmaXhlciBmcm9tICdhdXRvcHJlZml4ZXInO1xuaW1wb3J0IHBvc3Rjc3MsIHsgUHJvY2Vzc09wdGlvbnMgfSBmcm9tICdwb3N0Y3NzJztcbmltcG9ydCBDbGVhbkNTUyBmcm9tICdjbGVhbi1jc3MnO1xuaW1wb3J0IGNwYXRoIGZyb20gJ2Nhbm9uaWNhbC1wYXRoJztcblxuaW1wb3J0IHsgZ2xvYkZpbGVzQXN5bmMsIHdyaXRlRmlsZUFzeW5jLCBta2RpcnAgfSBmcm9tICcuLi9mcy9pbmRleC5qcyc7XG5pbXBvcnQgeyBpc0dsb2IsIGxvZ1dhcm4gfSBmcm9tICcuLi91dGlscy9pbmRleC5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2Fzc0NvbXBpbGVPcHRpb25zIHtcbiAgbWluaWZ5PzogYm9vbGVhbjtcbiAgcG9zdENzcz86IGJvb2xlYW47XG4gIHNhc3NPcHRpb25zPzogT3B0aW9uczwnc3luYyc+O1xufVxuXG4vKipcbiAqIENvbXBpbGVzIC5zY3NzIGZpbGVzIHRvIC5jc3MgZmlsZXMgd2l0aGluIGEgYHJvb3REaXJgIGFuZCBvdXRwdXRzIHRoZW0gdG8gdGhlIGBvdXRwdXREaXJgLlxuICogQHBhcmFtIHtzdHJpbmdbXSB8IHN0cmluZ30gZmlsZXMgQW4gYXJyYXkgb2YgZmlsZW5hbWVzLCBvciBhIGdsb2IgcGF0dGVybiB0byBmaW5kIGZpbGVzLlxuICogQHBhcmFtIHtzdHJpbmd9IHJvb3REaXIgVGhlIGNvbW1vbiByb290IGRpcmVjdG9yeSBpbiB3aGljaCB0aGUgaW5wdXQgZmlsZXMgbGl2ZS4gVGhpcyBpcyB1c2VkIHRvIGJ1aWxkIHRoZSBzdHJ1Y3R1cmUgd2l0aGluIHRoZSBvdXRwdXQgZGlyZWN0b3J5LlxuICogQHBhcmFtIHtzdHJpbmd9IG91dHB1dERpciBUaGUgb3V0cHV0IGRpcmVjdG9yeSB3aGVyZSB0aGUgLmNzcyBmaWxlcyB3aWxsIGJlIHdyaXR0ZW4gdG8uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb21waWxlU2FzcyhmaWxlczogc3RyaW5nW10gfCBzdHJpbmcsIHJvb3REaXI6IHN0cmluZywgb3V0cHV0RGlyOiBzdHJpbmcsIG9wdGlvbnM6IFNhc3NDb21waWxlT3B0aW9ucyA9IHsgbWluaWZ5OiB0cnVlLCBwb3N0Q3NzOiB0cnVlIH0pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gIGlmICh0eXBlb2YgZmlsZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgZmlsZXMgPSBpc0dsb2IoZmlsZXMpID8gYXdhaXQgZ2xvYkZpbGVzQXN5bmMoZmlsZXMsIHt9KSBhcyBzdHJpbmdbXSA6IFtmaWxlc107XG4gIH1cblxuICByb290RGlyID0gY3BhdGgucmVzb2x2ZShyb290RGlyKS5yZXBsYWNlKC9cXC8/JC8sICcvJyk7XG4gIG91dHB1dERpciA9IGNwYXRoLnJlc29sdmUob3V0cHV0RGlyKTtcbiAgbGV0IGluY2x1ZGVkRmlsZXM6IHN0cmluZ1tdID0gW107XG5cbiAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gY29tcGlsZShmaWxlLCB7IGxvYWRQYXRoczogWydub2RlX21vZHVsZXMnXSwgc291cmNlTWFwOiBmYWxzZSwgLi4ub3B0aW9ucy5zYXNzT3B0aW9ucyB9KTtcbiAgICBpbmNsdWRlZEZpbGVzID0gaW5jbHVkZWRGaWxlcy5jb25jYXQocmVzdWx0LmxvYWRlZFVybHMubWFwKHVybCA9PiBjcGF0aC5yZXNvbHZlKHVybC5wYXRobmFtZSkpKTtcbiAgICBcbiAgICBsZXQgY3NzQ29udGVudCA9IHJlc3VsdC5jc3M7XG5cbiAgICBpZiAob3B0aW9ucy5wb3N0Q3NzKSB7XG4gICAgICBjc3NDb250ZW50ID0gYXdhaXQgcnVuUG9zdENzcyhmaWxlLCBjc3NDb250ZW50KTtcbiAgICB9XG4gICAgXG4gICAgaWYgKG9wdGlvbnMubWluaWZ5KSB7XG4gICAgICBjc3NDb250ZW50ID0gbWluaWZ5Q3NzKGNzc0NvbnRlbnQpO1xuICAgIH1cblxuICAgIGNvbnN0IHJlbGF0aXZlRmlsZVBhdGggPSBjcGF0aC5yZXNvbHZlKGZpbGUpLnJlcGxhY2Uocm9vdERpciwgJycpLnJlcGxhY2UoL15cXC8vLCAnJykucmVwbGFjZSgvXFwuc2NzcyQvLCAnLmNzcycpO1xuICAgIGNvbnN0IG91dHB1dEZpbGVQYXRoID0gY3BhdGguam9pbihvdXRwdXREaXIsIHJlbGF0aXZlRmlsZVBhdGgpO1xuICAgIGNvbnN0IG91dHB1dFBhdGggPSBjcGF0aC5kaXJuYW1lKG91dHB1dEZpbGVQYXRoKTtcblxuICAgIG1rZGlycChvdXRwdXRQYXRoKTtcbiAgICBhd2FpdCB3cml0ZUZpbGVBc3luYyhvdXRwdXRGaWxlUGF0aCwgY3NzQ29udGVudCwgJ3V0Zi04Jyk7XG4gIH1cblxuICByZXR1cm4gaW5jbHVkZWRGaWxlcztcbn1cblxuLyoqXG4gKiBSdW5zIENTUyB0cmFuc2Zvcm1lcnMgb24gdGhlIHByb3ZpZGVkIENTUyBjb250ZW50LlxuICogQHBhcmFtIGZpbGVuYW1lIFRoZSBDU1MgZmlsZW5hbWUuXG4gKiBAcGFyYW0gY3NzIFRoZSBDU1MgY29udGVudC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1blBvc3RDc3MoZmlsZW5hbWU6IHN0cmluZywgY3NzOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBhdXRvcHJlZml4ZXJPcHRpb25zOiBhdXRvcHJlZml4ZXIuT3B0aW9ucyA9IHtcbiAgICBvdmVycmlkZUJyb3dzZXJzbGlzdDogW1xuICAgICAgJ2xhc3QgMiB2ZXJzaW9ucycsXG4gICAgICAnbm90IGllIDw9IDEwJyxcbiAgICAgICdub3QgaWVfbW9iIDw9IDEwJ1xuICAgIF0sXG4gICAgY2FzY2FkZTogZmFsc2VcbiAgfTtcbiAgY29uc3QgcG9zdGNzc09wdGlvbnM6IFByb2Nlc3NPcHRpb25zID0geyBmcm9tOiBmaWxlbmFtZSB9O1xuICBjb25zdCBwb3N0Q3NzUGx1Z2luczogYW55W10gPSBbYXV0b3ByZWZpeGVyKGF1dG9wcmVmaXhlck9wdGlvbnMpXTtcbiAgY29uc3QgcG9zdENzc1Jlc3VsdCA9IGF3YWl0IHBvc3Rjc3MocG9zdENzc1BsdWdpbnMpLnByb2Nlc3MoY3NzLCBwb3N0Y3NzT3B0aW9ucyk7XG4gIHBvc3RDc3NSZXN1bHQud2FybmluZ3MoKS5mb3JFYWNoKHdhcm5pbmcgPT4gbG9nV2Fybih3YXJuaW5nLnRleHQpKTtcbiAgcmV0dXJuIHBvc3RDc3NSZXN1bHQuY3NzO1xufVxuXG4vKipcbiAqIE1pbmlmaWVzIENTUyBjb250ZW50LlxuICogQHBhcmFtIGNzcyBUaGUgQ1NTIGNvbnRlbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtaW5pZnlDc3MoY3NzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IENsZWFuQ1NTKHsgcmViYXNlOiBmYWxzZSB9KS5taW5pZnkoY3NzKS5zdHlsZXM7XG59XG4iXX0=