zoukankan      html  css  js  c++  java
  • nextjs服务端渲染原理

    1. 简单的介绍一下

    nextjs是react进行服务端渲染的一个工具,默认以根目录下的pages为渲染路由

    比如我在pages目录下创建一个index.js文件,然后export default一个组件,就会在页面上呈现出来这个组件

    这个特性作为他最知名的优点,所以被人认为是一个很很好的后端渲染工具

    多用一段时间,会踩到一些坑,功能都不是白用的,想用那么牛逼的东西,要是知道的太肤浅,驾驭不了也很难受。

    所以我们不得不深入了解一下

    2. webpack config

    用脚趾头想一下,要让react代码在服务端跑,还不是得用webpack编译嘛

    所以nextjs内部肯定偷偷的封装了一层webpack的编译工具

    next怎么去配置webpack呢

    方法1

    在更目录下的next.config.js里写配置

    方法2

    写个自定义的server 然后执行

    比如第一种张这个样子

    const path = require('path')
    const webpack = require('webpack')
    const withTs = require('@zeit/next-typescript')
    const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
    
    module.exports = withTs({
      webpack(config) {
        config.resolve.alias = {
          'styled-components': path.resolve('node_modules', 'styled-components')
        }
    
        if (process.env.ANALYZE) {
          config.plugins.push(
            new BundleAnalyzerPlugin({
              analyzerMode: 'server',
              openAnalyzer: true
            })
          )
        }
    
        config.plugins.push(new webpack.ContextReplacementPlugin(/moment[/\]locale$/, /zh-cn/))
    
        config.plugins.push(new webpack.EnvironmentPlugin(['ENV']))
    
        return config
      }
    })

    第二种样子会特别一点,只需要注意中间let conf的那一段代码就好了

    const { createServer } = require('http');
    const { parse } = require('url');
    const next = require('next');
    const withScss = require('@zeit/next-sass');
    const withTs = require('@zeit/next-typescript')
    const dev = process.env.NODE_ENV !== 'production'
    
    let conf = {
      pageExtensions: ['jsx', 'js', 'mdsx'],
      webpack(config) {
        config.module.rules.push(
          {
            test: /.(mdsx)$/,
            use: ['next-babel-loader', 'zeus-md-next-loader', 'zeus-md-loader']
          }
        );
        return config;
      }
    }
    conf = withScss(conf)
    conf = withTs(conf)
    const app = next({ dev, conf })
    const handle = app.getRequestHandler()
    
    app.prepare().then(() => {
      createServer((req, res) => {
        const parsedUrl = parse(req.url, true)
        const { pathname, query } = parsedUrl
    
        if (pathname === '/') {
          app.render(req, res, '/home', query)
        } else {
          handle(req, res, parsedUrl)
        }
      }).listen(8082, err => {
        if (err) throw err
        console.log('> Ready on http://localhost:8082')
      })
    })

    当然并不是要用自定义服务器就不能抽离next.config.js了

    是可以的,next有一个server,所以我们才会有next build, next dev, next start的命令。

    这个server和我们自定义的server差不多,他会在执行next()这个方法的时候去找option.conf,如果找不到就会去找next.config.js里的了,那找到了就不管next.config.js了

    对了,他也有自己默认的配置,所以我们写的配置是拿过去和原有的config合并的,不是代替原来的,因此这些config的写法和webpack里的是有点点区别的,多会去使用push,assign之类的

    总而言之next的webpack的自定义能力还是比较强的,不需要担心配置webpack

    3. 热更新

    使用热更新是一件让开发很爽的事情,对于前端来说,代码和展示是同步的好么,对了我说的不是那种刷新浏览器的热更新,是不刷新的那种热更新

    nextjs的热更新的同步很快的,快到让开发觉得觉得从此写前端是一件很嗨皮的事情了。我觉得一个后端如果发现了这个秘密,都会每天偷偷的撸几个前端页面嗨皮一下了

    盲目的沉迷是就是误入歧途,所以我决定做一个理性的追随者

    实现的原理比较简(fu)单(za)

    Nodejs 热更新 原理及代码   来自某个网友的回答

    1. 监视文件被改动的时候

    2. 将缓冲区中已加载的对应模块清除

    3. 此时缓冲区中就不保留有该文件模块的代码

    4. 直至下一个请求该文件模块到来时,才会去重新加载一遍对应的模块,而正是改动之后的文件模块。

    • 如何更新模块代码

    • 如何使用新模块处理请求

    • 如何释放老模块的资源

  • 相关阅读:
    mongodb 安装为windos service
    30分钟搭建一个小型网站框架(python django)
    WAL学习
    postgres读写性能测试(本地、NFS)
    小麦带你看postgres(代码模块结构)
    使用zookeeper实现分布式master选举(c 接口版本)
    Alluxio1.0.1最新版(Tachyon为其前身)介绍,+HDFS分布式环境搭建
    CAF(C++ actor framework)(序列化之复杂类,分析 还有自己不懂的细思恐极函数实现)(三)
    CAF(C++ actor framework)(序列化之类,无需序列化,直接传)(二)
    CAF(C++ actor framework)(序列化之结构体,任意嵌套STL)(一)
  • 原文地址:https://www.cnblogs.com/sowhite/p/9323445.html
Copyright © 2011-2022 走看看