nuxt3踩坑记录

3,774 阅读4分钟

踩坑一:重置打包路径出现的问题

背景:由于项目要求,我需要将nuxt3的项目全部放于/v2目录下,通过www.xxx.com.hk/V2/ 访问项目,方便运维查找到这个链接时将路径指向nuxt3,于是踩坑之路开始了

首先我的配置

第一步:将pages目录下加了一个V2目录,所有文件放于这个目录中,其他路径不变

image.png

第二步:nuxt.config.ts中配置

app: {
        baseURL: '/',
        buildAssetsDir: '/V2/',
        cdnURL: ''
    }

第三步:执行打包命令

npm run develop-build
pm2 start ecosystem.config.js
这时候,问题出现
  1. 报错404 找不到/V2/路径

image.png

  1. 我很纳闷,不知道哪里出了问题,去官网寻求答案,看到有个这样的配置,试了下,页面可以打开了,大概原理是将这些列出的路径提前预渲染

image.png

  1. 原以为就此大功告成,没想到又遇到了问题,由于我其中一个页面是动态渲染的,没法在这直接列出,在nuxt2中可以配置generate属性加载动态路由,但nuxt3中这个方案似乎没起作用
  2. 我再次寻找其他方案,其中有个配置是可以将ssr:false,这样所有的页面都能打开了,但这明显是不行的,ssr怎么能关闭呢!如果关闭了,我用nuxt3的意义又何在呢!!只能再次放弃
最终解决方案

最后还是我可爱的老大帮我找到了问题出现的原因,原来是我的第一步配置:buildAssetsDir出了问题,根据我的配置,打包出来的文件是这样的

image.png

但是,我们打包后的静态资源路径,应该要是这样的xxx/_nuxt/xxx.js,也就是说,和其他框架不一样,根据nuxt3的原有设定,打包后的路径即使做修改,_nuxt这个东西也不能丢(这就是它坑的地方)!但我又不能直接把V2替换成_nuxt,于是,老大帮我重新写了配置

   app: {
        baseURL: '/',
        buildAssetsDir: '/V2/_nuxt/',
        cdnURL: ''
    }

在这个配置下,打包后的路径变成了

image.png

最终,静态资源请求到的路径是www.xxx.com.hk/V2/_nuxt/xx… 能够正常打开,大功告成!

踩坑二:设置路由映射出现的问题

背景:由于这个页面是重构来的,原来的老路径依旧需要使用,但我的新页面路径并不叫这个名,这时候就需要用到路由映射了,我需要在请求/V2/sale-detail-:id.html的时候自动映射到../pages/V2/saleAndRent/detail-[id]下的目录

  • 问题出现

nuxt2中,我们可以通过设置routes的path和component属性完成配置,but!nuxt3的配置中是没有这个配置的,因为他会寻找所有目录下的名称自动形成路由,这也就导致了我无法在配置文件中直接修改

  • 解决方案

还好,虽然无法修改配置,但可以直接写一个文件将它覆盖,在根目录下新建一个文件app/router.options.js,写入以下配置:

const customRoutes = [
    {
        name: 'sale',
        path: '/V2/sale-detail-:id.html',
        component: () => import('../pages/V2/saleAndRent/detail-[id]')
    },
    {
        name: 'rent',
        path: '/V2/rent-detail-:id.html',
        component: () => import('../pages/V2/saleAndRent/detail-[id]')
    },
    {
        name: 'sale1',
        path: '/sale-detail-:id.html',
        component: () => import('../pages/V2/saleAndRent/detail-[id]')
    },
    {
        name: 'rent1',
        path: '/rent-detail-:id.html',
        component: () => import('../pages/V2/saleAndRent/detail-[id]')
    }
];
export default {
    routes: _routes => [..._routes, ...customRoutes]
};

大功告成!

踩坑三:ga4埋点

  • nuxt3官网有ga4埋点方案,nuxt.com/modules/gta… ,但这个方案是针对setup结构进行的,没有用到setup的项目用这个包会很麻烦,有很多需要重写的配置,还不如自己直接写一个,于是我只能寻求其他解决方案
  • 后面找到了vue-gtag-next包,试了下目前没有什么问题,在这里贴出来
  1. plugins/vue-gtag.client.js
import VueGtag, { trackRouter } from 'vue-gtag-next';

export default defineNuxtPlugin((nuxtApp) => {
    nuxtApp.vueApp.use(VueGtag, {
        property: {
            id: 'G-xxx'
        }
    });
    trackRouter(useRouter());
});
  1. 在debug环境查看:安装Google插件Analytics Debugger

image.png

踩坑四:环境配置判断

  • 原本只要通过process.env.NODE_ENV就能获取当前环境,但是nuxt3在打包的时候会将development切换成production,于是不管你是哪个环境你打包后都是production,这就很扎心

image.png

  • 于是只能利用其他的配置来判断环境,暂时先放弃process.env.NODE_ENV方案
  1. 在根目录添加.env.development和.env.production文件,内容分别为VITE_NUXT_ENV=development、VITE_NUXT_ENV=production
  2. 安装dotenv、在package.json中修改配置,指定当前环境运行的文件
"scripts": {
    "develop-build": "cross-env NODE_ENV=development nuxt build --no-lock --dotenv .env.development",
    "master-build": "cross-env NODE_ENV=production nuxt build --no-lock --dotenv .env.production",
  }
  1. 最后,在客户端使用时,通过import.meta.env.VITE_NUXT_ENV导入
const NUXT_ENV = import.meta.env.VITE_NUXT_ENV;
if (NUXT_ENV == 'development') {
  ...
} else if (NUXT_ENV == 'production') {
  ...
} else {
  ...
}

踩坑五:覆盖覆盖TS报错失败

  • 使用的TS写代码,项目中出现了很多this.parent?.XXXthis.parent?.XXX、this.refs.swipe.swipeTo等一些没有经过类型定义的方法,从而导致报错

image.png

  • 网上找了很多解决方案,基本都是建议在types下面建一个ts文件进行类型拓展,类似这样:
import { ComponentCustomProperties } from 'vue';

declare module 'vue' {
  interface ComponentCustomProperties {
    $handleShare: () => void;
  }
}
  • 但我试过了,目前没起到什么作用,这个问题至今没有解决,虽然留着也不影响项目运行,毕竟它报错不好看呐!如果谁有好的解决方案希望能给我点指导🤣感谢