UNPKG

9.52 kBJavaScriptView Raw
1'use strict';
2/**
3 * es、es6、js文件打包
4 *
5 * @class Es2
6 * {
7 * src:'', <string> 源文件路径
8 * dist:'', <string> 输出路径
9 * debug:true [boolean] 默认:true,debug模式将生成调试信息
10 * }
11 */
12class Es2{
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 rollup:require('rollup'),
22 rollup_json:require('rollup-plugin-json'),
23 rollup_nodeResolve:require('rollup-plugin-node-resolve'),
24 rollup_commonjs:require('rollup-plugin-commonjs'),
25 rollup_typescript2:require('rollup-plugin-typescript2'),
26 rollup_replace:require('rollup-plugin-replace'),
27 replaceGlobal:require('./replaceGlobal'),
28 pathInfo:require('./getPathInfo'),
29 rollup_vue:require('rollup-plugin-vue')
30 },
31 config = _ts.config = {};
32
33 //配置写入到_ts.config
34 for(let i in option){
35 config[i] = option[i];
36 };
37
38 //默认开启debug模式
39 config.debug = config.debug === undefined ? true : config.debug;
40
41 //检查如果是.d.ts文件,则编译对应的.ts文件。和修改输出文件路径
42 if(config.src.substr(-5) === '.d.ts'){
43 config.src = config.src.substr(0,config.src.length - 5) + '.ts';
44
45 config.dist = (()=>{
46 if(config.dist.substr(-5) === '.d.js'){
47 return config.dist.substr(0,config.dist.length - 5) + '.js';
48 };
49 return config.dist;
50 })();
51 };
52
53 config.srcInfo = m.pathInfo(config.src);
54
55
56 return new Promise((resolve,reject)=>{
57 //检查文件是否为有效的类型
58 let isSupport = (()=>{
59 let extensions = ['js','es','es6','ts','tsx','jsx'],
60 fileType = config.srcInfo.extension;
61 return extensions.some((item,index)=>{
62 return fileType === '.'+item;
63 });
64 })();
65 if(isSupport){
66 try {
67 _ts.init().then(v => {
68 resolve(v);
69 }).catch(e => {
70 reject(e);
71 });
72 } catch (error) {
73 reject({
74 status:'error',
75 msg:`初始化失败 ${m.path.join(fws.fwsPath,'lib','es2.js')}`,
76 info:error
77 });
78 };
79 }else{
80 reject({
81 status:'error',
82 msg:typeof config.src === 'string' ? `${config.src} 不是有效的文件` : `参数传入错误`
83 });
84 };
85 });
86 }
87
88 init(){
89 const _ts = this,
90 m = _ts.m,
91 config = _ts.config,
92 fileType = config.srcInfo.extension;
93
94 //设置编译插件
95 let plugins = [
96 m.rollup_replace({
97 'process.env.NODE_ENV': JSON.stringify(config.debug ? 'development' : 'production')
98 }),
99
100 //允许引入json文件
101 m.rollup_json(),
102
103 //允许引入node模块
104 m.rollup_nodeResolve({
105 jsnext:true,
106 main:true,
107 extensions:['.mjs', '.js', '.jsx', '.json', '.tsx', '.es6']
108 }),
109
110 //由于node_modules大多数包都是CommonJS规范,因此需要
111 m.rollup_commonjs(),
112
113 m.rollup_typescript2({
114 tsconfigDefaults:{
115 compilerOptions:{
116 alwaysStrict:true,
117 lib:'ES3',
118 module:'ES2015',
119 sourceMap:true,
120 inlineSourceMap:true,
121 moduleResolution:'node',
122 jsx:'react',
123 jsxFactory:'React.createElement'
124 }
125 }
126 })
127 ];
128
129 //项目类型是vue的话,则添加vue支持组件
130 if(fws.config.projectType === 'vue'){
131 let cssPath = `dev/css/${config.srcInfo.name}.css`;
132 plugins.push(m.rollup_vue.default({css:cssPath}))
133 };
134
135 //typescript编译选项(用于编译JS、ES6等文件)
136 let tsOption = {
137 alwaysStrict:true, //是否启用严格模式
138 lib:'ES3', //编译库'ES3','ES5','ES2015','ES2016','ES2017','Latest'
139 module:'ES2015', //代码生成规范'None','CommonJs','AMD','UMD','System','ES2015'
140 sourceMap:true //生成map文件
141 };
142
143 //react文件类型修改编译选项
144 if(fileType === '.tsx' || fileType === '.jsx'){
145 tsOption.jsx = 'react';
146 };
147
148 //将编译插件传递到插件列表
149 plugins.push(require('./tsPlugin')(tsOption));
150
151 // let cache = fws.cache[config.src] ? fws.cache[config.src] : null;
152
153 // console.time('编译');
154
155 //编译方法
156 let render = (resolve,reject)=>{
157 m.rollup.rollup({
158 input:config.src,
159 cache:true,
160 plugins:plugins,
161 onwarn:function(warning){
162 if (warning.code === 'THIS_IS_UNDEFINED') {return;}
163 console.warn( warning.message );
164 }
165 }).then(v => {
166 // 保存缓存
167 // fws.cache[config.src] = v.cache;
168
169 let format = (()=>{
170 if(config.srcInfo.extension === '.js'){
171 return 'es';
172 };
173 let fileContent = m.fs.readFileSync(config.src).toString();
174
175 if(/\nexport /ig.test(fileContent) || fileContent.indexOf('export ') === 0){
176 return 'umd';
177 }else{
178 return 'iife';
179 };
180 })();
181
182 //设置文件输出选项
183 let result = v.generate({
184 format:format, //amd、cjs、es、iife、umd
185 sourcemap:'inline',
186 // file:config.dist,
187 name:config.srcInfo.name//模块名即输入的文件名
188 });
189
190 //输出文件
191 result.then(v => {
192 let code = v.code,
193 map = '//# sourceMappingURL=data:application/json;charset=utf-8;base64,'+new Buffer(JSON.stringify(v.map)).toString('base64'),
194 outCode,
195 distDir = m.path.dirname(config.dist);
196 if(code){
197 code = m.replaceGlobal(code);
198 };
199
200 //将代码转换成为兼容cmd和hjs的规范
201 code = code.replace("typeof define === 'function' && define.amd ? define(factory) :","typeof define === 'function' && define.amd ? define(factory) : \r\n typeof define === 'function' && (define.cmd || define.hjs) ? define(function(require,exports,module){module.exports = factory()}) :");
202
203 outCode = config.debug ? code + map : code;
204
205 //写入文件到硬盘
206 m.fs.ensureDir(distDir,err => {
207 if(err){
208 reject({
209 status:'error',
210 msg:`${distDir} 创建错误`,
211 info:err
212 });
213 }else{
214 try {
215 m.fs.writeFileSync(config.dist,outCode);
216 resolve({
217 status:'success',
218 msg:`写入 ${config.dist}`,
219 distPath:config.dist,
220 data:outCode
221 });
222 } catch (error) {
223 reject({
224 status:'error',
225 msg:`写入失败 ${config.dist}`,
226 distPath:config.dist,
227 info:error
228 });
229 };
230 };
231 });
232 // console.timeEnd('编译');
233 }).catch(e => {
234 reject({
235 status:'error',
236 msg:`${config.src} 编译结果出错`,
237 info:e
238 });
239 });
240 }).catch(e => {
241 reject({
242 status:'error',
243 msg:`${config.src} 编译过程错误`,
244 info:e
245 });
246 });
247 };
248
249 return new Promise(render);
250 }
251}
252module.exports = Es2;