https://codesandbox.io/s/ww5n6p5mll
Accessing URL object like new URL('http://example.com');
anywhere in server side code.
URL object is accessible globally in server side since it is defined as global interface in node.js.
https://nodejs.org/docs/latest-v10.x/api/globals.html#globals_url
Accessing URL object in server side code causes "ReferenceError URL is not defined".
It had been accessible before and including v2.3.4.
What is your node version?
I found reproduction code in codesandbox is misleading since downgrading to [email protected] didn't solve this issue.
I suppose codesandbox runs older version of node.js or I'm completely misunderstanding system structure of codesandbox.
Anyway, I could reproduce this issue on my local env with following steps.
npx create-nuxt-app url-test
with default settingsnew URL('http://example.com');
in beforeCreate in pages/index.vuenpm run dev
then
npm i [email protected]
npm run dev
@manniL I have tested several minor versions of node v10 including 10.15.1
, 10.6.0
, 10.5.0
, 10.0.0
.
Can't repro.
beforeCreate(){ const a = new URL('http://example.com'); console.log(a) }
Please provide a reproduction repo or similar if you still experience this error
Whoops. Testing with mode: 'spa'
is not a good idea 馃槀
Can repro.
And, npm run dev
reproduces, while npm run build && npm start
does not.
confirm
Also experiencing this issue. Running yarn run dev
leads to a ReferenceError: URL is not defined
error, while running yarn run generate
does not.
Nuxt v2.5.1
Node v10.15.3
I looked into this a bit and it seems that eg URL is (and has been) a non-enumerable property on the global
object. Eg global.Buffer
can still be used but that is enumerable (for now, it will become non-enumerable in v12 probably).
Not sure where to look further for this, but probably its a babel / core-js issue? As a side note, core-js v3 has a URL polyfill.
I'm getting the same issue on Node 10.15.3 (current stable as of this date).
In my case, I'm importing a module that uses URL from the vue file. There are two or three ways to reproduce my case.
URL
dom object"lib": ["dom"]
npm i @types/node
import { Url } from "url"
and/or
import * as url from "url"
const URL = url.Url
VSCode throws error that Url
is a type/interface but it's used as a value in first case. In both cases, they 'work' despite VSCode throwing error, but doesn't work properly. For example:
console.log(new Url("http://localhost:3001"))
prints a Url instance where all properties are null
.
Third or second case:
console.log(URL)
just throws reference error that URL is not defined.
As expected, URL
works just fine in the vue files.
Node version: 10.2.1
Nuxt version: 2.4.0
I am also still getting this, running [email protected], using TypeScript, and after following the instructions on how to include "core-js@3" in my build: when server side rendering, URL is undefined, no matter the form (including many that @chulman444 tried). When accessing URL in the browser, it works fine.
I was able to temporarily get around it by including import "core-js/modules/web.url";
in my scripts, but this seems unnecessary.
Any update on this issue? Currently experiencing the same issue. Server side Url is undefined .
Using node version 12.3.1 and Nuxt 2.8.1
@clarkdo As you are the build grandmaster, do you maybe have an idea how URL
could not be available?
When I test vanilla Vue ssr (from the vue-meta examples) I cannot reproduce this issue. So it seems to be something in Nuxt?
This is because we're using runInNewContext: true
by default in dev mode for avoiding memory leak, but vue does't inject URL
in sandbox global https://github.com/vuejs/vue/blob/master/src/server/bundle-renderer/create-bundle-runner.js#L9.
You can use runInNewContext: false
, but it may cause unexpected memory leak in dev mode.
So I created a pr in Vue for adding URL https://github.com/vuejs/vue/pull/10414.
Another tricky way is using require('url') which will require module outside new context:
created () {
if (process.server) {
const URL = require('url').URL;
console.log(new URL("http://foo"));
}
}
Here's a temporary workaround that pulls from the appropriate place depending on the context.
// ./url.js
import * as url from 'url'
// Create the URL contructor for node or use the existing one for the browser
const urlConstructor = (process.server) ? url.URL : URL
// Create the URLSearchParams contructor for node or use the existing one for the browser
const paramsConstructor = (process.server) ? url.URLSearchParams : URLSearchParams
export { urlConstructor as URL }
export { paramsConstructor as URLSearchParams }
And you just pull it in like this
import { URL, URLSearchParams } from './url'
Another (slightly altered) temporary workaround:
if (process.server) {
const { URLSearchParams } = require('url')
global.URLSearchParams = URLSearchParams
}
Hi @pi0 this should be fixed in the next release according to your recent merge?
Is this in theory fixed in 2.11.0?
@nassan it is not. 2.11.0 was released 17th Dec, the fix was merged into the dev branch on 19th Jan.
I used to have this error too but with the new 2.11.0 I only have Request is not defined
buuuuut in production as well ;-;
Most helpful comment
This is because we're using
runInNewContext: true
by default in dev mode for avoiding memory leak, but vue does't injectURL
in sandbox global https://github.com/vuejs/vue/blob/master/src/server/bundle-renderer/create-bundle-runner.js#L9.You can use
runInNewContext: false
, but it may cause unexpected memory leak in dev mode.So I created a pr in Vue for adding URL https://github.com/vuejs/vue/pull/10414.
Another tricky way is using require('url') which will require module outside new context: