在 Nuxt 中加载 JSON 时如何从 tree-shaking 和代码拆分中获益?

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

我有一个 nuxt-app,里面有很多 post。我最近重构了这个项目,我不会再 generate 所有 post 了,因为这样做会花费太多时间。

相反,我有一个页面,我可以通过 url 查询获取匹配的 post 内容: www.mypage.com/posts/?post=my-post-slug

因为内容位于静态 json 文件中,例如:

/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

我读了 post https://github.com/nuxt/nuxt.js/issues/123 关于如何以最佳方式加载 json。

我决定在 fetch() 钩子中做这样的事情:

// ... 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
}

如前所述,我没有生成实际的 post,但我在 sitemap.xml.

中生成了所有 post url

当 运行 在 analyze 模式下生成时,我现在有一个 huuuuge 包大小 (app.js),我不明白为什么...... -> 查看所附图片。 (注意:app.js 有 34MB 的荒谬大小!!!!)

  1. 我不明白为什么我的所有 post json 都出现在捆绑包的静态和分布式部分???
  2. 我完全不明白他们为什么会出现在那里。我希望它们只位于静态文件夹中,但不包含在应用程序包中。 (您可以看到包含 events.bundle.de.json 之类的文件。例如,我需要这些文件来获取所有 post 的列表。我也在我的获取挂钩中这样做。

如果有人能指出为什么包含这些文件(两次),我将非常高兴!

这些文件没有“两次”包含在内。你需要它们,所以你在本地 static 文件夹中有它们。

与此同时,如果您不 want/need 让它们公开并从代码拆分中受益,您应该将它们放在 src 目录中,这要归功于 Webpack,如 post 您已链接(即使是 2017 年的链接仍然有效!)。

在这里,由于您正在调用 axios 并使用 target: 'static',即使没有 JS,它也会捆绑您的整个工作,并且它会提前完成。所以,为了拥有所有的可能性,我认为它包括所有在最终的捆绑包中。

如果您只想加载需要的内容而不传送大 static 目录,您应该动态导入它们。您可以使用 :通过传递实际的 postSlug.

仅加载需要的 JSON

PS:风格方面,更喜欢使用 async/await.then 已弃用),也可能 $axios.$get.

虽然我认为@kissu 的回答是回答了我标题中的问题,但并不是我问题的解决方案。为了完整起见,我将 post 经过长时间调试后发现的内容。我仍然不太明白为什么会发生这种情况,但也许有人也可以对此发表评论:

在我的 nuxt-project 中,我正在使用一个实用程序文件 getData.js,我将其中的一个函数 getDataServer 导入到我的一个 vuex 存储模块中。

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

代码如下所示:

// 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`)
}

只有通过导入而不是执行该函数,webpack 才会将它在我的根文件夹中找到的每个 .json 文件打包到我的 app.js.

这就是为什么我的包中出现了一个 dist 文件夹,如果没有删除的话。 (我在我原来的问题中谈到了这一点,我把东西包括了两次)。

我什至创建了额外的文件夹和 .json 文件来查看,无论如何它们都捆绑在一起。

仅在从我的项目中删除 getData.js 后,我的包才变得干净。

我明白了require这个命令,webpack不能tree-shake的东西,所以我本来以为有些code-splitting的功能是行不通的,没想到的是这段代码会 自动获取我文件夹中的每个 .json ...

有谁知道为什么导入该函数会以充当所有 .json 的通配符的方式执行它? 对我来说它仍然没有任何意义。

感谢和欢呼。