Universal-webpack服务端渲染

厉令
2023-12-01

Universal-webpack

帮助搭建用于同构,即同时可以在客户端和服务端使用的Webpack。

Demo

我的Demo:universal-webpack + koa + react + webpack。
官方Demo

Webpack 2

目前仅支持Webpack2.

npm install webpack --save
npm install extract-text-webpack-plugin --save   

使用

以往我们会创建一个标准的 webpack.config.js 。
此时,我们需要创建另外两个配置文件:webpack.config.client.babel.js 和 webpack.config.client.babel.js。如下:

webpack.config.client.babel.js

import { client } from 'universal-webpack/config'
import settings from './universal-webpack-settings'
import configuration from './webpack.config'

export default client(configuration, settings)

代替webpack.config.js来完成客户端的打包。

webpack.config.server.babel.js

import { server } from 'universal-webpack/config'
import settings from './universal-webpack-settings'
import configuration from './webpack.config'

export default server(configuration, settings)

universal-webpack-settings.json

{
    "server":
    {
        "input": "./source/server.js",
        "output": "./build/server/server.js"
    }
}

output所对应的文件由input对应的文件使用Webpack根据webpack.config.server.babel.js中的配置生成。

server.js

服务器启动,官方Demo如下:

// express.js
import path from 'path'
import http from 'http'
import express from 'express'
import http_proxy from 'http-proxy'

// react-router
import routes from '../client/routes.js'

// Redux
import store from '../client/store.js'

// The server code must export a function
// (`parameters` may contain some miscellaneous library-specific stuff)
export default function(parameters)
{
    // Create HTTP server
    const app = new express()
    const server = new http.Server(app)

    // Serve static files
    app.use(express.static(path.join(__dirname, '..', 'build/assets')))

    // Proxy API calls to API server
    const proxy = http_proxy.createProxyServer({ target: 'http://localhost:xxxx' })
    app.use('/api', (req, res) => proxy.web(req, res))

    // React application rendering
    app.use((req, res) =>
    {
        // Match current URL to the corresponding React page
        // (can use `react-router`, `redux-router`, `react-router-redux`, etc)
        react_router_match_url(routes, req.originalUrl).then((error, result) =>
        {
            if (error)
            {
                res.status(500)
                return res.send('Server error')
            }

            // Render React page

            const page = redux.provide(result, store)

            res.status(200)
            res.send('<!doctype html>' + '\n' + ReactDOM.renderToString(<Html>{page}</Html>))
        })
    })

    // Start the HTTP server
    server.listen()
}

但这个文件不是真正的入口文件,需要另一个文件,我们需要另一个文件来启动服务。

start-server.js

var startServer = require('universal-webpack/server')
var settings = require('../universal-webpack-settings')
// `configuration.context` and `configuration.output.path` are used
var configuration = require('../webpack.config')

startServer(configuration, settings)

调用这个入口文件,实质上是调用了通过Webpack打包之后的server.js。

开发环境的启动命令大致如下:

webpack-dev-server --hot --inline --config "./webpack.config.client.babel.js" --port XXXX --colors --display-error-details
//启动一个webpack-dev-server,真正的Development Server会从这里请求一些静态文件(比如:boundle.js)。
//Universal-webpack不会再服务端释放任何资源,所有资源都在客户端)。
webpack --watch --config "./webpack.config.server.babel.js" --colors --display-error-details
//打包服务端代码
nodemon "./source/start-server" --watch "./build/server"
启动服务器

生产环境的启动命令大致如下:

webpack --config "./webpack.config.client.babel.js" --colors --display-error-details
webpack --config "./webpack.config.server.babel.js" --colors --display-error-details
node "./source/start-server"

Chunks

返回webpack最终所输出的文件信息:

build/webpack-chunks.json

{
    javascript:
    {
        main: `/assets/main.785f110e7775ec8322cf.js`
    },

    styles:
    {
        main: `/assets/main.785f110e7775ec8322cf.css`
    }
}
 类似资料: