ssr-plugin-react 6.2.70 → 6.2.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
- ssr-plugin-react:build: cache hit, replaying output 499ad528bd0d3598
1
+ ssr-plugin-react:build: cache hit, replaying output 01b00897ba7382a0
2
2
  ssr-plugin-react:build:
3
- ssr-plugin-react:build: > ssr-plugin-react@6.2.70 build /home/runner/work/ssr/ssr/packages/plugin-react
3
+ ssr-plugin-react:build: > ssr-plugin-react@6.2.71 build /home/runner/work/ssr/ssr/packages/plugin-react
4
4
  ssr-plugin-react:build: > concurrently "tsc -p ./tsconfig.cjs.json " " tsc -p ./tsconfig.esm.json"
5
5
  ssr-plugin-react:build:
6
- ssr-plugin-react:build: [0] tsc -p ./tsconfig.cjs.json exited with code 0
7
6
  ssr-plugin-react:build: [1] tsc -p ./tsconfig.esm.json exited with code 0
7
+ ssr-plugin-react:build: [0] tsc -p ./tsconfig.cjs.json exited with code 0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## [6.2.71](https://github.com/zhangyuang/ssr/compare/plugin-react@6.2.70...plugin-react@6.2.71) (2024-01-27)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * plugin-react close[#321](https://github.com/zhangyuang/ssr/issues/321) ([a1b69f8](https://github.com/zhangyuang/ssr/commit/a1b69f8ba467b86d3d7fc1fc63d78f97bf3b8afb))
7
+
8
+
9
+
1
10
  ## [6.2.70](https://github.com/zhangyuang/ssr/compare/plugin-react@6.2.69...plugin-react@6.2.70) (2024-01-24)
2
11
 
3
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ssr-plugin-react",
3
- "version": "6.2.70",
3
+ "version": "6.2.71",
4
4
  "description": "plugin-react for ssr",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./esm/index.js",
