可以将./server.ts本身设置为SSR构建的入口点吗?

问题描述 投票:0回答:1

我使用

pnpm create vite
搭建了一个新的vite项目。为了使其可重复,这些是我在出现提示时的选择:

  • 选择框架:其他
  • 选择一个变体:create-vite-extra
  • 选择模板:ssr-vue
  • 选择一个变体:非流媒体
  • 选择一个变体:TypeScript

我想使用 TypeScript 来生成生成的

./server.js
,而不仅仅是
./src
中的代码,所以我将
server.js
“转换”(即现在重命名)为
server.ts

此时我意识到我必须自己构建

./server.ts
,并让 vite 构建所谓的服务器端入口点
./src/entry-server.ts

我使用 vite 来避免必须配置构建 TypeScript 的噩梦,所以我想知道将

./server.ts
本身设置为 SSR 构建的入口点是否可行?这样,SSR 仍然可以工作。

我陷入困境的部分是如何实际导入

./src/entry-server.ts
,现在
./server.ts
是我的入口点(即
render = (await import('./dist/server/entry-server.js')).render
现在不再构建
entry-server.js
不再工作)。

typescript vue.js vite server-side-rendering
1个回答
0
投票

我有一些工作。这是我所做的,以防对其他人有用:

./vite.config.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path';

import { PORT, STATIC_URL } from './src/lib/env';

export default defineConfig(({ command, mode }) => {
  const buildTarget = process.env.BUILD_TARGET;

  // Common configuration used for both dev and building.
  const baseConfig = {
    plugins: [vue()],
    server: {
      host: '127.0.0.1',
      port: PORT,
      hmr: {
        host: '127.0.0.1',
      },
    },    
    resolve: {
      alias: {
        '@': path.resolve(__dirname, 'src')
      }
    }
  };

  // Build-specific options
  if (buildTarget === 'entry-client') {
    return {
      ...baseConfig,
      base: STATIC_URL,
      build: {
        outDir: 'dist/client'
      }
    };
  } else if (buildTarget === 'entry-server') {
    return {
      ...baseConfig,
      base: STATIC_URL,
      build: {
        manifest: true,
        ssr: 'src/entry-server.ts',
        outDir: 'dist/server'
      }
    };
  } else if (buildTarget === 'node-server') {
    return {
      ...baseConfig,
      publicDir: false,
      base: STATIC_URL,
      build: {
        ssr: 'server.ts',
        outDir: 'dist/node',
      }
    };
  } else {
    return baseConfig;
  }
});

package.json
脚本部分:

  "scripts": {
    "build:ssr-entry-client": "BUILD_TARGET=entry-client vite build",
    "build:ssr-entry-server": "BUILD_TARGET=entry-server vite build",
    "build:ssr-node-server": "BUILD_TARGET=node-server vite build",
    "build:ssr": "npm run build:ssr-entry-client && npm run build:ssr-entry-server && npm run build:ssr-node-server",
    "dev": "nodemon --exec tsx server.ts --watch server.ts --watch src --ext ts,js --ignore dist --ignore node_modules",
    "prod": "pnpm build:ssr && NODE_ENV=production node dist/node/server.js"
  },

最后,在我的 server.ts 中,我有一个解析实用程序来绝对解析路径:

// Detect absolute path to /frontend
function getRootDir(): string {
  const currentPath = process.cwd();
  const frontendIndex = currentPath.indexOf('/frontend');
  return currentPath.slice(0, frontendIndex + '/frontend'.length);
}
const rootDir = getRootDir();

function resolve(p: string): string {
  return path.resolve(rootDir, p);
}

// Wrap server creation to avoid top level await's.
async function createServer() {
  // Cached page chrome
  const templateHtml = isProduction
    ? await fs.readFile(resolve('dist/client/index.html'), 'utf-8')
    : ''
...

使用我的

resolve
实用程序进行动态文件加载/导入的一个副作用是导入
import render = (await import(resolve('dist/server/entry-server.js'))).render
(注意它现在被包裹在
resolve
中),这在我的问题中对我来说是有问题的,现在对vite来说是不透明的,因此对于
node-server
构建,vite 不会为
entry-server.js
及其传递依赖项生成资产。在这一点上,这对我来说似乎是一次幸福的意外;我已经把所有的东西都内置了
dist/server

© www.soinside.com 2019 - 2024. All rights reserved.