1 | /**
|
2 | * 文件关键字替换
|
3 | * @memberOf Watch
|
4 | */
|
5 | class ReplaceTask {
|
6 | constructor(option){
|
7 | const _ts = this;
|
8 |
|
9 | option = option || {};
|
10 |
|
11 | let m = _ts.m = {
|
12 | fs:require('fs-extra'),
|
13 | path:require('path'),
|
14 | pathInfo:require('./getPathInfo'),
|
15 | getDirFilesPath:require('./getDirFilesPath'),
|
16 | tip:require('./tip')
|
17 | },
|
18 | config = _ts.config = {};
|
19 |
|
20 | //配置写入到_ts.config
|
21 | for(let i in option){
|
22 | config[i] = option[i];
|
23 | };
|
24 |
|
25 | return ()=>{
|
26 | return new Promise((resolve,reject)=>{
|
27 | let taskList = _ts.taskList(),
|
28 | result = {
|
29 | status:'success'
|
30 | },
|
31 | f = async ()=>{
|
32 | for(let i=0,len=taskList.length; i<len; i++){
|
33 | let subTask = await taskList[i]();
|
34 | if(subTask.status === 'success'){
|
35 | m.tip.success(subTask.msg);
|
36 | };
|
37 | };
|
38 | result.msg = '关键字匹配替换完成';
|
39 | return result;
|
40 | };
|
41 | if(taskList.length === 0){
|
42 | result.msg = '无需要匹配替换的文件';
|
43 | resolve(result);
|
44 | return;
|
45 | };
|
46 |
|
47 | f().then(v => {
|
48 | resolve(v);
|
49 | }).catch(e => {
|
50 | reject(e);
|
51 | });
|
52 | });
|
53 | };
|
54 | }
|
55 | taskList(){
|
56 | const _ts = this,
|
57 | m = _ts.m,
|
58 | config = _ts.config,
|
59 | rule = config.rule;
|
60 |
|
61 | let tasks = [],
|
62 |
|
63 | //获取目录内所有文件
|
64 | data = m.getDirFilesPath({
|
65 | srcDir:config.src,
|
66 | ignoreDir:[], //不排除任何目录
|
67 | ignore_:false //不排除以"_"开始的文件
|
68 | });
|
69 |
|
70 | //遍历替换规则,如果类型为'*'则会匹配所有的`.js`、`.css`、`.html`、`.htm`、`.json`、`.xml`文件,否则只匹配替换指定类型的文件
|
71 | for(let i in rule){
|
72 | if(i === '*'){
|
73 | let allType = ['js','css','html','htm','json','xml'];
|
74 | allType.forEach(item => {
|
75 | if(data['.'+item]){
|
76 | for(let file in data['.'+item]){
|
77 | tasks.push(
|
78 | ()=>{
|
79 | return _ts.replace({
|
80 | src:file,
|
81 | dist:file,
|
82 | rule:rule[i]
|
83 | })
|
84 | }
|
85 | );
|
86 | };
|
87 | };
|
88 | });
|
89 | }else if(data[i]){
|
90 | for(let file in data[i]){
|
91 | tasks.push(
|
92 | ()=>{
|
93 | return _ts.replace({
|
94 | src:file,
|
95 | dist:file,
|
96 | rule:rule[i]
|
97 | })
|
98 | }
|
99 | );
|
100 | };
|
101 | };
|
102 | };
|
103 | return tasks;
|
104 | }
|
105 | replace(option){
|
106 | const _ts = this,
|
107 | m = _ts.m;
|
108 | let src = option.src,
|
109 | dist = option.dist,
|
110 | rule = option.rule,
|
111 | distDir = m.path.dirname(src);
|
112 |
|
113 | let fileInfo = m.pathInfo(src);
|
114 | return new Promise((resolve,reject)=>{
|
115 | //如果不是有效的文件,返回失败
|
116 | if(fileInfo.type !== 'file'){
|
117 | reject({
|
118 | status:'error',
|
119 | msg:`文件不存在 ${src}`
|
120 | });
|
121 | };
|
122 |
|
123 | let fileContent = m.fs.readFileSync(src).toString();
|
124 | rule.forEach(item => {
|
125 | let find = item.find,
|
126 | replace = item.replace;
|
127 |
|
128 | //遍历全局变量,如果需要查找的有全局变量,此处需要用全局变量对应的值进行替换
|
129 | for(let i in fws.globalReplace){
|
130 | if(find.indexOf(i) > -1){
|
131 | find = find.replaceAll(i,fws.globalReplace[i]);
|
132 | };
|
133 | };
|
134 |
|
135 | //如果传入的查询关键是是字符串,则转换为正则。否则还是使用正则
|
136 | if(typeof find === 'string'){
|
137 | fileContent = fileContent.replaceAll(find,replace);
|
138 | }else{
|
139 | fileContent = fileContent.replace(find,replace);
|
140 | };
|
141 |
|
142 | m.fs.ensureDir(distDir,err => {
|
143 | if(err){
|
144 | reject({
|
145 | status:'error',
|
146 | msg:`${distDir} 创建错误`,
|
147 | info:err
|
148 | });
|
149 | }else{
|
150 | try {
|
151 | m.fs.writeFileSync(dist,fileContent);
|
152 | resolve({
|
153 | status:'success',
|
154 | msg:`写入 ${dist}`,
|
155 | distPath:dist,
|
156 | data:fileContent
|
157 | });
|
158 | } catch (error) {
|
159 | reject({
|
160 | status:'error',
|
161 | msg:`写入失败 ${dist}`,
|
162 | distPath:dist,
|
163 | info:error
|
164 | });
|
165 | };
|
166 | };
|
167 | });
|
168 | });
|
169 |
|
170 | });
|
171 | }
|
172 |
|
173 | };
|
174 |
|
175 | module.exports = ReplaceTask; |
\ | No newline at end of file |