从0搭建前端项目架构-第二篇-服务端渲染配置

91 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

Hi, 大家好。

上一篇文章总结了webpack基础配置,这篇文章开始总结服务端渲染配置。

0x1 在client目录里新建服务端入口文件server-entry.js

    cd cliennt    touch server-entry.js

0x2 在server-entry.js里面写的是导出前端代码

    import React from 'react';    import App from './App.jsx';        export default <App />

0x3 因为打包时不能打包服务端文件,需要新建webpack.config.server.js来配置

1.target:node 代表运行在node环境中。

2.libraryTarget: 'commonjs2' 代表遵循common.js规范

    const path = require('path');    
    module.exports = {        
        target:'node',        
        entry: {            
            app: path.join(__dirname,'../client/server-entry.js')        
        },        
        output: {            
            filename: 'server-entry.js',            
            path: path.join(__dirname,'../dist'),            
            publicPath: '',            
            libraryTarget: 'commonjs2'        
        },        
        module: {            
            rules: [{
                test: /.jsx$/,                   
                loader: 'babel-loader'                
             },{                    
                 test: /.js$/,                    
                 loader: 'babel-loader',                    
                         exclude: [                        path.join(__dirname,'../node_modules')                    ]                }            ]        }    }

0x4 在package.json中添加build:server为打包服务端文件。build打包前后端文件

    "build:server": "webpack --config build/webpack.config.server.js",    "build": "build:client && build:server"

0x5 从上面打包看,每次打包的文件都没有覆盖。为了覆盖之前打包的文件,安装rimraf。同时在在package.json中配置

    npm i rimraf -D    
    "clear": "rimraf dist",    
    "build""npm run clear && npm run build:client && npm run build:server"

0x6 以上服务端配置就ok了。可以开始写服务端express代码了。创建server目录,在server目录下创建server.js

    mkdir server    
    cd server    
    touch server.js

0x7 安装express

    npm i express -S

0x8 在server.js中写express代码

    const express = require('express')    
    const ReactSSR = require('react-dom/server')    
    const serverEntry = require('../dist/server-entry').default        
    const app = express()        
    app.get('*',(req,res)=>{        
        const data = ReactSSR.renderToString(serverEntry)        
        res.send(data)    })        
    app.listen('3333',()=>{        console.log('server is listening on 3333')    })

0x10 运行npm run build 和 npm start ,在127.0.0.1:3333上就能看到显示在页面上的内容了。但是这只是在js中输出的,并没有放到html的body里面。下面操作来将内容放到body。

****1.在client目录下创建template.html

  <!DOCTYPE html>  <html lang="en">  <head>      <meta charset="UTF-8">      <meta name="viewport" content="width=device-width, initial-scale=1.0">      <meta http-equiv="X-UA-Compatible" content="ie=edge">      <title>Document</title>  </head>  <body>      <div id="root">          <app></app>      </div>  </body>  </html>

    2.修改client目录下app.js。将document.body改为document.getElementById('root')。这样是将html渲染到id为root的div下面。

    3.将template.html整体渲染,在webpack.config.client.js指定到template.html

  plugins:[      new HTMlPlugin({          template:path.join(__dirname,'../client/template.html')      })  ]

    4.在server/server.js里面读取打包后的dist/index.html。用fs模块去读index.html,把读取的内容send出去。****\

  const express = require('express')  
  const ReactSSR = require('react-dom/server')  
  const serverEntry = require('../dist/server-entry').default  
  const fs = require('fs')  const path = require('path')    //新增  
  const template = fs.readFileSync(path.join(__dirname,'../dist/index.html'),'utf8')    //新增,为了不让打包后的js文件返回html内容。  需要同时将webpack.config.client.js和  webpack.config.server.js里面的publicPath设置为public    
  const app = express()  app.use('/public',express.static(path.join(__dirname,'../dist')))    
  app.get('*',(req,res)=>{      
      const data = ReactSSR.renderToString(serverEntry)      //新增      res.send(template.replace('<app></app>',data))  })    app.listen('3333',()=>{      console.log('server is listening on 3333')  })

以上就配置好服务端渲染了。但是有个问题,每次修改都需要npm run build打包一下,npm start重启下服务。这样在实际工作中很浪费时间。下一篇文章中,我们会解决这个问题。