sveltenetlify-cli

Does netlify dev work with Svelte/vite (not sveltekit)?


I am trying to use netlify serverless functions with svelte/vite using netlify dev. Im running svelte 3.52.0, vite 3.2.3, node 16.14.0, netlify-cli 12.2.7 (Windows).

When I run netlify dev and choose either "Svelte npm run dev" or Svelte npm run build it "hangs" constantly displaying "Waiting for framework port 5173" and states this can be configured using 'targetPort' property in netlify.toml.

So in netlify.toml I have

[build]
  command = "npm run build"
  publish="dist"
  functions="functions"
[dev]
  targetPort=5173
  port=8888

But it does the same. It "works" ("* *") if I choose any of the three vite options but then the serverless function I set up is giving me: Request from ::1: GET /.netlify/functions/getProjects Response with status 404 in 2ms.

My App.svelte (not doing anything with data yet but setup below was to test)

<script>
  async function myProjects() {
    let projects = []
    const url = `/.netlify/functions/getProjects`
    const res = await fetch(url)
      .then(r => r.json())
      .then(data => {
        projects = data
      })
  }
</script>

<main>
  <button on:click={myProjects}>MyProjects</button>
</main>

getProjects.js is in netlify\functions\getProjects folder and is:

const { MongoClient } = require('mongodb')
require('dotenv').config()

const mongoClient = new MongoClient(process.env.MONGODB_URI)
const clientPromise = mongoClient.connect()

const handler = async event => {
  try {
    const database = (await clientPromise).db(process.env.MONGODB_DATABASE)
    const collection = database.collection(process.env.MONGODB_COLLECTION)
    const results = await collection.find({}).limit(100).toArray()
    return {
      statuscode: 200,
      body: JSON.stringify(results)
    }
  } catch (error) {
    return { statusCode: 500, body: error.toString() }
  }
}
module.exports = { handler }

All the .env settings are correct and work with an express server so these should be good.

Any thoughts/suggestions appreciated.


Solution

  • After much dabbling, I was running Node 16.x and decided to update to Node 18.12.1. Next, the netlify.toml file that is working for me is:

    [build]
      publish="dist"
    [dev]
     command = "npm run dev"
      targetPort=5173
      port=8888
    [functions]
    node_bundler = "esbuild"
    

    My getProjects.js serverless function, in netlify/functions/getProjects folder is :

    const { MongoClient } = require('mongodb')
    require('dotenv').config()
    
    const mongoClient = new MongoClient(process.env.MONGODB_URI)
    const clientPromise = mongoClient.connect()
    if (clientPromise) {
      console.log('Connected to Mongodb')
    } else {
      console.log('NOT Connected toMongodb')
    }
    // terminal shows connected
    //
    export const handler = async (event, context) => {
      //
      const database = (await clientPromise).db(process.env.MONGODB_DATABASE)
      // console.log('after await promise')
      const collection = database.collection(process.env.MONGODB_COLLECTION)
      //
      try {
        const data = await collection.find({}).limit(100).toArray()
        // console.log('my results: ', data)
        return {
          statusCode: 200,
          body: JSON.stringify(data)
        }
      } catch (error) {
        return { statusCode: 500, body: error.toString() }
      }
    }
    

    My App.svelte is now:

    <script>
      import projects from './stores/projects'
    
      function showProjects() {
        console.log($projects)
      }
    </script>
    
    <main>
      <button on:click={showProjects}>MyProjects</button>
    </main>
    

    And I added a store ...

    import { writable } from 'svelte/store'
    
    // import Api functions
    import { getProjects } from '../backend/Api'
    
    const store = writable([], () => {
      setProjects()
      return () => {}
    })
    
    async function setProjects() {
      let projects = await getProjects()
      if (projects) {
        store.set(projects)
      }
    }
    
    //export default store
    const customProjectStore = {
      subscribe: store.subscribe
    }
    
    export default customProjectStore
    

    And that store calls an Api function ...

    export async function getProjects() {
      let projects = []
      const url = `/.netlify/functions/getProjects`
      const res = await fetch(url)
        .then(r => r.json())
        .then(data => {
          projects = data
        })
      return projects
    }
    

    This may seem like overkill but I like to use stores to call API for all backend stuff.

    The "My Projects" button in App.svelte shows the documents from the projects collection in Mongodb, using the serverless function method.