nuxt3使用记录二:页面构建的细节(特别是SSG)

nuxt3框架确实挺成熟的,构建页面很简单:

nuxt build // 混合渲染
nuxt generate // 静态页面渲染(SSG)

我刚开始接触静态构建这些概念,其实我甚至不知道静态页面构建完应该是什么样子的。我只是概念里知道,为了提高seo,构建的html文件里应该直接包含一些想让搜索引擎直接爬取的内容,而不是放到.js文件里。

所以,我之前构建的所谓纯静态页面,我始终觉得有问题,因为我看构建出来的那些html,压根没包含我的那些写在页面里固定的内容,但是我网上查了两个晚上,都没有很直观的图文能够告诉我静态页面构建出来应该是什么样子。但是我就感觉有问题,为什么我的html里没有我想看到的内容呢?内容全跑到js文件里去了,那爬虫还咋爬呢?

最关键的是,我运行项目时,页面都能正常展示,没有一点问题!

经过两三个晚上的琢磨,终于证明,我的感觉是没错的!我也找到了问题所在,记录一下,供大家参考:
于是我构建了个及其简单的项目,总共三个文件:

// app.vue
<template>
    <div >
        <span>你好</span>
    </div>
</template>

// nuxt.config.ts
export default defineNuxtConfig({
});

// package.json
{
    "name": "nuxt-app",
    "private": true,
    "type": "module",
    "scripts": {
        "dev": "nuxt dev", 
        "build": "nuxt build",
        "gen": "nuxt generate"
    },
    "dependencies": {
        "@css-render/vue3-ssr": "^0.15.12",
        "nuxt": "^3.11.1",
        "vue": "^3.4.21"
    }
}

对,最简单的nuxt项目只需要这些文件即可,然后我构建一下:

nuxt generate

构建出来的index.html:

<!DOCTYPE html><html><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preload" as="fetch" crossorigin="anonymous" href="/_payload.json?ccf91331-2280-4f32-b7d3-e5c89936e605">
<link rel="modulepreload" as="script" crossorigin href="/_nuxt/B77upTuD.js">
<link rel="prefetch" as="script" crossorigin href="/_nuxt/WOKRCPAL.js">
<link rel="prefetch" as="script" crossorigin href="/_nuxt/DENtxqNa.js">
<link rel="prefetch" as="script" crossorigin href="/_nuxt/BtqXWcxc.js">
<script type="module" src="/_nuxt/B77upTuD.js" crossorigin></script></head><body><div id="__nuxt">
<div><span>你好</span></div></div><div id="teleports"></div> ------你看这里,app.vue里的内容是完全体现在index.html里的
<script type="application/json" id="__NUXT_DATA__" data-ssr="true" data-src="/_payload.json?ccf91331-2280-4f32-b7d3-e5c89936e605">[{"state":1,"once":3,"_errors":5,"serverRendered":7,"path":8,"prerenderedAt":9},["Reactive",2],{},["Reactive",4],["Set"],["Reactive",6],{},true,"/",1712585224057]</script>
<script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>

但是,当时我的项目构建出来,却连一个我写的文字都没有,固定死的那种内容都没有,然后我发现了问题所在,我提炼成如下变化(app.vue变,其他不变):

// app.vue
<template>
    <div v-if="a">
        <span>你好</span>
    </div>
</template>
<script lang="ts" setup>
 const a = ref(false)
 onMounted(() => {
        a.value = true;
    });
</script>

是的,我项目最初的结构里,有一部分内容是有个v-if控制组件渲染的,并且这个布尔值是在onMounted里判断的,所以,问题就出在这,nuxt认为这种动态渲染的组件,不能构建成纯静态页面,需要js动态生成,

到这里,你是不是觉得还可以理解,毕竟页面内容确实是动态的,有依赖一个布尔值来确定是否生成。但是变一变,换下面这种情况:

// app.vue
<template>
    <div v-if="a">
        <nuxtPage />
    </div>
</template>
<script lang="ts" setup>
 const a = ref(false)
 onMounted(() => {
        a.value = true;
    });
</script>

// 新增pages文件夹,新增两个页面:
// pages/index.vue
<template>
    <div>我不太好</div>
</template>

// pages/pages.vue
<template>
    <div>你好</div>
</template>

你看,我新增的两个页面,都是纯纯的静态页面,所以在我的想法里,这两个页面应该能构建成纯纯的静态页面,然而不是的!

找遍构建出来的html文件,你也看不到里面包含你好我不太好这样的中文字眼,而是被编译到一个js文件里面去了!

但是,你运行项目都是能正常看到这些文字的!所以,没经验的我一度以为纯静态页面就是这样的!

是的,在我这几天调试时,一直有这么个警告:

 WARN  [nuxt] Your project has pages but the <NuxtPage /> component has not been used. You might be using the <RouterView /> component instead, which will not work correctly in Nuxt. You can set pages: false in nuxt.config if you do not wish to use the Nuxt vue-router integration.

其实就是因为<nuxtPage />被包含在v-if里面,所以nuxt认为我没有写这个。然后我当时真不明白为什么会提示这个,我明明写了呀
所以,固定的页面,也未必完整的渲染到html文件里

总结

  1. SSG渲染是会构建出包含内容的.html文件,是可以直接打开看到内容的那种!
  2. 不要轻易忽视框架给出的警告,哪怕你的项目运行起来没啥问题
  3. 完全不变的.vue页面也未必会被构建成包含其内容的.html文件,它还受到其他可变条件的影响,特别是<nuxtPage />,路由页面必须有这个,当有相关的警告时,不要忽视不理(就这一点,我觉得nuxt的机制仍然有问题,当然我不懂底层原理。也许确实做不到这点。)
  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lsjweiyi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值