简体   繁体   中英

How to benefit from tree-shaking and code-splitting while loading JSON in Nuxt?

I have a nuxt-app, where I have a lot of posts. I recently refactored the project and I won't generate all posts anymore, as it is just taking too much time to do that.

Instead I have a page where I would fetch the matching post content via url query: www.mypage.com/posts/?post=my-post-slug

Because the content is lying in static json files, for example in:

/static/data/posts/my-post-slug.json
/static/data/posts/my-post-slug_2.json
/static/data/posts/my-post-slug_3.json
/static/data/posts/my-post-slug_n.json

I read the post https://github.com/nuxt/nuxt.js/issues/123 about how to load json in the best way.

I decided to do something like this in the fetch() hook:

// ... simplified code
async fetch() {
  let postSlug = this.$route.query.post
  
  const post = this.$axios
    .get(`/posts/posts.de.${postSlug}.json`)
    .then((data) => {
      return data?.data
    })
    .catch((error) => {
      console.error('error: ', error)
      const code = parseInt(error.response && error.response.status)
      if (code === 404) {
        this.$nuxt.error({ statusCode: 404, message: 'Post not found' })
      }
    })


  this.activePost = post?.items?.[0] || false
}

As already said, I do not generate the actual posts, but I generate all post urls in my sitemap.xml.

When running the generate in analyze mode I have now a huuuuge bundle size (app.js), and I can't understand why... -> Check out the attached image. (Note: app.js has a ridiculous size of 34MB!!!!)

  1. I don't understand why all my post jsons appear in the static and the dist part of the bundle???
  2. I don't understand at all why they appear in there. I want them to just lie in the static folder, but not be included in the app bundle. (you can see that there are files like events.bundle.de.json included. I need those to fetch a list of all posts for example. I do that also within my fetch hook only.

I would be very happy if somebody could point out why those files are included (twice)!

在此处输入图像描述

Those files are not included "twice". You need them, so you do have them locally in your static folder.

Meanwhile, you should probably put them inside of your src directory if you don't want/need to have them exposed publicly and benefit from code-splitting thanks to Webpack as explained in the post you've linked (which is still valid even if it's a 2017 one.).

Here, since you're making an axios call and using target: 'static' , it will bundle your whole thing to work even without JS and it does that ahead of time. So, in order to have all the possibilities, it includes all in the final bundle I think.

If you want to only load what is needed while not shipping a big static directory, you should import them dynamically. You can use a dynamic import : load only the needed JSON by passing the actual postSlug .

PS: style-wise, prefer using async/await ( .then is deprecated) and maybe also $axios.$get .

Although I think @kissu s answer is answering my question in the title, it was not the solution for my problem. For the sake of completeness I will post what I found out after long and many hours of debugging. I still don't quite understand why this even happened, but maybe someone could comment on that as well:

In my nuxt-project I am using a utility file getData.js of which I import a function getDataServer into one of my vuex store modules.

// vuex store module: store/data.js
import { getPreviewData } from '~/api/getData'

The code looks like this:

// getData.js

// Get static JSON file (e.g. basic.de.json or posts.de.1.json)
export function getDataServer(fileProps) {
  return require(`~/${fileProps.path}${fileProps.name}.${fileProps.lang}${
    fileProps.page ? `.${fileProps.page}` : ''
  }.json`)
}

Only by importing and not even by executing that function webpack would bundle EVERY .json file it can find in my root folder into my app.js.

That is why I had a dist folder appearing in my bundle, if not deleted. (The point I talk about in my original question, where I have things included twice).

I even created additional folders and.json files to see, and they were all bundled no matter what.

Only after removing the getData.js from my project my bundle became clean.

I understand that with the require command, webpack cannot tree-shake things, so I would have expected that some code-splitting features would not work, but what I did not expect was that this bit of code would automatically get every .json in my folder ...

Does anyone know why importing that function would execute it in a way that acts as a wildcard for all.jsons? To me it still does not make any sense.

Thanks and cheers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM