ricokahler / next-plugin-preval

Pre-evaluate async functions during builds and import them like JSON
MIT License
255 stars 12 forks source link

Does the preval JSON gets sent to the client? #13

Closed kibebr closed 3 years ago

kibebr commented 3 years ago

Hi! First of all, thank you so much for developing this plugin.

I have a simple question. I'm using this plugin to develop a simple "news" app, and this is the Article page:

import {
  GetStaticProps,
  GetStaticPaths
} from 'next'
import { Article } from '../index'
import Image from 'next/image'
import articles from '../../fetchers/articles.preval'

interface ArticlePageProps {
  article: Article
}

export default function Article ({ article }: ArticlePageProps): JSX.Element {
  return (
    <div>
      <h1>{article.title}</h1>
    </div>
  )
}

// we get the correct article and pass it as props
export const getStaticProps: GetStaticProps = async ({ params }) => ({
  props: {
    article: params?.id === undefined ? null : articles.all.find(({ id }) => id === params.id)
  }
})

// articles.all is a list of Article; each Article has its own id; the id should be the path:
export const getStaticPaths: GetStaticPaths = async () => {
  const allArticlesIds =
    Object
    .values(articles.all)
    .map(({ id }) => id)

  return {
    paths: allArticlesIds.map(id => ({ params: { id } })),
    fallback: false
  }
}

My question is, even though I'm passing only one article as props, all the articles are still being imported at the top of the file. Does that mean that the whole list of articles (as JSON) will be fetched when the page is opened?

I'm sorry if this is not even related to the plugin.

And if so, is there any way to circumvent this?

Thanks!

ricokahler commented 3 years ago

Hi there!

The way you're using it, the articles should not be sent to the client. Next.js compiles away the getStaticProps calls and code from the client bundle.

See here

They mention using this tool to verify that code will be eliminated from the client bundle.

I copied your code in there and it does seem to confirm Next.js will eliminate that code.

image

And if so, is there any way to circumvent this?

If you want to be sure the code will be eliminated, you can use a dynamic import in getStaticProps like so:

export const getStaticPaths: GetStaticPaths = async () => {
  const { default: articles } = await import('../../fetchers/articles.preval');

  const allArticlesIds =
    Object
    .values(articles.all)
    .map(({ id }) => id)

  return {
    paths: allArticlesIds.map(id => ({ params: { id } })),
    fallback: false
  }
}

Hope that helps. Feel free to close if this answers your question!

kibebr commented 3 years ago

@ricokahler Awesome, thank you! Didn't know about that tool.

Another (last) question if you don't mind (probably more related to Next itself), if I'd like to create a search functionality where I can query for articles, I'd have to make an API or is there a way I can access the articles JSON data through server-less functions?

Thanks once again

EDIT: Just found out about Next's API routes, thank you!!

ricokahler commented 3 years ago

yup! just use next's api routes and import a preval there. this plugin works there too!