UNPKG

builder-isv

Version:

ISV 模块本地预览与云构建器

154 lines (130 loc) 3.91 kB
/** * @author 龙喜<xiaolong.lxl@alibaba-inc.com> * @description Renderer */ 'use strict'; // https://nodejs.org/dist/latest-v6.x/docs/api/events.html const EventEmitter = require('events'); const path = require('path'); const os = require('os'); const renderConfigLoader = require('../lib/renderConfigLoader'); const config = require('../config'); const utils = require('../lib/utils'); const Base = require('./base'); module.exports = class Renderer extends EventEmitter { /** * 构造一个构建器 * @param module 模块信息 */ constructor(module) { super(); // 设置上下文 this.config(module); } /** * 配置上下文 * @param module 模块信息(INVOKE_TYPE_BUILD 情况下有 outputDir 属性) */ config(module) { let rendererConfig = Renderer.getMatchedRendererConfig(module); this.id = `${module.moduleType}/${module.moduleName}`; // status: -1(错误) / 0(就绪) / 1(编译中)/ 2(编译成功) this.status = 0; this.module = module; this.rendererConfig = rendererConfig; this.outputDir = module.outputDir || path.join(config.defOptions.tmpPreviewDir, module.moduleType); utils.log.verbose('outputDir', this.outputDir); // 构建器匹配 if (this.builder && this.rendererConfig.match(module.abcInfo, module.packageInfo)) { utils.log.verbose('构建器类型匹配,切换构建入口(entry)'); this.builder.changeEntry(module); } else { if (this.builder) { this.builder.stop(); this.builder.destroy(); } let Builder = rendererConfig.getBuilder(); this.builder = new Builder(module.outputDir ? Base.INVOKE_TYPE_BUILD : Base.INVOKE_TYPE_PREVIEW); // 所有事件透传 this.builder.addListener('compileFailed', (err) => { this.status = -1; this.error = err; this.emit('compileFailed', err); }); this.builder.addListener('compileStart', () => { this.status = 1; this.emit('compileStart'); }); this.builder.addListener('compileSucceed', () => { this.status = 2; this.error = null; this.emit('compileSucceed'); }); this.builder.addListener('compileFinished', () => { this.emit('compileFinished'); }); } } /** * 页面渲染器 * @param params * @param queries * @param headers * @param {JSONStore} abcInfo * @param {JSONStore} packageInfo */ *render(params, queries, headers, abcInfo, packageInfo) { return yield this.rendererConfig.render(params, queries, headers, abcInfo, packageInfo); } /** * 开始构建 */ build() { if (this.status !== 0) { throw new Error('构建器已经运行过了'); } this.status = 1; // 开始构建 this.builder.start({ cwd: this.module.modulePath, module: this.module, outputDir: this.outputDir }); } /** * 等待构建完成,构建错误抛出 * @returns {Promise} */ waitUntilBundleFinished() { return new Promise((resolve, reject) => { if (this.status === 0 || this.status === 1) { this.once('compileFinished', () => { if (this.status === -1) { reject(this.error); } else { resolve(); } }); } else if (this.status === -1) { reject(this.error); } else { resolve(); } }); } /** * 获取匹配的渲染器配置 * @param module * @returns {*} */ static getMatchedRendererConfig(module) { let abcInfo = module.abcInfo; let packageInfo = module.packageInfo; for (let i = 0, renderers = renderConfigLoader.renderers; i < renderers.length; ++i) { if (renderers[i].match(abcInfo, packageInfo)) { return renderers[i]; } } throw new Error('找不到匹配的渲染器'); } };