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