fix(server): blank screen on mobile (#8460)

Co-authored-by: forehalo <forehalo@gmail.com>
This commit is contained in:
野声
2024-10-16 13:12:40 +08:00
committed by GitHub
parent 82916e8264
commit f393f89a3f
47 changed files with 425 additions and 212 deletions

View File

@@ -71,19 +71,23 @@ export const getPublicPath = (buildFlags: BuildFlags) => {
if (typeof process.env.PUBLIC_PATH === 'string') {
return process.env.PUBLIC_PATH;
}
const publicPath = '/';
if (process.env.COVERAGE || buildFlags.distribution === 'desktop') {
return publicPath;
if (
buildFlags.mode === 'development' ||
process.env.COVERAGE ||
buildFlags.distribution === 'desktop'
) {
return '/';
}
if (BUILD_TYPE === 'canary') {
return `https://dev.affineassets.com/`;
} else if (BUILD_TYPE === 'beta') {
return `https://beta.affineassets.com/`;
} else if (BUILD_TYPE === 'stable') {
return `https://prod.affineassets.com/`;
switch (BUILD_TYPE) {
case 'stable':
return 'https://prod.affineassets.com/';
case 'beta':
return 'https://beta.affineassets.com/';
default:
return 'https://dev.affineassets.com/';
}
return publicPath;
};
export const createConfiguration: (
@@ -126,7 +130,8 @@ export const createConfiguration: (
path: join(cwd, 'dist'),
clean: buildFlags.mode === 'production',
globalObject: 'globalThis',
publicPath: getPublicPath(buildFlags),
// NOTE(@forehalo): always keep it '/'
publicPath: '/',
workerPublicPath: '/',
},
target: ['web', 'es2022'],

View File

@@ -26,7 +26,7 @@ export class WebpackS3Plugin implements WebpackPluginInstance {
compiler.hooks.assetEmitted.tapPromise(
'WebpackS3Plugin',
async (asset, { outputPath }) => {
if (asset === 'index.html') {
if (asset.endsWith('.html')) {
return;
}
const assetPath = join(outputPath, asset);

View File

@@ -16,7 +16,7 @@
<title>AFFiNE</title>
<meta name="theme-color" content="#fafafa" />
<link rel="preconnect" href="<%= PUBLIC_PATH %>" />
<%= PRECONNECT %>
<link rel="manifest" href="/manifest.json" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" sizes="192x192" href="/favicon-192.png" />

View File

@@ -5,10 +5,16 @@ 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 type { Compiler } from 'webpack';
import webpack from 'webpack';
import { merge } from 'webpack-merge';
import { createConfiguration, rootPath, workspaceRoot } from './config.js';
import {
createConfiguration,
getPublicPath,
rootPath,
workspaceRoot,
} from './config.js';
import { getBuildConfig } from './runtime-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.`;
@@ -41,46 +47,106 @@ export function createWebpackConfig(cwd: string, flags: BuildFlags) {
}
: flags.entry;
const createHTMLPlugin = (entryName = 'app') => {
return new HTMLPlugin({
const publicPath = getPublicPath(flags);
const cdnOrigin = publicPath.startsWith('/')
? undefined
: new URL(publicPath).origin;
const templateParams = {
GIT_SHORT_SHA: gitShortHash(),
DESCRIPTION,
PRECONNECT: cdnOrigin
? `<link rel="preconnect" href="${cdnOrigin}" />`
: '',
VIEWPORT_FIT: flags.distribution === 'mobile' ? 'cover' : 'auto',
};
const createHTMLPlugins = (entryName: string) => {
const htmlPluginOptions = {
template: join(rootPath, 'webpack', 'template.html'),
inject: 'body',
filename: 'index.html',
minify: false,
templateParameters: templateParams,
chunks: [entryName],
filename: `${entryName === 'app' ? 'index' : entryName}.html`, // main entry should take name index.html
templateParameters: (compilation, assets) => {
if (entryName === 'app') {
// emit assets manifest for ssr
compilation.emitAsset(
`assets-manifest.json`,
new webpack.sources.RawSource(
JSON.stringify(
{
...assets,
gitHash: gitShortHash(),
description: DESCRIPTION,
},
null,
2
)
),
{
immutable: true,
}
);
}
return {
GIT_SHORT_SHA: gitShortHash(),
DESCRIPTION,
PUBLIC_PATH: config.output?.publicPath,
VIEWPORT_FIT: flags.distribution === 'mobile' ? 'cover' : 'auto',
};
},
});
} satisfies HTMLPlugin.Options;
if (entryName === 'app') {
return [
{
apply(compiler: Compiler) {
compiler.hooks.compilation.tap(
'assets-manifest-plugin',
compilation => {
HTMLPlugin.getHooks(compilation).beforeAssetTagGeneration.tap(
'assets-manifest-plugin',
arg => {
if (!compilation.getAsset('assets-manifest.json')) {
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: templateParams.GIT_SHORT_SHA,
description: templateParams.DESCRIPTION,
},
null,
2
)
),
{
immutable: false,
}
);
}
return arg;
}
);
}
);
},
},
new HTMLPlugin({
...htmlPluginOptions,
publicPath,
meta: {
'env:publicPath': publicPath,
},
}),
// selfhost html
new HTMLPlugin({
...htmlPluginOptions,
meta: {
'env:isSelfHosted': 'true',
'env:publicPath': '/',
},
filename: 'selfhost.html',
templateParameters: {
...htmlPluginOptions.templateParameters,
PRECONNECT: '',
},
}),
];
} else {
return [
new HTMLPlugin({
...htmlPluginOptions,
filename: `${entryName}.html`,
}),
];
}
};
return merge(config, {
entry: entry,
plugins: Object.keys(entry).map(createHTMLPlugin),
entry,
plugins: Object.keys(entry).map(createHTMLPlugins).flat(),
});
}