简体   繁体   English

我正在尝试将 NPM package 作为插件注入到 Next.js 应用程序上,以避免出现“找不到模块:无法解析‘child_process’”错误

[英]I'm Trying to Inject An NPM package As A Plugin on A Next.js App to Avoid A "Module not found: Can't resolve 'child_process'" Error

I have experience developing nuxt apps but I am new to next.js apps.我有开发 nuxt 应用程序的经验,但我是 next.js 应用程序的新手。 On the next.js app that I am trying to make, I'm having trouble getting 'google-auth-library' to work in a component .在我尝试制作的 next.js 应用程序中,我无法让“google-auth-library”在component中工作。 This is my code for the component in question:这是我的相关component代码:

components/Middle.tsx组件/Middle.tsx

import React from 'react';
import { Button } from 'react-bootstrap';
import { GoogleAuth } from 'google-auth-library';

const url = "https://us-central1-gtwitone.cloudfunctions.net/<functionname>";
const keyFilename = "/path/to/my/key.json";
//const functionsClient = CloudFunctionsServiceClient.v1.CloudFunctionsServiceClient;

class Middle extends React.Component {
    async main() {
      const auth = new GoogleAuth({keyFilename: keyFilename})

      //Create your client with an Identity token.
      const client = await auth.getIdTokenClient(url);
      const res = await client.request({url});
      console.log(res.data);
  }

    render() {
      return (
        <div className="col-md-12 text-center">
            <Button variant='primary' onClick={this.main}>
                Click me
            </Button>
        </div>
      );
    }
  }

export default Middle;

I know that the code in main() works in a regular node app.我知道 main() 中的代码适用于常规节点应用程序。 I made a node app where I put that function in an index.js file and ran it with node index.js and it ran perfectly.我制作了一个节点应用程序,我将 function 放在一个index.js文件中并使用node index.js运行它并且运行完美。 The problem is when I run this app with yarn dev I get a blank browser page and this in my terminal:问题是当我用yarn dev运行这个应用程序时,我得到一个空白的浏览器页面,并且在我的终端中是这样的:

<myusername>@<mycomputername> <myappname> % yarn dev
yarn run v1.22.17
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
wait  - compiling...
event - compiled client and server successfully in 214 ms (124 modules)
wait  - compiling / (client and server)...
wait  - compiling...
error - ./node_modules/google-auth-library/build/src/auth/googleauth.js:17:0
Module not found: Can't resolve 'child_process'

Import trace for requested module:
./node_modules/google-auth-library/build/src/index.js
./components/Middle.tsx
./pages/index.tsx

https://nextjs.org/docs/messages/module-not-found
Native Node.js APIs are not supported in the Edge Runtime. Found `child_process` imported.

Could not find files for / in .next/build-manifest.json
Could not find files for / in .next/build-manifest.json
^C
<myusername>@<mycomputername> <myappname> % 

I believe that this error is due to a problem with server side rendering.我认为此错误是由于服务器端呈现问题引起的。 I wrote a nuxt app where I had a similar issue, with a package called 'unity-webgl'.我写了一个 nuxt 应用程序,我遇到了类似的问题,其中有一个名为“unity-webgl”的 package。 I fixed the problem by injecting it into the app via a plugins folder.我通过plugins文件夹将其注入应用程序来解决问题。 I made this file:我做了这个文件:

plugins/plug-unity-webgl.client.js插件/插件-unity-webgl.client.js

import UnityWebgl from "unity-webgl";

export default ({ _ }, inject) => {
  const Unity = new UnityWebgl({
    loaderUrl: "/Build/tetris.loader.js",
    dataUrl: "/Build/tetris.data",
    frameworkUrl: "/Build/tetris.framework.js",
    codeUrl: "/Build/tetris.wasm",
  });
  inject("webgl", Unity);
};

I also needed to declare this in nuxt.config.js我还需要在 nuxt.config.js 中声明它

import colors from 'vuetify/es5/util/colors'

export default {
  // Set server port
  server: {
    port: 8080
  },
  /*
  ** Nuxt rendering mode
  ** See https://nuxtjs.org/api/configuration-mode
  */
  mode: 'universal',

  // Target: https://go.nuxtjs.dev/config-target
  target: 'static',

  // Global page headers: https://go.nuxtjs.dev/config-head
  head: {
    titleTemplate: '%s - appFrontend',
    title: 'appFrontend',
    htmlAttrs: {
      lang: 'en'
    },
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '' },
      { name: 'format-detection', content: 'telephone=no' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },

  // Global CSS: https://go.nuxtjs.dev/config-css
  css: [
  ],

  // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
  plugins: [
    '~/plugins/persistState.js',
    '~/plugins/axios.js',
    '~/plugins/plug-unity-webgl.client.js'
  ],

  // Auto import components: https://go.nuxtjs.dev/config-components
  components: true,

  // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
  buildModules: [
    // https://go.nuxtjs.dev/vuetify
    '@nuxtjs/vuetify'
  ],

  // Modules: https://go.nuxtjs.dev/config-modules
  modules: [
    // https://go.nuxtjs.dev/axios
    '@nuxtjs/axios'
  ],

  // Axios module configuration: https://go.nuxtjs.dev/config-axios
  axios: {
    // Workaround to avoid enforcing hard-coded localhost:3000: https://github.com/nuxt-community/axios-module/issues/308
    browserBaseURL: process.env.API_URL
  },

  // Vuetify module configuration: https://go.nuxtjs.dev/config-vuetify
  vuetify: {
    customVariables: ['~/assets/variables.scss'],
    theme: {
      dark: true,
      themes: {
        dark: {
          primary: colors.blue.darken2,
          accent: colors.grey.darken3,
          secondary: colors.amber.darken3,
          info: colors.teal.lighten1,
          warning: colors.amber.base,
          error: colors.deepOrange.accent4,
          success: colors.green.accent3
        }
      }
    }
  },

  // Build Configuration: https://go.nuxtjs.dev/config-build
  build: {
  }
}

Note the plugins arrary.请注意plugins列表。 So how would I do something similar with this next.js app I'm working on?那么我将如何对我正在开发的这个 next.js 应用程序做类似的事情呢? The next.config.js file looks way different than the nuxt.config.js file did: next.config.js文件看起来与 nuxt.config.js 文件有很大不同:

next.config.js下一步.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
}

module.exports = nextConfig

Can you inject plugins to get them to run client side only with a next.js app?您可以注入插件让它们仅使用 next.js 应用程序运行客户端吗? How would I do this?我该怎么做?

Update:更新:
Here is my Github repo of the code.这是我的 Github 代码回购协议。 The focus of this question is components/Middle.ts https://github.com/ChristianOConnor/call-to-cloud-exp本题重点是components/Middle.ts https://github.com/ChristianOConnor/call-to-cloud-exp

They key is that you have to put the GoogleAuth api call in the pages/api route.他们的关键是您必须将GoogleAuth api 调用放在pages/api路由中。 This is an example of how to call a Google Cloud Function. Btw, I made the basic template for the example with the command npx create-next-app@latest call-to-cloud-exp --typescript这是一个如何调用 Google Cloud Function 的示例。顺便说一句,我使用命令npx create-next-app@latest call-to-cloud-exp --typescript为该示例制作了基本模板

pages/api/google.ts页面/api/google.ts

// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next"
import { GoogleAuth } from "google-auth-library"

export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
    const url = process.env.FUNCTION_URL as string

    //Example with the key file, not recommended on GCP environment.
    const auth = new GoogleAuth({ keyFilename: process.env.KEYSTORE_PATH })

    //Create your client with an Identity token.
    const client = await auth.getIdTokenClient(url)
    const result = await client.request({ url })
    console.log(result.data)
    res.json({ data: result.data })
}

components/Middle.tsx组件/Middle.tsx

import React from "react"
import { Button } from "react-bootstrap"

class Middle extends React.Component {
  handleClick() {
        console.log("this is:", this)
    }
  
  // this talks with /pages/api/google
  async imCallingAnAPI() {
    const result = await fetch("/api/google")
    console.log({ result })
  }

  render() {
    return (
      <div className="col-md-12 text-center">
        <Button variant="primary" onClick={this.imCallingAnAPI}>
          Click me
        </Button>
      </div>
    )
  }
}

export default Middle

pages/index.tsx页面/index.tsx

import type { NextPage } from 'next'
import Header from '../components/Header';
import Footer from '../components/Footer';
import Middle from '../components/Middle';

const Home: NextPage = () => {
  return (
    <><main className='d-flex flex-column min-vh-100'>
      <Header />
      <br></br>
      <br></br>
      <Middle />
      </main>
      <footer>
        <Footer />
      </footer>
    </>
  )
}

export default Home

Try importing the package dynamically.尝试动态导入 package。 This could happen because of nextjs SSR.这可能是因为 nextjs SSR。 Call your component wherever you're using this npm package dynamically as shown in the docs below.在您使用此 npm package 的任何地方动态调用您的组件,如下面的文档所示。

const DynamicComponent = dynamic(() => import('../components/hello')) const DynamicComponent = dynamic(() => import('../components/hello'))

Refer from the doc:- https://nextjs.org/docs/advanced-features/dynamic-import参考文档:- https://nextjs.org/docs/advanced-features/dynamic-import

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Next.js / Webpack 5 中安装 Plaiceholder 导致:找不到模块:无法解析“child_process” - Installing Plaiceholder in Next.js / Webpack 5 causes: Module not found: Can't resolve 'child_process' 未找到模块:无法解析“child_process”NextJS + Nightmare - Module not found: Can't resolve 'child_process' NextJS + Nightmare Next.js 未找到中间件模块:无法解析“fs” - Next.js middleware Module not found: Can't resolve 'fs' Next.js:找不到模块:无法解析“canvg” - Next.js: Module not found: Can't resolve 'canvg' 找不到模块:使用 Electron React Boilerplate 时无法解析“child_process” - Module not found: Can't resolve 'child_process' while using Electron React Boilerplate 找不到模块:无法解析“child_process” - google-spreadsheet - Module not found: Can't resolve 'child_process' - google-spreadsheet 无法解析模块xmlhttprequest中的“ child_process” - Can't Resolve “child_process” in module xmlhttprequest 将 next.js 站点部署到 Netlify 时,如何解决“找不到模块:无法解析 [目录] 中的 [css 文件]”? - How do I resolve the "Module not found: Can't resolve [css file] in [directory]" when deploying next.js site to Netlify? 无法解析“child_process” - Can't resolve 'child_process' 未找到模块:无法在 next.js 项目中解析“../styles/global.css” - Module not found: Can't resolve '../styles/global.css' in an next.js project
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM