个人网站: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项目打包部署之后访问报错
查看日志:
Cannot find module ‘axios’ from xxx
此问题排查了很久始终未发现问题。突然灵光一现,找不到module是不是 在服务器npm install 是下载不了axios的包。于是,看了下服务器的node_modules ,果然没有axios依赖
查看本地的node_modules,其中有axios
最终,多次npm install 依然没有,只能将本地的 axios 直接打包到服务器的 node_modules 中
重启项目后就可以正常访问了
至于为什么在服务器npm install 不能安装 axios依赖不得而知。只是用土办法解决了问题
希望对你有帮助。