如何實現快應用多渠道打包

來源: 華為開發(fā)者論壇
作者:Mayism
時間:2021-04-08
17670
以H5快應用為例,我有2個H5 url需要轉換成2個不同的H5快應用,每個H5快應用的名稱、logo、包名都是不同的,但是我不想創(chuàng)建2個項目,而是在1個項目中完成這兩個H5快應用的打包??鞈媚芊褡龅侥??是否支持構建不同場景下的rpk包呢?

背景

在同一個項目中當有如下需求時:

不同的rpk圖標

不同的服務器域名

不同的包名

 不同的應用名稱

 不同的環(huán)境配置

以H5快應用為例,我有2個H5 url需要轉換成2個不同的H5快應用,每個H5快應用的名稱、logo、包名都是不同的,但是我不想創(chuàng)建2個項目,而是在1個項目中完成這兩個H5快應用的打包。快應用能否做到呢?是否支持構建不同場景下的rpk包呢?

解決方法

   快應用屬于前端開發(fā),不像原生app開發(fā)工具Android Studio自動支持多渠道打包。但是快應用是可以通過寫js腳本達到這個目的。以下解決步驟以打包兩個H5快應用為例,均使用快應用web組件加載,一個url是百度首頁,一個url是163首頁。

步驟1: 配置環(huán)境變量

在已經創(chuàng)建好的H5快應用項目根目錄下創(chuàng)建config目錄,該目錄下定義百度和163的環(huán)境值,如下圖所示:

ia_5000000002.png文件說明:

163:配置H5 url為163首頁的目錄,該目錄下config.js中定義了163首頁的H5 url,manifest.json文件是163 H5快應用的配置文件,配置163 H5快應用的包名、應用名稱、應用圖標等信息。

     config.js代碼:

module.exports = {

    url: "https://m.163.com"

}

baidu:配置H5 url為百度首頁的目錄。該目錄下config.js中定義了百度首頁的H5 url,manifest.json文件是百度H5快應用的配置文件,配置百度H5快應用的包名、應用名稱、應用圖標等信息。

config.js代碼:

module.exports = {

    url: "https://m.baidu.com"

}

Hello:應用首頁,hello.ux里使用web組件加載url,url值根據不同渠道是動態(tài)變化的,取值是來源于項目src目錄下創(chuàng)建的config.js文件中暴露的變量url,注意非步驟1環(huán)境新建的環(huán)境目錄config下面的文件。

<script>

  import router from "@system.router";

  import config from "../config.js"

  export default {

    props: ['websrc'],

    data: {

      title: "",

      // TODO Replace the link to the H5 app

      loadUrl: config.url,

      }

     }

      ...省略其他代碼

  </script>

步驟2:編寫node.js腳本代碼

在圖1中我們看到config目錄下有兩個js文件,prebuild.js 和postbuild.js。這兩個文件是已經編寫好的js腳本文件。

postbuild.js:編譯構建完成后的操作,用于將打包后的rpk文件從原始目錄dist輸出到自定義的out目錄,方便查看歷史構建的rpk版本。

prebuild.js:編譯構建之前執(zhí)行的js腳本。首先判斷當前的打包渠道參數值,根據對應的渠道替換該渠道下的環(huán)境文件,將該渠道下的manifest.json和config.js文件替換到src目錄下的同名文件;另一方面,刪除dist目錄下的rpk文件,確保編譯構建的rpk包是最新的。

prebuild.js示例代碼如下:

const path = require('path');

const fs = require("fs");

console.log("prebuild.js path="+path+", fs= "+fs);

//get env config

let faEnv = process.argv[2] ? process.argv[2] : '163';

console.log("faEnv : " + faEnv)

const projectPath = process.cwd();

console.log("projectPath= "+projectPath);

const configFilePath = path.join(projectPath, '/src/config.js');

console.log("configFilePath= "+configFilePath);

const manifestFilePath = path.join(projectPath, '/src/manifest.json');

console.log("manifestFilePath= "+manifestFilePath);

if (fs.existsSync(configFilePath)) {

    console.log("delete : config.js")

    fs.unlinkSync(configFilePath);

}

if (fs.existsSync(manifestFilePath)) {

    console.log("delete : manifest.json")

    fs.unlinkSync(manifestFilePath);

}

const distDirPath = path.join(projectPath, '/dist');

console.log("prebuild distDirPath= "+distDirPath);

if (fs.existsSync(distDirPath)) {

    console.log("postbuild.js exist  dist and out, begin copy rpk");

    fs.readdirSync(distDirPath).forEach(function (name) {

        var filePath = path.join(distDirPath, name);

        console.log("prebuild filePath= "+filePath+",name="+name);

        var stat = fs.statSync(filePath);

        if (stat.isFile()) {

            console.log("delete : rpk file");

            fs.unlinkSync(filePath);

        } 

    });

}

fs.copyFileSync(——${projectPath}/config/${faEnv}/config.js——, configFilePath);

fs.copyFileSync(——${projectPath}/config/${faEnv}/manifest.json——, manifestFilePath);

postbuild.js代碼如下:

const path = require('path');

const fs = require("fs");

console.log("postbuild.js path="+path+", fs= "+fs);

const projectPath = process.cwd();

console.log("projectPath= "+projectPath);

const distDirPath = path.join(projectPath, '/dist');

console.log("distDirPath= "+distDirPath);

const outDirPath = path.join(projectPath, '/out');

if (!fs.existsSync(outDirPath)) {

    //create output dir 

    console.log("out dir not exist and create")

     fs.mkdirSync(outDirPath);

}

if (fs.existsSync(distDirPath) && fs.existsSync(outDirPath)) {

    console.log("postbuild.js exist  dist and out, begin copy rpk");

    fs.readdirSync(distDirPath).forEach(function (name) {

        var filePath = path.join(distDirPath, name);

        console.log("filePath= "+filePath+",name="+name);

        var stat = fs.statSync(filePath);

        if (stat.isFile()) {

           var outrpkfilepath=path.join(outDirPath,name);

            fs.copyFileSync(filePath, outrpkfilepath);

        } 

    });

}

步驟3: 編譯構建

1)  IDE工具欄選擇Npm->Start Npm Library

2)  IDE工具欄選擇Npm->Npm install

   當完成以上步驟時,項目工程下會生成兩個文件package.json和fa-toolkit-3.1.2-Stable.301.tgz。其中fa-toolkit-3.1.2-Stable.301.tgz是編譯器版本文件,版本號取決于IDE中實際集成的版本。

打開編譯package.json文件,在scripts標簽下添加build_163、 buid_baidu、copyRpk腳本,引入步驟2中定義的js文件。

3)  build_163: 編譯構建163網頁的H5快應用,“node ./config/prebuild.js 163”中的163是Node命令執(zhí)行腳本的參數變量,此變量值對應prebuild.js中faEnv變量。腳本形式是標準的三部分:編譯前、編譯、編譯后,由&&連接組成,表示前一步完成了,再進行下一步。

build_baidu:編譯構建百度網頁的H5快應用。

4)  進入項目根目錄下執(zhí)行打開cmd,執(zhí)行npm run build_163,即可打包出163 H5快應用;執(zhí)行npm run build_baidu即可打包出百度H5快應用。也可直接在IDE中切換到終端,然后執(zhí)行同樣命令。

ia_5000000003.png

package.json內容如下:

{

  "name": "com.h5.demo",

  "version": "1.0.0",

  "description": "",

  "scripts": {

    "build_163": "node ./config/prebuild.js 163 && npm run fa-release && npm run copyRpk",

    "build_baidu": "node ./config/prebuild.js baidu && npm run fa-release && npm run copyRpk",

    "fa-build": "node node_modules/webpack/bin/webpack.js --progress --config ./node_modules/fa-toolkit/webpack.config.js",

    "copyRpk": "node ./config/postbuild.js",

    "fa-watch": "node node_modules/webpack/bin/webpack.js --watch --progress --config ./node_modules/fa-toolkit/webpack.config.js",

    "fa-release": "node ./node_modules/cross-env/src/bin/cross-env.js uglifyjs=true sign=release node_modules/webpack/bin/webpack.js --progress --config ./node_modules/fa-toolkit/webpack.config.js"

  },

  "devDependencies": {

    "fa-toolkit": "file:fa-toolkit-3.1.2-Stable.301.tgz",

    "cross-env": "^7.0.2"

  }

}

總結

快應用多渠道打包實現本質上是環(huán)境文件的替換,而這些環(huán)境判斷、文件替換都是基于標準的npm腳本、node.js中的文件操作。

Npm腳本:http://www.ruanyifeng.com/blog/2016/10/npm_scripts.html

https://docs.npmjs.com/cli/v7/using-npm/developers

Node.js文件操作:http://nodejs.cn/api/fs.html

立即登錄,閱讀全文
版權說明:
本文內容來自于華為開發(fā)者論壇,本站不擁有所有權,不承擔相關法律責任。文章內容系作者個人觀點,不代表快出海對觀點贊同或支持。如有侵權,請聯系管理員(zzx@kchuhai.com)刪除!
掃碼登錄
打開掃一掃, 關注公眾號后即可登錄/注冊
加載中
二維碼已失效 請重試
刷新
賬號登錄/注冊
小程序
快出海小程序
公眾號
快出海公眾號
商務合作
商務合作
投稿采訪
投稿采訪
出海管家
出海管家