const fs = require('fs'); const path = require('path'); const readline = require('readline'); const babel = require("@babel/core"); const iOSBabelConfig = { presets: [ [ '@babel/env', { targets: { safari: '8', }, }, ], ], }; const CodePieces = { headers: `/* * native-source-code.cc for Hippy * * The file is generated by js2cpp for Hippy. * js2cpp is maintenance by Lucas Pei * Copyright © ${new Date().getFullYear()} Tencent. All rights reserved. * * Generated at ${new Date().toString()}. * DO NOT EDIT IT. */ #include "core/napi/native-source-code.h" #include #include "core/base/macros.h" // clang-format off namespace {`, piece_1: ` } // namespace namespace hippy { static const std::unordered_map golbal_base_js_source_map{ {"bootstrap.js", {k_bootstrap, arraysize(k_bootstrap) - 1}}, // NOLINT {"hippy.js", {k_hippy, arraysize(k_hippy) - 1}}, // NOLINT`, piece_2: ` }; const NativeSourceCode GetNativeSourceCode(const std::string& filename) { const auto it = golbal_base_js_source_map.find(filename); return it != golbal_base_js_source_map.cend() ? it->second : NativeSourceCode{}; } } // namespace hippy `, }; let wraperFront_buffer = fs.readFileSync(`${__dirname}/wraperFront.js`); let wraperFront_byte_arr = []; for (let i = 0; i < wraperFront_buffer.length; i++) { wraperFront_byte_arr.push(wraperFront_buffer[i]); } let wraperEnd_buffer = fs.readFileSync(`${__dirname}/wraperEnd.js`); let wraperEnd_byte_arr = []; for(let i = 0; i < wraperEnd_buffer.length; i++) { wraperEnd_byte_arr.push(wraperEnd_buffer[i]); } function GetAllRequiredFiles(platform) { return new Promise((resole, reject) => { let rl = readline.createInterface({ input: fs.createReadStream(path.resolve(__dirname, `../../core/js/entry/${platform}/hippy.js`)) }); let filePaths = [ path.resolve(__dirname, './bootstrap.js'), path.resolve(__dirname, `../../core/js/entry/${platform}/hippy.js`), path.resolve(__dirname, '../../core/js/modules/ExceptionHandle.js'), ]; rl.on('line', (line) => { if(line.split('//')[0].indexOf('require') > -1) { let _path = line.split("('")[1].split("')")[0]; filePaths.push(`${__dirname}/../../core/js/entry/${platform}/${_path}`); } }); rl.on('close', () => { resole(filePaths); }); }); } function readFileToBuffer(platform, filePath) { switch(platform) { case 'android': { return fs.readFileSync(filePath); } case 'ios': { const code = fs.readFileSync(filePath).toString(); const compiled = babel.transform(code, iOSBabelConfig); return Buffer.from(compiled.code); } } } function GenerateCPP(platform, buildDirPath) { let code = CodePieces.headers; GetAllRequiredFiles(platform).then((files_arr) => { files_arr.forEach((filePath) => { let file_split_arr = filePath.split('/'); let file_name = file_split_arr[file_split_arr.length - 1].split('.')[0]; let file_buffer = readFileToBuffer(platform, filePath); let byte_arr = []; for(let i = 0; i < file_buffer.length; i++) { byte_arr.push(file_buffer[i]); } if(file_name === 'bootstrap' || file_name === 'ExceptionHandle') { code += ` const uint8_t k_${file_name}[] = { ${byte_arr.join(',')},0 }; // NOLINT`; } else { code += ` const uint8_t k_${file_name}[] = { ${wraperFront_byte_arr.join(',')},${byte_arr.join(',')},${wraperEnd_byte_arr.join(',')},0 }; // NOLINT`; } }); code += CodePieces.piece_1; for(let i = 2; i < files_arr.length; i++) { let file_split_arr = files_arr[i].split('/'); let file_name = file_split_arr[file_split_arr.length - 1].split('.')[0]; code += ` {"${file_name}.js", {k_${file_name}, arraysize(k_${file_name}) - 1}}, // NOLINT`; } code += CodePieces.piece_2; // step4 - create file const targetPath = `${buildDirPath}/native-source-code-${platform}.cc`; fs.writeFile(targetPath, code, function( err ) { if( err ) { console.log( "[writeFile error] : ", err ); return; } console.log(`${platform} convert success, output ${targetPath}`); }); }); } GenerateCPP('ios', path.resolve(__dirname, '../../core/napi/jsc')); GenerateCPP('android', path.resolve(__dirname, '../../core/napi/v8/')); /* eslint-disable */