[英]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.