UNPKG

nodram

Version:
180 lines (124 loc) 5.61 kB
import {RConfig} from "../../helpers/RConfig"; import {Utils} from "../../helpers/Utils"; import * as nodeSass from "node-sass"; import * as path from "path"; import * as postcss from "postcss"; import * as cssnano from "cssnano"; import * as autoprefixer from "autoprefixer"; import * as fs from "fs-extra"; import * as chalk from 'chalk'; import * as globby from 'globby'; import * as spinner from '../../helpers/spinner'; import * as del from 'del'; import {Observable, Observer} from "rxjs"; export class SassBuilder{ private config; constructor(){ this.config = new RConfig(); } public buildApp(path, observer: Observer<string>){ let newPath = `${path.split(".scss")[0]}.css`; nodeSass.render({file: path, outputStyle: 'compressed'}, (err, result) => { if (err) { observer.error(err); return; } this.prefixCss(result.css.toString('utf8')).then( prefixedCss => { try { fs.writeFileSync(newPath, prefixedCss.css, "utf8"); observer.next(`${path} completed`); observer.complete(); }catch(err) { observer.error(err); return; } }); }); } public buildBootstrap(observer: Observer<string>){ let styles = this.config.get("styles"); let bootstrapEntryFile = path.join(process.cwd(),styles.bootstrapDir,styles.bootstrapMainFile); let outDir = path.join(process.cwd(),styles.outDir); if (!fs.existsSync(bootstrapEntryFile)) { return observer.error("Bootstrap Files not found"); } nodeSass.render({file: bootstrapEntryFile, outputStyle: 'compressed'}, (err, result) => { if (err) return observer.error(err); this.prefixCss(result.css.toString('utf8')).then( prefixedCss => { try { let mapFile = outDir + "/main.css.map"; let cssFile = outDir + "/main.css"; fs.ensureFileSync(mapFile); fs.ensureFileSync(cssFile); fs.writeFileSync(mapFile, prefixedCss.map, "utf8"); fs.writeFileSync(cssFile, prefixedCss.css, "utf8"); observer.complete(); }catch(err) { return observer.error(err); } }); }); } private prefixCss(css: string):Promise<any>{ let config = this.config; let cssFile = path.join(`${config["outDir"]}/${config["cssFile"]}`); return new Promise( (resolve,reject) => { postcss([autoprefixer(config["prefix"]),cssnano]).process(css,{from : cssFile, to : cssFile, map: { inline: false }}).then(result => resolve(result)); }); } public cleanFiles(files: Array<string>) { let start = new Date(); return Observable.create(observer => { spinner.start('Cleaning files...'); del(files).then(paths => { let time: number = new Date().getTime() - start.getTime(); spinner.stop(); observer.next(`${chalk.green('✔')} ${chalk.blue(`Cleaned Files (css): ${Utils.timeHuman(time)}`)}`); observer.complete(); }); }) } public compileBootstrapSass() { spinner.start('Compiling Bootstrap files...'); return new Observable(observer => { let start: Date = new Date(); Observable.create(ob => this.buildBootstrap(ob)) .subscribe(data => {}, err => this.handleTaskError(err,observer), ()=> { this.completeTask("Compiled Bootstrap Sass",start,observer); observer.complete(); }) }) } public compileAppSass() { spinner.start('Compiling App files...'); const config = this.config.get("styles"); return new Observable(observer => { let start: Date = new Date(); globby(config.appFilesPaths).then(paths => { //when no files in in glob if (paths.length == 0) return this.handleTaskError(`Sass App Files not found`, observer); // call the builder Observable.from(paths) .map(path => Observable.create(ob => this.buildApp(path, ob))).concatAll() .subscribe(data => { }, err => this.handleTaskError(err, observer), () => { this.completeTask("Compiled App Sass", start, observer); observer.complete(); }); }).catch(err => this.handleTaskError(err, observer)); }) } private completeTask(message: string, startDate: Date, observer: Observer<string>){ spinner.stop(); let time: number = new Date().getTime() - startDate.getTime(); observer.next(`${chalk.green('✔')} ${chalk.blue(`${message}: ${time}ms`)}`); } private handleTaskError(message: string, observer: Observer<string>){ spinner.stop(); observer.next(`${chalk.red('✖')} ${chalk.yellow(message)}`); } }