nuxt-community / axios-module

Secure and easy axios integration for Nuxt 2
https://axios.nuxtjs.org
MIT License
1.19k stars 246 forks source link

not work with nuxt 3 #536

Open n4an opened 3 years ago

n4an commented 3 years ago

not work with nuxt 3

Eliophot commented 3 years ago

Hello, same pb with nuxt3

Cannot restart nuxt:  options is not defined 
xiaobai-world commented 3 years ago

i got same problem image

musacivak commented 3 years ago

we can try but same problem again

hiracky16 commented 3 years ago

I got a same problem. I tryed to add this setting to my nuxt config. This solved this problem but a new error occurred on the client side.

modules: [
    "@nuxtjs/axios"
  ],
  axios: {
    baseURL: 'http://localhost:4000',
    options: {
      headers: {}
    }
  },

image

xiongsongsong commented 3 years ago

I think "@nuxtjs/axios" is not required. because useFetch instead it. although useFetch has some bugs.

hiracky16 commented 3 years ago

@xiongsongsong Thank you. I didn't know that it is possible to use useFetch. I'll watch for that some bug. πŸ‘€

gcming commented 3 years ago

@xiongsongsong Thank you. I didn't know that it is possible to use useFetch. I'll watch for that some bug. πŸ‘€

There seems to be no other better solution

rnotorni commented 3 years ago

I set it as below and updated nuxt3(3.0.0-27247485.fb4359e) and it worked.

  modules: [
    ['@nuxtjs/axios',{proxyHeaders:false}],
  ],

The reason I set proxyHeaders to false is because I get an error that serializer is not defined

https://github.com/nuxt-community/axios-module/blob/main/lib/plugin.js#L210-L219

However, I don't think this has solved it.

andysay commented 2 years ago

Cannot restart nuxt: serialize is not defined

Rasul1996 commented 2 years ago

Same problem

ShellarFX commented 2 years ago

You can temporary turn off proxyHeaders in nuxt.config.ts

modules: ["@nuxtjs/axios"],
axios: {
    proxyHeaders: false,
},
sammyaxe commented 2 years ago

In my case I needed to add baseUrl config to get it to work

publicRuntimeConfig: {
        axios: {
            baseURL: '......'
        }
    },
    modules: [
        ['@nuxtjs/axios',{proxyHeaders:false}]
    ],
imamnf commented 2 years ago

I get an error like this, I don't know how to solve it.

Nuxt version v3.0.0-27324955.23397e6

image

sammyaxe commented 2 years ago

I get an error like this, I don't know how to solve it.

Nuxt version v3.0.0-27324955.23397e6

image

please check my answer above, you need to provide baseURL

imamnf commented 2 years ago

I get an error like this, I don't know how to solve it. Nuxt version v3.0.0-27324955.23397e6 image

please check my answer above, you need to provide baseURL

I've add the baseURL to the config, but still got the error

modules: ["@nuxtjs/axios", {proxyHeaders: false}], publicRuntimeConfig: { axios: { baseURL: process.env.AXIOS_BASE_URL || 'http://localhost:3000/api' } }

rnotorni commented 2 years ago

@imamnf

Did you include the following commit?

https://github.com/nuxt-community/axios-module/pull/516/commits/c539548728c11aa1a1f64e6fbc127165c09a9ada

Without this commit, even the client will try to get the baseURL on the server side. Because process.browser is returning false.

https://github.com/nuxt-community/axios-module/blob/a99b56c11166cc1b0cde89fe5982c853ced17c57/lib/plugin.js#L196-L198

imamnf commented 2 years ago

@imamnf

Did you include the following commit?

c539548

Without this commit, even the client will try to get the baseURL on the server side. Because process.browser is returning false.

https://github.com/nuxt-community/axios-module/blob/a99b56c11166cc1b0cde89fe5982c853ced17c57/lib/plugin.js#L196-L198

how to include that? I don't know where the file is

rnotorni commented 2 years ago

Sorry.

This hasn't been released yet :bow:

