UNPKG

werkzeug

Version:

compiles ts, coffee, sass/scss, less/ stylus and packs browser ready bundles

282 lines (208 loc) 6.97 kB
Emitter = require 'events' FS = require 'fs' Path = require 'path' Config = require './config' Server = require './server' Walker = require './walker' Watcher = require './watcher' Compiler = require './compiler' Packer = require './packer' FSU = require './utils/fsu' PH = require './utils/path-helper' Log = require('./utils/log').mapLogs() #TODO: add multiple in and out paths!!! #TODO: refactor path-helper somehow in cfg!!! #TODO: add post processors (like autoprefixer)!!! #TODO: fix errors for empty project!!! #TODO: refactor error handling -> use info object??? #TODO: fix errors for multiple instances in the same project #TODO: set ts.noEmitOnError = true and merge packer errors back to compiler errors??? #TODO: make source maps optional!!! #TODO: enable cli flag for different configs, maybe run configs concurrently #TODO: watch current wz config and restart app on change #TODO: remember TREESHAKING for the build process (if it ever comes)??? #TODO: implement salter??? class Werkzeug extends Emitter @ignores = 'node_modules$|\\.DS_Store$|dist$|\\.idea$|\\.git$|gulpfile\\.coffee$|Gruntfile\\.coffee$' @interests = '\\.coffee$|\\.ts$|\\.sass$|\\.scss$|\\.less$|\\.styl$' @updateDelay = 500 constructor: (base, cfg) -> super() Log() Log.info 'werkzeug', 'starting ...' Log.startTicker 'werkzeug starting' @cfg = new Config(base, cfg) @walker = new Walker (@) @watcher = new Watcher (@) @compiler = new Compiler(@) @packer = new Packer (@) if @cfg.packer.enabled and @cfg.out @server = new Server (@) if @cfg.server.enabled and @cfg.out @inDir = Path.join @cfg.base, @cfg.in @errors = [] @files = [] @fileMap = {} @idle = true @initialized = false @dirty = false # clear all output paths and add them to ignores paths = PH.getPaths(@cfg) for path in paths FSU.rmDir path if FSU.isDir path FS.mkdirSync path ignore = Path.relative @cfg.base, path ignore = ignore.replace(/\\/g, '\\\\').replace(/\//g, '\\/').replace(/\./g, '\\.') + '$' WZ.ignores += '|' + ignore @ignores = new RegExp("(#{WZ.ignores})") @interests = new RegExp("(#{WZ.interests})") process.on 'exit', @terminate process.on 'SIGINT', @terminate process.on 'SIGTERM', @terminate watch: () -> return if not @idle or @watcher.watching #TODO: make server optional @server.init() if @server @watcher.watch() null walk: () -> return if not @idle @idle = false @walker.walk() null walked: () -> @idle = true @compile() null compile: () -> return if not @idle if @initialized Log.startTicker 'compiling' else Log.setTicker 'compiling' @idle = false compiling = @compiler.compile() @cleanFiles() @dirty = false if not compiling @idle = true if not @watcher.watching @pack() else if not @initialized or not @packer @packed() null compiled: () -> @idle = true if not @compiler.errors.length @pack() else @packed() null pack: () -> return if not @idle @idle = false if @packer Log.setTicker 'packing' @packer.pack @compiler.files else @packed() null packed: () -> @idle = true t = Log.stopTicker() e = @compiler.errors.concat (@packer?.errors or []) el = e.length wl = @compiler.warnings.length w = @watcher.watching @compiler.logErrors() @packer.logErrors() if @packer if el + wl console.log '' if not @initialized @initialized = true s = if w then "startup" else "single run" else if @compiler.files and @compiler.files.length s = "ready" Log.info('werkzeug', s, t, el) if s if w if @dirty @update() else if @compiler.files and @compiler.files.length now = new Date() h = now.getHours() m = now.getMinutes() s = now.getSeconds() h = '0' + h if h < 10 m = '0' + m if m < 10 s = '0' + s if s < 10 Log.info 'werkzeug', 'watching' + ' ... ' + (h + ':' + m + ':' + s + ' - ' + @cfg.base) else @terminate() null update: () -> @dirty = true return if not @idle or not @initialized clearTimeout @updateTimeout @updateTimeout = setTimeout @updateNow, WZ.updateDelay null updateNow: () => return if not @idle @compile() null cleanFiles: () -> @errors = [] for path, file of @fileMap if file.dirty if file.removed index = @files.indexOf file @files.splice index, 1 if index > -1 delete @fileMap[file.path] else file.dirty = false file.added = false file.changed = false file.errors = null null fileAdded: (path) -> return null if path.indexOf(@inDir) != 0 file = @fileMap[path] if file file.removed = false else @files.push(file = @fileMap[path] = {}) file.path = path file.added = Date.now() file.dirty = true file.errors = null @update() #console.log 'fileAdded: ', path null fileChanged: (path) -> file = @fileMap[path] return if not file file.changed = Date.now() file.dirty = true file.errors = null @update() #console.log 'fileChanged: ', path null fileRemoved: (path) -> file = @fileMap[path] return if not file file.removed = Date.now() file.dirty = true @update() #console.log 'fileRemoved: ', path null ignore: (path) -> @ignores.test path interested: (path) -> @interests.test path terminate: () => Log() clearTimeout @updateTimeout @compiler.exit() @packer.exit() if @packer @server.exit() if @server process.removeAllListeners() setTimeout () -> process.exit 0 null module.exports = WZ = Werkzeug