• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16var path = require('path')
17var fs = require('fs')
18var shell = require('shelljs');
19const md5 = require('md5');
20
21const red = '\u001b[31m';
22const reset = '\u001b[39m';
23const multiResourceBuild = {};
24const systemModules = [];
25
26;(function readSystemModules() {
27  const systemModulesPath = path.resolve(__dirname,'../../api');
28  if (fs.existsSync(systemModulesPath)) {
29    systemModules.push(...fs.readdirSync(systemModulesPath));
30  }
31})();
32
33function deleteFolderRecursive(url) {
34  let files = [];
35  if (fs.existsSync(url)) {
36    files = fs.readdirSync(url);
37    files.forEach(function(file) {
38      const curPath = path.join(url, file);
39      if (fs.statSync(curPath).isDirectory()) {
40        deleteFolderRecursive(curPath);
41      } else {
42        fs.unlinkSync(curPath);
43      }
44    });
45    fs.rmdir(url, function(err) {});
46  }
47}
48
49function readManifest(manifestFilePath) {
50  let manifest = {};
51  try {
52    if (fs.existsSync(manifestFilePath)) {
53      const jsonString = fs.readFileSync(manifestFilePath).toString();
54      manifest = JSON.parse(jsonString);
55    }
56  } catch (e) {
57    throw Error('\u001b[31m' + 'ERROR: the manifest.json file format is invalid.' +
58      '\u001b[39m').message;
59  }
60  return manifest;
61}
62
63function loadEntryObj(projectPath, device_level, abilityType, manifestFilePath) {
64  let entryObj = {};
65  switch (abilityType) {
66    case 'page':
67      const appJSPath = path.resolve(projectPath, 'app.js');
68      if (device_level === 'card') {
69        entryObj = addPageEntryObj(readManifest(manifestFilePath), projectPath);
70      } else {
71        if (!fs.existsSync(appJSPath)) {
72          throw Error(red + 'ERROR: missing app.js' + reset).message;
73        }
74        entryObj['./app'] = path.resolve(projectPath, './app.js?entry');
75      }
76      break;
77    case 'form':
78      entryObj = addPageEntryObj(readManifest(manifestFilePath), projectPath);
79      entryObj[`./${abilityType}`] =  path.resolve(projectPath, `./${abilityType}.js?entry`);
80      break;
81    case 'testrunner':
82      break;
83    default:
84      entryObj[`./${abilityType}`] =  path.resolve(projectPath, `./${abilityType}.js?entry`);
85      break;
86  }
87  return entryObj;
88}
89
90function addPageEntryObj(manifest, projectPath) {
91  let entryObj = {};
92  const pages = manifest.pages;
93  if (pages === undefined) {
94    throw Error('ERROR: missing pages').message;
95  }
96  pages.forEach((element) => {
97    const sourcePath = element;
98    const hmlPath = path.join(projectPath, sourcePath + '.hml');
99    const aceSuperVisualPath = process.env.aceSuperVisualPath || '';
100    const visualPath = path.join(aceSuperVisualPath, sourcePath + '.visual');
101    const isHml = fs.existsSync(hmlPath);
102    const isVisual = fs.existsSync(visualPath);
103    if (isHml && isVisual) {
104      throw Error(red + 'ERROR: ' + sourcePath + ' cannot both have hml && visual').message;
105    } else if (isHml) {
106      entryObj['./' + element] = path.resolve(projectPath, './' + sourcePath + '.hml?entry');
107    } else if (isVisual) {
108      entryObj['./' + element] = path.resolve(aceSuperVisualPath, './' + sourcePath +
109        '.visual?entry');
110    }
111  })
112  return entryObj;
113}
114
115function compileCardModule(env) {
116  if (process.env.aceModuleJsonPath && fs.existsSync(process.env.aceModuleJsonPath)) {
117    const moduleJsonConfig = JSON.parse(fs.readFileSync(process.env.aceModuleJsonPath).toString());
118    if (moduleJsonConfig.module &&
119      (moduleJsonConfig.module.uiSyntax === 'ets' || moduleJsonConfig.module.language === 'ets')) {
120      process.env.DEVICE_LEVEL = 'card';
121    } else if (validateCardModule(moduleJsonConfig) && !process.env.compileCardModule) {
122      process.env.compileCardModule = true;
123      const cmd = `webpack --config webpack.rich.config.js --env compilerType=${env.compilerType} ` +
124        `DEVICE_LEVEL=card aceModuleRoot=${process.env.projectPath} ` +
125        `aceModuleJsonPath=${process.env.aceModuleJsonPath} aceProfilePath=${process.env.aceProfilePath} ` +
126        `watchMode=${process.env.watchMode} cachePath=${process.env.cachePath} ` +
127        `aceModuleBuild=${process.env.buildPath}`;
128      shell.exec(cmd, (err) => {
129        if (err) {
130          throw Error(err).message;
131        }
132      })
133    }
134  }
135}
136
137function validateCardModule(moduleJsonConfig) {
138  if (moduleJsonConfig.module && moduleJsonConfig.module.extensionAbilities) {
139    for (let i = 0; i < moduleJsonConfig.module.extensionAbilities.length; i++) {
140      const extensionAbility = moduleJsonConfig.module.extensionAbilities[i];
141      if (extensionAbility.type && extensionAbility.type === 'form') {
142        return true;
143      }
144    }
145  }
146  return false;
147}
148
149function hashProjectPath(projectPath) {
150  process.env.hashProjectPath = "_" + md5(projectPath);
151}
152
153function checkMultiResourceBuild(aceBuildJson) {
154  if (aceBuildJson && fs.existsSync(aceBuildJson)) {
155    try {
156      const content = JSON.parse(fs.readFileSync(aceBuildJson));
157      if (content["multiResourceBuild"]) {
158        multiResourceBuild.value = content["multiResourceBuild"]
159      }
160      if (content["projectRootPath"]) {
161        process.env.projectRootPath = content["projectRootPath"]
162      }
163    } catch (error) {
164    }
165  }
166}
167
168function readWorkerFile() {
169  const workerEntryObj = {};
170  if (process.env.aceBuildJson && fs.existsSync(process.env.aceBuildJson)) {
171    const workerConfig = JSON.parse(fs.readFileSync(process.env.aceBuildJson).toString());
172    if(workerConfig.workers) {
173      workerConfig.workers.forEach(worker => {
174        if (!/\.(js)$/.test(worker)) {
175          worker += '.js';
176        }
177        const relativePath = path.relative(process.env.projectPath, worker);
178        if (filterWorker(relativePath)) {
179          workerEntryObj[relativePath.replace(/\.(ts|js)$/,'').replace(/\\/g, '/')] = worker;
180        }
181      })
182      return workerEntryObj;
183    }
184  }
185  return null;
186}
187
188function filterWorker(workerPath) {
189  return /\.(ts|js)$/.test(workerPath);
190}
191
192function compareCache(cachePath) {
193  const entryFile = path.join(cachePath, 'entry.json');
194  const cssFile = process.env.watchCSSFiles;
195
196  let files = [];
197  let cssObject = {};
198  if (fs.existsSync(cssFile)) {
199    cssObject = JSON.parse(fs.readFileSync(cssFile));
200    if (cssObject['clear'] === true) {
201      deleteFolderRecursive(cachePath);
202      return;
203    }
204    Object.keys(cssObject).forEach(key => {
205      if (key !== 'entry') {
206        files.push(key);
207      }
208    })
209  }
210
211  if (fs.existsSync(entryFile)) {
212    files = files.concat(JSON.parse(fs.readFileSync(entryFile)));
213  }
214
215  for(let file of files) {
216    if (!fs.existsSync(file)) {
217      deleteFolderRecursive(cachePath);
218      break;
219    } else if (cssObject['atime'] && cssObject['atime'][file]) {
220      if (cssObject['atime'][file] !== fs.statSync(file).atime.toString()) {
221        deleteFolderRecursive(cachePath);
222        break;
223      }
224    }
225  }
226}
227
228function parseAbilityName(abilityType, projectPath) {
229  if (abilityType === 'page') {
230    return path.resolve(__dirname, projectPath, 'app.js');
231  } else {
232    return path.resolve(__dirname, projectPath, abilityType + '.js');
233  }
234}
235
236module.exports = {
237  deleteFolderRecursive: deleteFolderRecursive,
238  readManifest: readManifest,
239  loadEntryObj: loadEntryObj,
240  compileCardModule: compileCardModule,
241  hashProjectPath: hashProjectPath,
242  checkMultiResourceBuild: checkMultiResourceBuild,
243  multiResourceBuild: multiResourceBuild,
244  readWorkerFile: readWorkerFile,
245  compareCache: compareCache,
246  systemModules: systemModules,
247  parseAbilityName: parseAbilityName
248};