React ssr框架Next.js 的生產實踐

首先感慨一句, next 真是一個版本狂人啊,一週就一個下版本

1. 按照官網的方式初始化一個Next.js項目遇到的一些問題

  • 默認初始化的框架樣式支持sass,組件級別的[name].module.css,但默認不支持less,官方提供了配置less的方法css

    `yarn add @zeit/next-less less`
    // next.config.js
    const withLess = require('@zeit/next-less')
    module.exports = withLess({
      webpack(config, options) {
          config.resolve = {
              alias: {
                ...config.resolve.alias,
                // 配置alias同時要在tsconfig.json 配置 baseUrl,paths
                "@": path.resolve(__dirname, ".") 
              },
              extensions: [".ts", ".tsx", ".js", ".jsx", ".less", ".css"]
        };
        return config
      }
    })

    從新啓動後會報 Error: Cannot find module 'webpack' 因而就安裝webpack但默認安裝的是webpack@5.x,按照這個 issue,要替換成 webpack@4.x 才能夠html

  • Next.js 打包後靜態資源路徑中的 _next 目錄哪來的 ?
    參考此文
    打包配置 配置assetPrefix,至關於webpack裏面的publicPath(將靜態資源放在cdn)
    但打包後html引入的靜態資源地址會多一層_next目錄,解決方案:
    本身代碼裏建立 _next 目錄太過繁瑣,且消耗性能,故讓運維在拷貝靜態資源時,在oss目錄上多加一層 _next 目錄
  • ssr框架 ajax 請求庫的選擇node-fetchwindow, document的使用注意事項
  • getInitialProps getStaticProps getStaticPaths getServerSideProps區別
  • clint Link 跳轉時子頁面樣式文件獲取不到(好像只有開發階段有次問題,暫時未解決)
  • 當進行重構項目時,若是不想改變老項目的url(可能因爲url已經被百度seo收錄),能夠利用自定義node服務器,將老url轉發到新的url,參考文檔可是有個問題這種被轉發的url爲何瀏覽器請求會是 404,但頁面仍是會正常顯示,不知道是爲何???

2. 生產部署

  • 接入公司cicd規範,部署沒有使用傳統的pm2,而是把服務放在一個容器內,服務重啓靠node提供一個健康檢查接口,容器來保證服務穩定,當該接口沒有正常返回docker容器就會重啓應用
  • 因爲公司規範啓動node服務都是在容器內用 node app.js,但next默認啓動是靠next start啓動生產服務的。解決方案是:next提供了自定義服務器,我這裏採用了koa,將next做爲一箇中間件來處理參考node

    // https://www.nextjs.cn/docs/advanced-features/custom-server
    const Koa = require('koa') // 引入 koa
    const next = require('next') // nextjs 做爲中間件
    const routesMap = require('./route') // 新老url衝突時,將老url轉發
    
    const dev = process.env.NODE_ENV === 'development' // 判斷是否處於開發者狀態
    const app = next({ dev }) // 初始化 nextjs,判斷它是否處於 dev:開發者狀態,仍是production: 正式服務狀態
    const handle = app.getRequestHandler() // 拿到 http 請求的響應
    
    console.log('next dev環境===>', dev)
    
    const port = 8080
    
    // app.prepare:編譯 pages 文件夾下面的頁面文件,then 是保證 pages 下頁面所有編譯完了以後,咱們才能真正的啓動服務來響應請求。
    // 若是這些內容咱們沒有編譯完成,那麼啓動服務響應請求的時候可能會報錯。
    app.prepare().then(() => {
      const server = new Koa() // 聲明一個 server
    
      /** 這是 Koa 的核心用法:中間件。一般給 use 裏面寫一個函數,這個函數就是中間件。
       * params:
       *  ctx: Koa Context 將 node 的 request 和 response 對象封裝到單個對象中,爲請求上下文對象
       *  next: 調用後將執行流程轉入下一個中間件,若是當前中間件中沒有調用 next,整個中間件的執行流程則會在這裏終止,後續中間件不會獲得執行
       */
      server.use(async (ctx, next) => {
        if (routesMap[ctx.path]) {
          // 老url轉發~~~~,這種操做頁面能夠正常出來,但不知道爲何瀏覽器狀態碼會是404
          await app.render(ctx.req, ctx.res, routesMap[ctx.path])
        } else {
          await handle(ctx.req, ctx.res)
        }
        ctx.response = false
      })
    
      server.listen(port)
      console.log(`請訪問: http://localhost:${port}`)
相關文章
相關標籤/搜索