@@ -0,0 +1,65 @@
1
+
2
+ import { join } from 'path'
3
+ import { Mode } from 'ssr-types'
4
+ import { getCwd, loadConfig, setStyle, loadModuleFromFramework, getBuildConfig, addCommonChain } from 'ssr-common-utils'
5
+ import * as WebpackChain from 'webpack-chain'
6
+ import * as webpack from 'ssr-webpack4'
7
+
8
+ const MiniCssExtractPlugin = require(loadModuleFromFramework('ssr-mini-css-extract-plugin'))
9
+ const WebpackBar = require('webpackbar')
10
+
11
+ const getBaseConfig = (chain: WebpackChain, isServer: boolean) => {
12
+ const config = loadConfig()
13
+ const { moduleFileExtensions, chainBaseConfig, alias, define } = config
14
+ const mode = process.env.NODE_ENV as Mode
15
+
16
+ chain.mode(mode)
17
+ chain.module.strictExportPresence(true)
18
+ chain
19
+ .resolve
20
+ .modules
21
+ .add('node_modules')
22
+ .add(join(getCwd(), './node_modules'))
23
+ .end()
24
+ .extensions.merge(moduleFileExtensions)
25
+ .end()
26
+ .alias
27
+ .end()
28
+
29
+ alias && Object.keys(alias).forEach(item => {
30
+ chain.resolve.alias
31
+ .set(item, alias[item])
32
+ })
33
+ addCommonChain(chain, isServer)
34
+ setStyle(chain, /\.css$/, {
35
+ rule: 'css',
36
+ isServer,
37
+ importLoaders: 1
38
+ })
39
+
40
+ setStyle(chain, /\.less$/, {
41
+ rule: 'less',
42
+ loader: 'less-loader',
43
+ isServer,
44
+ importLoaders: 2
45
+ })
46
+
47
+ chain.plugin('minify-css').use(MiniCssExtractPlugin, getBuildConfig().cssBuildConfig)
48
+
49
+ chain.plugin('webpackBar').use(new WebpackBar({
50
+ name: isServer ? 'server' : 'client',
51
+ color: isServer ? '#f173ac' : '#45b97c'
52
+ }))
53
+ chain.plugin('ssrDefine').use(webpack.DefinePlugin, [{
54
+ ...process.env,
55
+ __isBrowser__: !isServer,
56
+ ...(isServer ? define?.server : define?.client),
57
+ ...define?.base
58
+ }])
59
+ chainBaseConfig(chain, isServer)
60
+ return config
61
+ }
62
+
63
+ export {
64
+ getBaseConfig
65
+ }
@@ -0,0 +1,66 @@
1
+ import { loadConfig, getSplitChunksOptions, getOutputPublicPath, loadModuleFromFramework, getBuildConfig, terserConfig, asyncChunkMap } from 'ssr-common-utils'
2
+ import * as WebpackChain from 'webpack-chain'
3
+ import { getBaseConfig } from './base'
4
+
5
+ const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin')
6
+ const safePostCssParser = require('postcss-safe-parser')
7
+ const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
8
+ const loadModule = loadModuleFromFramework
9
+
10
+ const getClientWebpack = (chain: WebpackChain) => {
11
+ const { isDev, chunkName, getOutput, cwd, chainClientConfig, host, fePort } = loadConfig()
12
+ const buildConfig = getBuildConfig()
13
+
14
+ const shouldUseSourceMap = isDev || Boolean(process.env.GENERATE_SOURCEMAP)
15
+ const publicPath = getOutputPublicPath()
16
+ getBaseConfig(chain, false)
17
+ chain.devtool(isDev ? 'eval-source-map' : (shouldUseSourceMap ? 'source-map' : false))
18
+ chain.entry(chunkName)
19
+ .add(require.resolve('../entry/client-entry'))
20
+ .end()
21
+ .output
22
+ .path(getOutput().clientOutPut)
23
+ .filename(buildConfig.jsBuldConfig.fileName)
24
+ .chunkFilename(buildConfig.jsBuldConfig.chunkFileName)
25
+ .publicPath(publicPath)
26
+ .end()
27
+ chain.optimization
28
+ .runtimeChunk(true)
29
+ .splitChunks(getSplitChunksOptions(asyncChunkMap))
30
+ .when(!isDev, optimization => {
31
+ optimization.minimizer('terser')
32
+ .use(loadModule('terser-webpack-plugin'), [terserConfig()])
33
+ optimization.minimizer('optimize-css').use(loadModule('optimize-css-assets-webpack-plugin'), [{
34
+ cssProcessorOptions: {
35
+ parser: safePostCssParser,
36
+ map: shouldUseSourceMap ? {
37
+ inline: false,
38
+ annotation: true
39
+ } : false
40
+ }
41
+ }])
42
+ })
43
+
44
+ chain.plugin('moduleNotFound').use(ModuleNotFoundPlugin, [cwd])
45
+
46
+ chain.plugin('manifest').use(loadModule('webpack-manifest-plugin'), [{
47
+ fileName: 'asset-manifest.json'
48
+ }])
49
+
50
+ chain.when(isDev, chain => {
51
+ chain.plugin('fast-refresh').use(new ReactRefreshWebpackPlugin({
52
+ overlay: {
53
+ sockHost: host,
54
+ sockPort: fePort
55
+ }
56
+ }))
57
+ })
58
+
59
+ chainClientConfig(chain) // 合并用户自定义配置
60
+
61
+ return chain.toConfig()
62
+ }
63
+
64
+ export {
65
+ getClientWebpack
66
+ }
@@ -0,0 +1,2 @@
1
+ export * from './client'
2
+ export * from './server'
@@ -0,0 +1,56 @@
1
+ import { join } from 'path'
2
+ import { loadConfig, nodeExternals, loadModuleFromFramework } from 'ssr-common-utils'
3
+ import * as WebpackChain from 'webpack-chain'
4
+ import * as webpack from 'ssr-webpack4'
5
+
6
+ import { getBaseConfig } from './base'
7
+
8
+ const getServerWebpack = (chain: WebpackChain) => {
9
+ const config = loadConfig()
10
+ const { isDev, cwd, getOutput, chainServerConfig, whiteList, chunkName } = config
11
+ const shouldUseSourceMap = isDev || Boolean(process.env.GENERATE_SOURCEMAP)
12
+ getBaseConfig(chain, true)
13
+ chain.devtool(isDev ? 'inline-source-map' : false)
14
+ chain.target('node')
15
+ chain.entry(chunkName)
16
+ .add(require.resolve('../entry/server-entry'))
17
+ .end()
18
+ .output
19
+ .path(getOutput().serverOutPut)
20
+ .filename('[name].server.js')
21
+ .libraryTarget('commonjs')
22
+
23
+ const modulesDir = [join(cwd, './node_modules')]
24
+ chain.externals(nodeExternals({
25
+ whitelist: whiteList,
26
+ // externals Dir contains example/xxx/node_modules ssr/node_modules
27
+ modulesDir
28
+ }))
29
+ if (!isDev) {
30
+ chain.optimization.minimizer('terser')
31
+ .use(loadModuleFromFramework('terser-webpack-plugin'), [{
32
+ terserOptions: {
33
+ keep_fnames: true
34
+ },
35
+ extractComments: false,
36
+ parallel: true,
37
+ cache: true,
38
+ sourceMap: shouldUseSourceMap
39
+ }])
40
+ }
41
+ chain.when(isDev, () => {
42
+ chain.watch(true)
43
+ })
44
+
45
+ chain.plugin('serverLimit').use(webpack.optimize.LimitChunkCountPlugin, [{
46
+ maxChunks: 1
47
+ }])
48
+
49
+ chainServerConfig(chain) // 合并用户自定义配置
50
+
51
+ return chain.toConfig()
52
+ }
53
+
54
+ export {
55
+ getServerWebpack
56
+ }
@@ -0,0 +1,57 @@
1
+ import { createElement } from 'react'
2
+ import * as ReactDOM from 'react-dom'
3
+ import { proxy } from 'valtio'
4
+ import 'react-router' // for vite prebundle list
5
+ import { BrowserRouter, Route, Switch } from 'react-router-dom'
6
+ import { preloadComponent, isMicro, setStoreContext, setStore } from 'ssr-common-utils'
7
+ import { wrapComponent } from 'ssr-hoc-react'
8
+ import { LayoutProps } from 'ssr-types'
9
+ import { STORE_CONTEXT as Context } from '_build/create-context'
10
+ import { Routes } from './create-router'
11
+ import { AppContext } from './context'
12
+
13
+ const { FeRoutes, layoutFetch, App, store } = Routes
14
+
15
+ const clientRender = async (): Promise<void> => {
16
+ const IApp = App ?? function (props: LayoutProps) {
17
+ return props.children!
18
+ }
19
+ setStoreContext(Context)
20
+ for (const key in store) {
21
+ store[key] = proxy(window.__VALTIO_DATA__?.[key])
22
+ }
23
+ setStore(store ?? {})
24
+ const baseName = isMicro() ? window.clientPrefix : window.prefix
25
+ const routes = await preloadComponent(FeRoutes, baseName)
26
+ ReactDOM[window.__USE_SSR__ ? 'hydrate' : 'render'](
27
+ createElement(BrowserRouter, {
28
+ basename: baseName
29
+ }, createElement(AppContext as any, {
30
+ children: createElement(Switch, null,
31
+ createElement(IApp as any, null, createElement(Switch, null,
32
+ routes.map(item => {
33
+ const { fetch, component, path } = item
34
+ component.fetch = fetch
35
+ component.layoutFetch = layoutFetch
36
+ const WrappedComponent = wrapComponent(component)
37
+ return createElement(Route, {
38
+ exact: true,
39
+ key: path,
40
+ path: path,
41
+ render: () => createElement(WrappedComponent, {
42
+ key: location.pathname
43
+ })
44
+ })
45
+ }))))
46
+ }))
47
+ , document.querySelector(window.ssrDevInfo.rootId ?? '#app'))
48
+ if (!window.__USE_VITE__) {
49
+ (module as any)?.hot?.accept?.()
50
+ }
51
+ }
52
+
53
+ clientRender()
54
+
55
+ export {
56
+ clientRender
57
+ }
@@ -0,0 +1,40 @@
1
+ import { useReducer, createElement } from 'react'
2
+ import { IProps, Action, IWindow, ReactRoutesType } from 'ssr-types'
3
+ import { STORE_CONTEXT as Context } from '_build/create-context'
4
+ import { Routes } from './create-router'
5
+
6
+ const { reducer, state } = Routes as ReactRoutesType
7
+
8
+ const userState = state ?? {}
9
+ const userReducer = reducer ?? function () {}
10
+
11
+ const isDev = process.env.NODE_ENV !== 'production'
12
+
13
+ // 客户端的 context 只需要创建一次,在页面整个生命周期内共享
14
+ declare const window: IWindow
15
+
16
+ function defaultReducer (state: any, action: Action) {
17
+ switch (action.type) {
18
+ case 'updateContext':
19
+ if (isDev) {
20
+ console.log('[SSR:updateContext]: dispatch updateContext with action')
21
+ console.log(action)
22
+ }
23
+ return { ...state, ...action.payload }
24
+ }
25
+ }
26
+
27
+ const initialState = Object.assign({}, userState ?? {}, window.__INITIAL_DATA__)
28
+
29
+ function combineReducer (state: any, action: any) {
30
+ return defaultReducer(state, action) || userReducer(state, action)
31
+ }
32
+ export function AppContext (props: IProps) {
33
+ const [state, dispatch] = useReducer(combineReducer, initialState)
34
+ return createElement(Context.Provider, {
35
+ value: {
36
+ state,
37
+ dispatch
38
+ }
39
+ }, props.children)
40
+ }
@@ -0,0 +1,19 @@
1
+ // The file is provisional,don't modify it
2
+
3
+ import { Context, createContext } from 'react'
4
+ import { IContext } from 'ssr-types'
5
+ let STORE_CONTEXT: Context<IContext>
6
+ if (__isBrowser__) {
7
+ STORE_CONTEXT = window.STORE_CONTEXT || createContext<IContext>({
8
+ state: {}
9
+ })
10
+ window.STORE_CONTEXT = STORE_CONTEXT
11
+ } else {
12
+ STORE_CONTEXT = createContext<IContext>({
13
+ state: {}
14
+ })
15
+ }
16
+
17
+ export {
18
+ STORE_CONTEXT
19
+ }
@@ -0,0 +1,10 @@
1
+ import { combineRoutes } from 'ssr-common-utils'
2
+ import * as declareRoutes from '_build/ssr-declare-routes'
3
+ import * as ManualRoutes from '_build/ssr-manual-routes'
4
+ import { ReactRoutesType } from 'ssr-types'
5
+
6
+ const Routes = combineRoutes(declareRoutes, ManualRoutes) as ReactRoutesType
7
+
8
+ export {
9
+ Routes
10
+ }
@@ -0,0 +1,106 @@
1
+ import { PassThrough } from 'stream'
2
+ import * as React from 'react'
3
+ import { createElement } from 'react'
4
+ import { StaticRouter } from 'react-router-dom'
5
+ import { renderToString, renderToNodeStream } from 'react-dom/server'
6
+ import { findRoute, getManifest, logGreen, normalizePath, getAsyncCssChunk, getAsyncJsChunk, splitPageInfo, reactRefreshFragment, localStorageWrapper, checkRoute, useStore } from 'ssr-common-utils'
7
+ import { ISSRContext, IConfig, ReactESMPreloadFeRouteItem, DynamicFC, StaticFC } from 'ssr-types'
8
+ import { serialize } from 'ssr-serialize-javascript'
9
+ import { STORE_CONTEXT as Context } from '_build/create-context'
10
+ import { Routes } from './create-router'
11
+
12
+ const { FeRoutes, layoutFetch, state, Layout, store } = Routes
13
+
14
+ const serverRender = async (ctx: ISSRContext, config: IConfig) => {
15
+ const { mode, parallelFetch, prefix, isVite, isDev, clientPrefix, stream, rootId, hashRouter } = config
16
+ const rawPath = ctx.request.path ?? ctx.request.url
17
+ const path = normalizePath(rawPath, prefix)
18
+ const routeItem = findRoute<ReactESMPreloadFeRouteItem>(FeRoutes, path)
19
+ checkRoute({ routeItem, path })
20
+ const { fetch, webpackChunkName, component } = routeItem
21
+
22
+ const fn = async () => {
23
+ const dynamicCssOrder = await getAsyncCssChunk(ctx, webpackChunkName, config)
24
+ const dynamicJsOrder = await getAsyncJsChunk(ctx, webpackChunkName, config)
25
+ const manifest = await getManifest(config)
26
+
27
+ const injectCss = ((isVite && isDev) ? [
28
+ <script src="/@vite/client" type="module" key="vite-client" />,
29
+ <script key="vite-react-refresh" type="module" dangerouslySetInnerHTML={{
30
+ __html: reactRefreshFragment
31
+ }} />
32
+ ] : dynamicCssOrder.map(css => manifest[css]).filter(Boolean).map(css => <link rel='stylesheet' key={css} href={css} />))
33
+ .concat((isVite && isDev) ? [] : dynamicJsOrder.map(js => manifest[js]).filter(Boolean).map(js =>
34
+ <link href={js} as="script" rel={isVite ? 'modulepreload' : 'preload'} key={js} />
35
+ ))
36
+
37
+ const injectScript = [
38
+ ...(isVite ? [<script key="viteWindowInit" dangerouslySetInnerHTML={{
39
+ __html: 'window.__USE_VITE__=true'
40
+ }} />] : []),
41
+ ...((isVite && isDev) ? [<script type="module" src='/node_modules/ssr-plugin-react/esm/entry/client-entry.js' key="vite-react-entry" />] : []),
42
+ ...dynamicJsOrder.map(js => manifest[js]).filter(Boolean).map(item => <script key={item} src={item} type={isVite ? 'module' : 'text/javascript'} />)
43
+ ]
44
+ const staticList = {
45
+ injectCss,
46
+ injectScript
47
+ }
48
+
49
+ const isCsr = !!(mode === 'csr' || ctx.request.query?.csr)
50
+ const Component = isCsr ? React.Fragment : (component.name === 'dynamicComponent' ? (await (component as DynamicFC)()).default : component as StaticFC)
51
+
52
+ if (isCsr) {
53
+ logGreen(`Current path ${path} use csr render mode`)
54
+ }
55
+
56
+ let [layoutFetchData, fetchData] = [{}, {}]
57
+
58
+ if (!isCsr) {
59
+ const currentFetch = fetch ? (await fetch()).default : null
60
+ const lF = layoutFetch ? layoutFetch({ ctx }) : Promise.resolve({})
61
+ const CF = currentFetch ? currentFetch({ ctx }) : Promise.resolve({});
62
+ [layoutFetchData, fetchData] = parallelFetch ? await Promise.all([lF, CF]) : [await lF, await CF]
63
+ }
64
+
65
+ const combineData = isCsr ? null : Object.assign(state ?? {}, layoutFetchData ?? {}, fetchData ?? {})
66
+ const ssrDevInfo = { manifest: isDev ? manifest : '', rootId }
67
+ const innerHTML = splitPageInfo({
68
+ 'window.__USE_SSR__': !isCsr,
69
+ 'window.__INITIAL_DATA__': isCsr ? {} : serialize(combineData),
70
+ 'window.__USE_VITE__': isVite,
71
+ 'window.prefix': `"${prefix}"`,
72
+ 'window.clientPrefix': `"${clientPrefix ?? ''}"`,
73
+ 'window.ssrDevInfo': JSON.stringify(ssrDevInfo),
74
+ 'window.hashRouter': Boolean(hashRouter),
75
+ 'window.__VALTIO_DATA__': isCsr ? {} : serialize(useStore())
76
+ })
77
+ const injectState = <script dangerouslySetInnerHTML={{ __html: innerHTML }} />
78
+ // with jsx type error, use createElement here
79
+ const ele = createElement(StaticRouter, {
80
+ location: ctx.request.url,
81
+ basename: prefix === '/' ? undefined : prefix
82
+ }, createElement(Context.Provider, {
83
+ value: {
84
+ state: combineData
85
+ }
86
+ }, createElement(Layout, {
87
+ ctx: ctx,
88
+ config: config,
89
+ staticList: staticList,
90
+ injectState: injectState
91
+ }, createElement(Component, null))))
92
+ // for ctx.body will loose asynclocalstorage context, consume stream in advance like vue2/3
93
+ return stream ? renderToNodeStream(ele).pipe(new PassThrough()) : renderToString(ele)
94
+ }
95
+
96
+ return await localStorageWrapper.run({
97
+ context: Context,
98
+ ctx,
99
+ store
100
+ }, fn)
101
+ }
102
+
103
+ export {
104
+ serverRender,
105
+ Routes
106
+ }
package/src/index.ts ADDED
@@ -0,0 +1,49 @@
1
+ import { loadConfig } from 'ssr-common-utils'
2
+
3
+ const { isVite, optimize } = loadConfig()
4
+ const spinner = require('ora')('Building')
5
+
6
+ export function clientPlugin () {
7
+ return {
8
+ name: 'plugin-react',
9
+ start: async () => {
10
+ if (isVite) {
11
+ const { viteStart } = await import('./tools/vite')
12
+ await viteStart()
13
+ } else {
14
+ if (optimize) {
15
+ spinner.start()
16
+ const { viteBuildClient } = await import('./tools/vite')
17
+ await viteBuildClient()
18
+ process.env.NODE_ENV = 'development'
19
+ spinner.stop()
20
+ const { webpackStart } = await import('./tools/webpack')
21
+ await webpackStart()
22
+ } else {
23
+ const { webpackStart } = await import('./tools/webpack')
24
+ await webpackStart()
25
+ }
26
+ }
27
+ },
28
+ build: async () => {
29
+ if (isVite) {
30
+ const { viteBuild } = await import('./tools/vite')
31
+ await viteBuild()
32
+ } else {
33
+ if (optimize) {
34
+ spinner.start()
35
+ const { viteBuildClient } = await import('./tools/vite')
36
+ await viteBuildClient()
37
+ spinner.stop()
38
+ const { webpackBuild } = await import('./tools/webpack')
39
+ await webpackBuild()
40
+ } else {
41
+ const { webpackBuild } = await import('./tools/webpack')
42
+ await webpackBuild()
43
+ }
44
+ }
45
+ }
46
+ }
47
+ }
48
+
49
+ export * from './tools/vite'
@@ -0,0 +1,147 @@
1
+ import { build, UserConfig } from 'vite'
2
+ import {
3
+ loadConfig, chunkNamePlugin, rollupOutputOptions, manifestPlugin, commonConfig,
4
+ asyncOptimizeChunkPlugin, getOutputPublicPath, judgeAntd
5
+ } from 'ssr-common-utils'
6
+ import react from '@vitejs/plugin-react'
7
+ import { createStyleImportPlugin, AndDesignVueResolve, VantResolve, ElementPlusResolve, NutuiResolve, AntdResolve } from 'ssr-vite-plugin-style-import'
8
+ const { getOutput, reactServerEntry, reactClientEntry, viteConfig, supportOptinalChaining, isDev, define, babelOptions, optimize } = loadConfig()
9
+ const { clientOutPut, serverOutPut } = getOutput()
10
+ const isAntd5 = judgeAntd() === 5
11
+ const extraInclude = ([] as string[]).concat(isAntd5 ? ['react-is'] : [])
12
+
13
+ const styleImportConfig = {
14
+ include: ['**/*.vue', '**/*.ts', '**/*.js', '**/*.tsx', '**/*.jsx', /chunkName/],
15
+ resolves: [
16
+ AndDesignVueResolve(),
17
+ VantResolve(),
18
+ ElementPlusResolve(),
19
+ NutuiResolve(),
20
+ AntdResolve()
21
+ ]
22
+ }
23
+ const serverPlugins = [
24
+ react({
25
+ ...viteConfig?.()?.server?.defaultPluginOptions,
26
+ jsxRuntime: 'automatic',
27
+ babel: {
28
+ ...babelOptions,
29
+ plugins: [
30
+ ...babelOptions?.plugins ?? [],
31
+ ...!supportOptinalChaining ? [
32
+ '@babel/plugin-proposal-optional-chaining',
33
+ '@babel/plugin-proposal-nullish-coalescing-operator'
34
+ ] : []
35
+ ]
36
+ }
37
+ }),
38
+ viteConfig?.()?.common?.extraPlugin,
39
+ viteConfig?.()?.server?.extraPlugin,
40
+ createStyleImportPlugin(styleImportConfig)
41
+ ].filter(Boolean)
42
+
43
+ const serverConfig: UserConfig = {
44
+ ...commonConfig(),
45
+ ...viteConfig?.().server?.otherConfig,
46
+ plugins: viteConfig?.()?.server?.processPlugin?.(serverPlugins) ?? serverPlugins,
47
+ esbuild: {
48
+ ...viteConfig?.().server?.otherConfig?.esbuild,
49
+ keepNames: true,
50
+ logOverride: { 'this-is-undefined-in-esm': 'silent' }
51
+ },
52
+ optimizeDeps: {
53
+ ...viteConfig?.().server?.otherConfig?.optimizeDeps,
54
+ include: extraInclude.concat(...viteConfig?.().server?.otherConfig?.optimizeDeps?.include ?? []),
55
+ esbuildOptions: {
56
+ ...viteConfig?.().server?.otherConfig?.optimizeDeps?.esbuildOptions,
57
+ // @ts-expect-error
58
+ bundle: isDev
59
+ }
60
+ },
61
+ build: {
62
+ ...viteConfig?.().server?.otherConfig?.build,
63
+ ssr: reactServerEntry,
64
+ outDir: serverOutPut,
65
+ rollupOptions: {
66
+ ...viteConfig?.().server?.otherConfig?.build?.rollupOptions,
67
+ input: isDev ? reactClientEntry : reactServerEntry, // setting prebundle list by client-entry in dev
68
+ output: {
69
+ entryFileNames: 'Page.server.js',
70
+ assetFileNames: rollupOutputOptions().assetFileNames
71
+ }
72
+ }
73
+ },
74
+ define: {
75
+ ...viteConfig?.().server?.otherConfig?.define,
76
+ __isBrowser__: false,
77
+ ...define?.base,
78
+ ...define?.server
79
+ }
80
+ }
81
+ const clientPlugins = [
82
+ react({
83
+ ...viteConfig?.()?.client?.defaultPluginOptions,
84
+ jsxRuntime: 'automatic',
85
+ ...babelOptions
86
+ }),
87
+ viteConfig?.()?.common?.extraPlugin,
88
+ viteConfig?.()?.client?.extraPlugin,
89
+ createStyleImportPlugin(styleImportConfig)
90
+ ].filter(Boolean)
91
+ const clientConfig: UserConfig = {
92
+ ...commonConfig(),
93
+ ...viteConfig?.().client?.otherConfig,
94
+ base: isDev ? '/' : getOutputPublicPath(),
95
+ esbuild: {
96
+ ...viteConfig?.().client?.otherConfig?.esbuild,
97
+ keepNames: true,
98
+ logOverride: { 'this-is-undefined-in-esm': 'silent' }
99
+ },
100
+ optimizeDeps: {
101
+ ...viteConfig?.().client?.otherConfig?.optimizeDeps,
102
+ include: ['react-router', ...extraInclude].concat(...viteConfig?.().client?.otherConfig?.optimizeDeps?.include ?? []),
103
+ exclude: ['ssr-hoc-react'].concat(...viteConfig?.().client?.otherConfig?.optimizeDeps?.exclude ?? [])
104
+ },
105
+ plugins: viteConfig?.()?.client?.processPlugin?.(clientPlugins) ?? clientPlugins,
106
+ build: {
107
+ ...viteConfig?.().client?.otherConfig?.build,
108
+ ...(optimize ? { write: false } : {}),
109
+ ssrManifest: true,
110
+ outDir: clientOutPut,
111
+ rollupOptions: {
112
+ ...viteConfig?.().client?.otherConfig?.build?.rollupOptions,
113
+ input: reactClientEntry,
114
+ output: rollupOutputOptions(),
115
+ plugins: [chunkNamePlugin(), asyncOptimizeChunkPlugin(), manifestPlugin()]
116
+ }
117
+ },
118
+ define: {
119
+ ...viteConfig?.().client?.otherConfig?.define,
120
+ __isBrowser__: true,
121
+ ...define?.base,
122
+ ...define?.client
123
+ }
124
+ }
125
+ const viteStart = async () => {
126
+ //
127
+ }
128
+ const viteBuild = async () => {
129
+ await build({ ...clientConfig, mode: 'production' })
130
+ await build({ ...serverConfig, mode: 'production' })
131
+ }
132
+
133
+ const viteBuildClient = async () => {
134
+ await build({ ...clientConfig, mode: 'production' }).catch(_ => { })
135
+ }
136
+ const viteBuildServer = async () => {
137
+ await build({ ...serverConfig, mode: 'production' })
138
+ }
139
+
140
+ export {
141
+ viteBuild,
142
+ viteStart,
143
+ serverConfig,
144
+ clientConfig,
145
+ viteBuildClient,
146
+ viteBuildServer
147
+ }
@@ -0,0 +1,20 @@
1
+ import * as WebpackChain from 'webpack-chain'
2
+
3
+ export const webpackStart = async () => {
4
+ const { startServerBuild } = await import('ssr-webpack/cjs/server')
5
+ const { getServerWebpack } = await import('../config/server')
6
+ const serverConfigChain = new WebpackChain()
7
+
8
+ const { startClientServer } = await import('ssr-webpack')
9
+ const { getClientWebpack } = await import('../config')
10
+ const clientConfigChain = new WebpackChain()
11
+ await Promise.all([startServerBuild(getServerWebpack(serverConfigChain)), startClientServer(getClientWebpack(clientConfigChain))])
12
+ }
13
+
14
+ export const webpackBuild = async () => {
15
+ const { startServerBuild, startClientBuild } = await import('ssr-webpack')
16
+ const { getClientWebpack, getServerWebpack } = await import('../config')
17
+ const serverConfigChain = new WebpackChain()
18
+ const clientConfigChain = new WebpackChain()
19
+ await Promise.all([startServerBuild(getServerWebpack(serverConfigChain)), startClientBuild(getClientWebpack(clientConfigChain))])
20
+ }