// dev-static.js的代码
const vm = require('vm')
const path = require('path')
const axios = require('axios')
const webpack = require('webpack')
const NativeModule = require('module')
const ReactDomServer = require('react-dom/server')
const MemoryFileSystem = require("memory-fs")
const webpackServerConfig = require('../../config/webpack.server.js')
const Module = require('module')
const mfs = new MemoryFileSystem()
const requireFromString = require('require-from-string')
const serverCompile = webpack(webpackServerConfig)
let serverBundle
// 关键:将webpack输入指定内存中
serverCompile.outputFileSystem = mfs
serverCompile.watch({}, (err, stats) => {
if (err) throw err
const info = stats.toJson()
if (stats.hasErrors()) {
info.errors.forEach(err => console.error(err))
}
if (stats.hasWarnings()) {
info.warnings.forEach(err => console.error(err))
}
// 读取bundle在内存中的路径
const bundlePath = path.join(
webpackServerConfig.output.path,
webpackServerConfig.output.filename
)
const bundle = mfs.readFileSync(bundlePath, 'utf-8')
const m = new Module()
m._compile(bundle, 'server_entry.js')
// console.log(m)
serverBundle = m.exports
// serverBundle = requireFromString(bundle, 'server_entry.js')
})
function getTemplate() {
return new Promise((resolve, reject) => {
axios.get('http://localhost:3000/public/index.html').then(res => {
resolve(res.data)
}).catch(reject)
})
}
module.exports = function devSSR(app) {
app.get('*', (req, res) => {
getTemplate().then(tpl => {
const content = ReactDomServer.renderToString(serverBundle)
res.send(
tpl.replace('', content)
)
})
})
}
webpack.server.js
const path = require('path');
const nodeExternals = require('webpack-node-externals');
module.exports = {
mode: process.env.NODE_ENV,
// JS 执行入口文件
entry: './server/server.js',
target: 'node',
// 为了不打包进 node_modules 目录下的第三方模块
externals: [nodeExternals()],
output: {
// 为了以 CommonJS2 规范导出渲染函数,以给采用 Nodejs 编写的 HTTP 服务调用
libraryTarget: 'commonjs2',
// 把最终可在 Nodejs 中运行的代码输出到一个 bundle.js 文件
filename: 'server_entry.js',
// 输出文件都放到 dist 目录下
path: path.resolve(__dirname, '../dist'),
publicPath: '/public'
},
// 启用node的__dirname
node: {
__filename: false,
__dirname: false
},
module: {
rules: [
{
test: /.jsx?$/,
use: ['babel-loader'],
exclude: /node_modules/,
}
]
},
devtool: 'source-map' // 输出 source-map 方便直接调试 ES6 源码
};
package.json
{
"name": "ssr",
"version": "1.0.0",
"description": "react-ssr",
"private": true,
"scripts": {
"start": "node dist/server.js",
"clear": "rimraf dist",
"build:client": "cross-env NODE_ENV=production webpack --config config/webpack.client.pro.js",
"build:server": "cross-env NODE_ENV=production webpack --config config/webpack.server.js",
"dev:client": "cross-env NODE_ENV=development webpack-dev-server --config config/webpack.client.dev.js",
"dev:server": "cross-env NODE_ENV=development node server/server.js",
"build": "npm run clear && npm run build:client && npm run build:server"
},
"keywords": [
"ssr"
],
"author": "zkj",
"license": "ISC",
"dependencies": {
"axios": "^0.18.0",
"babel-polyfill": "^6.26.0",
"express": "^4.16.4",
"history": "^4.7.2",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"chalk": "^2.4.1",
"clean-webpack-plugin": "^1.0.0",
"cross-env": "^5.2.0",
"css-loader": "^1.0.1",
"file-loader": "^2.0.0",
"happypack": "^5.0.0",
"html-webpack-plugin": "^3.2.0",
"http-proxy-middleware": "^0.19.1",
"memory-fs": "^0.4.1",
"mini-css-extract-plugin": "^0.4.5",
"node-sass": "^4.10.0",
"postcss-flexbugs-fixes": "^4.1.0",
"postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.4.0",
"progress-bar-webpack-plugin": "^1.11.0",
"react-hot-loader": "^4.3.12",
"require-from-string": "^2.0.2",
"rimraf": "^2.6.2",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"uglifyjs-webpack-plugin": "^2.0.1",
"url-loader": "^1.1.2",
"webpack": "^4.26.1",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.10",
"webpack-merge": "^4.1.4",
"webpack-node-externals": "^1.7.2"
}
}
报错信息
请大佬帮忙看下,具体的报错好像就是m._compile这里报的,我把这行代码注释掉后就不报错了,但实在没想到相关的原因