簡體   English   中英

Next.js 啟動應用程序時運行函數/腳本

[英]Next.js run function/script when starting app

我有一個(服務器端)function 我想在第一次啟動我的 next.js 服務器時運行。 通常我會在我的package.json腳本定義中做這樣的事情: node./path/to/script.js && next start 但是有問題的腳本從“webpacked”代碼中導入了幾個資源,所以這並不容易。 (我知道可以使用--experimental-modules在 node.js 中打開 es6 支持,但這會帶來自己的問題,我寧願不要 go 進入那個兔子洞)

到目前為止,我擁有的最佳解決方案是創建一個 api 端點來運行這些腳本,然后在啟動后手動點擊該端點。 但這似乎是一種黑客攻擊,如果有人發現這個端點,它可能會被用於某種 DoS 攻擊。

有沒有更好的解決方案,只允許注冊一個函數/回調以在應用程序啟動時運行? 我想一個可能的地方是next.config.js ,但我在可能的設置列表中看不到任何可能的地方。

我猜你可以在 next.config 文件中使用 webpack 配置來注冊一個新插件並在構建完成后運行它。

module.exports = {
    webpack: (config, options) => {
        config.plugins.push(
            {
                apply: (compiler) => {
                    compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
                        console.log(".. Run after build")
                    });
                }
            }    
        )
        return config
    },
}

輸入代碼后是否可以運行api?

_app.js

const MyApp({pageProps}) {
   useEffect(() => {
   /* call to run API on app mount */
      return ( /* Call to clean up after app unmounted*/);
   },[])

   return (
      <Component {...pageProps} />
   );
}
export default MyApp;

另一種解決方案可能是在應用程序的索引/入口點上使用 Next 的getServerSidePropsgetStaticProps

index.js

export default function foo({props}) {
   /* Do something */
   return( /* return something to renderer */);
}

export function getServerSideProps() {
   const caller = fetch(/* Return from running API endpoint*/)
   return (
      props: caller;
   )
}

Next.js 中的兩個 get* 函數都將在組件呈現之前運行,以確保已獲取數據。 它們用於獲取數據,但我不明白為什么它們不能用作黑客來強制 API 在啟動附近運行。

我為 2022 年底找到的唯一解決方案是使用一些 bash 腳本。 其實很簡單。 原bash回答我的開發腳本:

start_dev.sh

yarn run dev & curl -I http://localhost:3002 & wait

我的制作腳本:

開始.sh

yarn run start & curl -I http://localhost:3000 & wait

在這里,我使用 curl 來查看我的網站。 這會導致網站實際啟動通常在首次訪問時啟動的腳本。 當然,您可以將啟動腳本放在任何您想要的地方,不需要使用主頁。

就我而言,我需要一些數據庫准備和頁面數據緩存。 所以我為此使用 NextConnect。 這里我舉一個例子(我有每個頁面的模擬代碼和 api 路由):

export async function getServerSideProps({ req, res }) {
    const middlewares = NextConnect().use(waitDB).use(withUser).use(withPagesCache)
    await middlewares.run(req, res);
    ...
}

我的 withUser 中間件:

export default async function (req, res, next) {
  let cookies = getCookies({ req, res });
  let { user_id, token } = cookies;
  // some logic. You are free to use your globals, your DB and so on.
  console.log("Test this middleware");

  next();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM