Vue2 项目重构为 nuxt.js 项目 axios 踩的坑

个人网站:https://aijianli.site/ 可以免费在线制作简历,提供PDF下载,方便快捷。

为了解决自己开发的简历制作网站爱简历的 SEO 问题 ,将前端 Vue 项目改造成 nuxt.js 项目。在此过程中axios的引用出现的问题困扰良久,差点放弃改造。以下记录下了问题解决的办法。

一、axios 引入问题

1.1 引入全局 js, axios 引入报错

重构的第一步就是将原 Vue 项目中在 main.js 引入的 js 放到 plugins 中去 。原Vue项目中引入了自己封装的 core.js 。如下

import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui';

Vue.use(ElementUI)
// 注册模块
import "./components/util-js/global-regist-module.js"

Vue.config.productionTip = false
import "../node_modules/element-ui/lib/theme-chalk/index.css";
import "./assets/js/core.js";
import "./assets/css/cover-elementui-style.less";
import router from './router';


new Vue({
  render: h => h(App),
  router: router
}).$mount('#resume-creator-user')

在 nuxt.js 项目中,通过 plugins 配置项目初始化时需要引入的js,因此在 nuxt.config.js中配置了core.js

plugins: [
    '@/plugins/element-ui',
    // core 中使用到了window,使用ssr会直接报错,此组件不适用ssr
    { src: '@/plugins/core', ssr: true },
 ]

此时启动项目就会报错:

require() of ES Module D:\project\aijianli\test\node_modules\axios\index.js from D:\project\aijianli\test\node_modules\vue-server-renderer\build.dev.js not supported. Instead change the require of index.js in D:\project\aijianli\test\node_modules\vue-server-renderer\build.dev.js to a dynamic import() which is available in all CommonJS modules.

查阅了大量blog, 通过使用低版本 axios, 使用 @bundled-es-modules/axios 都未能解决。报如下错

## Cannot use import statement outside a module

到此,实在没有更好的办法,只能在使用 nuxt.js 自带的 @nuxtjs/axios

1.2 axios 开发的内容改造成 @nuxtjs/axios

将原本使用 axios 开发的内容改造成 @nuxtjs/axios
原Vue的axios拦截器

import axios from "axios";
import {
    Notification
} from "element-ui";
import qs from "qs";

const baseUrl = "https://aijianli.site/api";
// const baseUrl = "http://localhost:8081/api";
let config = {
    baseURL: baseUrl,
    timeout: 60000,
    responseType: 'json',
    headers: {
        ["Access-Control-Allow-Origin"]: '*',
        ['Pragma: no-cache']: false,
        ['Access-Control-Allow-Methods']: 'POST,GET,OPTIONS,DELETE',
        ['Access-Control-Allow-Headers']: 'x-requested-with,content-type'
    }
};
const instance = axios.create(config)

//请求拦截器
instance.interceptors.request.use(
    (config) => {
        if (config.url !== "/api/user/login" && config.url !== "/api/user/regist") { // 判断请求是否是登录接口
            config.headers.token = localStorage.getItem("token"); // 如果不是登录接口,就给请求头里面设置token
        }
        return config; // 返回这个配置对象,如果没有返回,这个请求就不会发送出去
    },
    (error) => {
        return Promise.reject(error);
    }
)

// 响应拦截器
instance.interceptors.response.use(
    (res) => {
        let code = res.data.state // 获取后端返回的状态码

        if (code === 200) { // 成功
            if (res.data.message) {
                Notification({
                    message: res.data.message,
                    type: "success"
                })
            }
            return res.data // 返回里面的数据,在使用这个axios时,获取到的东西就是这里返回的东西
        } else {
            Notification({
                message: res.data.message,
                type: "error"
            })
            return Promise.reject(res.data.message);
        }

    },
    (error) => {
        Notification({
            message: "服务器错误:" + error.message,
            type: "error"
        })
        return Promise.reject(error);
    }
)
class axiosUtil {
    constructor() {
        this.axios = instance;
    }

    post(url, datas) {
        return this.axios.post(url, datas)
    }

    get(url, datas) {
        url = url + qs.stringify(datas, {
            addQueryPrefix: true
        })
        return this.axios.get(url);
    }

    //在此封装所有的后端接口
    /*-------------用户相关接口的开始-------------------------- */
    /**
     * 用户注册
     * @param {*} data 
     * @returns 
     */
    regist(datas) {
        return this.post("/user/regist", datas);
    }

    login(datas) {
        return this.post("/user/login", datas);
    }
    // 所有接口

}

改造成

import {
    Notification
} from "element-ui";

import axiosUtil from "../assets/js/api.js";
export default function ({ $axios }) {
    //请求拦截器
    $axios.interceptors.request.use(
        (config) => {
            console.log("---进入了请求拦截器-----")
            console.log(config)
            if (process.client && config.url !== "/api/user/login" && config.url !== "/api/user/regist") { // 判断请求是否是登录接口
                config.headers.token = localStorage.getItem("token"); // 如果不是登录接口,就给请求头里面设置token
            }
            return config; // 返回这个配置对象,如果没有返回,这个请求就不会发送出去
        },
        (error) => {
            return Promise.reject(error);
        }
    )

    // 响应拦截器
    $axios.interceptors.response.use(
        (res) => {
            let code = res.data.state // 获取后端返回的状态码

            if (code === 200) { // 成功
                if (res.data.message) {
                    Notification({
                        message: res.data.message,
                        type: "success"
                    })
                }
                return res.data // 返回里面的数据,在使用这个axios时,获取到的东西就是这里返回的东西
            } else {
                Notification({
                    message: res.data.message,
                    type: "error"
                })
                return Promise.reject(res.data.message);
            }

        },
        (error) => {
            Notification({
                message: "服务器错误:" + error.message,
                type: "error"
            })
            return Promise.reject(error);
        }
    )

    // 将所有 api 放到 $axios.api
    let util = new axiosUtil($axios);
    $axios.api = util;
}

因此,建议Vue项目改造成 nuxt.js 项目首先就是先改造 axios,直接改造成 nuxt 自带的插件

二、部署报错问题

第一步中改造了axios,在本地允许正常,将nuxt项目打包部署之后访问报错

image.png
查看日志:
Cannot find module ‘axios’ from xxx
image.png

此问题排查了很久始终未发现问题。突然灵光一现,找不到module是不是 在服务器npm install 是下载不了axios的包。于是,看了下服务器的node_modules ,果然没有axios依赖

image.png

查看本地的node_modules,其中有axios

image.png

最终,多次npm install 依然没有,只能将本地的 axios 直接打包到服务器的 node_modules 中

image.png

重启项目后就可以正常访问了

image.png

至于为什么在服务器npm install 不能安装 axios依赖不得而知。只是用土办法解决了问题

希望对你有帮助。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Vue SSR(Server Side Rendering)服务端渲染是一种在服务器端将Vue组件渲染成HTML字符串的技术。Vue SSR可以提高应用程序的性能和搜索引擎优化。在此基础上,Nuxt.js是一个基于Vue.js的通用应用框架,它通过一个命令行工具来创建和管理Vue SSR应用程序。Nuxt.js提供了一些默认的配置,使得创建Vue SSR应用程序变得非常简单。 CNode社区是一个专门讨论Node.js技术的社区,许多Node.js开发者都会在这里交流。在本文中,我们将使用Nuxt.js来创建一个CNode社区的SSR应用程序。我们将使用CNode社区提供的API来获取帖子列表,然后使用Nuxt.js来将其渲染成HTML字符串,最后将其呈现给用户。 首先,我们需要安装Nuxt.js和一些必要的依赖项。可以使用以下命令来安装: ``` npm install --save nuxt axios ``` 接下来,我们需要配置Nuxt.js。我们可以在项目的根目录中创建一个`nuxt.config.js`文件来配置Nuxt.js。我们需要配置Nuxt.js的一些选项,例如页面路由、构建选项、插件等等。以下是一个简单的配置示例: ```javascript module.exports = { head: { title: 'CNode社区', meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, ], }, modules: ['@nuxtjs/axios'], axios: { baseURL: 'https://cnodejs.org/api/v1', }, plugins: ['~/plugins/vue-markdown.js'], }; ``` 在上面的配置中,我们设置了页面标题,设置了meta标签,使用了`@nuxtjs/axios`模块来发送HTTP请求,设置了API的基本URL,以及添加了一个Vue插件来渲染Markdown。 接下来,我们需要创建页面。在Nuxt.js中,每个`.vue`文件都可以作为一个页面,它们位于`pages`目录中。我们可以创建一个名为`index.vue`的文件来显示CNode社区的帖子列表。以下是`index.vue`的示例代码: ```html <template> <div> <h1>CNode社区</h1> <ul> <li v-for="post in posts" :key="post.id"> <router-link :to="'/post/' + post.id">{{ post.title }}</router-link> </li> </ul> </div> </template> <script> export default { asyncData({ $axios }) { return $axios.get('/topics').then((res) => { return { posts: res.data.data }; }); }, }; </script> ``` 在上面的代码中,我们使用Vue.js的`v-for`指令来遍历每个帖子,并使用Vue.js的`router-link`组件来呈现帖子标题和链接。我们还使用Nuxt.js提供的`asyncData`方法来在服务器端获取帖子列表。在这个方法中,我们使用了`$axios`模块来发送HTTP请求,获取帖子列表数据,并将其存储在`posts`变量中。 最后,我们需要启动应用程序。可以使用以下命令来启动: ``` npm run dev ``` 这将启动一个本地服务器,可以在浏览器中访问`http://localhost:3000`来查看我们的应用程序。 总结一下,通过Nuxt.jsVue SSR技术,我们可以快速创建一个CNode社区帖子列表的SSR应用程序。我们只需要简单地配置Nuxt.js,然后创建一个`.vue`文件作为页面,并使用`asyncData`方法来获取数据和渲染页面。 ### 回答2: Vue SSR服务端渲染是指在服务端将Vue组件渲染为HTML,然后将其发送给浏览器进行展示。这种技术的好处是可以提高页面的渲染速度和SEO友好性。 Nuxt.js是一个基于Vue.js的服务端渲染应用框架,它提供了很多方便的特性和工具,可以帮助我们快速开发和部署Vue SSR应用。 CNode社区是一个以Node.js为后端,Vue.js为前端的技术社区。我们可以使用Nuxt.js来打造CNode社区的SSR应用,从而提升用户体验和搜索引擎的收录。 首先,我们可以使用Nuxt.js的CLI工具来初始化一个新的项目,选择SSR模式。然后,我们可以根据CNode社区的需求,创建相应的页面组件,如首页、帖子详情页、用户个人中心等。 在创建这些页面组件的过程中,我们可以使用Nuxt.js提供的一些特性,如动态路由、全局组件等,来简化开发和提升复用性。 在每个页面组件中,我们可以通过asyncData方法来获取数据,并将其作为组件的属性进行渲染。这样,我们就可以在服务端获取数据并渲染好HTML,然后将其发送到浏览器进行展示。 为了提高页面的加载速度,我们可以使用Nuxt.js的代码拆分功能,将不同页面的代码拆分成多个小块,并按需加载。这样,用户只需要加载当前页面所需的代码,可以减少页面的加载时间。 最后,我们可以使用Nuxt.js的部署工具来快速部署CNode社区的SSR应用。Nuxt.js支持将应用打包成静态文件,并可以轻松地部署到各种服务器或服务商上。 总结来说,通过深入学习Vue SSR服务端渲染,借助Nuxt.js框架,我们可以有效地打造CNode社区的SSR应用,提升用户体验和搜索引擎的收录,从而更好地为用户提供技术交流和资源分享的平台。 ### 回答3: Vue SSR(服务端渲染)是一种将Vue应用程序在服务器端进行渲染的技术。通过使用服务器端渲染,可以将静态HTML页面返回给客户端浏览器,从而提高首次加载速度和搜索引擎的抓取能力。而Nuxt.js是一个基于Vue SSR的框架,提供了一整套开箱即用的功能以快速构建Vue SSR应用程序。 在使用Nuxt.js构建CNode社区时,我们可以深入学习Vue SSR服务端渲染的原理和技巧。首先,我们需要了解Nuxt.js提供的目录结构和配置文件,这些会帮助我们更好地组织和管理前端开发流程。接下来,我们需要学习如何使用Nuxt.js的路由系统和异步数据获取功能,这些能帮助我们实现动态的页面渲染和数据预取。 在深入学习Vue SSR服务端渲染时,我们还需要了解服务器端渲染的优势和限制。通过SSR,我们可以提供更好的搜索引擎优化和用户体验,但也需要注意应用程序中可能出现的问题,比如对于某些浏览器不支持的特性、第三方库的兼容性和性能方面的考虑等。 除此之外,为了更好地打造CNode社区,我们还需要学习如何使用Nuxt.js的插件系统和组件库,以及如何与后端API进行交互和数据处理。通过深入学习Vue SSR服务端渲染和使用Nuxt.js打造CNode社区,我们可以提升自己的前端开发技能,并且能够快速构建出高效、可扩展的Vue SSR应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值