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>` + `
` + 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`
}
}