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. 直至下一個請求該文件模塊到來時,才會去重新加載一遍對應的模塊,而正是改動之后的文件模塊。

  • 如何更新模塊代碼

  • 如何使用新模塊處理請求

  • 如何釋放老模塊的資源

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM