mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
refactor: webpack config (#11421)
This commit is contained in:
@@ -17,7 +17,7 @@ if (typeof window !== 'undefined') {
|
|||||||
debug.enable('*');
|
debug.enable('*');
|
||||||
console.warn('Debug logs enabled');
|
console.warn('Debug logs enabled');
|
||||||
}
|
}
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (BUILD_CONFIG.debug) {
|
||||||
debug.enable('*,-micromark');
|
debug.enable('*,-micromark');
|
||||||
console.warn('Debug logs enabled');
|
console.warn('Debug logs enabled');
|
||||||
}
|
}
|
||||||
|
|||||||
3
packages/common/env/package.json
vendored
3
packages/common/env/package.json
vendored
@@ -12,7 +12,8 @@
|
|||||||
"./workspace": "./src/workspace.ts",
|
"./workspace": "./src/workspace.ts",
|
||||||
"./workspace/legacy-cloud": "./src/workspace/legacy-cloud/index.ts",
|
"./workspace/legacy-cloud": "./src/workspace/legacy-cloud/index.ts",
|
||||||
"./filter": "./src/filter.ts",
|
"./filter": "./src/filter.ts",
|
||||||
"./blocksuite": "./src/blocksuite/index.ts"
|
"./blocksuite": "./src/blocksuite/index.ts",
|
||||||
|
"./worker": "./src/worker.ts"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@affine/templates": "workspace:*",
|
"@affine/templates": "workspace:*",
|
||||||
|
|||||||
1
packages/common/env/src/global.ts
vendored
1
packages/common/env/src/global.ts
vendored
@@ -17,6 +17,7 @@ export function setupGlobal() {
|
|||||||
isMobile: false,
|
isMobile: false,
|
||||||
isSelfHosted: false,
|
isSelfHosted: false,
|
||||||
publicPath: '/',
|
publicPath: '/',
|
||||||
|
workerPath: '/js/',
|
||||||
};
|
};
|
||||||
|
|
||||||
if (globalThis.navigator) {
|
if (globalThis.navigator) {
|
||||||
|
|||||||
7
packages/common/env/src/worker.ts
vendored
Normal file
7
packages/common/env/src/worker.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function getWorkerUrl(name: string) {
|
||||||
|
if (BUILD_CONFIG.debug && !name.endsWith('.worker.js')) {
|
||||||
|
throw new Error(`worker should be named with '.worker.js', get ${name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return environment.workerPath + name + '?v=' + BUILD_CONFIG.appVersion;
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
"./utils": "./src/utils/index.ts",
|
"./utils": "./src/utils/index.ts",
|
||||||
"./app-config-storage": "./src/app-config-storage.ts",
|
"./app-config-storage": "./src/app-config-storage.ts",
|
||||||
"./op": "./src/op/index.ts",
|
"./op": "./src/op/index.ts",
|
||||||
|
"./atom": "./src/atom/index.ts",
|
||||||
".": "./src/index.ts"
|
".": "./src/index.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@affine/component": "workspace:*",
|
"@affine/component": "workspace:*",
|
||||||
"@affine/core": "workspace:*",
|
"@affine/core": "workspace:*",
|
||||||
|
"@affine/env": "workspace:*",
|
||||||
"@affine/i18n": "workspace:*",
|
"@affine/i18n": "workspace:*",
|
||||||
"@affine/nbstore": "workspace:*",
|
"@affine/nbstore": "workspace:*",
|
||||||
"@blocksuite/affine": "workspace:*",
|
"@blocksuite/affine": "workspace:*",
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import { ClientSchemeProvider } from '@affine/core/modules/url/providers/client-
|
|||||||
import { configureBrowserWorkbenchModule } from '@affine/core/modules/workbench';
|
import { configureBrowserWorkbenchModule } from '@affine/core/modules/workbench';
|
||||||
import { WorkspacesService } from '@affine/core/modules/workspace';
|
import { WorkspacesService } from '@affine/core/modules/workspace';
|
||||||
import { configureBrowserWorkspaceFlavours } from '@affine/core/modules/workspace-engine';
|
import { configureBrowserWorkspaceFlavours } from '@affine/core/modules/workspace-engine';
|
||||||
|
import { getWorkerUrl } from '@affine/env/worker';
|
||||||
import { I18n } from '@affine/i18n';
|
import { I18n } from '@affine/i18n';
|
||||||
import { StoreManagerClient } from '@affine/nbstore/worker/client';
|
import { StoreManagerClient } from '@affine/nbstore/worker/client';
|
||||||
import { defaultBlockMarkdownAdapterMatchers } from '@blocksuite/affine/adapters';
|
import { defaultBlockMarkdownAdapterMatchers } from '@blocksuite/affine/adapters';
|
||||||
@@ -51,11 +52,7 @@ import { AffineTheme } from './plugins/affine-theme';
|
|||||||
import { AIButton } from './plugins/ai-button';
|
import { AIButton } from './plugins/ai-button';
|
||||||
|
|
||||||
const storeManagerClient = new StoreManagerClient(
|
const storeManagerClient = new StoreManagerClient(
|
||||||
new OpClient(
|
new OpClient(new Worker(getWorkerUrl('nbstore.worker.js')))
|
||||||
new Worker(
|
|
||||||
new URL(/* webpackChunkName: "nbstore" */ './nbstore.ts', import.meta.url)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
window.addEventListener('beforeunload', () => {
|
window.addEventListener('beforeunload', () => {
|
||||||
storeManagerClient.dispose();
|
storeManagerClient.dispose();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"references": [
|
"references": [
|
||||||
{ "path": "../../component" },
|
{ "path": "../../component" },
|
||||||
{ "path": "../../core" },
|
{ "path": "../../core" },
|
||||||
|
{ "path": "../../../common/env" },
|
||||||
{ "path": "../../i18n" },
|
{ "path": "../../i18n" },
|
||||||
{ "path": "../../../common/nbstore" },
|
{ "path": "../../../common/nbstore" },
|
||||||
{ "path": "../../../../blocksuite/affine/all" },
|
{ "path": "../../../../blocksuite/affine/all" },
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
export const config = {
|
|
||||||
entry: {
|
|
||||||
app: './src/app/index.tsx',
|
|
||||||
shell: './src/shell/index.tsx',
|
|
||||||
backgroundWorker: './src/background-worker/index.ts',
|
|
||||||
popup: './src/popup/index.tsx',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -2,7 +2,13 @@ import path from 'node:path';
|
|||||||
|
|
||||||
import type { _AsyncVersionOf } from 'async-call-rpc';
|
import type { _AsyncVersionOf } from 'async-call-rpc';
|
||||||
import { AsyncCall } from 'async-call-rpc';
|
import { AsyncCall } from 'async-call-rpc';
|
||||||
import type { UtilityProcess, WebContents } from 'electron';
|
import type {
|
||||||
|
BaseWindow,
|
||||||
|
OpenDialogOptions,
|
||||||
|
SaveDialogOptions,
|
||||||
|
UtilityProcess,
|
||||||
|
WebContents,
|
||||||
|
} from 'electron';
|
||||||
import {
|
import {
|
||||||
app,
|
app,
|
||||||
dialog,
|
dialog,
|
||||||
@@ -57,7 +63,6 @@ class HelperProcessManager {
|
|||||||
this.ready = new Promise((resolve, reject) => {
|
this.ready = new Promise((resolve, reject) => {
|
||||||
helperProcess.once('spawn', () => {
|
helperProcess.once('spawn', () => {
|
||||||
try {
|
try {
|
||||||
this.#connectMain();
|
|
||||||
logger.info('[helper] forked', helperProcess.pid);
|
logger.info('[helper] forked', helperProcess.pid);
|
||||||
resolve();
|
resolve();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -91,11 +96,15 @@ class HelperProcessManager {
|
|||||||
|
|
||||||
// bridge main <-> helper process
|
// bridge main <-> helper process
|
||||||
// also set up the RPC to the helper process
|
// also set up the RPC to the helper process
|
||||||
#connectMain() {
|
connectMain(window: BaseWindow) {
|
||||||
const dialogMethods = pickAndBind(dialog, [
|
const dialogMethods = {
|
||||||
'showOpenDialog',
|
showOpenDialog: async (opts: OpenDialogOptions) => {
|
||||||
'showSaveDialog',
|
return dialog.showOpenDialog(window, opts);
|
||||||
]);
|
},
|
||||||
|
showSaveDialog: async (opts: SaveDialogOptions) => {
|
||||||
|
return dialog.showSaveDialog(window, opts);
|
||||||
|
},
|
||||||
|
};
|
||||||
const shellMethods = pickAndBind(shell, [
|
const shellMethods = pickAndBind(shell, [
|
||||||
'openExternal',
|
'openExternal',
|
||||||
'showItemInFolder',
|
'showItemInFolder',
|
||||||
|
|||||||
@@ -63,8 +63,6 @@ export class MainWindowManager {
|
|||||||
defaultHeight: 800,
|
defaultHeight: 800,
|
||||||
});
|
});
|
||||||
|
|
||||||
await ensureHelperProcess();
|
|
||||||
|
|
||||||
const browserWindow = new BrowserWindow({
|
const browserWindow = new BrowserWindow({
|
||||||
titleBarStyle: isMacOS()
|
titleBarStyle: isMacOS()
|
||||||
? 'hiddenInset'
|
? 'hiddenInset'
|
||||||
@@ -88,6 +86,8 @@ export class MainWindowManager {
|
|||||||
sandbox: false,
|
sandbox: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const helper = await ensureHelperProcess();
|
||||||
|
helper.connectMain(browserWindow);
|
||||||
|
|
||||||
if (isLinux()) {
|
if (isLinux()) {
|
||||||
browserWindow.setIcon(
|
browserWindow.setIcon(
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@affine/component": "workspace:*",
|
"@affine/component": "workspace:*",
|
||||||
"@affine/core": "workspace:*",
|
"@affine/core": "workspace:*",
|
||||||
|
"@affine/env": "workspace:*",
|
||||||
"@affine/i18n": "workspace:*",
|
"@affine/i18n": "workspace:*",
|
||||||
"@affine/nbstore": "workspace:*",
|
"@affine/nbstore": "workspace:*",
|
||||||
"@blocksuite/affine": "workspace:*",
|
"@blocksuite/affine": "workspace:*",
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import {
|
|||||||
WorkspacesService,
|
WorkspacesService,
|
||||||
} from '@affine/core/modules/workspace';
|
} from '@affine/core/modules/workspace';
|
||||||
import { configureBrowserWorkspaceFlavours } from '@affine/core/modules/workspace-engine';
|
import { configureBrowserWorkspaceFlavours } from '@affine/core/modules/workspace-engine';
|
||||||
|
import { getWorkerUrl } from '@affine/env/worker';
|
||||||
import { I18n } from '@affine/i18n';
|
import { I18n } from '@affine/i18n';
|
||||||
import { StoreManagerClient } from '@affine/nbstore/worker/client';
|
import { StoreManagerClient } from '@affine/nbstore/worker/client';
|
||||||
import { defaultBlockMarkdownAdapterMatchers } from '@blocksuite/affine/adapters';
|
import { defaultBlockMarkdownAdapterMatchers } from '@blocksuite/affine/adapters';
|
||||||
@@ -414,12 +415,7 @@ export function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createStoreManagerClient() {
|
function createStoreManagerClient() {
|
||||||
const worker = new Worker(
|
const worker = new Worker(getWorkerUrl('nbstore.worker.js'));
|
||||||
new URL(
|
|
||||||
/* webpackChunkName: "nbstore-worker" */ './worker.ts',
|
|
||||||
import.meta.url
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const { port1: nativeDBApiChannelServer, port2: nativeDBApiChannelClient } =
|
const { port1: nativeDBApiChannelServer, port2: nativeDBApiChannelClient } =
|
||||||
new MessageChannel();
|
new MessageChannel();
|
||||||
AsyncCall<typeof NbStoreNativeDBApis>(NbStoreNativeDBApis, {
|
AsyncCall<typeof NbStoreNativeDBApis>(NbStoreNativeDBApis, {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"references": [
|
"references": [
|
||||||
{ "path": "../../component" },
|
{ "path": "../../component" },
|
||||||
{ "path": "../../core" },
|
{ "path": "../../core" },
|
||||||
|
{ "path": "../../../common/env" },
|
||||||
{ "path": "../../i18n" },
|
{ "path": "../../i18n" },
|
||||||
{ "path": "../../../common/nbstore" },
|
{ "path": "../../../common/nbstore" },
|
||||||
{ "path": "../../../../blocksuite/affine/all" },
|
{ "path": "../../../../blocksuite/affine/all" },
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@affine/component": "workspace:*",
|
"@affine/component": "workspace:*",
|
||||||
"@affine/core": "workspace:*",
|
"@affine/core": "workspace:*",
|
||||||
|
"@affine/env": "workspace:*",
|
||||||
"@affine/i18n": "workspace:*",
|
"@affine/i18n": "workspace:*",
|
||||||
"@affine/nbstore": "workspace:*",
|
"@affine/nbstore": "workspace:*",
|
||||||
"@blocksuite/affine": "workspace:*",
|
"@blocksuite/affine": "workspace:*",
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
import { PopupWindowProvider } from '@affine/core/modules/url';
|
import { PopupWindowProvider } from '@affine/core/modules/url';
|
||||||
import { configureBrowserWorkbenchModule } from '@affine/core/modules/workbench';
|
import { configureBrowserWorkbenchModule } from '@affine/core/modules/workbench';
|
||||||
import { configureBrowserWorkspaceFlavours } from '@affine/core/modules/workspace-engine';
|
import { configureBrowserWorkspaceFlavours } from '@affine/core/modules/workspace-engine';
|
||||||
|
import { getWorkerUrl } from '@affine/env/worker';
|
||||||
import { StoreManagerClient } from '@affine/nbstore/worker/client';
|
import { StoreManagerClient } from '@affine/nbstore/worker/client';
|
||||||
import { Framework, FrameworkRoot, getCurrentStore } from '@toeverything/infra';
|
import { Framework, FrameworkRoot, getCurrentStore } from '@toeverything/infra';
|
||||||
import { OpClient } from '@toeverything/infra/op';
|
import { OpClient } from '@toeverything/infra/op';
|
||||||
@@ -22,16 +23,12 @@ import { RouterProvider } from 'react-router-dom';
|
|||||||
|
|
||||||
let storeManagerClient: StoreManagerClient;
|
let storeManagerClient: StoreManagerClient;
|
||||||
|
|
||||||
|
const workerUrl = getWorkerUrl('nbstore.worker.js');
|
||||||
if (window.SharedWorker) {
|
if (window.SharedWorker) {
|
||||||
const worker = new SharedWorker(
|
const worker = new SharedWorker(workerUrl, { name: 'affine-shared-worker' });
|
||||||
new URL(/* webpackChunkName: "nbstore" */ './nbstore.ts', import.meta.url),
|
|
||||||
{ name: 'affine-shared-worker' }
|
|
||||||
);
|
|
||||||
storeManagerClient = new StoreManagerClient(new OpClient(worker.port));
|
storeManagerClient = new StoreManagerClient(new OpClient(worker.port));
|
||||||
} else {
|
} else {
|
||||||
const worker = new Worker(
|
const worker = new Worker(workerUrl);
|
||||||
new URL(/* webpackChunkName: "nbstore" */ './nbstore.ts', import.meta.url)
|
|
||||||
);
|
|
||||||
storeManagerClient = new StoreManagerClient(new OpClient(worker));
|
storeManagerClient = new StoreManagerClient(new OpClient(worker));
|
||||||
}
|
}
|
||||||
window.addEventListener('beforeunload', () => {
|
window.addEventListener('beforeunload', () => {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"references": [
|
"references": [
|
||||||
{ "path": "../../component" },
|
{ "path": "../../component" },
|
||||||
{ "path": "../../core" },
|
{ "path": "../../core" },
|
||||||
|
{ "path": "../../../common/env" },
|
||||||
{ "path": "../../i18n" },
|
{ "path": "../../i18n" },
|
||||||
{ "path": "../../../common/nbstore" },
|
{ "path": "../../../common/nbstore" },
|
||||||
{ "path": "../../../../blocksuite/affine/all" },
|
{ "path": "../../../../blocksuite/affine/all" },
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@affine/component": "workspace:*",
|
"@affine/component": "workspace:*",
|
||||||
"@affine/core": "workspace:*",
|
"@affine/core": "workspace:*",
|
||||||
|
"@affine/env": "workspace:*",
|
||||||
"@affine/i18n": "workspace:*",
|
"@affine/i18n": "workspace:*",
|
||||||
"@affine/nbstore": "workspace:*",
|
"@affine/nbstore": "workspace:*",
|
||||||
"@affine/track": "workspace:*",
|
"@affine/track": "workspace:*",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { PopupWindowProvider } from '@affine/core/modules/url';
|
|||||||
import { configureBrowserWorkbenchModule } from '@affine/core/modules/workbench';
|
import { configureBrowserWorkbenchModule } from '@affine/core/modules/workbench';
|
||||||
import { configureBrowserWorkspaceFlavours } from '@affine/core/modules/workspace-engine';
|
import { configureBrowserWorkspaceFlavours } from '@affine/core/modules/workspace-engine';
|
||||||
import createEmotionCache from '@affine/core/utils/create-emotion-cache';
|
import createEmotionCache from '@affine/core/utils/create-emotion-cache';
|
||||||
|
import { getWorkerUrl } from '@affine/env/worker';
|
||||||
import { StoreManagerClient } from '@affine/nbstore/worker/client';
|
import { StoreManagerClient } from '@affine/nbstore/worker/client';
|
||||||
import { CacheProvider } from '@emotion/react';
|
import { CacheProvider } from '@emotion/react';
|
||||||
import { Framework, FrameworkRoot, getCurrentStore } from '@toeverything/infra';
|
import { Framework, FrameworkRoot, getCurrentStore } from '@toeverything/infra';
|
||||||
@@ -23,19 +24,16 @@ const cache = createEmotionCache();
|
|||||||
|
|
||||||
let storeManagerClient: StoreManagerClient;
|
let storeManagerClient: StoreManagerClient;
|
||||||
|
|
||||||
|
const workerUrl = getWorkerUrl('nbstore.worker.js');
|
||||||
|
|
||||||
if (
|
if (
|
||||||
window.SharedWorker &&
|
window.SharedWorker &&
|
||||||
localStorage.getItem('disableSharedWorker') !== 'true'
|
localStorage.getItem('disableSharedWorker') !== 'true'
|
||||||
) {
|
) {
|
||||||
const worker = new SharedWorker(
|
const worker = new SharedWorker(workerUrl);
|
||||||
new URL(/* webpackChunkName: "nbstore" */ './nbstore.ts', import.meta.url),
|
|
||||||
{ name: 'affine-shared-worker' }
|
|
||||||
);
|
|
||||||
storeManagerClient = new StoreManagerClient(new OpClient(worker.port));
|
storeManagerClient = new StoreManagerClient(new OpClient(worker.port));
|
||||||
} else {
|
} else {
|
||||||
const worker = new Worker(
|
const worker = new Worker(workerUrl);
|
||||||
new URL(/* webpackChunkName: "nbstore" */ './nbstore.ts', import.meta.url)
|
|
||||||
);
|
|
||||||
storeManagerClient = new StoreManagerClient(new OpClient(worker));
|
storeManagerClient = new StoreManagerClient(new OpClient(worker));
|
||||||
}
|
}
|
||||||
window.addEventListener('beforeunload', () => {
|
window.addEventListener('beforeunload', () => {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"references": [
|
"references": [
|
||||||
{ "path": "../../component" },
|
{ "path": "../../component" },
|
||||||
{ "path": "../../core" },
|
{ "path": "../../core" },
|
||||||
|
{ "path": "../../../common/env" },
|
||||||
{ "path": "../../i18n" },
|
{ "path": "../../i18n" },
|
||||||
{ "path": "../../../common/nbstore" },
|
{ "path": "../../../common/nbstore" },
|
||||||
{ "path": "../../track" },
|
{ "path": "../../track" },
|
||||||
|
|||||||
@@ -54,18 +54,15 @@ export default {
|
|||||||
inlineSourcesContent: true,
|
inlineSourcesContent: true,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
define: {
|
define: Object.entries(
|
||||||
'process.env.CAPTCHA_SITE_KEY': `"${process.env.CAPTCHA_SITE_KEY}"`,
|
getBuildConfig(new Package('@affine/web'), {
|
||||||
...Object.entries(
|
mode: 'development',
|
||||||
getBuildConfig(new Package('@affine/web'), {
|
channel: 'canary',
|
||||||
mode: 'development',
|
})
|
||||||
channel: 'canary',
|
).reduce((envs, [key, value]) => {
|
||||||
})
|
envs[`BUILD_CONFIG.${key}`] = JSON.stringify(value);
|
||||||
).reduce((envs, [key, value]) => {
|
return envs;
|
||||||
envs[`BUILD_CONFIG.${key}`] = JSON.stringify(value);
|
}, {}),
|
||||||
return envs;
|
|
||||||
}, {}),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { useDebugValue, useEffect, useState } from 'react';
|
|||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
|
||||||
// the `process.env.NODE_ENV !== 'production'` condition is resolved by the build tool
|
// the `process.env.NODE_ENV !== 'production'` condition is resolved by the build tool
|
||||||
/* eslint-disable react-hooks/rules-of-hooks */
|
|
||||||
|
|
||||||
const noop: (...args: any[]) => any = () => {};
|
const noop: (...args: any[]) => any = () => {};
|
||||||
|
|
||||||
@@ -67,7 +66,7 @@ export const useRefEffect = <T>(
|
|||||||
|
|
||||||
// Show the current ref value in development
|
// Show the current ref value in development
|
||||||
// in react dev tools
|
// in react dev tools
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (BUILD_CONFIG.debug) {
|
||||||
useDebugValue(internalRef.ref_.current);
|
useDebugValue(internalRef.ref_.current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
import type { PropertyDeclaration } from 'lit';
|
import type { PropertyDeclaration } from 'lit';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
|
|
||||||
const DEV_MODE = process.env.NODE_ENV !== 'production';
|
|
||||||
|
|
||||||
type DistributiveOmit<T, K extends string | number | symbol> = T extends any
|
type DistributiveOmit<T, K extends string | number | symbol> = T extends any
|
||||||
? K extends keyof T
|
? K extends keyof T
|
||||||
? Omit<T, K>
|
? Omit<T, K>
|
||||||
@@ -245,7 +243,7 @@ export const createComponent = <
|
|||||||
}: Options<I, E>): ReactWebComponent<I, E> => {
|
}: Options<I, E>): ReactWebComponent<I, E> => {
|
||||||
const eventProps = new Set(Object.keys(events ?? {}));
|
const eventProps = new Set(Object.keys(events ?? {}));
|
||||||
|
|
||||||
if (DEV_MODE) {
|
if (BUILD_CONFIG.debug) {
|
||||||
for (const p of reservedReactProperties) {
|
for (const p of reservedReactProperties) {
|
||||||
if (p in elementClass.prototype && !(p in HTMLElement.prototype)) {
|
if (p in elementClass.prototype && !(p in HTMLElement.prototype)) {
|
||||||
// Note, this effectively warns only for `ref` since the other
|
// Note, this effectively warns only for `ref` since the other
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { getWorkerUrl } from '@affine/env/worker';
|
||||||
import { ListLayoutHandlerExtension } from '@blocksuite/affine/blocks/list';
|
import { ListLayoutHandlerExtension } from '@blocksuite/affine/blocks/list';
|
||||||
import { ParagraphLayoutHandlerExtension } from '@blocksuite/affine/blocks/paragraph';
|
import { ParagraphLayoutHandlerExtension } from '@blocksuite/affine/blocks/paragraph';
|
||||||
import {
|
import {
|
||||||
@@ -6,15 +7,7 @@ import {
|
|||||||
} from '@blocksuite/affine/gfx/turbo-renderer';
|
} from '@blocksuite/affine/gfx/turbo-renderer';
|
||||||
|
|
||||||
function createPainterWorker() {
|
function createPainterWorker() {
|
||||||
const worker = new Worker(
|
const worker = new Worker(getWorkerUrl('turbo-painter-entry.worker.js'));
|
||||||
/* webpackChunkName: "turbo-painter-entry" */ new URL(
|
|
||||||
'./turbo-painter-entry.worker.ts',
|
|
||||||
import.meta.url
|
|
||||||
),
|
|
||||||
{
|
|
||||||
type: 'module',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return worker;
|
return worker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { mixpanel, sentry } from '@affine/track';
|
import { mixpanel, sentry } from '@affine/track';
|
||||||
import { APP_SETTINGS_STORAGE_KEY } from '@toeverything/infra';
|
import { APP_SETTINGS_STORAGE_KEY } from '@toeverything/infra/atom';
|
||||||
|
|
||||||
mixpanel.init();
|
mixpanel.init();
|
||||||
sentry.init();
|
sentry.init();
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export const Captcha = () => {
|
|||||||
return (
|
return (
|
||||||
<Turnstile
|
<Turnstile
|
||||||
className={style.captchaWrapper}
|
className={style.captchaWrapper}
|
||||||
siteKey={process.env.CAPTCHA_SITE_KEY || '1x00000000000000000000AA'}
|
siteKey={BUILD_CONFIG.CAPTCHA_SITE_KEY || '1x00000000000000000000AA'}
|
||||||
onSuccess={handleTurnstileSuccess}
|
onSuccess={handleTurnstileSuccess}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,19 +9,24 @@ import { DebugLogger } from '@affine/debug';
|
|||||||
import { apis } from '@affine/electron-api';
|
import { apis } from '@affine/electron-api';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { useService } from '@toeverything/infra';
|
import { useService } from '@toeverything/infra';
|
||||||
import { useLayoutEffect } from 'react';
|
import { useLayoutEffect, useRef } from 'react';
|
||||||
|
|
||||||
const logger = new DebugLogger('ImportWorkspaceDialog');
|
const logger = new DebugLogger('ImportWorkspaceDialog');
|
||||||
|
|
||||||
export const ImportWorkspaceDialog = ({
|
export const ImportWorkspaceDialog = ({
|
||||||
close,
|
close,
|
||||||
}: DialogComponentProps<GLOBAL_DIALOG_SCHEMA['import-workspace']>) => {
|
}: DialogComponentProps<GLOBAL_DIALOG_SCHEMA['import-workspace']>) => {
|
||||||
|
const effectRef = useRef(false);
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const workspacesService = useService(WorkspacesService);
|
const workspacesService = useService(WorkspacesService);
|
||||||
|
|
||||||
// TODO(@Peng): maybe refactor using xstate?
|
// TODO(@Peng): maybe refactor using xstate?
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
let canceled = false;
|
if (effectRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
effectRef.current = true;
|
||||||
|
|
||||||
// a hack for now
|
// a hack for now
|
||||||
// when adding a workspace, we will immediately let user select a db file
|
// when adding a workspace, we will immediately let user select a db file
|
||||||
// after it is done, it will effectively add a new workspace to app-data folder
|
// after it is done, it will effectively add a new workspace to app-data folder
|
||||||
@@ -32,7 +37,7 @@ export const ImportWorkspaceDialog = ({
|
|||||||
}
|
}
|
||||||
logger.info('load db file');
|
logger.info('load db file');
|
||||||
const result = await apis.dialog.loadDBFile();
|
const result = await apis.dialog.loadDBFile();
|
||||||
if (result.workspaceId && !canceled) {
|
if (result.workspaceId) {
|
||||||
_addLocalWorkspace(result.workspaceId);
|
_addLocalWorkspace(result.workspaceId);
|
||||||
workspacesService.list.revalidate();
|
workspacesService.list.revalidate();
|
||||||
close({
|
close({
|
||||||
@@ -50,9 +55,6 @@ export const ImportWorkspaceDialog = ({
|
|||||||
})().catch(err => {
|
})().catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
return () => {
|
|
||||||
canceled = true;
|
|
||||||
};
|
|
||||||
}, [close, t, workspacesService]);
|
}, [close, t, workspacesService]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -191,13 +191,9 @@ export const BackupSettingPanel = () => {
|
|||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const backupService = useService(BackupService);
|
const backupService = useService(BackupService);
|
||||||
|
|
||||||
const handlePageChange = useCallback(() => {
|
|
||||||
backupService.revalidate();
|
|
||||||
}, [backupService]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
backupService.revalidate();
|
backupService.revalidate();
|
||||||
}, [backupService, handlePageChange]);
|
}, [backupService]);
|
||||||
|
|
||||||
const isLoading = useLiveData(backupService.isLoading$);
|
const isLoading = useLiveData(backupService.isLoading$);
|
||||||
const backupWorkspaces = useLiveData(backupService.pageBackupWorkspaces$);
|
const backupWorkspaces = useLiveData(backupService.pageBackupWorkspaces$);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { getWorkerUrl } from '@affine/env/worker';
|
||||||
import { OpClient } from '@toeverything/infra/op';
|
import { OpClient } from '@toeverything/infra/op';
|
||||||
|
|
||||||
import type { ClientOps } from './ops';
|
import type { ClientOps } from './ops';
|
||||||
@@ -6,12 +7,7 @@ export class PDFRenderer extends OpClient<ClientOps> {
|
|||||||
private readonly worker: Worker;
|
private readonly worker: Worker;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
const worker = new Worker(
|
const worker = new Worker(getWorkerUrl('pdf.worker.js'));
|
||||||
/* webpackChunkName: "pdf.worker" */ new URL(
|
|
||||||
'./worker.ts',
|
|
||||||
import.meta.url
|
|
||||||
)
|
|
||||||
);
|
|
||||||
super(worker);
|
super(worker);
|
||||||
|
|
||||||
this.worker = worker;
|
this.worker = worker;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { getWorkerUrl } from '@affine/env/worker';
|
||||||
import { OpClient } from '@toeverything/infra/op';
|
import { OpClient } from '@toeverything/infra/op';
|
||||||
|
|
||||||
import type { WorkerOps } from './worker-ops';
|
import type { WorkerOps } from './worker-ops';
|
||||||
@@ -9,12 +10,7 @@ export function getWorkspaceProfileWorker() {
|
|||||||
return worker;
|
return worker;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawWorker = new Worker(
|
const rawWorker = new Worker(getWorkerUrl('workspace-profile.worker.js'));
|
||||||
new URL(
|
|
||||||
/* webpackChunkName: "workspace-profile-worker" */ './in-worker.ts',
|
|
||||||
import.meta.url
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
worker = new OpClient<WorkerOps>(rawWorker);
|
worker = new OpClient<WorkerOps>(rawWorker);
|
||||||
return worker;
|
return worker;
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ export const schemeToChannel = {
|
|||||||
|
|
||||||
export const channelToScheme = {
|
export const channelToScheme = {
|
||||||
stable: 'affine',
|
stable: 'affine',
|
||||||
canary:
|
canary: BUILD_CONFIG.debug ? 'affine-dev' : 'affine-canary',
|
||||||
process.env.NODE_ENV === 'development' ? 'affine-dev' : 'affine-canary',
|
|
||||||
beta: 'affine-beta',
|
beta: 'affine-beta',
|
||||||
internal: 'affine-internal',
|
internal: 'affine-internal',
|
||||||
} as Record<Channel, Scheme>;
|
} as Record<Channel, Scheme>;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export const createIsland = () => {
|
|||||||
Provider: ({ children }: React.PropsWithChildren) => {
|
Provider: ({ children }: React.PropsWithChildren) => {
|
||||||
const target = useLiveData(targetLiveData$);
|
const target = useLiveData(targetLiveData$);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (provided === true && process.env.NODE_ENV !== 'production') {
|
if (provided === true && BUILD_CONFIG.debug) {
|
||||||
throw new Error('Island should not be provided more than once');
|
throw new Error('Island should not be provided more than once');
|
||||||
}
|
}
|
||||||
provided = true;
|
provided = true;
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ type Middleware = (
|
|||||||
|
|
||||||
function createMixpanel() {
|
function createMixpanel() {
|
||||||
let mixpanel;
|
let mixpanel;
|
||||||
if (process.env.MIXPANEL_TOKEN) {
|
if (BUILD_CONFIG.MIXPANEL_TOKEN) {
|
||||||
mixpanelBrowser.init(process.env.MIXPANEL_TOKEN || '', {
|
mixpanelBrowser.init(BUILD_CONFIG.MIXPANEL_TOKEN || '', {
|
||||||
track_pageview: true,
|
track_pageview: true,
|
||||||
persistence: 'localStorage',
|
persistence: 'localStorage',
|
||||||
api_host: 'https://telemetry.affine.run',
|
api_host: 'https://telemetry.affine.run',
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ function createSentry() {
|
|||||||
if (!globalThis.SENTRY_RELEASE) {
|
if (!globalThis.SENTRY_RELEASE) {
|
||||||
// https://docs.sentry.io/platforms/javascript/guides/react/#configure
|
// https://docs.sentry.io/platforms/javascript/guides/react/#configure
|
||||||
client = Sentry.init({
|
client = Sentry.init({
|
||||||
dsn: process.env.SENTRY_DSN,
|
dsn: BUILD_CONFIG.SENTRY_DSN,
|
||||||
debug: BUILD_CONFIG.debug ?? false,
|
debug: BUILD_CONFIG.debug ?? false,
|
||||||
environment: process.env.BUILD_TYPE ?? 'development',
|
environment: BUILD_CONFIG.appBuildType,
|
||||||
integrations: [
|
integrations: [
|
||||||
Sentry.reactRouterV6BrowserTracingIntegration({
|
Sentry.reactRouterV6BrowserTracingIntegration({
|
||||||
useEffect,
|
useEffect,
|
||||||
|
|||||||
@@ -1,35 +1,26 @@
|
|||||||
import { getConfig, start } from '@affine-tools/cli/bundle';
|
import { BundleCommand } from '@affine-tools/cli/bundle';
|
||||||
import { Workspace } from '@affine-tools/utils/workspace';
|
import { Package } from '@affine-tools/utils/workspace';
|
||||||
import webpack from 'webpack';
|
|
||||||
|
|
||||||
export default async () => {
|
export default async () => {
|
||||||
const ws = new Workspace();
|
|
||||||
const webpackConfig = await getConfig(ws.getPackage('@affine/web'), true);
|
|
||||||
const definedPort = webpackConfig.devServer?.port ?? 8080;
|
|
||||||
|
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise<void>((resolve, reject) => {
|
||||||
start(webpack(webpackConfig), {
|
BundleCommand.dev(new Package('@affine/web'), {
|
||||||
...webpackConfig.devServer,
|
|
||||||
onListening: server => {
|
onListening: server => {
|
||||||
// dev server has already started
|
// dev server has already started
|
||||||
if (server.options.port !== definedPort) {
|
if (server.options.port !== 8080) {
|
||||||
server.compiler.close(reject);
|
server.compiler.close(reject);
|
||||||
server.stop().catch(reject);
|
server.stop().catch(reject);
|
||||||
resolve();
|
resolve();
|
||||||
|
} else {
|
||||||
|
server.middleware?.waitUntilValid?.(stats => {
|
||||||
|
if (stats?.hasErrors()) {
|
||||||
|
reject(new Error('Webpack build failed'));
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
proxy: [],
|
}).catch(reject);
|
||||||
})
|
|
||||||
.then(server => {
|
|
||||||
server.middleware?.waitUntilValid?.(stats => {
|
|
||||||
if (stats?.hasErrors()) {
|
|
||||||
reject(new Error('Webpack build failed'));
|
|
||||||
} else {
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(reject);
|
|
||||||
});
|
});
|
||||||
console.log('Dev server started');
|
console.log('Dev server started');
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ export const test = base.extend<{
|
|||||||
electronRoot.join('package.json').value
|
electronRoot.join('package.json').value
|
||||||
);
|
);
|
||||||
// overwrite the app name
|
// overwrite the app name
|
||||||
packageJson.name = 'affine-test-' + id;
|
packageJson.name = '@affine/electron-test-' + id;
|
||||||
// overwrite the path to the main script
|
// overwrite the path to the main script
|
||||||
packageJson.main = './main.js';
|
packageJson.main = './main.js';
|
||||||
// write to the cloned dist
|
// write to the cloned dist
|
||||||
|
|||||||
5
tools/@types/build-config/__all.d.ts
vendored
5
tools/@types/build-config/__all.d.ts
vendored
@@ -33,6 +33,11 @@ declare interface BUILD_CONFIG_TYPE {
|
|||||||
// see: tools/workers
|
// see: tools/workers
|
||||||
imageProxyUrl: string;
|
imageProxyUrl: string;
|
||||||
linkPreviewUrl: string;
|
linkPreviewUrl: string;
|
||||||
|
|
||||||
|
CAPTCHA_SITE_KEY: string;
|
||||||
|
SENTRY_DSN: string;
|
||||||
|
MIXPANEL_TOKEN: string;
|
||||||
|
DEBUG_JOTAI: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare var BUILD_CONFIG: BUILD_CONFIG_TYPE;
|
declare var BUILD_CONFIG: BUILD_CONFIG_TYPE;
|
||||||
|
|||||||
1
tools/@types/env/__all.d.ts
vendored
1
tools/@types/env/__all.d.ts
vendored
@@ -37,6 +37,7 @@ declare type Environment = {
|
|||||||
|
|
||||||
// runtime configs
|
// runtime configs
|
||||||
publicPath: string;
|
publicPath: string;
|
||||||
|
workerPath: string
|
||||||
};
|
};
|
||||||
|
|
||||||
var process: {
|
var process: {
|
||||||
|
|||||||
@@ -1,75 +1,130 @@
|
|||||||
import type { Package } from '@affine-tools/utils/workspace';
|
import { rmSync } from 'node:fs';
|
||||||
import webpack, { type Compiler, type Configuration } from 'webpack';
|
import { cpus } from 'node:os';
|
||||||
import WebpackDevServer from 'webpack-dev-server';
|
|
||||||
import { merge } from 'webpack-merge';
|
import { Logger } from '@affine-tools/utils/logger';
|
||||||
|
import { Package } from '@affine-tools/utils/workspace';
|
||||||
|
import { merge } from 'lodash-es';
|
||||||
|
import webpack from 'webpack';
|
||||||
|
import WebpackDevServer, {
|
||||||
|
type Configuration as DevServerConfiguration,
|
||||||
|
} from 'webpack-dev-server';
|
||||||
|
|
||||||
import { Option, PackageCommand } from './command';
|
import { Option, PackageCommand } from './command';
|
||||||
import { createWebpackConfig } from './webpack';
|
import { createHTMLTargetConfig, createWorkerTargetConfig } from './webpack';
|
||||||
|
|
||||||
function getChannel() {
|
function getBundleConfigs(pkg: Package) {
|
||||||
const channel = process.env.BUILD_TYPE ?? 'canary';
|
const core = new Package('@affine/core');
|
||||||
switch (channel) {
|
|
||||||
case 'canary':
|
const workerConfigs = [
|
||||||
case 'beta':
|
createWorkerTargetConfig(
|
||||||
case 'stable':
|
pkg,
|
||||||
case 'internal':
|
core.srcPath.join(
|
||||||
return channel;
|
'modules/workspace-engine/impls/workspace-profile.worker.ts'
|
||||||
default: {
|
).value
|
||||||
throw new Error(
|
),
|
||||||
`BUILD_TYPE must be one of canary, beta, stable, internal, received [${channel}]`
|
createWorkerTargetConfig(
|
||||||
|
pkg,
|
||||||
|
core.srcPath.join('modules/pdf/renderer/pdf.worker.ts').value
|
||||||
|
),
|
||||||
|
createWorkerTargetConfig(
|
||||||
|
pkg,
|
||||||
|
core.srcPath.join('blocksuite/extensions/turbo-painter.worker.ts').value
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
switch (pkg.name) {
|
||||||
|
case '@affine/admin': {
|
||||||
|
return [createHTMLTargetConfig(pkg, pkg.srcPath.join('index.tsx').value)];
|
||||||
|
}
|
||||||
|
case '@affine/web':
|
||||||
|
case '@affine/mobile':
|
||||||
|
case '@affine/ios':
|
||||||
|
case '@affine/android': {
|
||||||
|
workerConfigs.push(
|
||||||
|
createWorkerTargetConfig(
|
||||||
|
pkg,
|
||||||
|
pkg.srcPath.join('nbstore.worker.ts').value
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return [
|
||||||
|
createHTMLTargetConfig(
|
||||||
|
pkg,
|
||||||
|
pkg.srcPath.join('index.tsx').value,
|
||||||
|
{},
|
||||||
|
workerConfigs.map(config => config.name)
|
||||||
|
),
|
||||||
|
...workerConfigs,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
case '@affine/electron-renderer': {
|
||||||
|
return [
|
||||||
|
createHTMLTargetConfig(
|
||||||
|
pkg,
|
||||||
|
{
|
||||||
|
index: pkg.srcPath.join('app/index.tsx').value,
|
||||||
|
shell: pkg.srcPath.join('shell/index.tsx').value,
|
||||||
|
popup: pkg.srcPath.join('popup/index.tsx').value,
|
||||||
|
backgroundWorker: pkg.srcPath.join('background-worker/index.ts')
|
||||||
|
.value,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
additionalEntryForSelfhost: false,
|
||||||
|
injectGlobalErrorHandler: false,
|
||||||
|
emitAssetsManifest: false,
|
||||||
|
},
|
||||||
|
workerConfigs.map(config => config.name)
|
||||||
|
),
|
||||||
|
...workerConfigs,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new Error(`Unsupported package: ${pkg.name}`);
|
||||||
}
|
}
|
||||||
|
const IN_CI = !!process.env.CI;
|
||||||
|
const httpProxyMiddlewareLogLevel = IN_CI ? 'silent' : 'error';
|
||||||
|
|
||||||
export async function getConfig(pkg: Package, dev: boolean) {
|
const defaultDevServerConfig = {
|
||||||
let config = createWebpackConfig(pkg, {
|
host: '0.0.0.0',
|
||||||
mode: dev ? 'development' : 'production',
|
allowedHosts: 'all',
|
||||||
channel: getChannel(),
|
hot: false,
|
||||||
});
|
liveReload: true,
|
||||||
|
client: {
|
||||||
let configOverride: Configuration | undefined;
|
overlay: process.env.DISABLE_DEV_OVERLAY === 'true' ? false : undefined,
|
||||||
const overrideConfigPath = pkg.join('webpack.config.ts');
|
logging: process.env.CI ? 'none' : 'error',
|
||||||
|
},
|
||||||
if (overrideConfigPath.isFile()) {
|
historyApiFallback: {
|
||||||
const override = await import(overrideConfigPath.toFileUrl().toString());
|
rewrites: [
|
||||||
configOverride = override.config ?? override.default;
|
{
|
||||||
}
|
from: /.*/,
|
||||||
|
to: () => {
|
||||||
if (configOverride) {
|
return process.env.SELF_HOSTED === 'true'
|
||||||
config = merge(config, configOverride);
|
? '/selfhost.html'
|
||||||
}
|
: '/index.html';
|
||||||
|
},
|
||||||
return config;
|
},
|
||||||
}
|
],
|
||||||
|
},
|
||||||
export async function start(
|
proxy: [
|
||||||
compiler: Compiler,
|
{
|
||||||
config: Configuration['devServer']
|
context: '/api',
|
||||||
): Promise<WebpackDevServer> {
|
target: 'http://localhost:3010',
|
||||||
const devServer = new WebpackDevServer(config, compiler);
|
logLevel: httpProxyMiddlewareLogLevel,
|
||||||
|
},
|
||||||
await devServer.start();
|
{
|
||||||
|
context: '/socket.io',
|
||||||
return devServer;
|
target: 'http://localhost:3010',
|
||||||
}
|
ws: true,
|
||||||
|
logLevel: httpProxyMiddlewareLogLevel,
|
||||||
export async function build(compiler: Compiler) {
|
},
|
||||||
compiler.run((error, stats) => {
|
{
|
||||||
if (error) {
|
context: '/graphql',
|
||||||
console.error(error);
|
target: 'http://localhost:3010',
|
||||||
process.exit(1);
|
logLevel: httpProxyMiddlewareLogLevel,
|
||||||
}
|
},
|
||||||
if (stats) {
|
],
|
||||||
if (stats.hasErrors()) {
|
} as DevServerConfiguration;
|
||||||
console.error(stats.toString('errors-only'));
|
|
||||||
process.exit(1);
|
|
||||||
} else {
|
|
||||||
console.log(stats.toString('minimal'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export class BundleCommand extends PackageCommand {
|
export class BundleCommand extends PackageCommand {
|
||||||
static override paths = [['bundle'], ['webpack'], ['pack'], ['bun']];
|
static override paths = [['bundle'], ['webpack'], ['pack'], ['bun']];
|
||||||
@@ -83,19 +138,60 @@ export class BundleCommand extends PackageCommand {
|
|||||||
});
|
});
|
||||||
|
|
||||||
async execute() {
|
async execute() {
|
||||||
this.logger.info(`Packing package ${this.package}...`);
|
const pkg = this.workspace.getPackage(this.package);
|
||||||
|
|
||||||
const config = await getConfig(
|
if (this.dev) {
|
||||||
this.workspace.getPackage(this.package),
|
await BundleCommand.dev(pkg);
|
||||||
this.dev
|
} else {
|
||||||
);
|
await BundleCommand.build(pkg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async build(pkg: Package) {
|
||||||
|
process.env.NODE_ENV = 'production';
|
||||||
|
const logger = new Logger('bundle');
|
||||||
|
logger.info(`Packing package ${pkg.name}...`);
|
||||||
|
logger.info('Cleaning old output...');
|
||||||
|
rmSync(pkg.distPath.value, { recursive: true, force: true });
|
||||||
|
|
||||||
|
const config = getBundleConfigs(pkg);
|
||||||
|
// @ts-expect-error allow
|
||||||
|
config.parallelism = cpus().length;
|
||||||
|
|
||||||
const compiler = webpack(config);
|
const compiler = webpack(config);
|
||||||
|
|
||||||
if (this.dev) {
|
compiler.run((error, stats) => {
|
||||||
await start(compiler, config.devServer);
|
if (error) {
|
||||||
} else {
|
console.error(error);
|
||||||
await build(compiler);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
if (stats) {
|
||||||
|
if (stats.hasErrors()) {
|
||||||
|
console.error(stats.toString('errors-only'));
|
||||||
|
process.exit(1);
|
||||||
|
} else {
|
||||||
|
console.log(stats.toString('minimal'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async dev(pkg: Package, devServerConfig?: DevServerConfiguration) {
|
||||||
|
process.env.NODE_ENV = 'development';
|
||||||
|
const logger = new Logger('bundle');
|
||||||
|
logger.info(`Starting dev server for ${pkg.name}...`);
|
||||||
|
|
||||||
|
const config = getBundleConfigs(pkg);
|
||||||
|
// @ts-expect-error allow
|
||||||
|
config.parallelism = cpus().length;
|
||||||
|
|
||||||
|
const compiler = webpack(config);
|
||||||
|
|
||||||
|
const devServer = new WebpackDevServer(
|
||||||
|
merge({}, defaultDevServerConfig, devServerConfig),
|
||||||
|
compiler
|
||||||
|
);
|
||||||
|
|
||||||
|
await devServer.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,19 +8,14 @@ import { once } from 'lodash-es';
|
|||||||
import type { Compiler, WebpackPluginInstance } from 'webpack';
|
import type { Compiler, WebpackPluginInstance } from 'webpack';
|
||||||
import webpack from 'webpack';
|
import webpack from 'webpack';
|
||||||
|
|
||||||
import type { BuildFlags } from './types.js';
|
export const getPublicPath = (BUILD_CONFIG: BUILD_CONFIG_TYPE) => {
|
||||||
|
|
||||||
export const getPublicPath = (
|
|
||||||
flags: BuildFlags,
|
|
||||||
BUILD_CONFIG: BUILD_CONFIG_TYPE
|
|
||||||
) => {
|
|
||||||
const { BUILD_TYPE } = process.env;
|
const { BUILD_TYPE } = process.env;
|
||||||
if (typeof process.env.PUBLIC_PATH === 'string') {
|
if (typeof process.env.PUBLIC_PATH === 'string') {
|
||||||
return process.env.PUBLIC_PATH;
|
return process.env.PUBLIC_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
flags.mode === 'development' ||
|
BUILD_CONFIG.debug ||
|
||||||
BUILD_CONFIG.distribution === 'desktop' ||
|
BUILD_CONFIG.distribution === 'desktop' ||
|
||||||
BUILD_CONFIG.distribution === 'ios' ||
|
BUILD_CONFIG.distribution === 'ios' ||
|
||||||
BUILD_CONFIG.distribution === 'android'
|
BUILD_CONFIG.distribution === 'android'
|
||||||
@@ -58,11 +53,15 @@ const gitShortHash = once(() => {
|
|||||||
|
|
||||||
const currentDir = Path.dir(import.meta.url);
|
const currentDir = Path.dir(import.meta.url);
|
||||||
|
|
||||||
function getHTMLPluginOptions(
|
export interface CreateHTMLPluginConfig {
|
||||||
flags: BuildFlags,
|
filename?: string;
|
||||||
BUILD_CONFIG: BUILD_CONFIG_TYPE
|
additionalEntryForSelfhost?: boolean;
|
||||||
) {
|
injectGlobalErrorHandler?: boolean;
|
||||||
const publicPath = getPublicPath(flags, BUILD_CONFIG);
|
emitAssetsManifest?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHTMLPluginOptions(BUILD_CONFIG: BUILD_CONFIG_TYPE) {
|
||||||
|
const publicPath = getPublicPath(BUILD_CONFIG);
|
||||||
const cdnOrigin = publicPath.startsWith('/')
|
const cdnOrigin = publicPath.startsWith('/')
|
||||||
? undefined
|
? undefined
|
||||||
: new URL(publicPath).origin;
|
: new URL(publicPath).origin;
|
||||||
@@ -79,144 +78,159 @@ function getHTMLPluginOptions(
|
|||||||
return {
|
return {
|
||||||
template: currentDir.join('template.html').toString(),
|
template: currentDir.join('template.html').toString(),
|
||||||
inject: 'body',
|
inject: 'body',
|
||||||
filename: 'index.html',
|
|
||||||
minify: false,
|
minify: false,
|
||||||
templateParameters: templateParams,
|
templateParameters: templateParams,
|
||||||
chunks: ['app'],
|
chunks: ['app'],
|
||||||
} satisfies HTMLPlugin.Options;
|
} satisfies HTMLPlugin.Options;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createShellHTMLPlugin(
|
const AssetsManifestPlugin = {
|
||||||
flags: BuildFlags,
|
apply(compiler: Compiler) {
|
||||||
BUILD_CONFIG: BUILD_CONFIG_TYPE
|
compiler.hooks.compilation.tap('assets-manifest-plugin', compilation => {
|
||||||
) {
|
HTMLPlugin.getHooks(compilation).beforeAssetTagGeneration.tap(
|
||||||
const htmlPluginOptions = getHTMLPluginOptions(flags, BUILD_CONFIG);
|
'assets-manifest-plugin',
|
||||||
|
arg => {
|
||||||
return new HTMLPlugin({
|
if (!compilation.getAsset('assets-manifest.json')) {
|
||||||
...htmlPluginOptions,
|
compilation.emitAsset(
|
||||||
chunks: ['shell'],
|
`assets-manifest.json`,
|
||||||
filename: `shell.html`,
|
new webpack.sources.RawSource(
|
||||||
});
|
JSON.stringify(
|
||||||
}
|
{
|
||||||
|
...arg.assets,
|
||||||
export function createBackgroundWorkerHTMLPlugin(
|
js: arg.assets.js.map(file =>
|
||||||
flags: BuildFlags,
|
file.substring(arg.assets.publicPath.length)
|
||||||
BUILD_CONFIG: BUILD_CONFIG_TYPE
|
|
||||||
) {
|
|
||||||
const htmlPluginOptions = getHTMLPluginOptions(flags, BUILD_CONFIG);
|
|
||||||
|
|
||||||
return new HTMLPlugin({
|
|
||||||
...htmlPluginOptions,
|
|
||||||
chunks: ['backgroundWorker'],
|
|
||||||
filename: `background-worker.html`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createPopupHTMLPlugin(
|
|
||||||
flags: BuildFlags,
|
|
||||||
BUILD_CONFIG: BUILD_CONFIG_TYPE
|
|
||||||
) {
|
|
||||||
const htmlPluginOptions = getHTMLPluginOptions(flags, BUILD_CONFIG);
|
|
||||||
|
|
||||||
return new HTMLPlugin({
|
|
||||||
...htmlPluginOptions,
|
|
||||||
chunks: ['popup'],
|
|
||||||
filename: `popup.html`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createHTMLPlugins(
|
|
||||||
flags: BuildFlags,
|
|
||||||
BUILD_CONFIG: BUILD_CONFIG_TYPE
|
|
||||||
): WebpackPluginInstance[] {
|
|
||||||
const publicPath = getPublicPath(flags, BUILD_CONFIG);
|
|
||||||
const globalErrorHandler = [
|
|
||||||
'js/global-error-handler.js',
|
|
||||||
readFileSync(currentDir.join('./error-handler.js').toString(), 'utf-8'),
|
|
||||||
];
|
|
||||||
|
|
||||||
const htmlPluginOptions = getHTMLPluginOptions(flags, BUILD_CONFIG);
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
apply(compiler: Compiler) {
|
|
||||||
compiler.hooks.compilation.tap(
|
|
||||||
'assets-manifest-plugin',
|
|
||||||
compilation => {
|
|
||||||
HTMLPlugin.getHooks(compilation).beforeAssetTagGeneration.tap(
|
|
||||||
'assets-manifest-plugin',
|
|
||||||
arg => {
|
|
||||||
if (
|
|
||||||
!BUILD_CONFIG.isElectron &&
|
|
||||||
!compilation.getAsset(globalErrorHandler[0])
|
|
||||||
) {
|
|
||||||
compilation.emitAsset(
|
|
||||||
globalErrorHandler[0],
|
|
||||||
new webpack.sources.RawSource(globalErrorHandler[1])
|
|
||||||
);
|
|
||||||
arg.assets.js.unshift(
|
|
||||||
arg.assets.publicPath + globalErrorHandler[0]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!compilation.getAsset('assets-manifest.json')) {
|
|
||||||
compilation.emitAsset(
|
|
||||||
globalErrorHandler[0],
|
|
||||||
new webpack.sources.RawSource(globalErrorHandler[1])
|
|
||||||
);
|
|
||||||
compilation.emitAsset(
|
|
||||||
`assets-manifest.json`,
|
|
||||||
new webpack.sources.RawSource(
|
|
||||||
JSON.stringify(
|
|
||||||
{
|
|
||||||
...arg.assets,
|
|
||||||
js: arg.assets.js.map(file =>
|
|
||||||
file.substring(arg.assets.publicPath.length)
|
|
||||||
),
|
|
||||||
css: arg.assets.css.map(file =>
|
|
||||||
file.substring(arg.assets.publicPath.length)
|
|
||||||
),
|
|
||||||
gitHash:
|
|
||||||
htmlPluginOptions.templateParameters.GIT_SHORT_SHA,
|
|
||||||
description:
|
|
||||||
htmlPluginOptions.templateParameters.DESCRIPTION,
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
2
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
{
|
css: arg.assets.css.map(file =>
|
||||||
immutable: false,
|
file.substring(arg.assets.publicPath.length)
|
||||||
}
|
),
|
||||||
);
|
gitHash: gitShortHash(),
|
||||||
}
|
description: DESCRIPTION,
|
||||||
|
},
|
||||||
return arg;
|
null,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
),
|
||||||
|
{
|
||||||
|
immutable: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const GlobalErrorHandlerPlugin = {
|
||||||
|
apply(compiler: Compiler) {
|
||||||
|
const globalErrorHandler = [
|
||||||
|
'js/global-error-handler.js',
|
||||||
|
readFileSync(currentDir.join('./error-handler.js').toString(), 'utf-8'),
|
||||||
|
];
|
||||||
|
|
||||||
|
compiler.hooks.compilation.tap(
|
||||||
|
'global-error-handler-plugin',
|
||||||
|
compilation => {
|
||||||
|
HTMLPlugin.getHooks(compilation).beforeAssetTagGeneration.tap(
|
||||||
|
'global-error-handler-plugin',
|
||||||
|
arg => {
|
||||||
|
if (!compilation.getAsset(globalErrorHandler[0])) {
|
||||||
|
compilation.emitAsset(
|
||||||
|
globalErrorHandler[0],
|
||||||
|
new webpack.sources.RawSource(globalErrorHandler[1])
|
||||||
|
);
|
||||||
|
arg.assets.js.unshift(
|
||||||
|
arg.assets.publicPath + globalErrorHandler[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
},
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createHTMLPlugins(
|
||||||
|
BUILD_CONFIG: BUILD_CONFIG_TYPE,
|
||||||
|
config: CreateHTMLPluginConfig
|
||||||
|
): WebpackPluginInstance[] {
|
||||||
|
const publicPath = getPublicPath(BUILD_CONFIG);
|
||||||
|
const htmlPluginOptions = getHTMLPluginOptions(BUILD_CONFIG);
|
||||||
|
|
||||||
|
const plugins: WebpackPluginInstance[] = [];
|
||||||
|
plugins.push(
|
||||||
new HTMLPlugin({
|
new HTMLPlugin({
|
||||||
...htmlPluginOptions,
|
...htmlPluginOptions,
|
||||||
|
chunks: ['index'],
|
||||||
|
filename: config.filename,
|
||||||
publicPath,
|
publicPath,
|
||||||
meta: {
|
meta: {
|
||||||
'env:publicPath': publicPath,
|
'env:publicPath': publicPath,
|
||||||
},
|
},
|
||||||
}),
|
})
|
||||||
// selfhost html
|
);
|
||||||
new HTMLPlugin({
|
|
||||||
...htmlPluginOptions,
|
if (BUILD_CONFIG.isElectron) {
|
||||||
meta: {
|
plugins.push(
|
||||||
'env:isSelfHosted': 'true',
|
new HTMLPlugin({
|
||||||
'env:publicPath': '/',
|
...htmlPluginOptions,
|
||||||
},
|
chunks: ['shell'],
|
||||||
filename: 'selfhost.html',
|
filename: 'shell.html',
|
||||||
templateParameters: {
|
publicPath,
|
||||||
...htmlPluginOptions.templateParameters,
|
meta: {
|
||||||
PRECONNECT: '',
|
'env:publicPath': publicPath,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
];
|
new HTMLPlugin({
|
||||||
|
...htmlPluginOptions,
|
||||||
|
filename: 'popup.html',
|
||||||
|
chunks: ['popup'],
|
||||||
|
publicPath,
|
||||||
|
meta: {
|
||||||
|
'env:publicPath': publicPath,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
new HTMLPlugin({
|
||||||
|
...htmlPluginOptions,
|
||||||
|
filename: 'background-worker.html',
|
||||||
|
chunks: ['backgroundWorker'],
|
||||||
|
publicPath,
|
||||||
|
meta: {
|
||||||
|
'env:publicPath': publicPath,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.emitAssetsManifest) {
|
||||||
|
plugins.push(AssetsManifestPlugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.injectGlobalErrorHandler) {
|
||||||
|
plugins.push(GlobalErrorHandlerPlugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.additionalEntryForSelfhost) {
|
||||||
|
plugins.push(
|
||||||
|
new HTMLPlugin({
|
||||||
|
...htmlPluginOptions,
|
||||||
|
chunks: ['index'],
|
||||||
|
meta: {
|
||||||
|
'env:isSelfHosted': 'true',
|
||||||
|
'env:publicPath': '/',
|
||||||
|
},
|
||||||
|
filename: 'selfhost.html',
|
||||||
|
templateParameters: {
|
||||||
|
...htmlPluginOptions.templateParameters,
|
||||||
|
PRECONNECT: '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugins;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,127 +1,99 @@
|
|||||||
import { createRequire } from 'node:module';
|
import { createRequire } from 'node:module';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
import { getBuildConfig } from '@affine-tools/utils/build-config';
|
import { getBuildConfig } from '@affine-tools/utils/build-config';
|
||||||
import { ProjectRoot } from '@affine-tools/utils/path';
|
import { ProjectRoot } from '@affine-tools/utils/path';
|
||||||
import type { Package } from '@affine-tools/utils/workspace';
|
import { Package } from '@affine-tools/utils/workspace';
|
||||||
import { PerfseePlugin } from '@perfsee/webpack';
|
import { PerfseePlugin } from '@perfsee/webpack';
|
||||||
import { sentryWebpackPlugin } from '@sentry/webpack-plugin';
|
import { sentryWebpackPlugin } from '@sentry/webpack-plugin';
|
||||||
import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin';
|
import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin';
|
||||||
import CopyPlugin from 'copy-webpack-plugin';
|
import CopyPlugin from 'copy-webpack-plugin';
|
||||||
import { compact } from 'lodash-es';
|
import { compact, merge } from 'lodash-es';
|
||||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
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 type { Configuration as DevServerConfiguration } from 'webpack-dev-server';
|
|
||||||
|
|
||||||
import { productionCacheGroups } from './cache-group.js';
|
import { productionCacheGroups } from './cache-group.js';
|
||||||
import {
|
import {
|
||||||
createBackgroundWorkerHTMLPlugin,
|
type CreateHTMLPluginConfig,
|
||||||
createHTMLPlugins,
|
createHTMLPlugins,
|
||||||
createPopupHTMLPlugin,
|
|
||||||
createShellHTMLPlugin,
|
|
||||||
} from './html-plugin.js';
|
} from './html-plugin.js';
|
||||||
import { WebpackS3Plugin } from './s3-plugin.js';
|
import { WebpackS3Plugin } from './s3-plugin.js';
|
||||||
import type { BuildFlags } from './types';
|
|
||||||
|
|
||||||
const require = createRequire(import.meta.url);
|
const require = createRequire(import.meta.url);
|
||||||
const cssnano = require('cssnano');
|
const cssnano = require('cssnano');
|
||||||
|
|
||||||
const IN_CI = !!process.env.CI;
|
const IN_CI = !!process.env.CI;
|
||||||
|
|
||||||
const OptimizeOptionOptions: (
|
const availableChannels = ['canary', 'beta', 'stable', 'internal'];
|
||||||
flags: BuildFlags
|
function getBuildConfigFromEnv(pkg: Package) {
|
||||||
) => webpack.Configuration['optimization'] = flags => ({
|
const channel = process.env.BUILD_TYPE ?? 'canary';
|
||||||
minimize: flags.mode === 'production',
|
const dev = process.env.NODE_ENV === 'development';
|
||||||
minimizer: [
|
if (!availableChannels.includes(channel)) {
|
||||||
new TerserPlugin({
|
throw new Error(
|
||||||
minify: TerserPlugin.swcMinify,
|
`BUILD_TYPE must be one of ${availableChannels.join(', ')}, received [${channel}]`
|
||||||
exclude: [/plugins\/.+\/.+\.js$/, /plugins\/.+\/.+\.mjs$/],
|
);
|
||||||
parallel: true,
|
}
|
||||||
extractComments: true,
|
|
||||||
terserOptions: {
|
|
||||||
ecma: 2020,
|
|
||||||
compress: {
|
|
||||||
unused: true,
|
|
||||||
},
|
|
||||||
mangle: {
|
|
||||||
keep_classnames: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
removeEmptyChunks: true,
|
|
||||||
providedExports: true,
|
|
||||||
usedExports: true,
|
|
||||||
sideEffects: true,
|
|
||||||
removeAvailableModules: true,
|
|
||||||
runtimeChunk: {
|
|
||||||
name: 'runtime',
|
|
||||||
},
|
|
||||||
splitChunks: {
|
|
||||||
chunks: 'all',
|
|
||||||
minSize: 1,
|
|
||||||
minChunks: 1,
|
|
||||||
maxInitialRequests: Number.MAX_SAFE_INTEGER,
|
|
||||||
maxAsyncRequests: Number.MAX_SAFE_INTEGER,
|
|
||||||
cacheGroups: productionCacheGroups,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export function createWebpackConfig(
|
return getBuildConfig(pkg, {
|
||||||
|
// @ts-expect-error checked
|
||||||
|
channel,
|
||||||
|
mode: dev ? 'development' : 'production',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createHTMLTargetConfig(
|
||||||
pkg: Package,
|
pkg: Package,
|
||||||
flags: BuildFlags
|
entry: string | Record<string, string>,
|
||||||
|
htmlConfig: Partial<CreateHTMLPluginConfig> = {},
|
||||||
|
deps?: string[]
|
||||||
): webpack.Configuration {
|
): webpack.Configuration {
|
||||||
const buildConfig = getBuildConfig(pkg, flags);
|
entry = typeof entry === 'string' ? { index: entry } : entry;
|
||||||
const httpProxyMiddlewareLogLevel = process.env.CI ? 'silent' : 'error';
|
|
||||||
|
|
||||||
const config = {
|
htmlConfig = merge(
|
||||||
name: 'affine',
|
{},
|
||||||
|
{
|
||||||
|
filename: 'index.html',
|
||||||
|
additionalEntryForSelfhost: true,
|
||||||
|
injectGlobalErrorHandler: true,
|
||||||
|
emitAssetsManifest: true,
|
||||||
|
},
|
||||||
|
htmlConfig
|
||||||
|
);
|
||||||
|
|
||||||
|
const buildConfig = getBuildConfigFromEnv(pkg);
|
||||||
|
|
||||||
|
const config: webpack.Configuration = {
|
||||||
|
//#region basic webpack config
|
||||||
|
name: entry['index'],
|
||||||
|
dependencies: deps,
|
||||||
context: pkg.path.value,
|
context: pkg.path.value,
|
||||||
experiments: {
|
experiments: {
|
||||||
topLevelAwait: true,
|
topLevelAwait: true,
|
||||||
outputModule: false,
|
outputModule: false,
|
||||||
syncWebAssembly: true,
|
syncWebAssembly: true,
|
||||||
},
|
},
|
||||||
entry: {
|
entry,
|
||||||
app: pkg.entry ?? './src/index.tsx',
|
|
||||||
},
|
|
||||||
output: {
|
output: {
|
||||||
environment: {
|
environment: {
|
||||||
module: true,
|
module: true,
|
||||||
dynamicImport: true,
|
dynamicImport: true,
|
||||||
},
|
},
|
||||||
filename:
|
filename: buildConfig.debug
|
||||||
flags.mode === 'production'
|
? 'js/[name].js'
|
||||||
? 'js/[name].[contenthash:8].js'
|
: 'js/[name].[contenthash:8].js',
|
||||||
: 'js/[name].js',
|
assetModuleFilename: buildConfig.debug
|
||||||
// In some cases webpack will emit files starts with "_" which is reserved in web extension.
|
? '[name].[contenthash:8][ext]'
|
||||||
chunkFilename: pathData =>
|
: 'assets/[name].[contenthash:8][ext][query]',
|
||||||
pathData.chunk?.name?.endsWith?.('worker')
|
|
||||||
? 'js/[name].[contenthash:8].js'
|
|
||||||
: flags.mode === 'production'
|
|
||||||
? 'js/chunk.[name].[contenthash:8].js'
|
|
||||||
: 'js/chunk.[name].js',
|
|
||||||
assetModuleFilename:
|
|
||||||
flags.mode === 'production'
|
|
||||||
? 'assets/[name].[contenthash:8][ext][query]'
|
|
||||||
: '[name].[contenthash:8][ext]',
|
|
||||||
devtoolModuleFilenameTemplate: 'webpack://[namespace]/[resource-path]',
|
|
||||||
hotUpdateChunkFilename: 'hot/[id].[fullhash].js',
|
|
||||||
hotUpdateMainFilename: 'hot/[runtime].[fullhash].json',
|
|
||||||
path: pkg.distPath.value,
|
path: pkg.distPath.value,
|
||||||
clean: flags.mode === 'production',
|
clean: false,
|
||||||
globalObject: 'globalThis',
|
globalObject: 'globalThis',
|
||||||
// NOTE(@forehalo): always keep it '/'
|
// NOTE(@forehalo): always keep it '/'
|
||||||
publicPath: '/',
|
publicPath: '/',
|
||||||
workerPublicPath: '/',
|
|
||||||
},
|
},
|
||||||
target: ['web', 'es2022'],
|
target: ['web', 'es2022'],
|
||||||
|
mode: buildConfig.debug ? 'development' : 'production',
|
||||||
mode: flags.mode,
|
devtool: buildConfig.debug ? 'cheap-module-source-map' : 'source-map',
|
||||||
|
|
||||||
devtool:
|
|
||||||
flags.mode === 'production' ? 'source-map' : 'cheap-module-source-map',
|
|
||||||
|
|
||||||
resolve: {
|
resolve: {
|
||||||
symlinks: true,
|
symlinks: true,
|
||||||
extensionAlias: {
|
extensionAlias: {
|
||||||
@@ -139,7 +111,9 @@ export function createWebpackConfig(
|
|||||||
).value,
|
).value,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region module config
|
||||||
module: {
|
module: {
|
||||||
parser: {
|
parser: {
|
||||||
javascript: {
|
javascript: {
|
||||||
@@ -151,6 +125,7 @@ export function createWebpackConfig(
|
|||||||
strictExportPresence: true,
|
strictExportPresence: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
//#region rules
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.m?js?$/,
|
test: /\.m?js?$/,
|
||||||
@@ -240,7 +215,7 @@ export function createWebpackConfig(
|
|||||||
{
|
{
|
||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
use: [
|
use: [
|
||||||
flags.mode === 'development'
|
buildConfig.debug
|
||||||
? 'style-loader'
|
? 'style-loader'
|
||||||
: MiniCssExtractPlugin.loader,
|
: MiniCssExtractPlugin.loader,
|
||||||
{
|
{
|
||||||
@@ -283,28 +258,16 @@ export function createWebpackConfig(
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
//#endregion
|
||||||
},
|
},
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region plugins
|
||||||
plugins: compact([
|
plugins: compact([
|
||||||
IN_CI ? null : new webpack.ProgressPlugin({ percentBy: 'entries' }),
|
!IN_CI && new webpack.ProgressPlugin({ percentBy: 'entries' }),
|
||||||
flags.mode === 'development'
|
...createHTMLPlugins(buildConfig, htmlConfig),
|
||||||
? null
|
|
||||||
: // todo: support multiple entry points
|
|
||||||
new MiniCssExtractPlugin({
|
|
||||||
filename: `[name].[contenthash:8].css`,
|
|
||||||
ignoreOrder: true,
|
|
||||||
}),
|
|
||||||
new VanillaExtractPlugin(),
|
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
'process.env.NODE_ENV': JSON.stringify(flags.mode),
|
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
|
||||||
'process.env.CAPTCHA_SITE_KEY': JSON.stringify(
|
|
||||||
process.env.CAPTCHA_SITE_KEY
|
|
||||||
),
|
|
||||||
'process.env.SENTRY_DSN': JSON.stringify(process.env.SENTRY_DSN),
|
|
||||||
'process.env.BUILD_TYPE': JSON.stringify(process.env.BUILD_TYPE),
|
|
||||||
'process.env.MIXPANEL_TOKEN': JSON.stringify(
|
|
||||||
process.env.MIXPANEL_TOKEN
|
|
||||||
),
|
|
||||||
'process.env.DEBUG_JOTAI': JSON.stringify(process.env.DEBUG_JOTAI),
|
|
||||||
...Object.entries(buildConfig).reduce(
|
...Object.entries(buildConfig).reduce(
|
||||||
(def, [k, v]) => {
|
(def, [k, v]) => {
|
||||||
def[`BUILD_CONFIG.${k}`] = JSON.stringify(v);
|
def[`BUILD_CONFIG.${k}`] = JSON.stringify(v);
|
||||||
@@ -313,90 +276,100 @@ export function createWebpackConfig(
|
|||||||
{} as Record<string, string>
|
{} as Record<string, string>
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
buildConfig.isAdmin && flags.mode !== 'production'
|
!buildConfig.debug &&
|
||||||
? null
|
// todo: support multiple entry points
|
||||||
: new CopyPlugin({
|
new MiniCssExtractPlugin({
|
||||||
patterns: [
|
filename: `[name].[contenthash:8].css`,
|
||||||
{
|
ignoreOrder: true,
|
||||||
// copy the shared public assets into dist
|
}),
|
||||||
from: pkg.workspace.getPackage('@affine/core').join('public')
|
new VanillaExtractPlugin(),
|
||||||
.value,
|
!buildConfig.isAdmin &&
|
||||||
},
|
new CopyPlugin({
|
||||||
],
|
patterns: [
|
||||||
}),
|
{
|
||||||
flags.mode === 'production' &&
|
// copy the shared public assets into dist
|
||||||
(buildConfig.isWeb || buildConfig.isMobileWeb || buildConfig.isAdmin) &&
|
from: new Package('@affine/core').join('public').value,
|
||||||
process.env.R2_SECRET_ACCESS_KEY
|
},
|
||||||
? new WebpackS3Plugin()
|
],
|
||||||
: null,
|
}),
|
||||||
|
!buildConfig.debug &&
|
||||||
|
(buildConfig.isWeb || buildConfig.isMobileWeb || buildConfig.isAdmin) &&
|
||||||
|
process.env.R2_SECRET_ACCESS_KEY &&
|
||||||
|
new WebpackS3Plugin(),
|
||||||
|
!buildConfig.debug &&
|
||||||
|
process.env.PERFSEE_TOKEN &&
|
||||||
|
new PerfseePlugin({
|
||||||
|
project: 'affine-toeverything',
|
||||||
|
}),
|
||||||
|
process.env.SENTRY_AUTH_TOKEN &&
|
||||||
|
process.env.SENTRY_ORG &&
|
||||||
|
process.env.SENTRY_PROJECT &&
|
||||||
|
sentryWebpackPlugin({
|
||||||
|
org: process.env.SENTRY_ORG,
|
||||||
|
project: process.env.SENTRY_PROJECT,
|
||||||
|
authToken: process.env.SENTRY_AUTH_TOKEN,
|
||||||
|
}),
|
||||||
|
// sourcemap url like # sourceMappingURL=76-6370cd185962bc89.js.map wont load in electron
|
||||||
|
// this is because the default file:// protocol will be ignored by Chromium
|
||||||
|
// so we need to replace the sourceMappingURL to assets:// protocol
|
||||||
|
// for example:
|
||||||
|
// replace # sourceMappingURL=76-6370cd185962bc89.js.map
|
||||||
|
// to # sourceMappingURL=assets://./{dir}/76-6370cd185962bc89.js.map
|
||||||
|
buildConfig.isElectron &&
|
||||||
|
new webpack.SourceMapDevToolPlugin({
|
||||||
|
append: pathData => {
|
||||||
|
return `\n//# sourceMappingURL=assets://./${pathData.filename}.map`;
|
||||||
|
},
|
||||||
|
filename: '[file].map',
|
||||||
|
}),
|
||||||
]),
|
]),
|
||||||
|
//#endregion
|
||||||
|
|
||||||
stats: {
|
stats: {
|
||||||
errorDetails: true,
|
errorDetails: true,
|
||||||
},
|
},
|
||||||
optimization: OptimizeOptionOptions(flags),
|
|
||||||
devServer: {
|
//#region optimization
|
||||||
host: '0.0.0.0',
|
optimization: {
|
||||||
allowedHosts: 'all',
|
minimize: !buildConfig.debug,
|
||||||
hot: false,
|
minimizer: [
|
||||||
liveReload: true,
|
new TerserPlugin({
|
||||||
client: {
|
minify: TerserPlugin.swcMinify,
|
||||||
overlay: process.env.DISABLE_DEV_OVERLAY === 'true' ? false : undefined,
|
exclude: [/plugins\/.+\/.+\.js$/, /plugins\/.+\/.+\.mjs$/],
|
||||||
logging: process.env.CI ? 'none' : 'error',
|
parallel: true,
|
||||||
},
|
extractComments: true,
|
||||||
historyApiFallback: {
|
terserOptions: {
|
||||||
rewrites: [
|
ecma: 2020,
|
||||||
{
|
compress: {
|
||||||
from: /.*/,
|
unused: true,
|
||||||
to: () => {
|
},
|
||||||
return process.env.SELF_HOSTED === 'true'
|
mangle: {
|
||||||
? '/selfhost.html'
|
keep_classnames: true,
|
||||||
: '/index.html';
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
}),
|
||||||
|
],
|
||||||
|
removeEmptyChunks: true,
|
||||||
|
providedExports: true,
|
||||||
|
usedExports: true,
|
||||||
|
sideEffects: true,
|
||||||
|
removeAvailableModules: true,
|
||||||
|
runtimeChunk: {
|
||||||
|
name: 'runtime',
|
||||||
},
|
},
|
||||||
static: [
|
splitChunks: {
|
||||||
{
|
chunks: 'all',
|
||||||
directory: pkg.workspace.getPackage('@affine/core').join('public')
|
minSize: 1,
|
||||||
.value,
|
minChunks: 1,
|
||||||
publicPath: '/',
|
maxInitialRequests: Number.MAX_SAFE_INTEGER,
|
||||||
watch: !IN_CI,
|
maxAsyncRequests: Number.MAX_SAFE_INTEGER,
|
||||||
staticOptions: {
|
cacheGroups: productionCacheGroups,
|
||||||
immutable: IN_CI,
|
},
|
||||||
maxAge: '1d',
|
},
|
||||||
},
|
//#endregion
|
||||||
},
|
};
|
||||||
],
|
|
||||||
proxy: [
|
|
||||||
{
|
|
||||||
context: '/api',
|
|
||||||
target: 'http://localhost:3010',
|
|
||||||
logLevel: httpProxyMiddlewareLogLevel,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
context: '/socket.io',
|
|
||||||
target: 'http://localhost:3010',
|
|
||||||
ws: true,
|
|
||||||
logLevel: httpProxyMiddlewareLogLevel,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
context: '/graphql',
|
|
||||||
target: 'http://localhost:3010',
|
|
||||||
logLevel: httpProxyMiddlewareLogLevel,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
} as DevServerConfiguration,
|
|
||||||
} satisfies webpack.Configuration;
|
|
||||||
|
|
||||||
if (flags.mode === 'production' && process.env.PERFSEE_TOKEN) {
|
if (buildConfig.debug && !IN_CI) {
|
||||||
config.plugins.push(
|
|
||||||
new PerfseePlugin({
|
|
||||||
project: 'affine-toeverything',
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags.mode === 'development' && !IN_CI) {
|
|
||||||
config.optimization = {
|
config.optimization = {
|
||||||
...config.optimization,
|
...config.optimization,
|
||||||
minimize: false,
|
minimize: false,
|
||||||
@@ -426,42 +399,186 @@ export function createWebpackConfig(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
|
||||||
process.env.SENTRY_AUTH_TOKEN &&
|
|
||||||
process.env.SENTRY_ORG &&
|
|
||||||
process.env.SENTRY_PROJECT
|
|
||||||
) {
|
|
||||||
config.plugins.push(
|
|
||||||
sentryWebpackPlugin({
|
|
||||||
org: process.env.SENTRY_ORG,
|
|
||||||
project: process.env.SENTRY_PROJECT,
|
|
||||||
authToken: process.env.SENTRY_AUTH_TOKEN,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
config.plugins = config.plugins.concat(createHTMLPlugins(flags, buildConfig));
|
|
||||||
|
|
||||||
if (buildConfig.isElectron) {
|
|
||||||
config.plugins.push(createShellHTMLPlugin(flags, buildConfig));
|
|
||||||
config.plugins.push(createBackgroundWorkerHTMLPlugin(flags, buildConfig));
|
|
||||||
config.plugins.push(createPopupHTMLPlugin(flags, buildConfig));
|
|
||||||
|
|
||||||
// sourcemap url like # sourceMappingURL=76-6370cd185962bc89.js.map wont load in electron
|
|
||||||
// this is because the default file:// protocol will be ignored by Chromium
|
|
||||||
// so we need to replace the sourceMappingURL to assets:// protocol
|
|
||||||
// for example:
|
|
||||||
// replace # sourceMappingURL=76-6370cd185962bc89.js.map
|
|
||||||
// to # sourceMappingURL=assets://./{dir}/76-6370cd185962bc89.js.map
|
|
||||||
config.plugins.push(
|
|
||||||
new webpack.SourceMapDevToolPlugin({
|
|
||||||
append: pathData => {
|
|
||||||
return `\n//# sourceMappingURL=assets://./${pathData.filename}.map`;
|
|
||||||
},
|
|
||||||
filename: '[file].map',
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createWorkerTargetConfig(
|
||||||
|
pkg: Package,
|
||||||
|
entry: string
|
||||||
|
): Omit<webpack.Configuration, 'name'> & { name: string } {
|
||||||
|
const workerName = path.basename(entry).replace(/\.([^.]+)$/, '');
|
||||||
|
if (!workerName.endsWith('.worker')) {
|
||||||
|
throw new Error('Worker name must end with `.worker.[ext]`');
|
||||||
|
}
|
||||||
|
const buildConfig = getBuildConfigFromEnv(pkg);
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: entry,
|
||||||
|
context: pkg.path.value,
|
||||||
|
experiments: {
|
||||||
|
topLevelAwait: true,
|
||||||
|
outputModule: false,
|
||||||
|
syncWebAssembly: true,
|
||||||
|
},
|
||||||
|
entry: {
|
||||||
|
[workerName]: entry,
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: 'js/[name].js',
|
||||||
|
path: pkg.distPath.value,
|
||||||
|
clean: false,
|
||||||
|
globalObject: 'globalThis',
|
||||||
|
// NOTE(@forehalo): always keep it '/'
|
||||||
|
publicPath: '/',
|
||||||
|
},
|
||||||
|
target: ['webworker', 'es2022'],
|
||||||
|
mode: buildConfig.debug ? 'development' : 'production',
|
||||||
|
devtool: buildConfig.debug ? 'cheap-module-source-map' : 'source-map',
|
||||||
|
resolve: {
|
||||||
|
symlinks: true,
|
||||||
|
extensionAlias: {
|
||||||
|
'.js': ['.js', '.ts'],
|
||||||
|
'.mjs': ['.mjs', '.mts'],
|
||||||
|
},
|
||||||
|
extensions: ['.js', '.ts'],
|
||||||
|
alias: {
|
||||||
|
yjs: ProjectRoot.join('node_modules', 'yjs').value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
module: {
|
||||||
|
parser: {
|
||||||
|
javascript: {
|
||||||
|
// Do not mock Node.js globals
|
||||||
|
node: false,
|
||||||
|
requireJs: false,
|
||||||
|
import: true,
|
||||||
|
// Treat as missing export as error
|
||||||
|
strictExportPresence: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.m?js?$/,
|
||||||
|
resolve: {
|
||||||
|
fullySpecified: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
enforce: 'pre',
|
||||||
|
include: /@blocksuite/,
|
||||||
|
use: ['source-map-loader'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
oneOf: [
|
||||||
|
{
|
||||||
|
test: /\.ts$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
loader: 'swc-loader',
|
||||||
|
options: {
|
||||||
|
// https://swc.rs/docs/configuring-swc/
|
||||||
|
jsc: {
|
||||||
|
preserveAllComments: true,
|
||||||
|
parser: {
|
||||||
|
syntax: 'typescript',
|
||||||
|
dynamicImport: true,
|
||||||
|
topLevelAwait: false,
|
||||||
|
tsx: false,
|
||||||
|
decorators: true,
|
||||||
|
},
|
||||||
|
target: 'es2022',
|
||||||
|
externalHelpers: false,
|
||||||
|
transform: {
|
||||||
|
useDefineForClassFields: false,
|
||||||
|
decoratorVersion: '2022-03',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sourceMaps: true,
|
||||||
|
inlineSourcesContent: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.tsx$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
loader: 'swc-loader',
|
||||||
|
options: {
|
||||||
|
// https://swc.rs/docs/configuring-swc/
|
||||||
|
jsc: {
|
||||||
|
preserveAllComments: true,
|
||||||
|
parser: {
|
||||||
|
syntax: 'typescript',
|
||||||
|
dynamicImport: true,
|
||||||
|
topLevelAwait: false,
|
||||||
|
tsx: true,
|
||||||
|
decorators: true,
|
||||||
|
},
|
||||||
|
target: 'es2022',
|
||||||
|
externalHelpers: false,
|
||||||
|
transform: {
|
||||||
|
react: {
|
||||||
|
runtime: 'automatic',
|
||||||
|
},
|
||||||
|
useDefineForClassFields: false,
|
||||||
|
decoratorVersion: '2022-03',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sourceMaps: true,
|
||||||
|
inlineSourcesContent: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
plugins: compact([
|
||||||
|
new webpack.DefinePlugin(
|
||||||
|
Object.entries(buildConfig).reduce(
|
||||||
|
(def, [k, v]) => {
|
||||||
|
def[`BUILD_CONFIG.${k}`] = JSON.stringify(v);
|
||||||
|
return def;
|
||||||
|
},
|
||||||
|
{} as Record<string, string>
|
||||||
|
)
|
||||||
|
),
|
||||||
|
process.env.SENTRY_AUTH_TOKEN &&
|
||||||
|
process.env.SENTRY_ORG &&
|
||||||
|
process.env.SENTRY_PROJECT &&
|
||||||
|
sentryWebpackPlugin({
|
||||||
|
org: process.env.SENTRY_ORG,
|
||||||
|
project: process.env.SENTRY_PROJECT,
|
||||||
|
authToken: process.env.SENTRY_AUTH_TOKEN,
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
stats: {
|
||||||
|
errorDetails: true,
|
||||||
|
},
|
||||||
|
optimization: {
|
||||||
|
minimize: !buildConfig.debug,
|
||||||
|
minimizer: [
|
||||||
|
new TerserPlugin({
|
||||||
|
minify: TerserPlugin.swcMinify,
|
||||||
|
exclude: [/plugins\/.+\/.+\.js$/, /plugins\/.+\/.+\.mjs$/],
|
||||||
|
parallel: true,
|
||||||
|
extractComments: true,
|
||||||
|
terserOptions: {
|
||||||
|
ecma: 2020,
|
||||||
|
compress: {
|
||||||
|
unused: true,
|
||||||
|
},
|
||||||
|
mangle: {
|
||||||
|
keep_classnames: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
removeEmptyChunks: true,
|
||||||
|
providedExports: true,
|
||||||
|
usedExports: true,
|
||||||
|
sideEffects: true,
|
||||||
|
removeAvailableModules: true,
|
||||||
|
runtimeChunk: false,
|
||||||
|
splitChunks: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,6 +50,10 @@ export function getBuildConfig(
|
|||||||
discordUrl: 'https://affine.pro/redirect/discord',
|
discordUrl: 'https://affine.pro/redirect/discord',
|
||||||
imageProxyUrl: '/api/worker/image-proxy',
|
imageProxyUrl: '/api/worker/image-proxy',
|
||||||
linkPreviewUrl: '/api/worker/link-preview',
|
linkPreviewUrl: '/api/worker/link-preview',
|
||||||
|
CAPTCHA_SITE_KEY: process.env.CAPTCHA_SITE_KEY ?? '',
|
||||||
|
SENTRY_DSN: process.env.SENTRY_DSN ?? '',
|
||||||
|
MIXPANEL_TOKEN: process.env.MIXPANEL_TOKEN ?? '',
|
||||||
|
DEBUG_JOTAI: process.env.DEBUG_JOTAI ?? '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
get beta() {
|
get beta() {
|
||||||
|
|||||||
@@ -923,6 +923,7 @@ export const PackageList = [
|
|||||||
workspaceDependencies: [
|
workspaceDependencies: [
|
||||||
'packages/frontend/component',
|
'packages/frontend/component',
|
||||||
'packages/frontend/core',
|
'packages/frontend/core',
|
||||||
|
'packages/common/env',
|
||||||
'packages/frontend/i18n',
|
'packages/frontend/i18n',
|
||||||
'packages/common/nbstore',
|
'packages/common/nbstore',
|
||||||
'blocksuite/affine/all',
|
'blocksuite/affine/all',
|
||||||
@@ -961,6 +962,7 @@ export const PackageList = [
|
|||||||
workspaceDependencies: [
|
workspaceDependencies: [
|
||||||
'packages/frontend/component',
|
'packages/frontend/component',
|
||||||
'packages/frontend/core',
|
'packages/frontend/core',
|
||||||
|
'packages/common/env',
|
||||||
'packages/frontend/i18n',
|
'packages/frontend/i18n',
|
||||||
'packages/common/nbstore',
|
'packages/common/nbstore',
|
||||||
'blocksuite/affine/all',
|
'blocksuite/affine/all',
|
||||||
@@ -976,6 +978,7 @@ export const PackageList = [
|
|||||||
workspaceDependencies: [
|
workspaceDependencies: [
|
||||||
'packages/frontend/component',
|
'packages/frontend/component',
|
||||||
'packages/frontend/core',
|
'packages/frontend/core',
|
||||||
|
'packages/common/env',
|
||||||
'packages/frontend/i18n',
|
'packages/frontend/i18n',
|
||||||
'packages/common/nbstore',
|
'packages/common/nbstore',
|
||||||
'blocksuite/affine/all',
|
'blocksuite/affine/all',
|
||||||
@@ -988,6 +991,7 @@ export const PackageList = [
|
|||||||
workspaceDependencies: [
|
workspaceDependencies: [
|
||||||
'packages/frontend/component',
|
'packages/frontend/component',
|
||||||
'packages/frontend/core',
|
'packages/frontend/core',
|
||||||
|
'packages/common/env',
|
||||||
'packages/frontend/i18n',
|
'packages/frontend/i18n',
|
||||||
'packages/common/nbstore',
|
'packages/common/nbstore',
|
||||||
'packages/frontend/track',
|
'packages/frontend/track',
|
||||||
|
|||||||
@@ -243,6 +243,7 @@ __metadata:
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@affine/component": "workspace:*"
|
"@affine/component": "workspace:*"
|
||||||
"@affine/core": "workspace:*"
|
"@affine/core": "workspace:*"
|
||||||
|
"@affine/env": "workspace:*"
|
||||||
"@affine/i18n": "workspace:*"
|
"@affine/i18n": "workspace:*"
|
||||||
"@affine/nbstore": "workspace:*"
|
"@affine/nbstore": "workspace:*"
|
||||||
"@blocksuite/affine": "workspace:*"
|
"@blocksuite/affine": "workspace:*"
|
||||||
@@ -656,6 +657,7 @@ __metadata:
|
|||||||
"@affine-tools/utils": "workspace:*"
|
"@affine-tools/utils": "workspace:*"
|
||||||
"@affine/component": "workspace:*"
|
"@affine/component": "workspace:*"
|
||||||
"@affine/core": "workspace:*"
|
"@affine/core": "workspace:*"
|
||||||
|
"@affine/env": "workspace:*"
|
||||||
"@affine/i18n": "workspace:*"
|
"@affine/i18n": "workspace:*"
|
||||||
"@affine/native": "workspace:*"
|
"@affine/native": "workspace:*"
|
||||||
"@affine/nbstore": "workspace:*"
|
"@affine/nbstore": "workspace:*"
|
||||||
@@ -724,6 +726,7 @@ __metadata:
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@affine/component": "workspace:*"
|
"@affine/component": "workspace:*"
|
||||||
"@affine/core": "workspace:*"
|
"@affine/core": "workspace:*"
|
||||||
|
"@affine/env": "workspace:*"
|
||||||
"@affine/i18n": "workspace:*"
|
"@affine/i18n": "workspace:*"
|
||||||
"@affine/nbstore": "workspace:*"
|
"@affine/nbstore": "workspace:*"
|
||||||
"@blocksuite/affine": "workspace:*"
|
"@blocksuite/affine": "workspace:*"
|
||||||
@@ -1012,6 +1015,7 @@ __metadata:
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@affine/component": "workspace:*"
|
"@affine/component": "workspace:*"
|
||||||
"@affine/core": "workspace:*"
|
"@affine/core": "workspace:*"
|
||||||
|
"@affine/env": "workspace:*"
|
||||||
"@affine/i18n": "workspace:*"
|
"@affine/i18n": "workspace:*"
|
||||||
"@affine/nbstore": "workspace:*"
|
"@affine/nbstore": "workspace:*"
|
||||||
"@affine/track": "workspace:*"
|
"@affine/track": "workspace:*"
|
||||||
|
|||||||
Reference in New Issue
Block a user