diff --git a/.gitignore b/.gitignore index 763accc2d32d83..c532bdfab0dbc7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .DS_Store node_modules dist +dist-ssr TODOs.md *.log test/temp diff --git a/src/node/build/buildPluginHtml.ts b/src/node/build/buildPluginHtml.ts index 08a251837083dc..aa44636f45c9aa 100644 --- a/src/node/build/buildPluginHtml.ts +++ b/src/node/build/buildPluginHtml.ts @@ -73,9 +73,8 @@ export const createBuildHtmlPlugin = async ( } const renderIndex = ( - root: string, - cssFileName: string, - bundleOutput: RollupOutput['output'] + bundleOutput: RollupOutput['output'], + cssFileName: string ) => { // inject css link processedHtml = injectCSS(processedHtml, cssFileName) diff --git a/src/node/build/index.ts b/src/node/build/index.ts index 56b9fde7b862fe..fac9c9706354e5 100644 --- a/src/node/build/index.ts +++ b/src/node/build/index.ts @@ -55,6 +55,10 @@ export interface BuildOptions { factory?: string fragment?: string } + /** + * Build for server-side rendering + */ + ssr?: boolean // The following are API only and not documented in the CLI. ----------------- @@ -127,6 +131,11 @@ const writeColors = { * Returns a Promise containing the build result. */ export async function build(options: BuildOptions = {}): Promise { + if (options.ssr) { + delete options.ssr + return ssrBuild(options) + } + process.env.NODE_ENV = 'production' const start = Date.now() @@ -149,7 +158,7 @@ export async function build(options: BuildOptions = {}): Promise { sourcemap = false } = options - const indexPath = emitIndex ? path.resolve(root, 'index.html') : null + const indexPath = path.resolve(root, 'index.html') const publicBasePath = base.replace(/([^/])$/, '$1/') // ensure ending slash const resolvedAssetsPath = path.join(outDir, assetsDir) const cssFileName = 'style.css' @@ -244,7 +253,7 @@ export async function build(options: BuildOptions = {}): Promise { ...rollupOutputOptions }) - const indexHtml = renderIndex(root, cssFileName, output) + const indexHtml = emitIndex ? renderIndex(output, cssFileName) : '' if (write) { const cwd = process.cwd() @@ -307,9 +316,11 @@ export async function build(options: BuildOptions = {}): Promise { } // copy over /public if it exists - const publicDir = path.resolve(root, 'public') - if (await fs.pathExists(publicDir)) { - await fs.copy(publicDir, path.resolve(outDir, 'public')) + if (emitAssets) { + const publicDir = path.resolve(root, 'public') + if (await fs.pathExists(publicDir)) { + await fs.copy(publicDir, path.resolve(outDir, 'public')) + } } } @@ -344,6 +355,8 @@ export async function ssrBuild( } = options return build({ + outDir: path.resolve(options.root || process.cwd(), 'dist-ssr'), + assetsDir: '.', ...options, rollupPluginVueOptions: { ...rollupPluginVueOptions, diff --git a/src/node/cli.ts b/src/node/cli.ts index e586097bd4ba45..5f2c8a29243942 100644 --- a/src/node/cli.ts +++ b/src/node/cli.ts @@ -27,6 +27,7 @@ Options: --sourcemap [boolean] output source maps for build (default: false) --minify [boolean | 'terser' | 'esbuild'] disable minification, or specify minifier to use. (default: 'terser') + --ssr [boolean] build for server-side rendering --jsx-factory [string] (default: React.createElement) --jsx-fragment [string] (default: React.Fragment) `)