1 | ;
|
2 | /**
|
3 | * tsx、ts编译为jsx、js
|
4 | *
|
5 | * @class Pug2html
|
6 | * {
|
7 | * src:'', <string> 源文件路径
|
8 | * dist:'', <string> 输出路径
|
9 | * debug:true [boolean] 默认:true,debug模式将生成调试信息
|
10 | * }
|
11 | */
|
12 | class Ts2{
|
13 | constructor(option){
|
14 | const _ts = this;
|
15 |
|
16 | option = option || {};
|
17 |
|
18 | let m = _ts.m = {
|
19 | fs:require('fs-extra'),
|
20 | path:require('path'),
|
21 | ts:require('typescript'),
|
22 | pathInfo:require('./getPathInfo'),
|
23 | replaceGlobal:require('./replaceGlobal')
|
24 | },
|
25 | config = _ts.config = {};
|
26 |
|
27 | //配置写入到_ts.config
|
28 | for(let i in option){
|
29 | config[i] = option[i];
|
30 | };
|
31 |
|
32 | //默认开启debug模式
|
33 | config.debug = config.debug === undefined ? true : config.debug;
|
34 |
|
35 | return new Promise((resolve,reject)=>{
|
36 | //检查文件是否为有效的类型
|
37 | let isSupport = (()=>{
|
38 | let extensions = ['ts','tsx','js','es','es6'],
|
39 | fileType = m.pathInfo(config.src).extension;
|
40 | return extensions.some((item,index)=>{
|
41 | return fileType === '.'+item;
|
42 | });
|
43 | })();
|
44 | if(isSupport){
|
45 | try {
|
46 | _ts.init().then(v => {
|
47 | resolve(v);
|
48 | }).catch(e => {
|
49 | reject(e);
|
50 | });
|
51 | } catch (error) {
|
52 | reject({
|
53 | status:'error',
|
54 | msg:`初始化失败 ${m.path.join(fwsPath,'lib','ts2.js')}`,
|
55 | info:error
|
56 | });
|
57 | };
|
58 | }else{
|
59 | reject({
|
60 | status:'error',
|
61 | msg:typeof config.src === 'string' ? `${config.src} 不是有效的文件` : `参数传入错误`
|
62 | });
|
63 | };
|
64 | });
|
65 | }
|
66 |
|
67 | init(){
|
68 | const _ts = this,
|
69 | m = _ts.m,
|
70 | config = _ts.config;
|
71 |
|
72 | //编译选项参考
|
73 | //https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API
|
74 | //https://www.typescriptlang.org/docs/handbook/compiler-options.html
|
75 | let option = {
|
76 | alwaysStrict:true, //是否启用严格模式
|
77 | lib: 'ES2016', //编译库'ES3','ES5','ES2015','ES2016','ES2017','Latest'
|
78 | module:'ES2015', //代码生成规范'None','CommonJs','AMD','UMD','System','ES2015'
|
79 | experimentalDecorators:true,
|
80 | //target:"ES2015",
|
81 | inlineSourceMap:config.debug, //在文件中嵌入map信息
|
82 | inlineSources:config.debug //生成源码图,需要inlineSourceMap开启
|
83 | },
|
84 | srcFileName = m.path.basename(config.src),
|
85 | fileContent = m.fs.readFileSync(config.src).toString();
|
86 |
|
87 | //编译方法
|
88 | let render = (resolve,reject)=>{
|
89 | let result;
|
90 | try {
|
91 | result = m.ts.transpileModule(
|
92 | fileContent,
|
93 | {
|
94 | compilerOptions:option,
|
95 | fileName:srcFileName
|
96 | }
|
97 | );
|
98 | } catch (err) {
|
99 | reject({
|
100 | status:'error',
|
101 | msg:`编译出错 ${config.src}`,
|
102 | info:err
|
103 | });
|
104 | };
|
105 |
|
106 |
|
107 | //将结果写入文件
|
108 | let distDir = m.path.dirname(config.dist);
|
109 | m.fs.ensureDir(distDir,(err)=>{
|
110 | if(err){
|
111 | reject({
|
112 | status:'error',
|
113 | msg:`创建失败 ${distDir}`,
|
114 | info:err
|
115 | });
|
116 | };
|
117 |
|
118 | try {
|
119 | if(result.outputText){
|
120 | result.outputText = m.replaceGlobal(result.outputText);
|
121 | };
|
122 | m.fs.writeFileSync(config.dist,result.outputText);
|
123 | resolve({
|
124 | status:'success',
|
125 | msg:`写入 ${config.dist}`,
|
126 | data:result.outputText
|
127 | });
|
128 | } catch (err) {
|
129 | reject({
|
130 | status:'error',
|
131 | msg:`写入失败 ${config.dist}`,
|
132 | info:err
|
133 | });
|
134 | };
|
135 | });
|
136 | };
|
137 |
|
138 | return new Promise(render);
|
139 | }
|
140 | }
|
141 | module.exports = Ts2;
|