diff --git a/README.md b/README.md index a58f80d3..e3205235 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,12 @@ client: assetPrefix: '/' apiUrl: 'http://localhost:5002/api' collaborationUrl: 'ws://localhost:5003' + # 以下为页面 meta 配置 + seoAppName: '云策文档' + seoDescription: '云策文档是一款开源知识管理工具。通过独立的知识库空间,结构化地组织在线协作文档,实现知识的积累与沉淀,促进知识的复用与流通。' + seoKeywords: '云策文档,协作,文档,前端面试题,fantasticit,https://github.com/fantasticit/think' + # 预先连接的来源,空格分割(比如图片存储服务器) + dnsPrefetch: '//wipi.oss-cn-shanghai.aliyuncs.com' server: prefix: '/api' diff --git a/config/dev.yaml b/config/dev.yaml index 0ae5eb64..fa7347e4 100644 --- a/config/dev.yaml +++ b/config/dev.yaml @@ -4,6 +4,12 @@ client: assetPrefix: '/' apiUrl: 'http://localhost:5002/api' collaborationUrl: 'ws://localhost:5003' + # 以下为页面 meta 配置 + seoAppName: '云策文档' + seoDescription: '云策文档是一款开源知识管理工具。通过独立的知识库空间,结构化地组织在线协作文档,实现知识的积累与沉淀,促进知识的复用与流通。' + seoKeywords: '云策文档,协作,文档,前端面试题,fantasticit,https://github.com/fantasticit/think' + # 预先连接的来源,空格分割(比如图片存储服务器) + dnsPrefetch: '//wipi.oss-cn-shanghai.aliyuncs.com' server: prefix: '/api' diff --git a/packages/client/copy-diagram-resources.js b/packages/client/copy-diagram-resources.js index 0fcc33c7..1d65d37f 100755 --- a/packages/client/copy-diagram-resources.js +++ b/packages/client/copy-diagram-resources.js @@ -2,5 +2,76 @@ * 将流程图编辑器所需的资源拷贝到 .next 目录中,配合 nginx 运行 */ const fs = require('fs-extra'); +const { getConfig } = require('@think/config'); +const config = getConfig(); -fs.copySync('./public', './.next'); +const buildManifestJson = () => { + return JSON.stringify({ + name: config.client.seoAppName, + short_name: config.client.seoAppName, + display: 'standalone', + start_url: '/', + theme_color: '#ffffff', + background_color: '#ffffff', + icons: [ + { + src: '/icon72.png', + sizes: '72x72', + type: 'image/png', + }, + { + src: '/icon96.png', + sizes: '96x96', + type: 'image/png', + }, + { + src: '/icon120.png', + sizes: '120x120', + type: 'image/png', + }, + { + src: '/icon128.png', + sizes: '128x128', + type: 'image/png', + }, + { + src: '/icon144.png', + sizes: '144x144', + type: 'image/png', + }, + { + src: '/icon152.png', + sizes: '152x152', + type: 'image/png', + }, + { + src: '/icon180.png', + sizes: '180x180', + type: 'image/png', + }, + { + src: '/icon192.png', + sizes: '192x192', + type: 'image/png', + }, + { + src: '/icon384.png', + sizes: '384x384', + type: 'image/png', + }, + { + src: '/icon512.png', + sizes: '512x512', + type: 'image/png', + }, + ], + }); +}; + +fs.copySync('./public', './.next', { + filter: (src) => { + // 生产环境使用 diagram.min.js + return !/diagram.js$/.test(src); + }, +}); +fs.outputFileSync('./.next/manifest.json', buildManifestJson()); diff --git a/packages/client/next.config.js b/packages/client/next.config.js index 75de308c..ca4387d2 100644 --- a/packages/client/next.config.js +++ b/packages/client/next.config.js @@ -11,6 +11,10 @@ const nextConfig = semi({ SERVER_API_URL: config.client.apiUrl, COLLABORATION_API_URL: config.client.collaborationUrl, ENABLE_ALIYUN_OSS: !!config.oss.aliyun.accessKeyId, + DNS_PREFETCH: (config.client.dnsPrefetch || '').split(' '), + SEO_APPNAME: config.client.seoAppName, + SEO_DESCRIPTION: config.client.seoDescription, + SEO_KEYWORDS: config.client.seoKeywords, }, webpack: (config, { dev, isServer }) => { config.resolve.plugins.push(new TsconfigPathsPlugin()); diff --git a/packages/client/public/favicon.ico b/packages/client/public/favicon.ico index 937b76a1..7c6b60ce 100644 Binary files a/packages/client/public/favicon.ico and b/packages/client/public/favicon.ico differ diff --git a/packages/client/public/icon120.png b/packages/client/public/icon120.png new file mode 100644 index 00000000..005f8a85 Binary files /dev/null and b/packages/client/public/icon120.png differ diff --git a/packages/client/public/icon128.png b/packages/client/public/icon128.png new file mode 100644 index 00000000..d5abf294 Binary files /dev/null and b/packages/client/public/icon128.png differ diff --git a/packages/client/public/icon144.png b/packages/client/public/icon144.png new file mode 100644 index 00000000..3200d16c Binary files /dev/null and b/packages/client/public/icon144.png differ diff --git a/packages/client/public/icon152.png b/packages/client/public/icon152.png new file mode 100644 index 00000000..7531f37f Binary files /dev/null and b/packages/client/public/icon152.png differ diff --git a/packages/client/public/icon180.png b/packages/client/public/icon180.png new file mode 100644 index 00000000..6fffbebf Binary files /dev/null and b/packages/client/public/icon180.png differ diff --git a/packages/client/public/icon192.png b/packages/client/public/icon192.png new file mode 100644 index 00000000..6d9a6b23 Binary files /dev/null and b/packages/client/public/icon192.png differ diff --git a/packages/client/public/icon384.png b/packages/client/public/icon384.png new file mode 100644 index 00000000..39664fcb Binary files /dev/null and b/packages/client/public/icon384.png differ diff --git a/packages/client/public/icon512.png b/packages/client/public/icon512.png new file mode 100644 index 00000000..7a8c1422 Binary files /dev/null and b/packages/client/public/icon512.png differ diff --git a/packages/client/public/icon72.png b/packages/client/public/icon72.png new file mode 100644 index 00000000..0cf2396d Binary files /dev/null and b/packages/client/public/icon72.png differ diff --git a/packages/client/public/icon96.png b/packages/client/public/icon96.png new file mode 100644 index 00000000..f969aa4e Binary files /dev/null and b/packages/client/public/icon96.png differ diff --git a/packages/client/src/components/logo/index.tsx b/packages/client/src/components/logo/index.tsx index 2cc0bc3c..4cbc5106 100644 --- a/packages/client/src/components/logo/index.tsx +++ b/packages/client/src/components/logo/index.tsx @@ -5,29 +5,27 @@ import styles from './index.module.scss'; const { Text } = Typography; -export const LogoName = '云策文档'; +export const LogoName = process.env.SEO_APPNAME; export const LogoImage = () => { return ( - - + - - - + stroke="none" + > + + diff --git a/packages/client/src/components/seo.tsx b/packages/client/src/components/seo.tsx index 07cb0f9d..6db2c9fb 100644 --- a/packages/client/src/components/seo.tsx +++ b/packages/client/src/components/seo.tsx @@ -16,9 +16,6 @@ export const Seo: React.FC = ({ title, needTitleSuffix = true }) => { return ( {needTitleSuffix ? buildTitle(title) : title} - - - ); }; diff --git a/packages/client/src/pages/_app.tsx b/packages/client/src/pages/_app.tsx index 4b8bf747..d5fe24de 100644 --- a/packages/client/src/pages/_app.tsx +++ b/packages/client/src/pages/_app.tsx @@ -12,7 +12,31 @@ function MyApp({ Component, pageProps }: AppProps) { return ( <> - + + + + + + + + + + + + + + + + + + + + {((process.env.DNS_PREFETCH || []) as string[]).map((url) => ( + + ))} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5ff08bdd..22cb56a2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -291,6 +291,7 @@ importers: bcryptjs: ^2.4.3 class-transformer: ^0.5.1 class-validator: ^0.13.2 + compression: ^1.7.4 date-fns: ^2.28.0 eslint: ^8.14.0 eslint-config-prettier: ^8.5.0 @@ -346,6 +347,7 @@ importers: bcryptjs: 2.4.3 class-transformer: 0.5.1 class-validator: 0.13.2 + compression: 1.7.4 date-fns: 2.28.0 express: 4.17.2 express-rate-limit: 6.2.0_express@4.17.2 @@ -4302,6 +4304,11 @@ packages: readable-stream: 1.1.14 dev: false + /bytes/3.0.0: + resolution: {integrity: sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=} + engines: {node: '>= 0.8'} + dev: false + /bytes/3.1.1: resolution: {integrity: sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==} engines: {node: '>= 0.8'} @@ -4604,6 +4611,26 @@ packages: resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} dev: true + /compressible/2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.51.0 + dev: false + + /compression/1.7.4: + resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} + engines: {node: '>= 0.8.0'} + dependencies: + accepts: 1.3.7 + bytes: 3.0.0 + compressible: 2.0.18 + debug: 2.6.9 + on-headers: 1.0.2 + safe-buffer: 5.1.2 + vary: 1.1.2 + dev: false + /compute-scroll-into-view/1.0.17: resolution: {integrity: sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==} dev: false @@ -6042,7 +6069,7 @@ packages: dependencies: '@tootallnate/once': 1.1.2 data-uri-to-buffer: 3.0.1 - debug: 4.3.3 + debug: 4.3.4 file-uri-to-path: 2.0.0 fs-extra: 8.1.0 ftp: 0.3.10 @@ -8277,6 +8304,11 @@ packages: ee-first: 1.1.1 dev: false + /on-headers/1.0.2: + resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} + engines: {node: '>= 0.8'} + dev: false + /once/1.4.0: resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} dependencies: