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