mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-10-05 15:49:06 +03:00
refactor(core): split web entry from core (#6082)
This pr is trying to split `web` and `electron` entries from `core`. It allows more platform-related optimization to be addressed in each entry. We should remove all browser/electron only codes from `core` eventually, this is the very first step for that.
This commit is contained in:
parent
26925c96e4
commit
332cd3b380
@ -11,7 +11,7 @@ runs:
|
|||||||
- name: Download tar.gz
|
- name: Download tar.gz
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: core
|
name: web
|
||||||
path: .
|
path: .
|
||||||
|
|
||||||
- name: Extract core artifacts
|
- name: Extract core artifacts
|
2
.github/deployment/front/Dockerfile
vendored
2
.github/deployment/front/Dockerfile
vendored
@ -1,6 +1,6 @@
|
|||||||
FROM openresty/openresty:1.25.3.1-0-buster
|
FROM openresty/openresty:1.25.3.1-0-buster
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY ./packages/frontend/core/dist ./dist
|
COPY ./packages/frontend/web/dist ./dist
|
||||||
COPY ./.github/deployment/front/nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
|
COPY ./.github/deployment/front/nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
|
||||||
COPY ./.github/deployment/front/affine.nginx.conf /etc/nginx/conf.d/affine.nginx.conf
|
COPY ./.github/deployment/front/affine.nginx.conf /etc/nginx/conf.d/affine.nginx.conf
|
||||||
|
|
||||||
|
2
.github/deployment/node/Dockerfile
vendored
2
.github/deployment/node/Dockerfile
vendored
@ -1,7 +1,7 @@
|
|||||||
FROM node:20-bookworm-slim
|
FROM node:20-bookworm-slim
|
||||||
|
|
||||||
COPY ./packages/backend/server /app
|
COPY ./packages/backend/server /app
|
||||||
COPY ./packages/frontend/core/dist /app/static
|
COPY ./packages/frontend/web/dist /app/static
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
|
22
.github/workflows/build-test.yml
vendored
22
.github/workflows/build-test.yml
vendored
@ -266,8 +266,8 @@ jobs:
|
|||||||
path: ./packages/backend/storage/storage.node
|
path: ./packages/backend/storage/storage.node
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
build-core:
|
build-web:
|
||||||
name: Build @affine/core
|
name: Build @affine/web
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@ -277,15 +277,15 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
electron-install: false
|
electron-install: false
|
||||||
full-cache: true
|
full-cache: true
|
||||||
- name: Build Core
|
- name: Build Web
|
||||||
# always skip cache because its fast, and cache configuration is always changing
|
# always skip cache because its fast, and cache configuration is always changing
|
||||||
run: yarn nx build @affine/core --skip-nx-cache
|
run: yarn nx build @affine/web --skip-nx-cache
|
||||||
- name: zip core
|
- name: zip web
|
||||||
run: tar -czf dist.tar.gz --directory=packages/frontend/core/dist .
|
run: tar -czf dist.tar.gz --directory=packages/frontend/web/dist .
|
||||||
- name: Upload core artifact
|
- name: Upload web artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: core
|
name: web
|
||||||
path: dist.tar.gz
|
path: dist.tar.gz
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
@ -485,7 +485,7 @@ jobs:
|
|||||||
test: true,
|
test: true,
|
||||||
}
|
}
|
||||||
needs:
|
needs:
|
||||||
- build-core
|
- build-web
|
||||||
- build-native
|
- build-native
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -516,8 +516,8 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: yarn workspace @affine/electron vitest
|
run: yarn workspace @affine/electron vitest
|
||||||
|
|
||||||
- name: Download core artifact
|
- name: Download web artifact
|
||||||
uses: ./.github/actions/download-core
|
uses: ./.github/actions/download-web
|
||||||
with:
|
with:
|
||||||
path: packages/frontend/electron/resources/web-static
|
path: packages/frontend/electron/resources/web-static
|
||||||
|
|
||||||
|
42
.github/workflows/deploy.yml
vendored
42
.github/workflows/deploy.yml
vendored
@ -38,8 +38,8 @@ jobs:
|
|||||||
name: server-dist
|
name: server-dist
|
||||||
path: ./packages/backend/server/dist
|
path: ./packages/backend/server/dist
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
build-core:
|
build-web:
|
||||||
name: Build @affine/core
|
name: Build @affine/web
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
environment: ${{ github.event.inputs.flavor }}
|
environment: ${{ github.event.inputs.flavor }}
|
||||||
steps:
|
steps:
|
||||||
@ -50,7 +50,7 @@ jobs:
|
|||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: ./.github/actions/setup-node
|
uses: ./.github/actions/setup-node
|
||||||
- name: Build Core
|
- name: Build Core
|
||||||
run: yarn nx build @affine/core --skip-nx-cache
|
run: yarn nx build @affine/web --skip-nx-cache
|
||||||
env:
|
env:
|
||||||
R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }}
|
R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }}
|
||||||
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||||
@ -64,15 +64,15 @@ jobs:
|
|||||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||||
PERFSEE_TOKEN: ${{ secrets.PERFSEE_TOKEN }}
|
PERFSEE_TOKEN: ${{ secrets.PERFSEE_TOKEN }}
|
||||||
- name: Upload core artifact
|
- name: Upload web artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: core
|
name: web
|
||||||
path: ./packages/frontend/core/dist
|
path: ./packages/frontend/web/dist
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
build-core-selfhost:
|
build-web-selfhost:
|
||||||
name: Build @affine/core selfhost
|
name: Build @affine/web selfhost
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
environment: ${{ github.event.inputs.flavor }}
|
environment: ${{ github.event.inputs.flavor }}
|
||||||
steps:
|
steps:
|
||||||
@ -83,7 +83,7 @@ jobs:
|
|||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: ./.github/actions/setup-node
|
uses: ./.github/actions/setup-node
|
||||||
- name: Build Core
|
- name: Build Core
|
||||||
run: yarn nx build @affine/core --skip-nx-cache
|
run: yarn nx build @affine/web --skip-nx-cache
|
||||||
env:
|
env:
|
||||||
BUILD_TYPE: ${{ github.event.inputs.flavor }}
|
BUILD_TYPE: ${{ github.event.inputs.flavor }}
|
||||||
SHOULD_REPORT_TRACE: false
|
SHOULD_REPORT_TRACE: false
|
||||||
@ -91,11 +91,11 @@ jobs:
|
|||||||
SELF_HOSTED: true
|
SELF_HOSTED: true
|
||||||
- name: Download selfhost fonts
|
- name: Download selfhost fonts
|
||||||
run: node ./scripts/download-blocksuite-fonts.mjs
|
run: node ./scripts/download-blocksuite-fonts.mjs
|
||||||
- name: Upload core artifact
|
- name: Upload web artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: selfhost-core
|
name: selfhost-web
|
||||||
path: ./packages/frontend/core/dist
|
path: ./packages/frontend/web/dist
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
build-storage:
|
build-storage:
|
||||||
@ -143,16 +143,16 @@ jobs:
|
|||||||
packages: 'write'
|
packages: 'write'
|
||||||
needs:
|
needs:
|
||||||
- build-server
|
- build-server
|
||||||
- build-core
|
- build-web
|
||||||
- build-core-selfhost
|
- build-web-selfhost
|
||||||
- build-storage
|
- build-storage
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Download core artifact
|
- name: Download core artifact
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: core
|
name: web
|
||||||
path: ./packages/frontend/core/dist
|
path: ./packages/frontend/web/dist
|
||||||
- name: Download server dist
|
- name: Download server dist
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
@ -218,14 +218,14 @@ jobs:
|
|||||||
registry-url: https://npm.pkg.github.com
|
registry-url: https://npm.pkg.github.com
|
||||||
scope: '@toeverything'
|
scope: '@toeverything'
|
||||||
|
|
||||||
- name: Remove core dist
|
- name: Remove web dist
|
||||||
run: rm -rf ./packages/frontend/core/dist
|
run: rm -rf ./packages/frontend/web/dist
|
||||||
|
|
||||||
- name: Download selfhost core artifact
|
- name: Download selfhost web artifact
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: selfhost-core
|
name: selfhost-web
|
||||||
path: ./packages/frontend/core/dist
|
path: ./packages/frontend/web/dist
|
||||||
|
|
||||||
- name: Install Node.js dependencies
|
- name: Install Node.js dependencies
|
||||||
run: |
|
run: |
|
||||||
|
10
.github/workflows/release-desktop.yml
vendored
10
.github/workflows/release-desktop.yml
vendored
@ -60,10 +60,10 @@ jobs:
|
|||||||
SKIP_PLUGIN_BUILD: 'true'
|
SKIP_PLUGIN_BUILD: 'true'
|
||||||
SKIP_NX_CACHE: 'true'
|
SKIP_NX_CACHE: 'true'
|
||||||
|
|
||||||
- name: Upload core artifact
|
- name: Upload web artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: core
|
name: web
|
||||||
path: packages/frontend/electron/resources/web-static
|
path: packages/frontend/electron/resources/web-static
|
||||||
|
|
||||||
make-distribution:
|
make-distribution:
|
||||||
@ -110,7 +110,7 @@ jobs:
|
|||||||
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: core
|
name: web
|
||||||
path: packages/frontend/electron/resources/web-static
|
path: packages/frontend/electron/resources/web-static
|
||||||
|
|
||||||
- name: Build Desktop Layers
|
- name: Build Desktop Layers
|
||||||
@ -188,7 +188,7 @@ jobs:
|
|||||||
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: core
|
name: web
|
||||||
path: packages/frontend/electron/resources/web-static
|
path: packages/frontend/electron/resources/web-static
|
||||||
|
|
||||||
- name: Build Desktop Layers
|
- name: Build Desktop Layers
|
||||||
@ -317,7 +317,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: core
|
name: web
|
||||||
path: web-static
|
path: web-static
|
||||||
- name: Zip web-static
|
- name: Zip web-static
|
||||||
run: zip -r web-static.zip web-static
|
run: zip -r web-static.zip web-static
|
||||||
|
@ -17,13 +17,13 @@
|
|||||||
"node": "<21.0.0"
|
"node": "<21.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "dev-core",
|
"dev": "yarn workspace @affine/cli dev",
|
||||||
"dev:electron": "yarn workspace @affine/electron dev",
|
"dev:electron": "yarn workspace @affine/electron dev",
|
||||||
"build": "yarn nx build @affine/core",
|
"build": "yarn nx build @affine/web",
|
||||||
"build:electron": "yarn nx build @affine/electron",
|
"build:electron": "yarn nx build @affine/electron",
|
||||||
"build:storage": "yarn nx run-many -t build -p @affine/storage",
|
"build:storage": "yarn nx run-many -t build -p @affine/storage",
|
||||||
"build:storybook": "yarn nx build @affine/storybook",
|
"build:storybook": "yarn nx build @affine/storybook",
|
||||||
"start:web-static": "yarn workspace @affine/core static-server",
|
"start:web-static": "yarn workspace @affine/web static-server",
|
||||||
"start:storybook": "yarn exec serve tests/storybook/storybook-static -l 6006",
|
"start:storybook": "yarn exec serve tests/storybook/storybook-static -l 6006",
|
||||||
"serve:test-static": "yarn exec serve tests/fixtures --cors -p 8081",
|
"serve:test-static": "yarn exec serve tests/fixtures --cors -p 8081",
|
||||||
"lint:eslint": "eslint . --ext .js,mjs,.ts,.tsx --cache",
|
"lint:eslint": "eslint . --ext .js,mjs,.ts,.tsx --cache",
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/server": "^4.10.0",
|
"@apollo/server": "^4.10.0",
|
||||||
"@auth/prisma-adapter": "^1.4.0",
|
"@auth/prisma-adapter": "^1.4.0",
|
||||||
"@aws-sdk/client-s3": "^3.515.0",
|
"@aws-sdk/client-s3": "^3.536.0",
|
||||||
"@google-cloud/opentelemetry-cloud-monitoring-exporter": "^0.17.0",
|
"@google-cloud/opentelemetry-cloud-monitoring-exporter": "^0.17.0",
|
||||||
"@google-cloud/opentelemetry-cloud-trace-exporter": "^2.1.0",
|
"@google-cloud/opentelemetry-cloud-trace-exporter": "^2.1.0",
|
||||||
"@google-cloud/opentelemetry-resource-util": "^2.1.0",
|
"@google-cloud/opentelemetry-resource-util": "^2.1.0",
|
||||||
|
1
packages/common/env/src/global.ts
vendored
1
packages/common/env/src/global.ts
vendored
@ -19,7 +19,6 @@ export const runtimeFlagsSchema = z.object({
|
|||||||
enableNewSettingModal: z.boolean(),
|
enableNewSettingModal: z.boolean(),
|
||||||
enableNewSettingUnstableApi: z.boolean(),
|
enableNewSettingUnstableApi: z.boolean(),
|
||||||
enableSQLiteProvider: z.boolean(),
|
enableSQLiteProvider: z.boolean(),
|
||||||
enableNotificationCenter: z.boolean(),
|
|
||||||
enableCloud: z.boolean(),
|
enableCloud: z.boolean(),
|
||||||
enableCaptcha: z.boolean(),
|
enableCaptcha: z.boolean(),
|
||||||
enableEnhanceShareMode: z.boolean(),
|
enableEnhanceShareMode: z.boolean(),
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { StorybookConfig } from '@storybook/react-vite';
|
import { StorybookConfig } from '@storybook/react-vite';
|
||||||
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
|
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
|
||||||
import { fileURLToPath } from 'url';
|
|
||||||
import { mergeConfig } from 'vite';
|
import { mergeConfig } from 'vite';
|
||||||
import { getRuntimeConfig } from '../../core/.webpack/runtime-config';
|
import { getRuntimeConfig } from '@affine/cli/src/webpack/runtime-config';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
stories: ['../src/ui/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
|
stories: ['../src/ui/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"@blocksuite/store": "*"
|
"@blocksuite/store": "*"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@affine/cli": "workspace:*",
|
||||||
"@affine/debug": "workspace:*",
|
"@affine/debug": "workspace:*",
|
||||||
"@affine/electron-api": "workspace:*",
|
"@affine/electron-api": "workspace:*",
|
||||||
"@affine/graphql": "workspace:*",
|
"@affine/graphql": "workspace:*",
|
||||||
|
@ -3,14 +3,9 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.14.0",
|
"version": "0.14.0",
|
||||||
"scripts": {
|
|
||||||
"build": "yarn -T run build-core",
|
|
||||||
"dev": "yarn -T run dev-core",
|
|
||||||
"static-server": "yarn -T run dev-core --static"
|
|
||||||
},
|
|
||||||
"exports": {
|
"exports": {
|
||||||
"./app": "./src/app.tsx",
|
"./app": "./src/app.tsx",
|
||||||
"./router": "./src/router.ts",
|
"./router": "./src/router.tsx",
|
||||||
"./bootstrap/setup": "./src/bootstrap/setup.ts",
|
"./bootstrap/setup": "./src/bootstrap/setup.ts",
|
||||||
"./bootstrap/register-plugins": "./src/bootstrap/register-plugins.ts",
|
"./bootstrap/register-plugins": "./src/bootstrap/register-plugins.ts",
|
||||||
"./*": "./src/*"
|
"./*": "./src/*"
|
||||||
@ -40,7 +35,6 @@
|
|||||||
"@emotion/react": "^11.11.3",
|
"@emotion/react": "^11.11.3",
|
||||||
"@emotion/server": "^11.11.0",
|
"@emotion/server": "^11.11.0",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@juggle/resize-observer": "^3.4.0",
|
|
||||||
"@marsidev/react-turnstile": "^0.5.3",
|
"@marsidev/react-turnstile": "^0.5.3",
|
||||||
"@radix-ui/react-collapsible": "^1.0.3",
|
"@radix-ui/react-collapsible": "^1.0.3",
|
||||||
"@radix-ui/react-dialog": "^1.0.5",
|
"@radix-ui/react-dialog": "^1.0.5",
|
||||||
@ -59,7 +53,6 @@
|
|||||||
"clsx": "^2.1.0",
|
"clsx": "^2.1.0",
|
||||||
"cmdk": "patch:cmdk@npm%3A0.2.0#~/.yarn/patches/cmdk-npm-0.2.0-302237a911.patch",
|
"cmdk": "patch:cmdk@npm%3A0.2.0#~/.yarn/patches/cmdk-npm-0.2.0-302237a911.patch",
|
||||||
"css-spring": "^4.1.0",
|
"css-spring": "^4.1.0",
|
||||||
"cssnano": "^6.0.4",
|
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
"foxact": "^0.2.31",
|
"foxact": "^0.2.31",
|
||||||
"fractional-indexing": "^3.2.0",
|
"fractional-indexing": "^3.2.0",
|
||||||
@ -67,7 +60,6 @@
|
|||||||
"history": "^5.3.0",
|
"history": "^5.3.0",
|
||||||
"idb": "^8.0.0",
|
"idb": "^8.0.0",
|
||||||
"image-blob-reduce": "^4.1.0",
|
"image-blob-reduce": "^4.1.0",
|
||||||
"intl-segmenter-polyfill-rs": "^0.1.7",
|
|
||||||
"jotai": "^2.6.5",
|
"jotai": "^2.6.5",
|
||||||
"jotai-devtools": "^0.8.0",
|
"jotai-devtools": "^0.8.0",
|
||||||
"jotai-effect": "^0.6.0",
|
"jotai-effect": "^0.6.0",
|
||||||
@ -76,10 +68,8 @@
|
|||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"lottie-react": "^2.4.0",
|
"lottie-react": "^2.4.0",
|
||||||
"lottie-web": "^5.12.2",
|
"lottie-web": "^5.12.2",
|
||||||
"mini-css-extract-plugin": "^2.8.0",
|
|
||||||
"nanoid": "^5.0.6",
|
"nanoid": "^5.0.6",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"postcss-loader": "^8.1.0",
|
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-error-boundary": "^4.0.12",
|
"react-error-boundary": "^4.0.12",
|
||||||
@ -108,24 +98,11 @@
|
|||||||
"@types/image-blob-reduce": "^4.1.4",
|
"@types/image-blob-reduce": "^4.1.4",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/uuid": "^9.0.8",
|
"@types/uuid": "^9.0.8",
|
||||||
"@types/webpack-env": "^1.18.4",
|
|
||||||
"@vanilla-extract/css": "^1.14.1",
|
"@vanilla-extract/css": "^1.14.1",
|
||||||
"copy-webpack-plugin": "^12.0.2",
|
|
||||||
"css-loader": "^6.10.0",
|
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"fake-indexeddb": "^5.0.2",
|
"fake-indexeddb": "^5.0.2",
|
||||||
"html-webpack-plugin": "^5.6.0",
|
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
"raw-loader": "^4.0.2",
|
"vitest": "1.4.0"
|
||||||
"source-map-loader": "^5.0.0",
|
|
||||||
"style-loader": "^3.3.4",
|
|
||||||
"swc-loader": "^0.2.6",
|
|
||||||
"thread-loader": "^4.0.2",
|
|
||||||
"vitest": "1.4.0",
|
|
||||||
"webpack": "^5.90.3",
|
|
||||||
"webpack-cli": "^5.1.4",
|
|
||||||
"webpack-dev-server": "^5.0.2",
|
|
||||||
"webpack-merge": "^5.10.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { apis } from '@affine/electron-api';
|
import { apis } from '@affine/electron-api';
|
||||||
|
import { setupGlobal } from '@affine/env/global';
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
import { assertExists } from '@blocksuite/global/utils';
|
||||||
import {
|
import {
|
||||||
type AppConfigSchema,
|
type AppConfigSchema,
|
||||||
@ -35,6 +36,8 @@ class AppConfigProxy {
|
|||||||
}
|
}
|
||||||
export const appConfigProxy = new AppConfigProxy();
|
export const appConfigProxy = new AppConfigProxy();
|
||||||
|
|
||||||
|
setupGlobal();
|
||||||
|
|
||||||
const storage = environment.isDesktop
|
const storage = environment.isDesktop
|
||||||
? new AppConfigStorage({
|
? new AppConfigStorage({
|
||||||
config: defaultAppConfig,
|
config: defaultAppConfig,
|
||||||
|
@ -1,43 +1 @@
|
|||||||
import './polyfill/intl-segmenter';
|
export * from './web';
|
||||||
import './polyfill/request-idle-callback';
|
|
||||||
import './polyfill/resize-observer';
|
|
||||||
|
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
|
||||||
import { StrictMode } from 'react';
|
|
||||||
import { createRoot } from 'react-dom/client';
|
|
||||||
|
|
||||||
import { App } from './app';
|
|
||||||
import { setup } from './bootstrap/setup';
|
|
||||||
import { performanceLogger } from './shared';
|
|
||||||
|
|
||||||
const performanceMainLogger = performanceLogger.namespace('main');
|
|
||||||
function main() {
|
|
||||||
performanceMainLogger.info('start');
|
|
||||||
|
|
||||||
// skip bootstrap setup for desktop onboarding
|
|
||||||
if (window.appInfo?.windowName !== 'onboarding') {
|
|
||||||
performanceMainLogger.info('setup start');
|
|
||||||
setup();
|
|
||||||
performanceMainLogger.info('setup done');
|
|
||||||
}
|
|
||||||
|
|
||||||
mountApp();
|
|
||||||
}
|
|
||||||
|
|
||||||
function mountApp() {
|
|
||||||
performanceMainLogger.info('import app');
|
|
||||||
const root = document.getElementById('app');
|
|
||||||
assertExists(root);
|
|
||||||
performanceMainLogger.info('render app');
|
|
||||||
createRoot(root).render(
|
|
||||||
<StrictMode>
|
|
||||||
<App />
|
|
||||||
</StrictMode>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
main();
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Failed to bootstrap app', err);
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { configureWorkspaceImplServices } from '@affine/workspace-impl';
|
import { configureWorkspaceImplServices } from '@affine/workspace-impl';
|
||||||
import type { ServiceCollection } from '@toeverything/infra';
|
import {
|
||||||
import { configureInfraServices } from '@toeverything/infra';
|
configureInfraServices,
|
||||||
|
type ServiceCollection,
|
||||||
|
} from '@toeverything/infra';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
configureBusinessServices,
|
configureBusinessServices,
|
||||||
|
@ -23,7 +23,10 @@
|
|||||||
"main": "./dist/main.js",
|
"main": "./dist/main.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@affine-test/kit": "workspace:*",
|
"@affine-test/kit": "workspace:*",
|
||||||
|
"@affine/component": "workspace:*",
|
||||||
|
"@affine/core": "workspace:*",
|
||||||
"@affine/env": "workspace:*",
|
"@affine/env": "workspace:*",
|
||||||
|
"@affine/i18n": "workspace:*",
|
||||||
"@affine/native": "workspace:*",
|
"@affine/native": "workspace:*",
|
||||||
"@blocksuite/blocks": "0.13.0-canary-202403140735-2367cd5",
|
"@blocksuite/blocks": "0.13.0-canary-202403140735-2367cd5",
|
||||||
"@blocksuite/lit": "0.13.0-canary-202403140735-2367cd5",
|
"@blocksuite/lit": "0.13.0-canary-202403140735-2367cd5",
|
||||||
@ -38,6 +41,7 @@
|
|||||||
"@electron-forge/maker-zip": "^7.3.0",
|
"@electron-forge/maker-zip": "^7.3.0",
|
||||||
"@electron-forge/plugin-auto-unpack-natives": "^7.3.0",
|
"@electron-forge/plugin-auto-unpack-natives": "^7.3.0",
|
||||||
"@electron-forge/shared-types": "^7.3.0",
|
"@electron-forge/shared-types": "^7.3.0",
|
||||||
|
"@emotion/react": "^11.11.4",
|
||||||
"@pengx17/electron-forge-maker-appimage": "^1.0.2",
|
"@pengx17/electron-forge-maker-appimage": "^1.0.2",
|
||||||
"@toeverything/infra": "workspace:*",
|
"@toeverything/infra": "workspace:*",
|
||||||
"@types/uuid": "^9.0.8",
|
"@types/uuid": "^9.0.8",
|
||||||
@ -51,7 +55,11 @@
|
|||||||
"fs-extra": "^11.2.0",
|
"fs-extra": "^11.2.0",
|
||||||
"glob": "^10.3.10",
|
"glob": "^10.3.10",
|
||||||
"jotai": "^2.6.5",
|
"jotai": "^2.6.5",
|
||||||
|
"jotai-devtools": "^0.8.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"react-router-dom": "^6.22.3",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
"semver": "^7.6.0",
|
"semver": "^7.6.0",
|
||||||
"tinykeys": "patch:tinykeys@npm%3A2.1.0#~/.yarn/patches/tinykeys-npm-2.1.0-819feeaed0.patch",
|
"tinykeys": "patch:tinykeys@npm%3A2.1.0#~/.yarn/patches/tinykeys-npm-2.1.0-819feeaed0.patch",
|
||||||
|
@ -4,24 +4,24 @@ import '@affine/component/theme/theme.css';
|
|||||||
import { AffineContext } from '@affine/component/context';
|
import { AffineContext } from '@affine/component/context';
|
||||||
import { GlobalLoading } from '@affine/component/global-loading';
|
import { GlobalLoading } from '@affine/component/global-loading';
|
||||||
import { NotificationCenter } from '@affine/component/notification-center';
|
import { NotificationCenter } from '@affine/component/notification-center';
|
||||||
|
import { WorkspaceFallback } from '@affine/core/components/workspace';
|
||||||
|
import { GlobalScopeProvider } from '@affine/core/modules/infra-web/global-scope';
|
||||||
|
import { CloudSessionProvider } from '@affine/core/providers/session-provider';
|
||||||
|
import { router } from '@affine/core/router';
|
||||||
|
import {
|
||||||
|
performanceLogger,
|
||||||
|
performanceRenderLogger,
|
||||||
|
} from '@affine/core/shared';
|
||||||
|
import createEmotionCache from '@affine/core/utils/create-emotion-cache';
|
||||||
|
import { configureWebServices } from '@affine/core/web';
|
||||||
import { createI18n, setUpLanguage } from '@affine/i18n';
|
import { createI18n, setUpLanguage } from '@affine/i18n';
|
||||||
import { CacheProvider } from '@emotion/react';
|
import { CacheProvider } from '@emotion/react';
|
||||||
import { getCurrentStore } from '@toeverything/infra/atom';
|
import { getCurrentStore } from '@toeverything/infra/atom';
|
||||||
import {
|
import { ServiceCollection } from '@toeverything/infra/di';
|
||||||
ServiceCollection,
|
|
||||||
ServiceProviderContext,
|
|
||||||
} from '@toeverything/infra/di';
|
|
||||||
import type { PropsWithChildren, ReactElement } from 'react';
|
import type { PropsWithChildren, ReactElement } from 'react';
|
||||||
import { lazy, memo, Suspense } from 'react';
|
import { lazy, Suspense } from 'react';
|
||||||
import { RouterProvider } from 'react-router-dom';
|
import { RouterProvider } from 'react-router-dom';
|
||||||
|
|
||||||
import { WorkspaceFallback } from './components/workspace';
|
|
||||||
import { CloudSessionProvider } from './providers/session-provider';
|
|
||||||
import { router } from './router';
|
|
||||||
import { performanceLogger, performanceRenderLogger } from './shared';
|
|
||||||
import createEmotionCache from './utils/create-emotion-cache';
|
|
||||||
import { configureWebServices } from './web';
|
|
||||||
|
|
||||||
const performanceI18nLogger = performanceLogger.namespace('i18n');
|
const performanceI18nLogger = performanceLogger.namespace('i18n');
|
||||||
const cache = createEmotionCache();
|
const cache = createEmotionCache();
|
||||||
|
|
||||||
@ -43,16 +43,14 @@ const future = {
|
|||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
async function loadLanguage() {
|
async function loadLanguage() {
|
||||||
if (environment.isBrowser) {
|
performanceI18nLogger.info('start');
|
||||||
performanceI18nLogger.info('start');
|
|
||||||
|
|
||||||
const i18n = createI18n();
|
const i18n = createI18n();
|
||||||
document.documentElement.lang = i18n.language;
|
document.documentElement.lang = i18n.language;
|
||||||
|
|
||||||
performanceI18nLogger.info('set up');
|
performanceI18nLogger.info('set up');
|
||||||
await setUpLanguage(i18n);
|
await setUpLanguage(i18n);
|
||||||
performanceI18nLogger.info('done');
|
performanceI18nLogger.info('done');
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let languageLoadingPromise: Promise<void> | null = null;
|
let languageLoadingPromise: Promise<void> | null = null;
|
||||||
@ -61,7 +59,7 @@ const services = new ServiceCollection();
|
|||||||
configureWebServices(services);
|
configureWebServices(services);
|
||||||
const serviceProvider = services.provider();
|
const serviceProvider = services.provider();
|
||||||
|
|
||||||
export const App = memo(function App() {
|
export function App() {
|
||||||
performanceRenderLogger.info('App');
|
performanceRenderLogger.info('App');
|
||||||
|
|
||||||
if (!languageLoadingPromise) {
|
if (!languageLoadingPromise) {
|
||||||
@ -70,15 +68,13 @@ export const App = memo(function App() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<ServiceProviderContext.Provider value={serviceProvider}>
|
<GlobalScopeProvider provider={serviceProvider}>
|
||||||
<CacheProvider value={cache}>
|
<CacheProvider value={cache}>
|
||||||
<AffineContext store={getCurrentStore()}>
|
<AffineContext store={getCurrentStore()}>
|
||||||
<CloudSessionProvider>
|
<CloudSessionProvider>
|
||||||
<DebugProvider>
|
<DebugProvider>
|
||||||
<GlobalLoading />
|
<GlobalLoading />
|
||||||
{runtimeConfig.enableNotificationCenter && (
|
<NotificationCenter />
|
||||||
<NotificationCenter />
|
|
||||||
)}
|
|
||||||
<RouterProvider
|
<RouterProvider
|
||||||
fallbackElement={<WorkspaceFallback key="RouterFallback" />}
|
fallbackElement={<WorkspaceFallback key="RouterFallback" />}
|
||||||
router={router}
|
router={router}
|
||||||
@ -88,7 +84,7 @@ export const App = memo(function App() {
|
|||||||
</CloudSessionProvider>
|
</CloudSessionProvider>
|
||||||
</AffineContext>
|
</AffineContext>
|
||||||
</CacheProvider>
|
</CacheProvider>
|
||||||
</ServiceProviderContext.Provider>
|
</GlobalScopeProvider>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
});
|
}
|
43
packages/frontend/electron/renderer/index.tsx
Normal file
43
packages/frontend/electron/renderer/index.tsx
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Side effect import, "declare global"
|
||||||
|
import '@affine/env/constant';
|
||||||
|
|
||||||
|
import { setup } from '@affine/core/bootstrap/setup';
|
||||||
|
import { performanceLogger } from '@affine/core/shared';
|
||||||
|
import { StrictMode } from 'react';
|
||||||
|
import { createRoot } from 'react-dom/client';
|
||||||
|
|
||||||
|
import { App } from './app';
|
||||||
|
|
||||||
|
const performanceMainLogger = performanceLogger.namespace('main');
|
||||||
|
function main() {
|
||||||
|
performanceMainLogger.info('start');
|
||||||
|
|
||||||
|
// skip bootstrap setup for desktop onboarding
|
||||||
|
if (window.appInfo?.windowName === 'onboarding') {
|
||||||
|
performanceMainLogger.info('skip setup');
|
||||||
|
} else {
|
||||||
|
performanceMainLogger.info('setup start');
|
||||||
|
setup();
|
||||||
|
performanceMainLogger.info('setup done');
|
||||||
|
}
|
||||||
|
|
||||||
|
mountApp();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mountApp() {
|
||||||
|
performanceMainLogger.info('import app');
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
const root = document.getElementById('app')!;
|
||||||
|
performanceMainLogger.info('render app');
|
||||||
|
createRoot(root).render(
|
||||||
|
<StrictMode>
|
||||||
|
<App />
|
||||||
|
</StrictMode>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
main();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to bootstrap app', err);
|
||||||
|
}
|
29
packages/frontend/electron/renderer/tsconfig.json
Normal file
29
packages/frontend/electron/renderer/tsconfig.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"noEmit": false,
|
||||||
|
"outDir": "../lib",
|
||||||
|
"allowJs": true
|
||||||
|
},
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "../../../common/env"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../core"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../component"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../../common/infra"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"include": ["."]
|
||||||
|
}
|
@ -12,8 +12,8 @@ const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|||||||
const repoRootDir = path.join(__dirname, '..', '..', '..', '..');
|
const repoRootDir = path.join(__dirname, '..', '..', '..', '..');
|
||||||
const electronRootDir = path.join(__dirname, '..');
|
const electronRootDir = path.join(__dirname, '..');
|
||||||
const publicDistDir = path.join(electronRootDir, 'resources');
|
const publicDistDir = path.join(electronRootDir, 'resources');
|
||||||
const affineCoreDir = path.join(repoRootDir, 'packages', 'frontend', 'core');
|
const webDir = path.join(repoRootDir, 'packages', 'frontend', 'electron');
|
||||||
const affineCoreOutDir = path.join(affineCoreDir, 'dist');
|
const affineWebOutDir = path.join(webDir, 'dist');
|
||||||
const publicAffineOutDir = path.join(publicDistDir, `web-static`);
|
const publicAffineOutDir = path.join(publicDistDir, `web-static`);
|
||||||
const releaseVersionEnv = process.env.RELEASE_VERSION || '';
|
const releaseVersionEnv = process.env.RELEASE_VERSION || '';
|
||||||
|
|
||||||
@ -21,8 +21,8 @@ console.log('build with following variables', {
|
|||||||
repoRootDir,
|
repoRootDir,
|
||||||
electronRootDir,
|
electronRootDir,
|
||||||
publicDistDir,
|
publicDistDir,
|
||||||
affineSrcDir: affineCoreDir,
|
affineSrcDir: webDir,
|
||||||
affineSrcOutDir: affineCoreOutDir,
|
affineSrcOutDir: affineWebOutDir,
|
||||||
publicAffineOutDir,
|
publicAffineOutDir,
|
||||||
releaseVersionEnv,
|
releaseVersionEnv,
|
||||||
});
|
});
|
||||||
@ -45,7 +45,7 @@ const nxFlag = SKIP_NX_CACHE ? '--skip-nx-cache' : '';
|
|||||||
|
|
||||||
// step 1: build web dist
|
// step 1: build web dist
|
||||||
if (!process.env.SKIP_WEB_BUILD) {
|
if (!process.env.SKIP_WEB_BUILD) {
|
||||||
spawnSync('yarn', ['nx', 'build', '@affine/core', nxFlag], {
|
spawnSync('yarn', ['nx', 'build', '@affine/web', nxFlag], {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
env: process.env,
|
env: process.env,
|
||||||
cwd,
|
cwd,
|
||||||
@ -58,10 +58,10 @@ if (!process.env.SKIP_WEB_BUILD) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// step 1.5: amend sourceMappingURL to allow debugging in devtools
|
// step 1.5: amend sourceMappingURL to allow debugging in devtools
|
||||||
await glob('**/*.{js,css}', { cwd: affineCoreOutDir }).then(files => {
|
await glob('**/*.{js,css}', { cwd: affineWebOutDir }).then(files => {
|
||||||
return files.map(async file => {
|
return files.map(async file => {
|
||||||
const dir = path.dirname(file);
|
const dir = path.dirname(file);
|
||||||
const fullpath = path.join(affineCoreOutDir, file);
|
const fullpath = path.join(affineWebOutDir, file);
|
||||||
let content = await fs.readFile(fullpath, 'utf-8');
|
let content = await fs.readFile(fullpath, 'utf-8');
|
||||||
// replace # sourceMappingURL=76-6370cd185962bc89.js.map
|
// replace # sourceMappingURL=76-6370cd185962bc89.js.map
|
||||||
// to # sourceMappingURL=assets://./{dir}/76-6370cd185962bc89.js.map
|
// to # sourceMappingURL=assets://./{dir}/76-6370cd185962bc89.js.map
|
||||||
@ -78,7 +78,7 @@ if (!process.env.SKIP_WEB_BUILD) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
await fs.move(affineCoreOutDir, publicAffineOutDir, { overwrite: true });
|
await fs.move(affineWebOutDir, publicAffineOutDir, { overwrite: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
// step 2: update app-updater.yml content with build type in resources folder
|
// step 2: update app-updater.yml content with build type in resources folder
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
"noImplicitOverride": true
|
"noImplicitOverride": true
|
||||||
},
|
},
|
||||||
"include": ["./src"],
|
"include": ["./src"],
|
||||||
"exclude": ["node_modules", "lib", "dist", "**/__tests__/**/*"],
|
"exclude": ["renderer", "node_modules", "lib", "dist", "**/__tests__/**/*"],
|
||||||
"references": [
|
"references": [
|
||||||
{
|
{
|
||||||
"path": "../../frontend/native"
|
"path": "../../frontend/native"
|
||||||
|
@ -306,9 +306,5 @@ export const builtInTemplates = {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
async function main() {
|
const templatesInGroup = await parseSnapshot();
|
||||||
const templatesInGroup = await parseSnapshot();
|
await buildScript(templatesInGroup);
|
||||||
await buildScript(templatesInGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
main();
|
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./templates.gen.ts",
|
".": "./templates.gen.ts",
|
||||||
"./edgeless": "./edgeless-templates.gen.ts"
|
"./edgeless": "./edgeless-templates.gen.ts",
|
||||||
|
"./build-edgeless": "./build-edgeless.mjs"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"jszip": "^3.10.1"
|
"jszip": "^3.10.1"
|
||||||
|
27
packages/frontend/web/package.json
Normal file
27
packages/frontend/web/package.json
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "@affine/web",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "AFFiNE Desktop Web application",
|
||||||
|
"private": true,
|
||||||
|
"browser": "src/index.tsx",
|
||||||
|
"scripts": {
|
||||||
|
"build": "yarn workspace @affine/cli build",
|
||||||
|
"dev": "yarn workspace @affine/cli dev",
|
||||||
|
"static-server": "yarn workspace @affine/cli dev --static"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@affine/component": "workspace:*",
|
||||||
|
"@affine/core": "workspace:*",
|
||||||
|
"@affine/env": "workspace:*",
|
||||||
|
"@juggle/resize-observer": "^3.4.0",
|
||||||
|
"intl-segmenter-polyfill-rs": "^0.1.7",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@affine/cli": "workspace:*",
|
||||||
|
"@types/react": "^18.2.60",
|
||||||
|
"@types/react-dom": "^18.2.19",
|
||||||
|
"typescript": "^5.3.3"
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@affine/core",
|
"name": "@affine/web",
|
||||||
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
||||||
"targets": {
|
"targets": {
|
||||||
"build": {
|
"build": {
|
||||||
@ -13,9 +13,9 @@
|
|||||||
"^build"
|
"^build"
|
||||||
],
|
],
|
||||||
"inputs": [
|
"inputs": [
|
||||||
"{projectRoot}/.webpack/**/*",
|
|
||||||
"{projectRoot}/**/*",
|
"{projectRoot}/**/*",
|
||||||
"{projectRoot}/public/**/*",
|
"{workspaceRoot}/tools/**/*",
|
||||||
|
"{workspaceRoot}/packages/frontend/core/**/*",
|
||||||
"{workspaceRoot}/packages/**/*",
|
"{workspaceRoot}/packages/**/*",
|
||||||
{
|
{
|
||||||
"env": "BUILD_TYPE"
|
"env": "BUILD_TYPE"
|
90
packages/frontend/web/src/app.tsx
Normal file
90
packages/frontend/web/src/app.tsx
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import '@affine/component/theme/global.css';
|
||||||
|
import '@affine/component/theme/theme.css';
|
||||||
|
|
||||||
|
import { AffineContext } from '@affine/component/context';
|
||||||
|
import { GlobalLoading } from '@affine/component/global-loading';
|
||||||
|
import { NotificationCenter } from '@affine/component/notification-center';
|
||||||
|
import { WorkspaceFallback } from '@affine/core/components/workspace';
|
||||||
|
import { GlobalScopeProvider } from '@affine/core/modules/infra-web/global-scope';
|
||||||
|
import { CloudSessionProvider } from '@affine/core/providers/session-provider';
|
||||||
|
import { router } from '@affine/core/router';
|
||||||
|
import {
|
||||||
|
performanceLogger,
|
||||||
|
performanceRenderLogger,
|
||||||
|
} from '@affine/core/shared';
|
||||||
|
import createEmotionCache from '@affine/core/utils/create-emotion-cache';
|
||||||
|
import { configureWebServices } from '@affine/core/web';
|
||||||
|
import { createI18n, setUpLanguage } from '@affine/i18n';
|
||||||
|
import { CacheProvider } from '@emotion/react';
|
||||||
|
import { getCurrentStore } from '@toeverything/infra/atom';
|
||||||
|
import { ServiceCollection } from '@toeverything/infra/di';
|
||||||
|
import type { PropsWithChildren, ReactElement } from 'react';
|
||||||
|
import { lazy, Suspense } from 'react';
|
||||||
|
import { RouterProvider } from 'react-router-dom';
|
||||||
|
|
||||||
|
const performanceI18nLogger = performanceLogger.namespace('i18n');
|
||||||
|
const cache = createEmotionCache();
|
||||||
|
|
||||||
|
const DevTools = lazy(() =>
|
||||||
|
import('jotai-devtools').then(m => ({ default: m.DevTools }))
|
||||||
|
);
|
||||||
|
|
||||||
|
const DebugProvider = ({ children }: PropsWithChildren): ReactElement => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Suspense>{process.env.DEBUG_JOTAI === 'true' && <DevTools />}</Suspense>
|
||||||
|
{children}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const future = {
|
||||||
|
v7_startTransition: true,
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
async function loadLanguage() {
|
||||||
|
performanceI18nLogger.info('start');
|
||||||
|
|
||||||
|
const i18n = createI18n();
|
||||||
|
document.documentElement.lang = i18n.language;
|
||||||
|
|
||||||
|
performanceI18nLogger.info('set up');
|
||||||
|
await setUpLanguage(i18n);
|
||||||
|
performanceI18nLogger.info('done');
|
||||||
|
}
|
||||||
|
|
||||||
|
let languageLoadingPromise: Promise<void> | null = null;
|
||||||
|
|
||||||
|
const services = new ServiceCollection();
|
||||||
|
configureWebServices(services);
|
||||||
|
const serviceProvider = services.provider();
|
||||||
|
|
||||||
|
export function App() {
|
||||||
|
performanceRenderLogger.info('App');
|
||||||
|
|
||||||
|
if (!languageLoadingPromise) {
|
||||||
|
languageLoadingPromise = loadLanguage().catch(console.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Suspense>
|
||||||
|
<GlobalScopeProvider provider={serviceProvider}>
|
||||||
|
<CacheProvider value={cache}>
|
||||||
|
<AffineContext store={getCurrentStore()}>
|
||||||
|
<CloudSessionProvider>
|
||||||
|
<DebugProvider>
|
||||||
|
<GlobalLoading />
|
||||||
|
<NotificationCenter />
|
||||||
|
<RouterProvider
|
||||||
|
fallbackElement={<WorkspaceFallback key="RouterFallback" />}
|
||||||
|
router={router}
|
||||||
|
future={future}
|
||||||
|
/>
|
||||||
|
</DebugProvider>
|
||||||
|
</CloudSessionProvider>
|
||||||
|
</AffineContext>
|
||||||
|
</CacheProvider>
|
||||||
|
</GlobalScopeProvider>
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
|
}
|
45
packages/frontend/web/src/index.tsx
Normal file
45
packages/frontend/web/src/index.tsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import './polyfill/intl-segmenter';
|
||||||
|
import './polyfill/request-idle-callback';
|
||||||
|
import './polyfill/resize-observer';
|
||||||
|
|
||||||
|
import { setup } from '@affine/core/bootstrap/setup';
|
||||||
|
import { performanceLogger } from '@affine/core/shared';
|
||||||
|
import { isDesktop } from '@affine/env/constant';
|
||||||
|
import { StrictMode } from 'react';
|
||||||
|
import { createRoot } from 'react-dom/client';
|
||||||
|
|
||||||
|
import { App } from './app';
|
||||||
|
|
||||||
|
const performanceMainLogger = performanceLogger.namespace('main');
|
||||||
|
function main() {
|
||||||
|
performanceMainLogger.info('start');
|
||||||
|
|
||||||
|
// skip bootstrap setup for desktop onboarding
|
||||||
|
if (isDesktop && window.appInfo?.windowName === 'onboarding') {
|
||||||
|
performanceMainLogger.info('skip setup');
|
||||||
|
} else {
|
||||||
|
performanceMainLogger.info('setup start');
|
||||||
|
setup();
|
||||||
|
performanceMainLogger.info('setup done');
|
||||||
|
}
|
||||||
|
|
||||||
|
mountApp();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mountApp() {
|
||||||
|
performanceMainLogger.info('import app');
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
const root = document.getElementById('app')!;
|
||||||
|
performanceMainLogger.info('render app');
|
||||||
|
createRoot(root).render(
|
||||||
|
<StrictMode>
|
||||||
|
<App />
|
||||||
|
</StrictMode>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
main();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to bootstrap app', err);
|
||||||
|
}
|
12
packages/frontend/web/tsconfig.json
Normal file
12
packages/frontend/web/tsconfig.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
|
"outDir": "lib",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"types": ["affine__env"],
|
||||||
|
"rootDir": "./src"
|
||||||
|
},
|
||||||
|
"include": ["./src"],
|
||||||
|
"references": [{ "path": "../core" }]
|
||||||
|
}
|
@ -11,7 +11,7 @@ const fontPath = join(
|
|||||||
'..',
|
'..',
|
||||||
'packages',
|
'packages',
|
||||||
'frontend',
|
'frontend',
|
||||||
'core',
|
'web',
|
||||||
'dist',
|
'dist',
|
||||||
'assets'
|
'assets'
|
||||||
);
|
);
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
|
import { getRuntimeConfig } from '@affine/cli/src/webpack/runtime-config';
|
||||||
import { setupGlobal } from '@affine/env/global';
|
import { setupGlobal } from '@affine/env/global';
|
||||||
|
|
||||||
import { getRuntimeConfig } from '../../packages/frontend/core/.webpack/runtime-config';
|
|
||||||
|
|
||||||
globalThis.runtimeConfig = getRuntimeConfig({
|
globalThis.runtimeConfig = getRuntimeConfig({
|
||||||
distribution: 'browser',
|
distribution: 'browser',
|
||||||
mode: 'development',
|
mode: 'development',
|
||||||
|
@ -3,7 +3,7 @@ import type { StorybookConfig } from '@storybook/react-vite';
|
|||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import { mergeConfig } from 'vite';
|
import { mergeConfig } from 'vite';
|
||||||
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
|
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
|
||||||
import { getRuntimeConfig } from '../../../packages/frontend/core/.webpack/runtime-config';
|
import { getRuntimeConfig } from '@affine/cli/src/webpack/runtime-config';
|
||||||
|
|
||||||
runCli(
|
runCli(
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
"test": "test-storybook"
|
"test": "test-storybook"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@affine/cli": "workspace:*",
|
||||||
"@affine/component": "workspace:*",
|
"@affine/component": "workspace:*",
|
||||||
"@affine/i18n": "workspace:*",
|
"@affine/i18n": "workspace:*",
|
||||||
"@affine/workspace-impl": "workspace:*",
|
"@affine/workspace-impl": "workspace:*",
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
{
|
{
|
||||||
"path": "../../packages/frontend/component"
|
"path": "../../packages/frontend/component"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "../../tools/cli"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "../../packages/common/env"
|
"path": "../../packages/common/env"
|
||||||
},
|
},
|
||||||
|
@ -2,25 +2,45 @@
|
|||||||
"name": "@affine/cli",
|
"name": "@affine/cli",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
"bin": {
|
|
||||||
"build-core": "./src/bin/build-core.mjs",
|
|
||||||
"dev-core": "./src/bin/dev-core.mjs"
|
|
||||||
},
|
|
||||||
"exports": {
|
|
||||||
"./config": "./src/config/index.ts"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@affine/env": "workspace:*",
|
||||||
|
"@affine/templates": "workspace:*",
|
||||||
|
"@aws-sdk/client-s3": "3.536.0",
|
||||||
|
"@blocksuite/presets": "0.13.0-canary-202403140735-2367cd5",
|
||||||
"@clack/core": "^0.3.4",
|
"@clack/core": "^0.3.4",
|
||||||
"@clack/prompts": "^0.7.0",
|
"@clack/prompts": "^0.7.0",
|
||||||
"@magic-works/i18n-codegen": "^0.5.0",
|
"@magic-works/i18n-codegen": "^0.5.0",
|
||||||
"ts-node": "^10.9.2"
|
"@napi-rs/simple-git": "^0.1.16",
|
||||||
},
|
"@perfsee/webpack": "^1.12.2",
|
||||||
"dependencies": {
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.11",
|
||||||
|
"@sentry/webpack-plugin": "^2.14.2",
|
||||||
|
"@types/webpack-env": "^1.18.4",
|
||||||
|
"@vanilla-extract/webpack-plugin": "^2.3.7",
|
||||||
|
"copy-webpack-plugin": "^12.0.2",
|
||||||
|
"css-loader": "^6.10.0",
|
||||||
|
"cssnano": "^6.1.0",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"vite": "^5.1.4"
|
"html-webpack-plugin": "^5.6.0",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
|
"mime-types": "^2.1.35",
|
||||||
|
"mini-css-extract-plugin": "^2.8.1",
|
||||||
|
"postcss-loader": "^8.1.0",
|
||||||
|
"raw-loader": "^4.0.2",
|
||||||
|
"source-map-loader": "^5.0.0",
|
||||||
|
"style-loader": "^3.3.4",
|
||||||
|
"swc-loader": "^0.2.6",
|
||||||
|
"terser-webpack-plugin": "^5.3.10",
|
||||||
|
"thread-loader": "^4.0.2",
|
||||||
|
"ts-node": "^10.9.2",
|
||||||
|
"vite": "^5.1.4",
|
||||||
|
"webpack": "^5.90.3",
|
||||||
|
"webpack-cli": "^5.1.4",
|
||||||
|
"webpack-dev-server": "^5.0.2",
|
||||||
|
"webpack-merge": "^5.10.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"scripts": {
|
||||||
"ts-node": "*"
|
"build": "node --loader ts-node/esm/transpile-only.mjs ./src/bin/build.ts",
|
||||||
|
"dev": "node --loader ts-node/esm/transpile-only.mjs ./src/bin/dev.ts"
|
||||||
},
|
},
|
||||||
"version": "0.14.0"
|
"version": "0.14.0"
|
||||||
}
|
}
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
import { spawnSync } from 'node:child_process';
|
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
|
|
||||||
const child = spawnSync(
|
|
||||||
process.execPath,
|
|
||||||
[
|
|
||||||
'--loader',
|
|
||||||
'ts-node/esm/transpile-only',
|
|
||||||
fileURLToPath(new URL('./build-core.ts', import.meta.url)),
|
|
||||||
...process.argv.slice(2),
|
|
||||||
],
|
|
||||||
{ stdio: 'inherit' }
|
|
||||||
);
|
|
||||||
|
|
||||||
if (child.status) process.exit(child.status);
|
|
@ -1,11 +1,13 @@
|
|||||||
import { spawn } from 'node:child_process';
|
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
|
||||||
|
import webpack from 'webpack';
|
||||||
|
|
||||||
import type { BuildFlags } from '../config/index.js';
|
import type { BuildFlags } from '../config/index.js';
|
||||||
import { projectRoot } from '../config/index.js';
|
import { projectRoot } from '../config/index.js';
|
||||||
import { buildI18N } from '../util/i18n.js';
|
import { buildI18N } from '../util/i18n.js';
|
||||||
|
import { createWebpackConfig } from '../webpack/webpack.config.js';
|
||||||
|
|
||||||
const cwd = path.resolve(projectRoot, 'packages/frontend/core');
|
let cwd: string;
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
const buildType = process.env.BUILD_TYPE_OVERRIDE || process.env.BUILD_TYPE;
|
const buildType = process.env.BUILD_TYPE_OVERRIDE || process.env.BUILD_TYPE;
|
||||||
@ -31,15 +33,20 @@ const getChannel = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let entry: string | undefined;
|
||||||
|
|
||||||
|
const { DISTRIBUTION } = process.env;
|
||||||
|
|
||||||
const getDistribution = () => {
|
const getDistribution = () => {
|
||||||
switch (process.env.DISTRIBUTION) {
|
switch (DISTRIBUTION) {
|
||||||
case 'browser':
|
case 'browser':
|
||||||
case 'desktop':
|
case undefined:
|
||||||
return process.env.DISTRIBUTION;
|
cwd = path.join(projectRoot, 'packages/frontend/web');
|
||||||
case undefined: {
|
|
||||||
console.log('DISTRIBUTION is not set, defaulting to browser');
|
|
||||||
return 'browser';
|
return 'browser';
|
||||||
}
|
case 'desktop':
|
||||||
|
cwd = path.join(projectRoot, 'packages/frontend/electron');
|
||||||
|
entry = path.join(cwd, 'renderer', 'index.tsx');
|
||||||
|
return DISTRIBUTION;
|
||||||
default: {
|
default: {
|
||||||
throw new Error('DISTRIBUTION must be one of browser, desktop');
|
throw new Error('DISTRIBUTION must be one of browser, desktop');
|
||||||
}
|
}
|
||||||
@ -51,24 +58,19 @@ const flags = {
|
|||||||
mode: 'production',
|
mode: 'production',
|
||||||
channel: getChannel(),
|
channel: getChannel(),
|
||||||
coverage: process.env.COVERAGE === 'true',
|
coverage: process.env.COVERAGE === 'true',
|
||||||
|
entry,
|
||||||
} satisfies BuildFlags;
|
} satisfies BuildFlags;
|
||||||
|
|
||||||
buildI18N();
|
buildI18N();
|
||||||
spawn(
|
|
||||||
'node',
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
[
|
webpack(createWebpackConfig(cwd!, flags), (err, stats) => {
|
||||||
'--loader',
|
if (err) {
|
||||||
'ts-node/esm/transpile-only',
|
console.error(err);
|
||||||
'../../../node_modules/webpack/bin/webpack.js',
|
process.exit(1);
|
||||||
'--mode',
|
|
||||||
'production',
|
|
||||||
'--env',
|
|
||||||
'flags=' + Buffer.from(JSON.stringify(flags), 'utf-8').toString('hex'),
|
|
||||||
].filter((v): v is string => !!v),
|
|
||||||
{
|
|
||||||
cwd,
|
|
||||||
stdio: 'inherit',
|
|
||||||
shell: true,
|
|
||||||
env: process.env,
|
|
||||||
}
|
}
|
||||||
);
|
if (stats?.hasErrors()) {
|
||||||
|
console.error(stats.toString('errors-only'));
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
});
|
@ -1,16 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
import { spawnSync } from 'node:child_process';
|
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
|
|
||||||
const child = spawnSync(
|
|
||||||
process.execPath,
|
|
||||||
[
|
|
||||||
'--loader',
|
|
||||||
'ts-node/esm/transpile-only',
|
|
||||||
fileURLToPath(new URL('./dev-core.ts', import.meta.url)),
|
|
||||||
...process.argv.slice(2),
|
|
||||||
],
|
|
||||||
{ stdio: 'inherit' }
|
|
||||||
);
|
|
||||||
|
|
||||||
if (child.status) process.exit(child.status);
|
|
@ -1,207 +0,0 @@
|
|||||||
import type { ChildProcess } from 'node:child_process';
|
|
||||||
import { spawn } from 'node:child_process';
|
|
||||||
import { existsSync } from 'node:fs';
|
|
||||||
import path from 'node:path';
|
|
||||||
|
|
||||||
import * as p from '@clack/prompts';
|
|
||||||
import { config } from 'dotenv';
|
|
||||||
|
|
||||||
import { type BuildFlags, projectRoot } from '../config/index.js';
|
|
||||||
import { watchI18N } from '../util/i18n.js';
|
|
||||||
|
|
||||||
const cwd = path.resolve(projectRoot, 'packages/frontend/core');
|
|
||||||
|
|
||||||
const flags: BuildFlags = {
|
|
||||||
distribution: 'browser',
|
|
||||||
mode: 'development',
|
|
||||||
channel: 'canary',
|
|
||||||
coverage: process.env.COVERAGE === 'true',
|
|
||||||
localBlockSuite: undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (process.argv.includes('--static')) {
|
|
||||||
await awaitChildProcess(
|
|
||||||
spawn(
|
|
||||||
'node',
|
|
||||||
[
|
|
||||||
'--loader',
|
|
||||||
'ts-node/esm/transpile-only',
|
|
||||||
'../../../node_modules/webpack/bin/webpack.js',
|
|
||||||
'serve',
|
|
||||||
'--mode',
|
|
||||||
'development',
|
|
||||||
'--no-client-overlay',
|
|
||||||
'--no-live-reload',
|
|
||||||
'--env',
|
|
||||||
'flags=' + Buffer.from(JSON.stringify(flags), 'utf-8').toString('hex'),
|
|
||||||
].filter((v): v is string => !!v),
|
|
||||||
{
|
|
||||||
cwd,
|
|
||||||
stdio: 'inherit',
|
|
||||||
shell: true,
|
|
||||||
env: process.env,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const files = ['.env', '.env.local'];
|
|
||||||
|
|
||||||
for (const file of files) {
|
|
||||||
if (existsSync(path.resolve(projectRoot, file))) {
|
|
||||||
config({
|
|
||||||
path: path.resolve(projectRoot, file),
|
|
||||||
});
|
|
||||||
console.log(`${file} loaded`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const buildFlags = await p.group(
|
|
||||||
{
|
|
||||||
distribution: () =>
|
|
||||||
p.select({
|
|
||||||
message: 'Distribution',
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
value: 'browser',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'desktop',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
initialValue: 'browser',
|
|
||||||
}),
|
|
||||||
mode: () =>
|
|
||||||
p.select({
|
|
||||||
message: 'Mode',
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
value: 'development',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'production',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
initialValue: 'development',
|
|
||||||
}),
|
|
||||||
channel: () =>
|
|
||||||
p.select({
|
|
||||||
message: 'Channel',
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
value: 'canary',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'beta',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'stable',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
initialValue: 'canary',
|
|
||||||
}),
|
|
||||||
coverage: () =>
|
|
||||||
p.confirm({
|
|
||||||
message: 'Enable coverage',
|
|
||||||
initialValue: process.env.COVERAGE === 'true',
|
|
||||||
}),
|
|
||||||
debugBlockSuite: () =>
|
|
||||||
p.confirm({
|
|
||||||
message: 'Debug blocksuite locally?',
|
|
||||||
initialValue: false,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
onCancel: () => {
|
|
||||||
p.cancel('Operation cancelled.');
|
|
||||||
process.exit(0);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (buildFlags.debugBlockSuite) {
|
|
||||||
const { config } = await import('dotenv');
|
|
||||||
const envLocal = config({
|
|
||||||
path: path.resolve(cwd, '.env.local'),
|
|
||||||
});
|
|
||||||
|
|
||||||
const localBlockSuite = await p.text({
|
|
||||||
message: 'local blocksuite PATH',
|
|
||||||
initialValue: envLocal.error
|
|
||||||
? undefined
|
|
||||||
: envLocal.parsed?.LOCAL_BLOCK_SUITE,
|
|
||||||
});
|
|
||||||
if (typeof localBlockSuite !== 'string') {
|
|
||||||
throw new Error('local blocksuite PATH is required');
|
|
||||||
}
|
|
||||||
if (!existsSync(localBlockSuite)) {
|
|
||||||
throw new Error(`local blocksuite not found: ${localBlockSuite}`);
|
|
||||||
}
|
|
||||||
flags.localBlockSuite = localBlockSuite;
|
|
||||||
}
|
|
||||||
|
|
||||||
flags.distribution = buildFlags.distribution as any;
|
|
||||||
flags.mode = buildFlags.mode as any;
|
|
||||||
flags.channel = buildFlags.channel as any;
|
|
||||||
flags.coverage = buildFlags.coverage;
|
|
||||||
|
|
||||||
watchI18N();
|
|
||||||
|
|
||||||
function awaitChildProcess(child: ChildProcess): Promise<number> {
|
|
||||||
return new Promise<number>((resolve, reject) => {
|
|
||||||
const handleExitCode = (code: number | null) => {
|
|
||||||
if (code) {
|
|
||||||
reject(
|
|
||||||
new Error(
|
|
||||||
`Child process at ${
|
|
||||||
(child as any).cwd
|
|
||||||
} fails: ${child.spawnargs.join(' ')}`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
resolve(0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
child.on('error', () => handleExitCode(child.exitCode));
|
|
||||||
child.on('exit', code => handleExitCode(code));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await awaitChildProcess(
|
|
||||||
spawn('node', ['build-edgeless.mjs'], {
|
|
||||||
cwd: path.resolve(projectRoot, 'packages/frontend/templates'),
|
|
||||||
stdio: 'inherit',
|
|
||||||
shell: true,
|
|
||||||
env: process.env,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
// Start webpack
|
|
||||||
await awaitChildProcess(
|
|
||||||
spawn(
|
|
||||||
'node',
|
|
||||||
[
|
|
||||||
'--loader',
|
|
||||||
'ts-node/esm/transpile-only',
|
|
||||||
'../../../node_modules/webpack/bin/webpack.js',
|
|
||||||
flags.mode === 'development' ? 'serve' : undefined,
|
|
||||||
'--mode',
|
|
||||||
flags.mode === 'development' ? 'development' : 'production',
|
|
||||||
'--env',
|
|
||||||
'flags=' + Buffer.from(JSON.stringify(flags), 'utf-8').toString('hex'),
|
|
||||||
].filter((v): v is string => !!v),
|
|
||||||
{
|
|
||||||
cwd,
|
|
||||||
stdio: 'inherit',
|
|
||||||
shell: true,
|
|
||||||
env: process.env,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error during build:', error);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
143
tools/cli/src/bin/dev.ts
Normal file
143
tools/cli/src/bin/dev.ts
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
import { existsSync } from 'node:fs';
|
||||||
|
import { join } from 'node:path';
|
||||||
|
|
||||||
|
import * as p from '@clack/prompts';
|
||||||
|
import { config } from 'dotenv';
|
||||||
|
import webpack from 'webpack';
|
||||||
|
import WebpackDevServer from 'webpack-dev-server';
|
||||||
|
|
||||||
|
import { type BuildFlags, projectRoot } from '../config/index.js';
|
||||||
|
import { watchI18N } from '../util/i18n.js';
|
||||||
|
import { createWebpackConfig } from '../webpack/webpack.config.js';
|
||||||
|
|
||||||
|
const flags: BuildFlags = {
|
||||||
|
distribution: 'browser',
|
||||||
|
mode: 'development',
|
||||||
|
channel: 'canary',
|
||||||
|
coverage: process.env.COVERAGE === 'true',
|
||||||
|
localBlockSuite: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
const files = ['.env', '.env.local'];
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
if (existsSync(join(projectRoot, file))) {
|
||||||
|
config({
|
||||||
|
path: join(projectRoot, file),
|
||||||
|
});
|
||||||
|
console.log(`${file} loaded`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildFlags = process.argv.includes('--static')
|
||||||
|
? { ...flags, debugBlockSuite: false }
|
||||||
|
: ((await p.group(
|
||||||
|
{
|
||||||
|
distribution: () =>
|
||||||
|
p.select({
|
||||||
|
message: 'Distribution',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 'browser',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'desktop',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: 'browser',
|
||||||
|
}),
|
||||||
|
mode: () =>
|
||||||
|
p.select({
|
||||||
|
message: 'Mode',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 'development',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'production',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: 'development',
|
||||||
|
}),
|
||||||
|
channel: () =>
|
||||||
|
p.select({
|
||||||
|
message: 'Channel',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 'canary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'beta',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'stable',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: 'canary',
|
||||||
|
}),
|
||||||
|
coverage: () =>
|
||||||
|
p.confirm({
|
||||||
|
message: 'Enable coverage',
|
||||||
|
initialValue: process.env.COVERAGE === 'true',
|
||||||
|
}),
|
||||||
|
debugBlockSuite: () =>
|
||||||
|
p.confirm({
|
||||||
|
message: 'Debug blocksuite locally?',
|
||||||
|
initialValue: false,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onCancel: () => {
|
||||||
|
p.cancel('Operation cancelled.');
|
||||||
|
process.exit(0);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)) as BuildFlags & { debugBlockSuite: boolean });
|
||||||
|
|
||||||
|
flags.distribution = buildFlags.distribution;
|
||||||
|
flags.mode = buildFlags.mode;
|
||||||
|
flags.channel = buildFlags.channel;
|
||||||
|
flags.coverage = buildFlags.coverage;
|
||||||
|
|
||||||
|
const cwd =
|
||||||
|
flags.distribution === 'browser'
|
||||||
|
? join(projectRoot, 'packages', 'frontend', 'web')
|
||||||
|
: join(projectRoot, 'packages', 'frontend', 'electron');
|
||||||
|
|
||||||
|
if (buildFlags.debugBlockSuite) {
|
||||||
|
const { config } = await import('dotenv');
|
||||||
|
const envLocal = config({
|
||||||
|
path: join(cwd, '.env.local'),
|
||||||
|
});
|
||||||
|
|
||||||
|
const localBlockSuite = await p.text({
|
||||||
|
message: 'local blocksuite PATH',
|
||||||
|
initialValue: envLocal.error
|
||||||
|
? undefined
|
||||||
|
: envLocal.parsed?.LOCAL_BLOCK_SUITE,
|
||||||
|
});
|
||||||
|
if (typeof localBlockSuite !== 'string') {
|
||||||
|
throw new Error('local blocksuite PATH is required');
|
||||||
|
}
|
||||||
|
if (!existsSync(localBlockSuite)) {
|
||||||
|
throw new Error(`local blocksuite not found: ${localBlockSuite}`);
|
||||||
|
}
|
||||||
|
flags.localBlockSuite = localBlockSuite;
|
||||||
|
}
|
||||||
|
|
||||||
|
watchI18N();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// @ts-expect-error no types
|
||||||
|
await import('@affine/templates/build-edgeless');
|
||||||
|
const config = createWebpackConfig(cwd, flags);
|
||||||
|
const compiler = webpack(config);
|
||||||
|
// Start webpack
|
||||||
|
const devServer = new WebpackDevServer(config.devServer, compiler);
|
||||||
|
|
||||||
|
await devServer.start();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error during build:', error);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
@ -6,6 +6,7 @@ export type BuildFlags = {
|
|||||||
channel: 'stable' | 'beta' | 'canary' | 'internal';
|
channel: 'stable' | 'beta' | 'canary' | 'internal';
|
||||||
coverage?: boolean;
|
coverage?: boolean;
|
||||||
localBlockSuite?: string;
|
localBlockSuite?: string;
|
||||||
|
entry?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const projectRoot = fileURLToPath(
|
export const projectRoot = fileURLToPath(
|
||||||
|
@ -69,7 +69,7 @@ export const productionCacheGroups = {
|
|||||||
test: (module: any) =>
|
test: (module: any) =>
|
||||||
module.nameForCondition &&
|
module.nameForCondition &&
|
||||||
/\.css$/.test(module.nameForCondition()) &&
|
/\.css$/.test(module.nameForCondition()) &&
|
||||||
!/^javascript/.test(module.type),
|
!module.type.startsWith('javascript'),
|
||||||
chunks: 'all' as const,
|
chunks: 'all' as const,
|
||||||
minSize: 1,
|
minSize: 1,
|
||||||
minChunks: 1,
|
minChunks: 1,
|
@ -1,29 +1,27 @@
|
|||||||
|
import { createRequire } from 'node:module';
|
||||||
import { join, resolve } from 'node:path';
|
import { join, resolve } from 'node:path';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import { createRequire } from 'node:module';
|
|
||||||
|
|
||||||
import type { Configuration as DevServerConfiguration } from 'webpack-dev-server';
|
import type { RuntimeConfig } from '@affine/env/global';
|
||||||
import { PerfseePlugin } from '@perfsee/webpack';
|
import { PerfseePlugin } from '@perfsee/webpack';
|
||||||
import { sentryWebpackPlugin } from '@sentry/webpack-plugin';
|
|
||||||
|
|
||||||
import CopyPlugin from 'copy-webpack-plugin';
|
|
||||||
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
|
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
|
||||||
|
import { sentryWebpackPlugin } from '@sentry/webpack-plugin';
|
||||||
|
import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin';
|
||||||
|
import CopyPlugin from 'copy-webpack-plugin';
|
||||||
|
import { compact } from 'lodash-es';
|
||||||
|
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||||
import TerserPlugin from 'terser-webpack-plugin';
|
import TerserPlugin from 'terser-webpack-plugin';
|
||||||
import webpack from 'webpack';
|
import webpack from 'webpack';
|
||||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
import type { Configuration as DevServerConfiguration } from 'webpack-dev-server';
|
||||||
import { compact } from 'lodash-es';
|
|
||||||
|
|
||||||
|
import { type BuildFlags, projectRoot } from '../config/index.js';
|
||||||
import { productionCacheGroups } from './cache-group.js';
|
import { productionCacheGroups } from './cache-group.js';
|
||||||
import type { BuildFlags } from '@affine/cli/config';
|
|
||||||
import { projectRoot } from '@affine/cli/config';
|
|
||||||
import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin';
|
|
||||||
import type { RuntimeConfig } from '@affine/env/global';
|
|
||||||
import { WebpackS3Plugin } from './s3-plugin.js';
|
import { WebpackS3Plugin } from './s3-plugin.js';
|
||||||
|
|
||||||
const IN_CI = !!process.env.CI;
|
const IN_CI = !!process.env.CI;
|
||||||
|
|
||||||
export const rootPath = join(fileURLToPath(import.meta.url), '..', '..');
|
export const rootPath = join(fileURLToPath(import.meta.url), '..', '..');
|
||||||
const workspaceRoot = join(rootPath, '..', '..', '..');
|
export const workspaceRoot = join(rootPath, '..', '..', '..');
|
||||||
|
|
||||||
const require = createRequire(rootPath);
|
const require = createRequire(rootPath);
|
||||||
|
|
||||||
@ -89,15 +87,15 @@ export const getPublicPath = (buildFlags: BuildFlags) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const createConfiguration: (
|
export const createConfiguration: (
|
||||||
|
cwd: string,
|
||||||
buildFlags: BuildFlags,
|
buildFlags: BuildFlags,
|
||||||
runtimeConfig: RuntimeConfig
|
runtimeConfig: RuntimeConfig
|
||||||
) => webpack.Configuration = (buildFlags, runtimeConfig) => {
|
) => webpack.Configuration = (cwd, buildFlags, runtimeConfig) => {
|
||||||
const blocksuiteBaseDir = buildFlags.localBlockSuite;
|
const blocksuiteBaseDir = buildFlags.localBlockSuite;
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
name: 'affine',
|
name: 'affine',
|
||||||
// to set a correct base path for the source map
|
// to set a correct base path for the source map
|
||||||
context: projectRoot,
|
context: cwd,
|
||||||
experiments: {
|
experiments: {
|
||||||
topLevelAwait: true,
|
topLevelAwait: true,
|
||||||
outputModule: false,
|
outputModule: false,
|
||||||
@ -124,7 +122,7 @@ export const createConfiguration: (
|
|||||||
devtoolModuleFilenameTemplate: 'webpack://[namespace]/[resource-path]',
|
devtoolModuleFilenameTemplate: 'webpack://[namespace]/[resource-path]',
|
||||||
hotUpdateChunkFilename: 'hot/[id].[fullhash].js',
|
hotUpdateChunkFilename: 'hot/[id].[fullhash].js',
|
||||||
hotUpdateMainFilename: 'hot/[runtime].[fullhash].json',
|
hotUpdateMainFilename: 'hot/[runtime].[fullhash].json',
|
||||||
path: join(rootPath, 'dist'),
|
path: join(cwd, 'dist'),
|
||||||
clean: buildFlags.mode === 'production',
|
clean: buildFlags.mode === 'production',
|
||||||
globalObject: 'globalThis',
|
globalObject: 'globalThis',
|
||||||
publicPath: getPublicPath(buildFlags),
|
publicPath: getPublicPath(buildFlags),
|
||||||
@ -315,7 +313,7 @@ export const createConfiguration: (
|
|||||||
postcssOptions: {
|
postcssOptions: {
|
||||||
config: resolve(
|
config: resolve(
|
||||||
rootPath,
|
rootPath,
|
||||||
'.webpack',
|
'webpack',
|
||||||
'postcss.config.cjs'
|
'postcss.config.cjs'
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -356,8 +354,9 @@ export const createConfiguration: (
|
|||||||
new CopyPlugin({
|
new CopyPlugin({
|
||||||
patterns: [
|
patterns: [
|
||||||
{
|
{
|
||||||
from: resolve(rootPath, 'public'),
|
// copy the shared public assets into dist
|
||||||
to: resolve(rootPath, 'dist'),
|
from: join(workspaceRoot, 'packages', 'frontend', 'core', 'public'),
|
||||||
|
to: join(cwd, 'dist'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
@ -375,11 +374,24 @@ export const createConfiguration: (
|
|||||||
overlay: process.env.DISABLE_DEV_OVERLAY === 'true' ? false : undefined,
|
overlay: process.env.DISABLE_DEV_OVERLAY === 'true' ? false : undefined,
|
||||||
},
|
},
|
||||||
historyApiFallback: true,
|
historyApiFallback: true,
|
||||||
static: {
|
static: [
|
||||||
directory: resolve(rootPath, 'public'),
|
{
|
||||||
publicPath: '/',
|
directory: join(
|
||||||
watch: true,
|
projectRoot,
|
||||||
},
|
'packages',
|
||||||
|
'frontend',
|
||||||
|
'core',
|
||||||
|
'public'
|
||||||
|
),
|
||||||
|
publicPath: '/',
|
||||||
|
watch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
directory: join(cwd, 'public'),
|
||||||
|
publicPath: '/',
|
||||||
|
watch: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
proxy: [
|
proxy: [
|
||||||
{
|
{
|
||||||
context: '/api/worker/',
|
context: '/api/worker/',
|
@ -1,9 +1,7 @@
|
|||||||
import type { RuntimeConfig } from '@affine/env/global';
|
import type { RuntimeConfig } from '@affine/env/global';
|
||||||
import type { BuildFlags } from '@affine/cli/config';
|
|
||||||
import { createRequire } from 'node:module';
|
|
||||||
|
|
||||||
const require = createRequire(import.meta.url);
|
import packageJson from '../../package.json' assert { type: 'json' };
|
||||||
const packageJson = require('../package.json');
|
import type { BuildFlags } from '../config';
|
||||||
|
|
||||||
export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
|
export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
|
||||||
const buildPreset: Record<BuildFlags['channel'], RuntimeConfig> = {
|
const buildPreset: Record<BuildFlags['channel'], RuntimeConfig> = {
|
||||||
@ -21,7 +19,6 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
|
|||||||
enableNewSettingUnstableApi: false,
|
enableNewSettingUnstableApi: false,
|
||||||
enableSQLiteProvider: true,
|
enableSQLiteProvider: true,
|
||||||
enableMoveDatabase: false,
|
enableMoveDatabase: false,
|
||||||
enableNotificationCenter: true,
|
|
||||||
enableCloud: true,
|
enableCloud: true,
|
||||||
enableCaptcha: true,
|
enableCaptcha: true,
|
||||||
enableEnhanceShareMode: false,
|
enableEnhanceShareMode: false,
|
||||||
@ -30,7 +27,7 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
|
|||||||
allowLocalWorkspace: false,
|
allowLocalWorkspace: false,
|
||||||
serverUrlPrefix: 'https://app.affine.pro',
|
serverUrlPrefix: 'https://app.affine.pro',
|
||||||
appVersion: packageJson.version,
|
appVersion: packageJson.version,
|
||||||
editorVersion: packageJson.dependencies['@blocksuite/presets'],
|
editorVersion: packageJson.devDependencies['@blocksuite/presets'],
|
||||||
appBuildType: 'stable',
|
appBuildType: 'stable',
|
||||||
},
|
},
|
||||||
get beta() {
|
get beta() {
|
||||||
@ -63,7 +60,6 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
|
|||||||
enableNewSettingUnstableApi: false,
|
enableNewSettingUnstableApi: false,
|
||||||
enableSQLiteProvider: true,
|
enableSQLiteProvider: true,
|
||||||
enableMoveDatabase: false,
|
enableMoveDatabase: false,
|
||||||
enableNotificationCenter: true,
|
|
||||||
enableCloud: true,
|
enableCloud: true,
|
||||||
enableCaptcha: true,
|
enableCaptcha: true,
|
||||||
enableEnhanceShareMode: false,
|
enableEnhanceShareMode: false,
|
||||||
@ -72,7 +68,7 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
|
|||||||
allowLocalWorkspace: false,
|
allowLocalWorkspace: false,
|
||||||
serverUrlPrefix: 'https://affine.fail',
|
serverUrlPrefix: 'https://affine.fail',
|
||||||
appVersion: packageJson.version,
|
appVersion: packageJson.version,
|
||||||
editorVersion: packageJson.dependencies['@blocksuite/presets'],
|
editorVersion: packageJson.devDependencies['@blocksuite/presets'],
|
||||||
appBuildType: 'canary',
|
appBuildType: 'canary',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -105,9 +101,6 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
|
|||||||
enableNewSettingUnstableApi: process.env.ENABLE_NEW_SETTING_UNSTABLE_API
|
enableNewSettingUnstableApi: process.env.ENABLE_NEW_SETTING_UNSTABLE_API
|
||||||
? process.env.ENABLE_NEW_SETTING_UNSTABLE_API === 'true'
|
? process.env.ENABLE_NEW_SETTING_UNSTABLE_API === 'true'
|
||||||
: currentBuildPreset.enableNewSettingUnstableApi,
|
: currentBuildPreset.enableNewSettingUnstableApi,
|
||||||
enableNotificationCenter: process.env.ENABLE_NOTIFICATION_CENTER
|
|
||||||
? process.env.ENABLE_NOTIFICATION_CENTER === 'true'
|
|
||||||
: currentBuildPreset.enableNotificationCenter,
|
|
||||||
enableCloud: process.env.ENABLE_CLOUD
|
enableCloud: process.env.ENABLE_CLOUD
|
||||||
? process.env.ENABLE_CLOUD === 'true'
|
? process.env.ENABLE_CLOUD === 'true'
|
||||||
: currentBuildPreset.enableCloud,
|
: currentBuildPreset.enableCloud,
|
@ -1,5 +1,5 @@
|
|||||||
import { join } from 'node:path';
|
|
||||||
import { readFile } from 'node:fs/promises';
|
import { readFile } from 'node:fs/promises';
|
||||||
|
import { join } from 'node:path';
|
||||||
|
|
||||||
import type { PutObjectCommandInput } from '@aws-sdk/client-s3';
|
import type { PutObjectCommandInput } from '@aws-sdk/client-s3';
|
||||||
import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
||||||
@ -7,7 +7,7 @@ import { lookup } from 'mime-types';
|
|||||||
import type { Compiler, WebpackPluginInstance } from 'webpack';
|
import type { Compiler, WebpackPluginInstance } from 'webpack';
|
||||||
|
|
||||||
export const R2_BUCKET =
|
export const R2_BUCKET =
|
||||||
process.env.R2_BUCKET! ??
|
process.env.R2_BUCKET ??
|
||||||
(process.env.BUILD_TYPE === 'canary' ? 'assets-dev' : 'assets-prod');
|
(process.env.BUILD_TYPE === 'canary' ? 'assets-dev' : 'assets-prod');
|
||||||
|
|
||||||
export class WebpackS3Plugin implements WebpackPluginInstance {
|
export class WebpackS3Plugin implements WebpackPluginInstance {
|
||||||
@ -15,7 +15,9 @@ export class WebpackS3Plugin implements WebpackPluginInstance {
|
|||||||
region: 'auto',
|
region: 'auto',
|
||||||
endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
|
endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
|
||||||
credentials: {
|
credentials: {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
accessKeyId: process.env.R2_ACCESS_KEY_ID!,
|
accessKeyId: process.env.R2_ACCESS_KEY_ID!,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
|
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
|
||||||
},
|
},
|
||||||
});
|
});
|
@ -10,7 +10,7 @@
|
|||||||
<meta name="theme-color" content="#fafafa" />
|
<meta name="theme-color" content="#fafafa" />
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||||
<link rel="icon" sizes="192x192" href="/chrome-192x192.png" />
|
<link rel="icon" sizes="192x192" href="/favicon-192.png" />
|
||||||
<meta name="emotion-insertion-point" content="" />
|
<meta name="emotion-insertion-point" content="" />
|
||||||
<meta property="description" content="<%= DESCRIPTION %>" />
|
<meta property="description" content="<%= DESCRIPTION %>" />
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image" />
|
@ -1,13 +1,14 @@
|
|||||||
import { execSync } from 'node:child_process';
|
import { execSync } from 'node:child_process';
|
||||||
import { join, resolve } from 'node:path';
|
import { join, resolve } from 'node:path';
|
||||||
|
|
||||||
|
import type { BuildFlags } from '@affine/cli/config';
|
||||||
|
import { Repository } from '@napi-rs/simple-git';
|
||||||
|
import HTMLPlugin from 'html-webpack-plugin';
|
||||||
import { once } from 'lodash-es';
|
import { once } from 'lodash-es';
|
||||||
import { merge } from 'webpack-merge';
|
import { merge } from 'webpack-merge';
|
||||||
import type { BuildFlags } from '@affine/cli/config';
|
|
||||||
import HTMLPlugin from 'html-webpack-plugin';
|
|
||||||
|
|
||||||
|
import { createConfiguration, rootPath, workspaceRoot } from './config.js';
|
||||||
import { getRuntimeConfig } from './runtime-config.js';
|
import { getRuntimeConfig } from './runtime-config.js';
|
||||||
import { createConfiguration, rootPath } from './config.js';
|
|
||||||
|
|
||||||
const DESCRIPTION = `There can be more than Notion and Miro. AFFiNE is a next-gen knowledge base that brings planning, sorting and creating all together.`;
|
const DESCRIPTION = `There can be more than Notion and Miro. AFFiNE is a next-gen knowledge base that brings planning, sorting and creating all together.`;
|
||||||
|
|
||||||
@ -16,27 +17,29 @@ const gitShortHash = once(() => {
|
|||||||
if (GITHUB_SHA) {
|
if (GITHUB_SHA) {
|
||||||
return GITHUB_SHA.substring(0, 9);
|
return GITHUB_SHA.substring(0, 9);
|
||||||
}
|
}
|
||||||
|
const repo = new Repository(workspaceRoot);
|
||||||
|
const shortSha = repo.head().target()?.substring(0, 9);
|
||||||
|
if (shortSha) {
|
||||||
|
return shortSha;
|
||||||
|
}
|
||||||
const sha = execSync(`git rev-parse --short HEAD`, {
|
const sha = execSync(`git rev-parse --short HEAD`, {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
}).trim();
|
}).trim();
|
||||||
return sha;
|
return sha;
|
||||||
});
|
});
|
||||||
|
|
||||||
export default async function (cli_env: any, _: any) {
|
export function createWebpackConfig(cwd: string, flags: BuildFlags) {
|
||||||
const flags: BuildFlags = JSON.parse(
|
|
||||||
Buffer.from(cli_env.flags, 'hex').toString('utf-8')
|
|
||||||
);
|
|
||||||
console.log('build flags', flags);
|
console.log('build flags', flags);
|
||||||
const runtimeConfig = getRuntimeConfig(flags);
|
const runtimeConfig = getRuntimeConfig(flags);
|
||||||
console.log('runtime config', runtimeConfig);
|
console.log('runtime config', runtimeConfig);
|
||||||
const config = createConfiguration(flags, runtimeConfig);
|
const config = createConfiguration(cwd, flags, runtimeConfig);
|
||||||
return merge(config, {
|
return merge(config, {
|
||||||
entry: {
|
entry: {
|
||||||
app: resolve(rootPath, 'src/index.tsx'),
|
app: flags.entry ?? resolve(cwd, 'src/index.tsx'),
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new HTMLPlugin({
|
new HTMLPlugin({
|
||||||
template: join(rootPath, '.webpack', 'template.html'),
|
template: join(rootPath, 'webpack', 'template.html'),
|
||||||
inject: 'body',
|
inject: 'body',
|
||||||
scriptLoading: 'module',
|
scriptLoading: 'module',
|
||||||
minify: false,
|
minify: false,
|
@ -6,5 +6,6 @@
|
|||||||
"moduleResolution": "Node",
|
"moduleResolution": "Node",
|
||||||
"outDir": "lib"
|
"outDir": "lib"
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src", "package.json"],
|
||||||
|
"references": [{ "path": "../../packages/common/env" }]
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
"skipLibCheck": true, // skip all type checks for .d.ts files
|
"skipLibCheck": true, // skip all type checks for .d.ts files
|
||||||
"paths": {
|
"paths": {
|
||||||
"@affine/core/*": ["./packages/frontend/core/src/*"],
|
"@affine/core/*": ["./packages/frontend/core/src/*"],
|
||||||
|
"@affine/core": ["./packages/frontend/core/src/index.ts"],
|
||||||
"@affine/cli/*": ["./tools/cli/src/*"],
|
"@affine/cli/*": ["./tools/cli/src/*"],
|
||||||
"@affine/server/*": ["./packages/backend/server/src/*"],
|
"@affine/server/*": ["./packages/backend/server/src/*"],
|
||||||
"@affine/component": ["./packages/frontend/component/src/index"],
|
"@affine/component": ["./packages/frontend/component/src/index"],
|
||||||
@ -90,9 +91,15 @@
|
|||||||
{
|
{
|
||||||
"path": "./packages/frontend/core"
|
"path": "./packages/frontend/core"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "./packages/frontend/web"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "./packages/frontend/electron/tsconfig.test.json"
|
"path": "./packages/frontend/electron/tsconfig.test.json"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "./packages/frontend/electron/renderer/tsconfig.json"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "./packages/frontend/graphql"
|
"path": "./packages/frontend/graphql"
|
||||||
},
|
},
|
||||||
|
@ -7,12 +7,7 @@
|
|||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"outDir": "lib"
|
"outDir": "lib"
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["vite.config.ts", "vitest.config.ts", "scripts"],
|
||||||
"vite.config.ts",
|
|
||||||
"vitest.config.ts",
|
|
||||||
"scripts",
|
|
||||||
"packages/frontend/core/.webpack/runtime-config.ts"
|
|
||||||
],
|
|
||||||
"references": [
|
"references": [
|
||||||
{
|
{
|
||||||
"path": "./packages/common/env"
|
"path": "./packages/common/env"
|
||||||
|
Loading…
Reference in New Issue
Block a user