payloadcms / payload-3.0-demo

The official demo for Payload 3.0
https://next-payload-3-0-test.vercel.app
474 stars 157 forks source link

Unable to pass payload config inside payload init function #31

Closed anjy7 closed 7 months ago

anjy7 commented 7 months ago
import { getPayload } from 'payload'

import payloadConfig from '../../payload.config.js'

export const getPayloadClient = () => getPayload({ config: payloadConfig })

Upon running the local api script outside the payload project, it throws scss errors: image

Steps to reproduce-

  1. Create a local api script to seed the data
  2. Run the script using ‘node script.js’ or ‘ts-node script.js’
paulpopus commented 7 months ago

What a head spinner this one was, so here's the current fix for this, you'll need to create a custom loadConfig function that tells node to ignore css files:

// loadConfig.ts

import { createRequire } from 'module'

export const loadConfig = async (path: string) => {
  const require = createRequire(import.meta.url)

  const CLIENT_EXTENSIONS = [
    '.scss',
    '.css',
    '.svg',
    '.png',
    '.jpg',
    '.eot',
    '.ttf',
    '.woff',
    '.woff2',
  ]

  CLIENT_EXTENSIONS.forEach((ext) => {
    require.extensions[ext] = () => null
  })

  const config = require(path).default

  return config
}

then in your script you wanna import the config using this function instead, eg:

// src/seed.ts
import { getPayload } from 'payload'
import dotenv from 'dotenv'
import { loadConfig } from './loadConfig'

dotenv.config()

export const seed = async () => {
  const config = await loadConfig('../payload.config')
  const payload = await getPayload({ config })

  const pages = await payload.find({
    collection: 'pages',
  })

  console.log(pages.docs)
  process.exit(1)
}

seed()

then you should be able to run the script with tsx src/seed

We are planning to streamline this whole process but currently this is the best way to do it

torbjorn-kvist commented 7 months ago

@paulpopus sorry for tagging, but wanted to ask if there is a "easy" way to follow or get notified about the streamlined process or is that something that will be "included" in the 3.0 release?

paulpopus commented 7 months ago

@torbjorn-kvist We don't know when it will happen right now but it's something we wanna do for 3.0 release for sure

Most likely we'll have a lot of guides for "working with Nextjs/Payload" etc where we'll expose this information more clearly

torbjorn-kvist commented 7 months ago

Okey! Thanks for the response!

I'm mostly asking because the "closed" answer is for a script running via tsx. I did some testing today with trying to use "local api" with v3 inside a firebase function.


import { defineSecret } from 'firebase-functions/params'
import { setGlobalOptions } from 'firebase-functions/v2'
import { onRequest } from 'firebase-functions/v2/https'
import { getPayload } from 'payload'

import config from '@/payload.config'

const MONGODB_URI = defineSecret('MONGODB_URI')
const PAYLOAD_SECRET = defineSecret('PAYLOAD_SECRET')

setGlobalOptions({
  region: 'europe-west1',
  secrets: [MONGODB_URI, PAYLOAD_SECRET],
  invoker: 'public',
})

export const testLocalApi = onRequest({ minInstances: 0 }, async (request, response) => {
  const payload = await getPayload({
    config: config,
  })

  const data = await payload.find({
    collection: 'users',
  })

  response.send(data)
})

Got the same error with .scss as the seed script mention in the issue. Tried to the do the loadConfig solution but got an error, which makes sense that it works in tsx but not inside an firebase function.

Error [ERR_REQUIRE_ESM]: require() of ES Module /user/path/worker/src/payload.config.js from /user/path/worker/loadConfig.js not supported.
Instead change the require of payload.config.js in /user/path/worker/loadConfig.js to a dynamic import() which is available in all CommonJS modules.

Not sure if this it quite out-of-scope of what Payload is targeting.