HBuilderX App打包

HBuilderX在Ubuntu下打App Wgt包

剖析HBuilderX结构,完成打包环境的移植。

  • 使用Debugview抓取HbuilderX打wgt包的调试信息,可得:

    [16764] 2023-05-16 09:50:20.583 [INFO:] node "D:/HBuilderX/plugins/node/node.exe"
    [16764] 2023-05-16 09:50:20.583 [INFO:] args ("--max-old-space-size=2048", "--no-warnings", "D:/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/vite-plugin-uni/bin/uni.js")
    
  • 看一下这个uni.js

    require('../dist/cli/index.js')
    
  • 跟着看一下/dist/cli/index.js,很明显是uniapp所使用的内部cli:

    cli
        .command('build')
        .option('--outDir ', `[string] output directory (default: dist)`)
        .option('--assetsInlineLimit ', `[number] static asset base64 inline threshold in bytes (default: 4096)`)
        .option('--sourcemap', `[boolean] output source maps for build (default: false)`)
        .option('--manifest', `[boolean] emit build manifest json`)
        .option('--ssrManifest', `[boolean] emit ssr manifest json`)
        .option('--emptyOutDir', `[boolean] force empty outDir when it's outside of root`, {
        default: true,
    })
        .option('-w, --watch', `[boolean] rebuilds when modules have changed on disk`)
        .action(action_1.runBuild);
    
  • 根据参数表整理一下调用命令:

    node --max-old-space-size=2048 --no-warnings "D:/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/vite-plugin-uni/bin/uni.js" build --platform app --outDir "D:/test/crp-app-dist"
    
  • 直接执行上述命令是不行的,因为uniapp的node_modules下根本就没有编译该工程所需的各种依赖,并且缺少很多环境变量。具体逻辑在/dist/cli/build.js/dist/index.js中都有所表现。

  • 首先,需要使用HbuilderX/plugins/npm下的npm而非shell环境变量下的npm以便使用HbuilderX/plugins下的各种node_modules

  • 其次,需要在执行前对环境变量做修补。以下是一个使用node.js成功在Windows下脱离HbuilderX主程序调用打包的例子:

    /**
     * @author myd
     */
    import {exec} from "child_process";
    import * as util from "util";
    import path from "path";
    import os from "os";
    
    const execAsync = util.promisify(exec);
    export const build = (repoName: string) => {
      const systemTempFolderPath = os.tmpdir();
      return new Promise(async (resolve, reject) => {
        try {
          const HBUILDER_DIR = "D:\\HBuilderX";
          const UNI_INPUT_DIR = path.join(systemTempFolderPath, repoName);
          const VITE_ROOT_DIR = UNI_INPUT_DIR;
          const UNI_HBUILDERX_PLUGINS = path.join(HBUILDER_DIR, 'plugins');
          const UNI_CLI_CONTEXT = path.join(UNI_HBUILDERX_PLUGINS, 'uniapp-cli-vite');
          const UNI_NPM_DIR = path.join(UNI_HBUILDERX_PLUGINS, 'npm');
          const UNI_NODE_DIR = path.join(UNI_HBUILDERX_PLUGINS, 'node');
          const NODE_ENV: any = 'production';
          const NODE = path.join(UNI_NODE_DIR, 'node');
          const UNI_CLI = path.join(UNI_CLI_CONTEXT, 'node_modules', '@dcloudio', 'vite-plugin-uni', 'bin', 'uni.js');
          const PATH_ADDONS = process.env.PATH + `;${UNI_INPUT_DIR}/node_modules/.bin;`;
          const childEnv = {
            ...process.env,
            PATH: PATH_ADDONS,
            HBUILDER_DIR,
            UNI_INPUT_DIR,
            VITE_ROOT_DIR,
            UNI_CLI_CONTEXT,
            UNI_HBUILDERX_PLUGINS,
            UNI_NPM_DIR,
            UNI_NODE_DIR,
            NODE_ENV,
            NODE
          };
          process.chdir(UNI_CLI_CONTEXT);
          const buildCommand = `"${NODE}" --max-old-space-size=2048 --no-warnings "${UNI_CLI}" build --platform app --outDir ${path.join(systemTempFolderPath, repoName + '-dist')}`
          const {stdout, stderr} = await execAsync(buildCommand, {env: {...childEnv}});
          console.error('stderr:', stderr);
          resolve(1)
        } catch (error) {
          console.error('Error during build:', error);
          reject(0)
        }
      })
    }
    
  • 调试成功后,将HbuilderX的主目录打包为tar并传到Linux服务器上展开:

    tar -cf ~/HbuilderX-3.9.5-darwin.tar /Applications/HBuilderX.app/Contents/HBuilderX
    scp -P 22 -r ~/HbuilderX-3.9.5-darwin.tar [email protected]:/root/
    tar -xf ./HbuilderX-3.9.5-darwin.tar
    

    注意,为了移植到Linux服务器上,一定要提取macOS版本的HbuilderX,因为Windows和Unix-Like的npm结构不同,即使npm-cli的实现是跨平台的。

  • HBuilderX 3.9.5使用的是Node 16.17.0。如果不确定Node版本,提取前在宿主机上查询HBuilderX使用的Node版本:

    myd@myddeMac-Pro ~ % /Applications/HBuilderX.app/Contents/HBuilderX/plugins/node/node -v
    v16.17.0
    
  • 为Linux服务器下载对应系统和架构的Node二进制包并覆盖HBuilderX所使用的node,这里以Linux-amd64-16.17.0为例:

    wget https://nodejs.org/download/release/v16.17.0/node-v16.17.0-linux-x64.tar.gz
    tar -xzvf ./node-v16.17.0-linux-x64.tar.gz
    cp ./node-v16.17.0-linux-x64/bin/node ./HBuilderX/plugins/node
    chmod +x ~/HBuilderX/plugins/node/node
    

    更多版本可以在https://nodejs.org/download/release/查看。

  • 部署uniapp-build项目。该项目的最低node版本为v18(公司内部项目,恕不提供外部下载)

    git clone https://****/myd/uniapp-build
    cd ./uniapp-build
    npm i
    npm run build
    npm run start
    
  • 比较难绷的是,公司服务器的Ubuntu 18.04缺少node 18的依赖glibc-2.28,因此需要进一步对系统环境进行修补。编译glibc-2.28

    sudo apt-get install g++ make gcc bison
    apt install -y gawk
    cd ~
    wget -c https://ftp.gnu.org/gnu/glibc/glibc-2.28.tar.gz
    tar -zxf glibc-2.28.tar.gz
    cd glibc-2.28
    mkdir glibc-build
    cd glibc-build
    ../configure --prefix=/opt/glibc-2.28
    make -j 6
    make install
    cd ~
    rm -rf ./glibc-2.28 ./glibc-2.28.tar.gz
    apt install -y patchelf
    # 直装的node使用如下命令
    patchelf --set-interpreter /opt/glibc-2.28/lib/ld-linux-x86-64.so.2 --set-rpath /opt/glibc-2.28/lib/:/lib/x86_64-linux-gnu/:/usr/lib/x86_64-linux-gnu/ /usr/local/bin/node
    # nvm使用如下命令
    patchelf --set-interpreter /opt/glibc-2.28/lib/ld-linux-x86-64.so.2 --set-rpath /opt/glibc-2.28/lib/:/lib/x86_64-linux-gnu/:/usr/lib/x86_64-linux-gnu/ /root/.nvm/versions/node/v18.18.2/bin/node
    # 记得修补HBuilderX的node
    patchelf --set-interpreter /opt/glibc-2.28/lib/ld-linux-x86-64.so.2 --set-rpath /opt/glibc-2.28/lib/:/lib/x86_64-linux-gnu/:/usr/lib/x86_64-linux-gnu/ ~/HBuilderX/plugins/node/node
    
  • 接下来修改uniapp-cli-vitepackage.json

    vi /root/HBuilderX/plugins/uniapp-cli-vite/package.json
    

    删除devDependencies节点下的@esbuild/darwin-arm64@esbuild/darwin-x64fsevents并安装对应目标平台的esbuild

    npm i -D -f @esbuild/[email protected]
    npm i -f
    
  • 访问http://server.ip:3000查看效果。注意初次拉代码时需要配置全局git用户并登录一次。

    git config --global credential.helper store
    

你可能感兴趣的:(vue.js,前端,uniapp)