In my case I am using patch-package to modify node_modules/@nuxtjs/axios/lib/plugin.js files

$cat patches/@nuxtjs+axios+5.13.6.patch

diff --git a/node_modules/@nuxtjs/axios/lib/module.js b/node_modules/@nuxtjs/axios/lib/module.js
index 36d41dd..e6f6b96 100755
--- a/node_modules/@nuxtjs/axios/lib/module.js
+++ b/node_modules/@nuxtjs/axios/lib/module.js
@@ -38,9 +38,9 @@ function axiosModule (_moduleOptions) {
   }

   // Transpile defu (IE11)
-  if (nuxt.options.build.transpile /* nuxt 1 */) {
-    nuxt.options.build.transpile.push(({ isClient }) => isClient && 'defu')
-  }
+  // if (nuxt.options.build.transpile /* nuxt 1 */) {
+  //   nuxt.options.build.transpile.push(({ isClient }) => isClient && 'defu')
+  // }

   // Default prefix
   const prefix = process.env.API_PREFIX || moduleOptions.prefix || '/'
diff --git a/node_modules/@nuxtjs/axios/lib/plugin.js b/node_modules/@nuxtjs/axios/lib/plugin.js
index fc4493e..b5388b7 100644
--- a/node_modules/@nuxtjs/axios/lib/plugin.js
+++ b/node_modules/@nuxtjs/axios/lib/plugin.js
@@ -193,9 +193,10 @@ export default (ctx, inject) => {
   // runtimeConfig
   const runtimeConfig = ctx.$config && ctx.$config.axios || {}
   // baseURL
-  const baseURL = process.browser
-    ? (runtimeConfig.browserBaseURL || runtimeConfig.browserBaseUrl || runtimeConfig.baseURL || runtimeConfig.baseUrl || '<%= options.browserBaseURL || '' %>')
-      : (runtimeConfig.baseURL || runtimeConfig.baseUrl || process.env._AXIOS_BASE_URL_ || '<%= options.baseURL || '' %>')
+  const baseURL = '<%= options.baseURL || '' %>'
+  // const baseURL = process.browser
+  //   ? (runtimeConfig.browserBaseURL || runtimeConfig.browserBaseUrl || runtimeConfig.baseURL || runtimeConfig.baseUrl || '<%= options.browserBaseURL || '' %>')
+  //     : (runtimeConfig.baseURL || runtimeConfig.baseUrl || process.env._AXIOS_BASE_URL_ || '<%= options.baseURL || '' %>')

   // Create fresh objects for all default header scopes
   // Axios creates only one which is shared across SSR requests!
BobbieGoede commented 2 years ago

Hmm the issue you are talking about should already be fixed by this PR nuxt/framework#516 but there haven't been any releases of the this module since June.

@pi0 is there are reason why changes haven't been released?

rnotorni commented 2 years ago

I think nuxt/framework#516 only fixes the problem with the baseURL.

I think there are at least three problems.

  1. serializer is not defined
  2. baseURL
  3. Expected pattern to be a non-empty string (in build)

The baseURL problem happens because process.browser and process.env are undefined in client. We can see this in console.log

γ‚Ήγ‚―γƒͺγƒΌγƒ³γ‚·γƒ§γƒƒγƒˆ 2021-12-22 11 55 03

Regarding the third, it happens in the following place at build time.

https://github.com/nuxt-community/axios-module/blob/main/lib/module.js#L41-L43

So nuxt/framework#516 will fix the baseURL problem and this issue itself will not be fixed.

bmulholland commented 2 years ago

Auth module depends on axios, so that package can't have nuxt 3 support until axios is fixed: https://github.com/nuxt-community/auth-module/issues/1520

bcspragu commented 2 years ago

I'm not familiar with what this plugin does, but for someone trying to get axios working quickly with Nuxt 3, you can add a quick plugin, like:

plugins/axios.ts ```ts import { defineNuxtPlugin } from '#app' import axios from 'axios' export default defineNuxtPlugin(() => { return { provide: { axios: () => { return axios.create({/* configuration here */}) } } } }) ```

And then you can access it like:

Usage example ```vue ```

This works with both SSR and client-side as far as I can tell.

Denoder commented 2 years ago

Here's a small module u can use to replicate this module while you guys wait for an update. You need to install axios, @nuxtjs/proxy, consola, and defu as devDependencies or dependencies for it to work.

I got the proxy plugin working but you have to use it a bit differently, for it to work the same you need to set axios.proxy as true then add a proxy object outside of the axios object with your proxy config (like you would when installing just the proxy module.)

Fixed.

nuxt.config.ts ```ts import { defineNuxtConfig } from 'nuxt3' // https://v3.nuxtjs.org/docs/directory-structure/nuxt.config export default defineNuxtConfig({ // no need to set @nuxtjs/proxy here buildModules: [ '~/modules/nuxt-axios', ], axios: { credentials: true, proxy: true // if you want to enable proxy }, proxy: { //proxy config } }) ```
/modules/nuxt-axios/index.ts ```ts import defu from 'defu' import consola from 'consola' import { resolve } from 'path' import { defineNuxtModule, addPluginTemplate } from '@nuxt/kit' const CONFIG_KEY = 'axios' const logger = consola.withScope('nuxt:axios') export default defineNuxtModule({ meta: { name: 'nuxt-axios', configKey: CONFIG_KEY, compatibility: { nuxt: '^3.0.0' } }, async setup(_moduleOptions, nuxt) { // Combine options const moduleOptions = { ...nuxt.options.axios, ..._moduleOptions, ...(nuxt.options.runtimeConfig && nuxt.options.runtimeConfig.axios) } // Default port const defaultPort = process.env.API_PORT || moduleOptions.port || process.env.PORT || process.env.npm_package_config_nuxt_port || (nuxt.options.server && nuxt.options.server.port) || 3000 // Default host let defaultHost = process.env.API_HOST || moduleOptions.host || process.env.HOST || process.env.npm_package_config_nuxt_host || (nuxt.options.server && nuxt.options.server.host) || 'localhost' /* istanbul ignore if */ if (defaultHost === '0.0.0.0') { defaultHost = 'localhost' } // Transpile defu (IE11) if (nuxt.options.build.transpile && process.client/* nuxt 1 */) { nuxt.options.build.transpile.push('defu') } // Default prefix const prefix = process.env.API_PREFIX || moduleOptions.prefix || '/' // HTTPS const https = Boolean(nuxt.options.server && nuxt.options.server.https) // Headers const headers = { common: { Accept: 'application/json, text/plain, */*' }, delete: {}, get: {}, head: {}, post: {}, put: {}, patch: {} } // Support baseUrl alternative if (moduleOptions.baseUrl) { moduleOptions.baseURL = moduleOptions.baseUrl delete moduleOptions.baseUrl } if (moduleOptions.browserBaseUrl) { moduleOptions.browserBaseURL = moduleOptions.browserBaseUrl delete moduleOptions.browserBaseUrl } // Apply defaults const options = defu(moduleOptions, { baseURL: `http://${defaultHost}:${defaultPort}${prefix}`, browserBaseURL: undefined, credentials: false, debug: false, progress: true, proxyHeaders: true, proxyHeadersIgnore: [ 'accept', 'cf-connecting-ip', 'cf-ray', 'content-length', 'content-md5', 'content-type', 'host', 'if-none-match', 'if-modified-since', 'x-forwarded-host', 'x-forwarded-port', 'x-forwarded-proto' ], proxy: false, retry: false, https, headers }) // ENV overrides /* istanbul ignore if */ if (process.env.API_URL) { options.baseURL = process.env.API_URL } /* istanbul ignore if */ if (process.env.API_URL_BROWSER) { options.browserBaseURL = process.env.API_URL_BROWSER } // Default browserBaseURL if (typeof options.browserBaseURL === 'undefined') { options.browserBaseURL = options.proxy ? prefix : options.baseURL } // Normalize options if (options.retry === true) { options.retry = {} } // Convert http:// to https:// if https option is on if (options.https === true) { const https = s => s.replace('http://', 'https://') options.baseURL = https(options.baseURL) options.browserBaseURL = https(options.browserBaseURL) } // globalName options.globalName = nuxt.options.globalName || 'nuxt' // Register plugin addPluginTemplate({ src: resolve(__dirname, 'plugin.ts'), filename: 'axios.options.mjs', options }) // Proxy integration if (options.proxy) { nuxt.options.proxy = typeof options.proxy === 'object' ? options.proxy : (typeof nuxt.options.proxy === 'object' ? nuxt.options.proxy : {}) nuxt['__module_container__'].requireModule('@nuxtjs/proxy') } // Set _AXIOS_BASE_URL_ for dynamic SSR baseURL process.env._AXIOS_BASE_URL_ = options.baseURL logger.debug(`baseURL: ${options.baseURL}`) logger.debug(`browserBaseURL: ${options.browserBaseURL}`) } }) ```
/modules/nuxt-axios/plugin.ts ```ts import { defineNuxtPlugin } from '#app' import Axios from 'axios' import defu from 'defu' '<% if (options.retry) { %>' import axiosRetry from 'axios-retry' '<% } %>' // Axios.prototype cannot be modified const axiosExtra = { setBaseURL(baseURL) { this.defaults.baseURL = baseURL }, setHeader(name, value, scopes = 'common') { for (const scope of Array.isArray(scopes) ? scopes : [scopes]) { if (!value) { delete this.defaults.headers[scope][name]; continue } this.defaults.headers[scope][name] = value } }, setToken(token, type, scopes = 'common') { const value = !token ? null : (type ? type + ' ' : '') + token this.setHeader('Authorization', value, scopes) }, onRequest(fn) { this.interceptors.request.use(config => fn(config) || config) }, onResponse(fn) { this.interceptors.response.use(response => fn(response) || response) }, onRequestError(fn) { this.interceptors.request.use(undefined, error => fn(error) || Promise.reject(error)) }, onResponseError(fn) { this.interceptors.response.use(undefined, error => fn(error) || Promise.reject(error)) }, onError(fn) { this.onRequestError(fn) this.onResponseError(fn) }, create(options) { return createAxiosInstance(defu(options, this.defaults)) } } // Request helpers ($get, $post, ...) for (const method of ['request', 'delete', 'get', 'head', 'options', 'post', 'put', 'patch']) { axiosExtra['$' + method] = function () { return this[method].apply(this, arguments).then(res => res && res.data) } } const extendAxiosInstance = axios => { for (const key in axiosExtra) { axios[key] = axiosExtra[key].bind(axios) } } const createAxiosInstance = axiosOptions => { // Create new axios instance const axios = Axios.create(axiosOptions) axios.CancelToken = Axios.CancelToken axios.isCancel = Axios.isCancel axios.isAxiosError = Axios.isAxiosError // Extend axios proto extendAxiosInstance(axios) // Intercept to apply default headers axios.onRequest((config) => { config.headers = { ...axios.defaults.headers.common, ...config.headers } }) // Setup interceptors '<% if (options.debug) { %>'; setupDebugInterceptor(axios); '<% } %>' '<% if (options.credentials) { %>'; setupCredentialsInterceptor(axios); '<% } %>' '<% if (options.progress) { %>'; setupProgress(axios); '<% } %>' '<% if (options.retry) { %>'; axiosRetry(axios, JSON.parse('<%= JSON.stringify(options.retry) %>')); '<% } %>' return axios } '<% if (options.debug) { %>' const log = (level, ...messages) => console[level]('[Axios]', ...messages) const setupDebugInterceptor = axios => { // request axios.onRequestError(error => { log('error', 'Request error:', error) }) // response axios.onResponseError(error => { log('error', 'Response error:', error) }) axios.onResponse(res => { log( 'info', '[' + (res.status + ' ' + res.statusText) + ']', '[' + res.config.method.toUpperCase() + ']', res.config.url) if (process.client) { console.log(res) } else { console.log(JSON.stringify(res.data, undefined, 2)) } return res }) } '<% } %>' '<% if (options.credentials) { %>' const setupCredentialsInterceptor = axios => { // Send credentials only to relative and API Backend requests axios.onRequest(config => { if (config.withCredentials === undefined) { if (!/^https?:\/\//i.test(config.url) || config.url.indexOf(config.baseURL) === 0) { config.withCredentials = true } } }) } '<% } %>' '<% if (options.progress) { %>' const setupProgress = (axios) => { if (process.server) { return } // A noop loading inteterface for when $nuxt is not yet ready const noopLoading = { finish: () => { }, start: () => { }, fail: () => { }, set: () => { } } const $loading = () => { const $nuxt = typeof window !== 'undefined' && window['$<%= options.globalName %>'] return ($nuxt && $nuxt.$loading && $nuxt.$loading.set) ? $nuxt.$loading : noopLoading } let currentRequests = 0 axios.onRequest(config => { if (config && config.progress === false) { return } currentRequests++ }) axios.onResponse(response => { if (response && response.config && response.config.progress === false) { return } currentRequests-- if (currentRequests <= 0) { currentRequests = 0 $loading().finish() } }) axios.onError(error => { if (error && error.config && error.config.progress === false) { return } currentRequests-- if (Axios.isCancel(error)) { if (currentRequests <= 0) { currentRequests = 0 $loading().finish() } return } $loading().fail() $loading().finish() }) const onProgress = e => { if (!currentRequests || !e.total) { return } const progress = ((e.loaded * 100) / (e.total * currentRequests)) $loading().set(Math.min(100, progress)) } axios.defaults.onUploadProgress = onProgress axios.defaults.onDownloadProgress = onProgress } '<% } %>' export default defineNuxtPlugin(ctx => { // runtimeConfig const runtimeConfig = ctx.$config && ctx.$config.axios || {} // baseURL const baseURL = process.client ? (runtimeConfig.browserBaseURL || runtimeConfig.browserBaseUrl || runtimeConfig.baseURL || runtimeConfig.baseUrl || '<%= options.browserBaseURL %>' || '') : (runtimeConfig.baseURL || runtimeConfig.baseUrl || process.env._AXIOS_BASE_URL_ || '<%= options.baseURL %>' || '') // Create fresh objects for all default header scopes // Axios creates only one which is shared across SSR requests! // https://github.com/mzabriskie/axios/blob/master/lib/defaults.js const headers = JSON.parse('<%= JSON.stringify(options.headers) %>') const axiosOptions = { baseURL, headers } '<% if (options.proxyHeaders) { %>' // Proxy SSR request headers if (process.server && ctx.ssrContext.req && ctx.ssrContext.req.headers) { const reqHeaders = { ...ctx.ssrContext.req.headers } for (const h of '<%= options.proxyHeadersIgnore %>'.split(',')) { delete reqHeaders[h] } axiosOptions.headers.common = { ...reqHeaders, ...axiosOptions.headers.common } } '<% } %>' if (process.server) { // Don't accept brotli encoding because Node can't parse it axiosOptions.headers.common['accept-encoding'] = 'gzip, deflate' } const axios = createAxiosInstance(axiosOptions) ctx.vueApp.provide('axios', axios); ctx.provide('axios', axios); }) ```
lacorde commented 2 years ago

I can testify, @bcspragu's proposal works like a charm !

Either way, some other community modules such as the nuxt-community/auth-module are waiting for this update to start migrating to Nuxt 3 themselves. Would love to see @Teranode's fix tested, and hopefully included.

Benyaminrmb commented 2 years ago

Sorry.

This hasn't been released yet πŸ™‡

In my case I am using patch-package to modify node_modules/@nuxtjs/axios/lib/plugin.js files

$cat patches/@nuxtjs+axios+5.13.6.patch

diff --git a/node_modules/@nuxtjs/axios/lib/module.js b/node_modules/@nuxtjs/axios/lib/module.js
index 36d41dd..e6f6b96 100755
--- a/node_modules/@nuxtjs/axios/lib/module.js
+++ b/node_modules/@nuxtjs/axios/lib/module.js
@@ -38,9 +38,9 @@ function axiosModule (_moduleOptions) {
   }

   // Transpile defu (IE11)
-  if (nuxt.options.build.transpile /* nuxt 1 */) {
-    nuxt.options.build.transpile.push(({ isClient }) => isClient && 'defu')
-  }
+  // if (nuxt.options.build.transpile /* nuxt 1 */) {
+  //   nuxt.options.build.transpile.push(({ isClient }) => isClient && 'defu')
+  // }

   // Default prefix
   const prefix = process.env.API_PREFIX || moduleOptions.prefix || '/'
diff --git a/node_modules/@nuxtjs/axios/lib/plugin.js b/node_modules/@nuxtjs/axios/lib/plugin.js
index fc4493e..b5388b7 100644
--- a/node_modules/@nuxtjs/axios/lib/plugin.js
+++ b/node_modules/@nuxtjs/axios/lib/plugin.js
@@ -193,9 +193,10 @@ export default (ctx, inject) => {
   // runtimeConfig
   const runtimeConfig = ctx.$config && ctx.$config.axios || {}
   // baseURL
-  const baseURL = process.browser
-    ? (runtimeConfig.browserBaseURL || runtimeConfig.browserBaseUrl || runtimeConfig.baseURL || runtimeConfig.baseUrl || '<%= options.browserBaseURL || '' %>')
-      : (runtimeConfig.baseURL || runtimeConfig.baseUrl || process.env._AXIOS_BASE_URL_ || '<%= options.baseURL || '' %>')
+  const baseURL = '<%= options.baseURL || '' %>'
+  // const baseURL = process.browser
+  //   ? (runtimeConfig.browserBaseURL || runtimeConfig.browserBaseUrl || runtimeConfig.baseURL || runtimeConfig.baseUrl || '<%= options.browserBaseURL || '' %>')
+  //     : (runtimeConfig.baseURL || runtimeConfig.baseUrl || process.env._AXIOS_BASE_URL_ || '<%= options.baseURL || '' %>')

   // Create fresh objects for all default header scopes
   // Axios creates only one which is shared across SSR requests!

its still not working image

tntsoft commented 2 years ago

Any news on this? Maybe someone can review the @Teranode pull request.

@pi0 could you please assist (not sure who to tag)?

nuxt/auth is dependent on this, and it's quite a pain to rewrite that authentication package in nuxt 3.

Denoder commented 2 years ago

@tntsoft You could try using these packages until they update theirs: https://github.com/Teranode/nuxt-module-alternatives

paleacci commented 2 years ago

create plugins/axios.js and add this code inside

`import axios from 'axios'

export default () => { return { provide: { axios: axios.default } } } `

then you can use this.$axios

lacorde commented 2 years ago

Seems like the upgrade is quite straightforward according to @Teranode, @bcspragu or @paleacci.

A first step could be to create a "next" branch that would allow axios-dependent projects to start migrating to Nuxt 3 ?

kissu commented 2 years ago

You don't really need that package anymore, ohmyfetch is the recommended approach anyway: https://v3.nuxtjs.org/api/utils/$fetch#fetch

gromann commented 1 year ago

I had the same issue and fixed it by building my own plugin using the normal axios npm module (advantage: you can build multiple plugins for multiple APIs and defining interceptors is pretty straight forward) I have described the steps you need in this article I hope that helps.

robertpatrick commented 1 year ago

This module does not work with Nuxt 3 (see discussion in #562). It seems that the author is not interested in making a real Nuxt 3 version of this module and is instead recommending the use of $fetch.

kissu commented 1 year ago

@robertpatrick here is my answer: https://stackoverflow.com/a/74966587/8816585

Basically, you don't need to use it anymore because it's included + lightweight (and with better support) because part of the unJS ecosystem. πŸ‘ŒπŸ»