UNPKG

fis3-parser-typescript

Version:

A parser plugin for fis3 to compile typescript(ts) file.

187 lines (154 loc) 5.73 kB
/** * fis.baidu.com */ var ts = require('typescript'); var util = require('util'); var ModuleKind = ts.ModuleKind; var JsxEmit = ts.JsxEmit; var ScriptTarget = ts.ScriptTarget; function transpileModule(content, transpileOptions, file) { var options = transpileOptions.compilerOptions; options.isolatedModules = true; options.allowNonTsExtensions = true; options.noLib = true; options.noResolve = true; var newLine = ts.getNewLineCharacter(options); var inputFileName = file.isJsXLike ? file.realpath.replace(/\.[^\.]+$/, '.tsx') : file.realpath.replace(/\.jsx$/, '.tsx'); var sourceFile = ts.createSourceFile(inputFileName, content, options.target); var sourceMapText, outputText; if (file.isMod) { sourceFile.moduleName = file.moduleId || file.id; } var compilerHost = { getSourceFile: function (fileName) { if (fileName === ts.normalizeSlashes(inputFileName)) { return sourceFile; } var info = fis.uri(fileName, file.dirname); if (info.file) { var f = info.file; var sf = ts.createSourceFile(f.isJsXLike ? f.realpath.replace(/\.[^\.]+$/, '.tsx') : f.realpath.replace(/\.jsx$/, '.tsx'), f.getContent(), options.target); if (f.isMod) { sf.moduleName = f.moduleId || f.id; } return sf; } return undefined; }, writeFile: function (name, text, writeByteOrderMark) { if (ts.fileExtensionIs(name, ".map")) { ts.Debug.assert(sourceMapText === undefined, "Unexpected multiple source map outputs for the file '" + name + "'"); sourceMapText = text; } else { ts.Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: " + name); outputText = text; } }, getDefaultLibFileName: function () { return "lib.d.ts"; }, useCaseSensitiveFileNames: function () { return false; }, getCanonicalFileName: function (fileName) { return fileName; }, getCurrentDirectory: function () { return ""; }, getNewLine: function () { return newLine; }, fileExists: function (fileName) { return fis.util.exists(fileName); }, readFile: function (fileName) { return ""; } }; var program = ts.createProgram([inputFileName], options, compilerHost); var diagnostics; var noticeDiagnostics; if (transpileOptions.reportDiagnostics) { diagnostics = []; ts.addRange(diagnostics, program.getSyntacticDiagnostics(sourceFile)); ts.addRange(diagnostics, program.getOptionsDiagnostics()); noticeDiagnostics = []; options.showNotices && ts.addRange(noticeDiagnostics, program.getSemanticDiagnostics(sourceFile)); } program.emit(); return { outputText: outputText, diagnostics: diagnostics, noticeDiagnostics: noticeDiagnostics, sourceMapText: sourceMapText }; } module.exports = function (content, file, opts) { // 用 html 语言处理一遍。 if (fis.compile.partial && file.ext === '.tsx' || file.ext === '.jsx' || file.isJsXLike) { content = fis.compile.partial(content, file, { ext: '.html', isHtmlLike: true }); } var conf = fis.util.clone(opts); if (!conf.sourceMap) { conf.inlineSources = false; } var result = transpileModule(content, { compilerOptions: conf, fileName: file.realpath, reportDiagnostics: true, moduleName: undefined }, file); result.diagnostics.forEach(function(e) { if(!e.file){ return; } var lineAndCharacterObj = e.file.getLineAndCharacterOfPosition(e.start); var line = lineAndCharacterObj.line; var character = lineAndCharacterObj.character; var message = ts.flattenDiagnosticMessageText(e.messageText, '\n'); var msg = util.format('Syntax Error: %s in [%s:%s]', message, line+1, character+1); throw new Error(msg); }); result.noticeDiagnostics.forEach(function(e) { if(!e.file){ return; } var lineAndCharacterObj = e.file.getLineAndCharacterOfPosition(e.start); var line = lineAndCharacterObj.line; var character = lineAndCharacterObj.character; var message = ts.flattenDiagnosticMessageText(e.messageText, '\n'); var msg = util.format('Notice Syntax Error: %s in [%s:%s]', message, line+1, character+1); fis.log[conf.noticeType] && fis.log[conf.noticeType](msg); }); if (result.sourceMapText) { var mapping = fis.file.wrap(file.dirname + '/' + file.filename + file.rExt + '.map'); // 修改 source 文件名。 var sourceMapObj = JSON.parse(result.sourceMapText); sourceMapObj.sources = [file.subpath]; result.sourceMapText = JSON.stringify(sourceMapObj, null, 4); mapping.setContent(result.sourceMapText); var url = mapping.getUrl(fis.compile.settings.hash, fis.compile.settings.domain); result.outputText = result.outputText.replace(/\n?\s*\/\/#\ssourceMappingURL=.*?(?:\n|$)/g, ''); result.outputText += '\n//# sourceMappingURL=' + url + '\n'; file.extras = file.extras || {}; file.extras.derived = file.extras.derived || []; file.extras.derived.push(mapping); } return result.outputText || ''; }; module.exports.defaultOptions = { // 1: JsxEmit.Preserve // 2: JsxEmit.React jsx: JsxEmit.React, // 1: ModuleKind.CommonJS // 2: ModuleKind.AMD // 3: ModuleKind.UMD // 4: ModuleKind.System module: ModuleKind.CommonJS, // 0: ScriptTarget.ES3 // 1: ScriptTarget.ES5 // 2: ScriptTarget.ES6 target: ScriptTarget.ES5, noImplicitAny: false, outDir: "built", rootDir: fis.project.getProjectPath(), sourceMap: false, inlineSources: true, emitDecoratorMetadata: true, experimentalDecorators: true, showNotices: false, noticeType: 'warn' // warn|error };