执行m._compile会报找不到模块,可是我都已经装了相关依赖了

来源:2-8 开发时的服务端渲染

默语eating

2018-12-02

// 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('<!--app-->', 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这里报的,我把这行代码注释掉后就不报错了,但实在没想到相关的原因

写回答

1回答

Jokcy

2018-12-03

试试把node_modules删了重新装一下

0
1
默语eating
已经解决了,是因为在webpack打包的时候入口文件写错了,编译的时候出错了,谢谢!
2018-12-03
共1条回复

React全栈+服务器渲染(ssr)打造社区Webapp

【毕设面试】只会写业务代码?out了,带你学会搭建属于自己的工程!

768 学习 · 414 问题

查看课程