简体   繁体   English

Next.js 启动应用程序时运行函数/脚本

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

I have a (server-side) function I'd like to run when first starting my next.js server.我有一个(服务器端)function 我想在第一次启动我的 next.js 服务器时运行。 Ordinarily I'd do something like this in my package.json script definition: node./path/to/script.js && next start .通常我会在我的package.json脚本定义中做这样的事情: node./path/to/script.js && next start But the script in question imports several resources from "webpacked" code, so that's not so easy.但是有问题的脚本从“webpacked”代码中导入了几个资源,所以这并不容易。 (I know it's possible to turn on es6 support in node.js with --experimental-modules , but this brings its own problems and I'd rather not go down that rabbit hole) (我知道可以使用--experimental-modules在 node.js 中打开 es6 支持,但这会带来自己的问题,我宁愿不要 go 进入那个兔子洞)

The best solution I have so far is to create an api endpoint to run these scripts and then either manually hit that endpoint after starting.到目前为止,我拥有的最佳解决方案是创建一个 api 端点来运行这些脚本,然后在启动后手动点击该端点。 But it seems like such a hack to do this, and it's possible that this endpoint could be used in some sort of DoS attack if someone found it.但这似乎是一种黑客攻击,如果有人发现这个端点,它可能会被用于某种 DoS 攻击。

Is there a better solution, something that just allows one to register a function/callback to be run when the app is starting?有没有更好的解决方案,只允许注册一个函数/回调以在应用程序启动时运行? I figured a likely place would be the next.config.js but I don't see anything likely in the list of possible settings.我想一个可能的地方是next.config.js ,但我在可能的设置列表中看不到任何可能的地方。

I guess you could use the webpack configuration on the next.config file to register a new plugin and run it after the build is done.我猜你可以在 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
    },
}

Could it be possible to run the api after entering the code?输入代码后是否可以运行api?

_app.js _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;

Another solution could be using a Next's getServerSideProps or getStaticProps on the index/entry point for the app另一种解决方案可能是在应用程序的索引/入口点上使用 Next 的getServerSidePropsgetStaticProps

index.js 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;
   )
}

both of the get* functions from Next.js will run before the component renders to ensure that the data has been fetched. Next.js 中的两个 get* 函数都将在组件呈现之前运行,以确保已获取数据。 They are used for data fetching, but I don't see why they couldn't be used as a hack to force the API to run near launch.它们用于获取数据,但我不明白为什么它们不能用作黑客来强制 API 在启动附近运行。

The only solution I've found for the end of 2022, is using some bash scripts.我为 2022 年底找到的唯一解决方案是使用一些 bash 脚本。 It's actually simple.其实很简单。 Original bash answer My dev script:原bash回答我的开发脚本:

start_dev.sh start_dev.sh

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

My production script:我的制作脚本:

start.sh开始.sh

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

Here, I use curl to peek my site.在这里,我使用 curl 来查看我的网站。 That causes the site to actually launch it's scripts that normally launch on first visit.这会导致网站实际启动通常在首次访问时启动的脚本。 For sure, you can place you startup scripts anywhere you want, using home page is not required.当然,您可以将启动脚本放在任何您想要的地方,不需要使用主页。

In my case, I need some database preparing and page data caching.就我而言,我需要一些数据库准备和页面数据缓存。 So I use NextConnect for that.所以我为此使用 NextConnect。 Here I give one example (I have simular code for each page and api route):这里我举一个例子(我有每个页面的模拟代码和 api 路由):

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

My withUser middleware:我的 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