From 3839a9bd15ad5e61cffd63dad0a0059606ffb3d8 Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Tue, 21 Nov 2023 17:44:29 +0000 Subject: [PATCH] build(electron): asar (#4965) Due to restrictions on how Electron package works, the `node_modules` should not be hoisted and not to use s/h-links at all. This is why we need to have two separate installs for electron and non-electron packages in the build. Tested via the following script ```bash #!/bin/bash echo "step 1: clean up" find . -name "node_modules" -prune -exec rm -rf '{}' + # git clean -dfX build_type=canary echo "step 2: install web dependencies" # firstly, build web static PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 SENTRYCLI_SKIP_DOWNLOAD=1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 HUSKY=1 yarn echo "step 3: generate assets" BUILD_TYPE="$build_type" yarn workspace @affine/electron generate-assets # cleanup node_modules find . -name "node_modules" -prune -exec rm -rf '{}' + echo "step 4: install electron dependencies" # install electron deps yarn config set nmHoistingLimits workspaces yarn config set enableScripts false yarn config set nmMode classic PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 HUSKY=0 yarn workspaces focus @affine/electron @affine/monorepo echo "step 5: build native" # build native yarn workspace @affine/native build yarn workspace @affine/storage build echo "step 6: build electron" # build electron yarn workspace @affine/electron build echo "step 7: package electron" # package SKIP_GENERATE_ASSETS=1 BUILD_TYPE="$build_type" HOIST_NODE_MODULES=1 yarn workspace @affine/electron package ``` --- .github/actions/setup-node/action.yml | 4 ++-- .github/workflows/build-desktop.yml | 3 ++- packages/frontend/electron/forge.config.mjs | 2 ++ packages/frontend/electron/package.json | 3 ++- .../scripts/macos-arm64-output-check.ts | 21 +++++-------------- yarn.lock | 21 ++++++++++++++----- 6 files changed, 29 insertions(+), 25 deletions(-) diff --git a/.github/actions/setup-node/action.yml b/.github/actions/setup-node/action.yml index d74ec72f19..f00e6b47ef 100644 --- a/.github/actions/setup-node/action.yml +++ b/.github/actions/setup-node/action.yml @@ -49,9 +49,9 @@ runs: cache: 'yarn' - name: Set nmMode - if: ${{ inputs.hard-link-nm == 'true' }} + if: ${{ inputs.hard-link-nm == 'false' }} shell: bash - run: yarn config set nmMode hardlinks-local + run: yarn config set nmMode classic - name: Set nmHoistingLimits if: ${{ inputs.nmHoistingLimits }} diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 74e97bf56a..8017e0edf7 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -159,7 +159,8 @@ jobs: env: SKIP_BUNDLE: true SKIP_WEB_BUILD: true - run: yarn workspace @affine/electron make --platform=darwin --arch=arm64 + HOIST_NODE_MODULES: 1 + run: yarn workspace @affine/electron package --platform=darwin --arch=arm64 - name: Output check if: ${{ matrix.spec.os == 'macos-latest' && matrix.spec.arch == 'arm64' }} diff --git a/packages/frontend/electron/forge.config.mjs b/packages/frontend/electron/forge.config.mjs index 6a01e66ae8..9e9e2d7978 100644 --- a/packages/frontend/electron/forge.config.mjs +++ b/packages/frontend/electron/forge.config.mjs @@ -122,8 +122,10 @@ export default { schemes: [productName.toLowerCase()], }, ], + asar: true, }, makers, + plugins: [{ name: '@electron-forge/plugin-auto-unpack-natives', config: {} }], hooks: { readPackageJson: async (_, packageJson) => { // we want different package name for canary build diff --git a/packages/frontend/electron/package.json b/packages/frontend/electron/package.json index 2ea9c68a52..ef4d567612 100644 --- a/packages/frontend/electron/package.json +++ b/packages/frontend/electron/package.json @@ -43,6 +43,7 @@ "@electron-forge/maker-dmg": "^6.4.2", "@electron-forge/maker-squirrel": "^6.4.2", "@electron-forge/maker-zip": "^6.4.2", + "@electron-forge/plugin-auto-unpack-natives": "^6.4.2", "@electron-forge/shared-types": "^6.4.2", "@electron/remote": "2.0.12", "@reforged/maker-appimage": "^3.3.1", @@ -50,7 +51,7 @@ "@types/uuid": "^9.0.5", "builder-util-runtime": "^9.2.1", "cross-env": "^7.0.3", - "electron": "^27.0.0", + "electron": "^27.1.0", "electron-log": "^5.0.0", "electron-squirrel-startup": "1.0.0", "electron-window-state": "^5.0.3", diff --git a/packages/frontend/electron/scripts/macos-arm64-output-check.ts b/packages/frontend/electron/scripts/macos-arm64-output-check.ts index 5158559fe3..307bf790fc 100644 --- a/packages/frontend/electron/scripts/macos-arm64-output-check.ts +++ b/packages/frontend/electron/scripts/macos-arm64-output-check.ts @@ -1,26 +1,15 @@ -import { readdir } from 'node:fs/promises'; +import fs from 'node:fs'; +import path from 'node:path'; import { fileURLToPath } from 'node:url'; const outputRoot = fileURLToPath( new URL( - '../out/canary/AFFiNE-canary-darwin-arm64/AFFiNE-canary.app/Contents/Resources/app', + '../out/canary/AFFiNE-canary-darwin-arm64/AFFiNE-canary.app/Contents/Resources', import.meta.url ) ); -const outputList = [ - ['dist', ['main.js', 'helper.js', 'preload.js', 'affine.darwin-arm64.node']], -] as [entry: string, expected: string[]][]; - -await Promise.all( - outputList.map(async ([entry, output]) => { - const files = await readdir(`${outputRoot}/${entry}`); - output.forEach(file => { - if (!files.includes(file)) { - throw new Error(`File ${entry}/${file} not found`); - } - }); - }) -); +// todo: use asar package to check contents +fs.existsSync(path.resolve(outputRoot, 'app.asar')); console.log('Output check passed'); diff --git a/yarn.lock b/yarn.lock index 44aa38cd04..64e72eab01 100644 --- a/yarn.lock +++ b/yarn.lock @@ -449,6 +449,7 @@ __metadata: "@electron-forge/maker-dmg": "npm:^6.4.2" "@electron-forge/maker-squirrel": "npm:^6.4.2" "@electron-forge/maker-zip": "npm:^6.4.2" + "@electron-forge/plugin-auto-unpack-natives": "npm:^6.4.2" "@electron-forge/shared-types": "npm:^6.4.2" "@electron/remote": "npm:2.0.12" "@reforged/maker-appimage": "npm:^3.3.1" @@ -457,7 +458,7 @@ __metadata: async-call-rpc: "npm:^6.3.1" builder-util-runtime: "npm:^9.2.1" cross-env: "npm:^7.0.3" - electron: "npm:^27.0.0" + electron: "npm:^27.1.0" electron-log: "npm:^5.0.0" electron-squirrel-startup: "npm:1.0.0" electron-updater: "npm:^6.1.5" @@ -4201,6 +4202,16 @@ __metadata: languageName: node linkType: hard +"@electron-forge/plugin-auto-unpack-natives@npm:^6.4.2": + version: 6.4.2 + resolution: "@electron-forge/plugin-auto-unpack-natives@npm:6.4.2" + dependencies: + "@electron-forge/plugin-base": "npm:6.4.2" + "@electron-forge/shared-types": "npm:6.4.2" + checksum: 3f541292d2ba4cebf1bc56c7e9b9d38e71a2f57f522753130c4c20d1cff8f2978ed4842f2993ddfed83db4054b2ea87d4a40d588583804b9591796e26e3e7a20 + languageName: node + linkType: hard + "@electron-forge/plugin-base@npm:6.4.2": version: 6.4.2 resolution: "@electron-forge/plugin-base@npm:6.4.2" @@ -19060,16 +19071,16 @@ __metadata: languageName: node linkType: soft -"electron@npm:^27.0.0": - version: 27.0.0 - resolution: "electron@npm:27.0.0" +"electron@npm:^27.0.0, electron@npm:^27.1.0": + version: 27.1.0 + resolution: "electron@npm:27.1.0" dependencies: "@electron/get": "npm:^2.0.0" "@types/node": "npm:^18.11.18" extract-zip: "npm:^2.0.1" bin: electron: cli.js - checksum: 486057738b20ec65a7ac9b30d615f94311a6b8ea900f94d1c6668c4e48bb6c9371a9131ee4349a3247031c292f97b8aa85448ec8e95b6998200a28bafe4aa6c2 + checksum: 8eed880bbda6efd55041cc855b93f632897139557761a913dd56c68a9e24bcb1c222a0b335f70e3df97e9692997f659d62600276bbf3714b374d841fed75bab4 languageName: node linkType: hard