Universal-webpack
帮助搭建用于同构,即同时可以在客户端和服务端使用的Webpack。
Demo
:universal-webpack + koa + react + webpack。
Webpack 2
目前仅支持Webpack2.
npm install webpack --savenpm 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.jsimport path from 'path'import http from 'http'import express from 'express'import http_proxy from 'http-proxy'// react-routerimport routes from '../client/routes.js'// Reduximport 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('' + '\n' + ReactDOM.renderToString({page})) }) }) // 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 usedvar 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-detailswebpack --config "./webpack.config.server.babel.js" --colors --display-error-detailsnode "./source/start-server"
Chunks
返回webpack最终所输出的文件信息:
build/webpack-chunks.json
{ javascript: { main: `/assets/main.785f110e7775ec8322cf.js` }, styles: { main: `/assets/main.785f110e7775ec8322cf.css` }}