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

353 views Asked by At

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.

2

There are 2 answers

0
Pick Avana On BEST ANSWER

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.

1
Ennoriel On

From the documentation, it seems to be possible to deploy a svelte project without svelteKit: https://docs.netlify.com/integrations/frameworks/#sveltekit-and-svelte.

Though, I don't recomand it. SvelteKit is now the prefered way to build & deploy a Svelte app. You'll have instant backend configuration without worrying to much on how to deploy it on Netlify or Vercel. It also means that you will find more people using it and documenting it this way.