nuxt踩坑记录

566 阅读2分钟

背景

公司国际版官网项目,2022年接手时还是nuxt1.0,考虑SEO、性能优化、开发效率的方面,决定将nuxt1.0升级到nuxt2.0:

  1. 开发迭代超过5年,项目较大,导致本地启动慢,而且热更新时经常内存溢出,需要重新启动,本地开发效率低
  2. nuxt1.0还使用得是webpack3,无法使用新特性对项目进行性能优化,间接影响网站SEO
  3. nuxt1.0文档缺失

页面mounted执行两次排查记录

nuxt官方对于mounted执行两次排查的github issue:github.com/nuxt/nuxt/i…

主要原因是客户端渲染时Vue Hydration异常,导致页面在服务端和客户端各执行一次,导致Hydration异常主要有以下几种情况:

第一种 页面布局不合理

比如行内元素内嵌套了块级元素,然后块级元素又使用了for或者if,本地console会报错:

[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.

image.png

排要想排查只能一行行代码检查是否是这种情况,最笨的办法:一点点删除代码,看看删除了那一块的代码后不再执行两遍。

第二种 DOM更新前操作DOM

这种情况需要使用this.$nextTick方法在Vue实例的DOM更新完成后执行DOM操作

第三种 layout未设置name

原因:github.com/nuxt/nuxt/i…

修复代码: github.com/nuxt/nuxt/p… 该问题在V2.12.1已修复

第四种 特殊组件

有些引入的组件会导致执行两边,比如swiper,这种情况除了替换组件,暂时未找到其他解决方法

Google Tag 接入

2023年7月1日起,Google 原UA媒体资源不再处理新的命中数据,需要迁移到GA4媒体资源,通过接入gtag.js代码实现数据收集。正好在这段时间升级nuxt,接入gtag.js代码兼容如下:

// nuxt1.0
npm install @nuxtjs/google-tag-manager
// nuxt.config.js
modules: [
    ['@nuxtjs/google-tag-manager', { id: 'GTM-xxxxx' }]
]

// nuxt2.0
npm install @nuxtjs/gtm
// nuxt.config.js
modules: [
    '@nuxtjs/gtm'
],
gtm: { id: 'GTM-xxxxx' }

CSS 优化

启用 CSS 提取

extractCSS 用于指定是否将组件中的 CSS 提取到单独的 CSS 文件中。

  • 当设置为 false 时,CSS 会内联到 HTML 文件中。缺点就是,查看源代码时,head中会有很大篇幅是CSS内容,不知道对SEO是否影响:

image.png

  • 当设置为 true 时,会生成一个独立的 CSS 文件,因为 nuxt1.0 没有内置 optimization 配置项,会打包一个css文件中,这个文件太大,有时会出现网页无样式时长过久。还好nuxt2.0 可以通过配置optimization拆分多个css文件,更有利于缓存和预加载隔离。它还可以只下载和解析所需的资源,从而提高页面性能。
// nuxt.config.js
export default {
  build: {
    extractCSS: true,
    optimization: {
      splitChunks: {
        cacheGroups: {
          styles: {
            name: 'styles',
            test: /.(css|vue)$/,
            chunks: 'all',
            enforce: true
          }
        }
      }
    }
  }
}

请注意, Vue 2.5.18 之前存在一个错误,该错误在使用此选项时删除了关键的 CSS 导入。

补充

配置splitChunks后构建会有一个警告信息,来自于 webpack 构建过程中使用了 extract-css-chunks-webpack-plugin 插件。警告信息提到了一个 "Conflicting order"(冲突的顺序)的问题。是因为多个相同组件在不同页面引入的顺序不一致导致,在我一个个定位调整顺序时,我想能不能通过eslint 一键 fixed 所有引入顺序问题,一查还真有 eslint-plugin-import-order,既可以根据字母顺序对每个组内的顺序进行排序,还可以进行分组:

// .eslintrc.js
module.exports = {
  plugins: ['import'],
  rules: {
    'import/order': [
      'warn',
      {
        // -   `builtin`:Node.js 内置模块
        // -   `external`:第三方模块
        // -   `internal`:项目内部的模块
        // -   `parent` 和 `sibling`:父级和同级目录中的模块
        // -   `index`:当前目录下的 `index` 文件
        groups: ['builtin', 'external', 'internal', ['parent', 'sibling'], 'index'],
        // 字母排序
        alphabetize: { order: 'asc', caseInsensitive: true },
        'newlines-between': 'always'
      }
    ]
}