const resolve = file => path.resolve(__dirname, file) function createRenderer (bundle, options) { return createBundleRenderer(bundle, Object.assign(options, { template, cache: LRU({ max: 1000, maxAge: 1000 * 60 * 15 }), basedir: resolve('./dist'), runInNewContext: false })) } let renderer; let readyPromise if (isProd) { const bundle = require('./dist/vue-ssr-server-bundle.json') const clientManifest = require('./dist/vue-ssr-client-manifest.json') renderer = createRenderer(bundle, { clientManifest }) } else { readyPromise = require('./build/setup-dev-server')(server, (bundle, options) => { renderer = createRenderer(bundle, options) }) }
使用express启动服务,代码片段如下:
const server = express(); //定义在启动服务钱先判断中间件中的缓存是否过期,是否直接调用dist文件。 const serve = (path, cache) => express.static(resolve(path), { maxAge: cache && isProd ? 1000 * 60 * 60 * 24 * 30 : 0 }) server.use('/dist', serve('./dist', true)) server.get('*', (req, res) => { const context = { title: 'hello', url: req.url } renderer.renderToString(context, (err, html) => { if (err) { res.status(500).end('Internal Server Error') return } res.end(html) }) })
判断端口是否被占用,片段代码如下:
function probe(port, callback) { let servers = net.createServer().listen(port) let calledOnce = false let timeoutRef = setTimeout(function() { calledOnce = true callback(false, port) }, 2000) timeoutRef.unref() let connected = false servers.on('listening', function() { clearTimeout(timeoutRef) if (servers) servers.close() if (!calledOnce) { calledOnce = true callback(true, port) } }) servers.on('error', function(err) { clearTimeout(timeoutRef) let result = true if (err.code === 'EADDRINUSE') result = false if (!calledOnce) { calledOnce = true callback(result, port) } }) } const checkPortPromise = new Promise((resolve) => { (function serverport(_port) { let pt = _port || 8080; probe(pt, function(bl, _pt) { // 端口被占用 bl 返回false // _pt:传入的端口号 if (bl === true) { // console.log("\n Static file server running at" + "\n\n=> http://localhost:" + _pt + '\n'); resolve(_pt); } else { serverport(_pt + 1) } }) })() }) checkPortPromise.then(data => { uri = 'http://localhost:' + data; console.log('启动服务路径'+uri) server.listen(data); });
到这里,基本的代码已经编写完成,webpack打包配置文件基本和官方保持不变,接下来可以尝试启动本地的项目服务,这里简要的使用网易严选首页作为demo示例,结果如下: