// server.js
const express = require('express');
const ReactSSR = require('react-dom/server');
const fs = require('fs');
const path = require('path');
const isDev = process.env.NODE_ENV === 'development';
const app = express();
if(!isDev) {
const serverEntry = require('../dist/server-entry').default;
const template = fs.readFileSync(path.join(__dirname, '../dist/index.html'),'utf-8');
app.use('/public',express.static(path.join(__dirname,'../dist')))
app.get('*', function (req, res) {
const appString = ReactSSR.renderToString(serverEntry)
res.send(template.replace(' <!-- app -->', appString))
})
} else {
const devStatic = require('./util/dev.static')
devStatic(app);
}
app.listen(3333, function () {
console.log('server is listening on 3333');
})
// dev.static.js
const axios = require('axios');
const path = require('path');
const MemoryFs = require('memory-fs');
const webpack = require('webpack');
const serverConfig = require('../../build/webpack.config.server');
const ReactDomServer = require('react-dom/server')
const mfs = new MemoryFs();
const serverCompiler = webpack(serverConfig);
const getTemplate = () => {
return new Promise((resolve,reject) => {
axios.get('http://localhost:8888/public/index.html')
.then(res => {
resolve(res.data);
})
.catch(err => {
console.err('get template error', err)
})
})
}
const Module = module.constructor;
serverCompiler.outputFileSystem = mfs;
let serverBundle
serverCompiler.watch({},(err,stats) => {
if(err) throw err
stats = stats.toJson();
stats.errors.forEach(err => console.error(err))
stats.warnings.forEach(warn => console.warn(warn))
const bundlePath = path.join(
serverConfig.output.path,
serverConfig.output.filename
)
const bundle = mfs.readFileSync(bundlePath,'utf-8');
const m = new Module();
m._compile(bundle);
serverBundle = m.default
})
module.exports = function(app) {
app.get('*', function(req,res) {
getTemplate().then(template => {
const content = ReactDomServer.renderToString(serverBundle)
res.send(template.replace('<!-- app -->',content))
})
})
}
// 报错
> new_webpack@1.0.0 dev:server /Users/winnie/work/learn/new_webpack
> cross-env NODE_ENV=development node server/server.js
server is listening on 3333
internal/validators.js:125
throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined
at validateString (internal/validators.js:125:11)
at Object.dirname (path.js:1260:5)
at Module._compile (internal/modules/cjs/loader.js:692:22)
at Watching.serverCompiler.watch [as handler] (/Users/winnie/work/learn/new_webpack/server/util/dev.static.js:41:7)
at compiler.hooks.done.callAsync (/Users/winnie/work/learn/new_webpack/node_modules/_webpack@4.39.1@webpack/lib/Watching.js:99:9)
at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/winnie/work/learn/new_webpack/node_modules/_tapable@1.1.3@tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)
at AsyncSeriesHook.lazyCompileHook (/Users/winnie/work/learn/new_webpack/node_modules/_tapable@1.1.3@tapable/lib/Hook.js:154:20)
at Watching._done (/Users/winnie/work/learn/new_webpack/node_modules/_webpack@4.39.1@webpack/lib/Watching.js:98:28)
at compiler.emitRecords.err (/Users/winnie/work/learn/new_webpack/node_modules/_webpack@4.39.1@webpack/lib/Watching.js:73:19)
at Compiler.emitRecords (/Users/winnie/work/learn/new_webpack/node_modules/_webpack@4.39.1@webpack/lib/Compiler.js:489:39)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! new_webpack@1.0.0 dev:server: `cross-env NODE_ENV=development node server/server.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the new_webpack@1.0.0 dev:server script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
帮忙看下是怎么回事吧?谢谢啦