text: 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 <lucaspei@tencent.com>
  * 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 <unordered_map>
  #include "core/base/macros.h"
  
  // clang-format off
  
  namespace {`,
      piece_1: `
  }  // namespace
  
  namespace hippy {
    static const std::unordered_map<std::string, NativeSourceCode> 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 */