UNPKG

nodram

Version:
232 lines (165 loc) 7.75 kB
import {Observable, Observer} from "rxjs"; import * as spinner from '../../../helpers/spinner'; import * as fs from 'fs-extra'; import * as path from 'path'; import * as chalk from 'chalk'; import * as _ from 'lodash'; import * as globby from 'globby'; import * as UglifyJS from 'uglify-js'; import {exec} from 'child_process'; import {Utils} from "../../../helpers/Utils"; import {RConfig} from "../../../helpers/RConfig"; export class ProdAppTask{ protected config; constructor(protected ROOT_DIR){ this.config = new RConfig(); } /** * Refractor app */ public refactorApp() { let start = new Date(); return Observable.create(observer => { spinner.start('Refactoring app...'); let subscriber = this.generateHTML() .concat(this.copyFiles()) .concat(this.rewriteProcfile()) .concat(this.removeModuleIdFromComponents()); subscriber.subscribe( data => {}, err => {observer.error(err)}, () => { let time: number = new Date().getTime() - start.getTime(); spinner.stop(); observer.next(`${chalk.green('✔')} ${chalk.blue(`Refactored App: ${Utils.timeHuman(time)}`)}`); observer.complete(); }); }) } public runWebpack(){ let start = new Date(); return Observable.create(observer => { spinner.start('Bundling app...'); exec('node_modules\\.bin\\webpack', {cwd : process.cwd(), maxBuffer: 1024 * 500}, (err, stdout, stderr) => { if (err) return observer.error(err); /* observer.next(stdout); observer.next(stderr);*/ let time: number = new Date().getTime() - start.getTime(); spinner.stop(); observer.next(`${chalk.green('✔')} ${chalk.blue(`Bundled App: ${Utils.timeHuman(time)}`)}`); return observer.complete(); }); }) } private generateHTML(){ const config = this.config; const indexHTML = path.join(this.ROOT_DIR,"/src/templates/index.prod.html"); const content = _.template(fs.readFileSync(indexHTML).toString()); const dest = path.join(process.cwd(),"/server/views/index.html"); //get settings const staticSite = config.get("staticSite"); const scriptsArray = config.get("scripts.bundles"); const scripts = Object.keys(scriptsArray).map(v => `${staticSite}/scripts/bundles/${v}.min.js`); const stylesArray = config.get("styles.bundles"); const styles = Object.keys(stylesArray).map(v => `${staticSite}/styles/bundles/${v}.min.css`); styles.push(`${staticSite}/styles/main.css`); const title = config.get("indexHTML.title"); const metas = config.get("indexHTML.metas"); const favicons = config.get("indexHTML.favicons"); const scriptsOutDir = config.get("scripts.outDir"); const clientBundleFile = config.get('scripts.clientBundleFile'); const clientScriptBundle = `${staticSite}/scripts/${clientBundleFile}`; return new Observable(observer => { fs.outputFile(dest, content({ title: title, metas: metas, favicons : favicons, styles : styles, scripts: scripts, clientScriptBundle : clientScriptBundle }), err => { if (err) { observer.error(err); } observer.complete(); }); }); } public copyFiles(){ const scriptRootDir= this.config.get("scripts.rootDir"); const src = path.join(this.ROOT_DIR,"/src/templates/browser.bootstrap.prod.ts"); const dest = path.join(process.cwd(),scriptRootDir,"browser.bootstrap.ts"); const src2 = path.join(this.ROOT_DIR,"/src/templates/server.prod.ts"); const dest2 = path.join(process.cwd(),"/server/server.ts"); const src3 = path.join(this.ROOT_DIR,"/src/templates/browser.module.prod.ts"); const dest3 = path.join(process.cwd(),scriptRootDir,"browser.module.ts"); const src4 = path.join(this.ROOT_DIR,"/src/templates/prod.gitignore"); const dest4 = path.join(process.cwd(),".gitignore"); return new Observable(observer => { try { fs.copySync(src, dest); fs.copySync(src2, dest2); fs.copySync(src3, dest3); fs.copySync(src4, dest4); observer.complete(); }catch(err){observer.error(err);} }); } private rewriteProcfile(){ return new Observable(observer => { let filename = path.join(process.cwd(),"Procfile"); fs.writeFile(filename,"web: node bin/server.js",'utf8',(err) =>{ if(err) return observer.error(err); return observer.complete(); }) }); } private removeModuleIdFromComponents(): Observable<any> { const rootDir = this.config.get("scripts.rootDir"); const patterns = `${rootDir}/**/*.component.ts`; return new Observable(observer => { let srcFiles = globby.sync(`${rootDir}/**/*.component.ts`); srcFiles.forEach(srcFile => { let contents = fs.readFileSync(srcFile).toString().split('\n'); let index = contents.findIndex(line => line.includes('moduleId: module.id')); if (index !== -1) { contents.splice(index, 1); fs.writeFileSync(srcFile, contents.join('\n'), 'utf8'); } }); observer.complete(); }); } public minifyBundleFiles(){ const srcFiles = this.config.get("scripts.bundles"); let bundles = Object.keys(srcFiles); return new Observable(observer => { spinner.start('Minifying library files...'); let start: Date = new Date(); Observable.from(bundles) .map(bundle => { let dest = path.join(process.cwd(), `/static/scripts/bundles/${bundle}.min.js`); return Observable.create(ob => this.minifyBundleFile(srcFiles[bundle], dest, ob)) }).concatAll().subscribe( data => observer.next(data), err => this.handleTaskError(err, observer), () => this.completeTask("Minified Library files", start, observer) ); }); } private minifyBundleFile(srcFiles: string[], dest: string, observer: Observer<string>){ const result = UglifyJS.minify(srcFiles); fs.ensureDir(path.dirname(dest), err => { if(err) return observer.error(err); fs.writeFileSync(dest, result.code, "utf8"); observer.complete(); }); } 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`)}`); observer.complete(); } private handleTaskError(message: string, observer: Observer<string>){ spinner.stop(); observer.error(`${chalk.red('✖')} ${chalk.yellow(message)}`); } }