denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
94k stars 5.23k forks source link

Support Vite #15427

Closed brillout closed 1 year ago

brillout commented 2 years ago

Is supporting Vite on Deno's radar?

Although many Node.js libraries already work with Deno, Vite is a whole different beast and probably needs changes on Deno's side.

Note that it's not only about supporting Vite, but also its entire ecosystem (SvelteKit, vite-plugin-ssr, etc.).

FYI Bun is working on supporting Vite: https://github.com/oven-sh/bun/issues/250#issuecomment-1195153860.

AnInternetTroll commented 2 years ago

Check out https://github.com/denoland/deno/issues/12577

bartlomieju commented 2 years ago

Yes, it's a personal goal of mine to support Vite. In fact you can already run Vite in Deno, although the invocation is somewhat long:

deno run -A --compat --unstable ./node_modules/.bin/vite build

There's a caveat though - HMR is still not supported (ie. vite dev subcommand won't refresh stuff in the browser), due to a single missing API (https://github.com/denoland/deno_std/pull/2457) that I hope to be fixed by the time Deno v1.25 is released. Besides that I was able to successfully build different projects using Vue or Svelte(Kit) with Vite.

We also hope to further improve experience and current proposal that is in the works will allow to invoke it as:

deno run -A npm:vite dev
LukaHarambasic commented 2 years ago

Heyho, Could some one explain me why Vite needs a special treatment? I'm aware what Vite has done and is going to do for the JS eco system / developer system. But why has a JS runtime to be adapted for a library? Is it a bug/ missing feature in Deno or is Vite a special snow flake? Thanks

Soremwar commented 2 years ago

@LukaHarambasic I don't see how any special treatment has been given to Vite. Deno has a compatibility layer with Node that enables the use of non packages with Deno, nothing additional to improving that layer has been done in order to support Vite

josh-hemphill commented 2 years ago

Vite just uses some of the still missing APIs from the node compat module, most of it isn't a change to the runtime. Though I'm curious how esbuild (which Vite depends on) is going to be handled, because by default Vite loads binaries for it, and still says in the docs that using webassembly version of esbuild is much slower.

kidonng commented 2 years ago

@josh-hemphill If we are talking about Node compat, the esbuild binary is already downloaded into node_modules by the package manager, when Vite child_process.spawns esbuild, the compat library will translate it to Deno.spawnChild. WASM version of esbuild is only added recently and for different use cases (e.g. on Deno Deploy).

bartlomieju commented 2 years ago

Inching closer on Vite support, finally able to use HMR:

https://user-images.githubusercontent.com/13602871/183830066-66d83ed4-973a-46da-90c8-ddf44a6a8fed.mov

bartlomieju commented 2 years ago

We've landed all necessary APIs to support Vite and we are able to run various Vite commands with success.

There are a few missing pieces to make the experience top notch and we'll address them in the next weeks.

For those who want to try it out for themselves, here's what you need to do (using Vue template):

  1. Make sure you have Deno v1.25 installed
  2. npm create vite@latest my-vue-app -- --template vue
  3. cd my-vue-app
  4. npm install <--- (this step will not be necessary in the future, right now we can't teach rollup to use Deno's NPM cache, but we'll address it by having symlinked node_modules/ directory)
  5. Change vite.config.js with following contents:
    
    import { defineConfig } from 'npm:vite'
    import vue from 'npm:@vitejs/plugin-vue'
    import "npm:vue@3.2.37/compiler-sfc" // <--- this step won't be needed in the future either

// https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()] })


6. `deno run -A --unstable npm:vite`

Feedback much appreciated!
pillowsoft commented 2 years ago

FYI, I tried your recommendation above and it seemed to work well for Vue. I then tried the same with svelte. Alas, that did not seem to work (it never resolved the localhost endpoint). No errors in the terminal. Here's the repro repo:

https://github.com/pillowsoft/my-svelte-deno-app

Just wanted to give you feedback as requested.

Looking forward to npm free vite builds!!!!

Screen Shot 2022-08-25 at 10 02 17 AM Screen Shot 2022-08-25 at 10 02 35 AM

I think I did things correctly and there are no errors when running. I can dig into it more if you like.

I'm also guessing there will be a new build of the vscode extension to handle the "npm:****" resolution errors?

P.S. brew install deno did not seem to give me 1.2.5, so I had to use the install.sh way

bartlomieju commented 2 years ago

FYI, I tried your recommendation above and it seemed to work well for Vue. I then tried the same with svelte. Alas, that did not seem to work (it never resolved the localhost endpoint). No errors in the terminal. Here's the repro repo:

https://github.com/pillowsoft/my-svelte-deno-app

Just wanted to give you feedback as requested.

I think I did things correctly and there are no errors when running. I can dig into it more if you like.

Thanks, much appreciated. I'll try to debug that later tonight.

I'm also guessing there will be a new build of the vscode extension to handle the "npm:****" resolution errors?

Yes, we're working on adding support for npm specifiers in the LSP

P.S. brew install deno did not seem to give me 1.2.5, so I had to use the install.sh way

I think the brew build might not be available yet.

karelklima commented 2 years ago

Feedback for Deno v1.25 - seems like Vite dev mode does not run on Windows yet.

I followed the steps in the previous comment, but the Vite dev server does not start. There is the following error message in console:

TypeError: Windows only supports ctrl-c (SIGINT) and ctrl-break (SIGBREAK).
    at bindSignal (deno:runtime/js/40_signals.js:14:16)
    at Object.addSignalListener (deno:runtime/js/40_signals.js:54:21)
    at Module.addSignalListener (https://deno.land/std@0.153.0/_deno_unstable.ts:34:17)
    at process.on (https://deno.land/std@0.153.0/node/process.ts:387:22)
    at process.once (https://deno.land/std@0.153.0/node/_events.mjs:525:8)
    at createServer (file:///***/deno/npm/registry.npmjs.org/vite/3.0.9/dist/node/chunks/dep-0fc8e132.js:59295:17)

The root cause is this line of code:

process.once('SIGTERM', exitProcess);

Which seems to come from here: https://github.com/vitejs/vite/blob/757a92f1c7c4fa961ed963edd245df77382dfde6/packages/vite/src/node/server/index.ts#L446

After removing the line manually the dev server seems to be running, although the app is stuck on loading state and there is only a blank screen in the browser.

Some good news though - vite build seems to work!

bartlomieju commented 2 years ago

FYI, I tried your recommendation above and it seemed to work well for Vue. I then tried the same with svelte. Alas, that did not seem to work (it never resolved the localhost endpoint). No errors in the terminal. Here's the repro repo:

Took a stab at it and I believe the problem is with "no dependencies found by scanner", however I'm not able to pinpoint the problem right now. I will resume debugging and fixes after the weekend.

CyberAP commented 2 years ago

I might be doing something completely wrong but I wasn't able to run it. That's an error I am getting (both for 3.x and 2.x Vite versions):

stas@Stanislavs-MacBook-Pro gitlab % deno run -A --unstable npm:vite build      
error: Uncaught TypeError: Promise.All is not a function
          Promise.All(
                  ^
    at https://deno.land/std@0.153.0/node/internal/streams/writable.mjs:937:19

I wonder if I am missing something here?

cjihrig commented 2 years ago

@CyberAP that typo was fixed a few hours ago in https://github.com/denoland/deno_std/pull/2569. On the next release it should be resolved.

brc-dd commented 2 years ago

I'm trying to fix compatibility between VitePress and deno, currently I'm getting this error:

Error: [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './dist/vue.runtime.esm-bundler.js' is not defined by "exports" in /home/osboxes/.cache/deno/npm/registry.npmjs.org/vue/3.2.37/package.json imported from /home/osboxes/.cache/deno/npm/registry.npmjs.org/vitepress/1.0.0-alpha.12/dist/node/serve-0ffe109f.js

But, vue's package.json already has this wildcard export: "./dist/*": "./dist/*", I guess deno is not considering such exports?

bartlomieju commented 2 years ago

I'm trying to fix compatibility between VitePress and deno, currently I'm getting this error:

Error: [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './dist/vue.runtime.esm-bundler.js' is not defined by "exports" in /home/osboxes/.cache/deno/npm/registry.npmjs.org/vue/3.2.37/package.json imported from /home/osboxes/.cache/deno/npm/registry.npmjs.org/vitepress/1.0.0-alpha.12/dist/node/serve-0ffe109f.js

But, vue's package.json already has this wildcard export: "./dist/*": "./dist/*", I guess deno is not considering such exports?

Yes, covered in https://github.com/denoland/deno/issues/15605, expect a fix next week in v1.25.1

bartlomieju commented 2 years ago

I'm trying to fix compatibility between VitePress and deno, currently I'm getting this error:

Error: [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './dist/vue.runtime.esm-bundler.js' is not defined by "exports" in /home/osboxes/.cache/deno/npm/registry.npmjs.org/vue/3.2.37/package.json imported from /home/osboxes/.cache/deno/npm/registry.npmjs.org/vitepress/1.0.0-alpha.12/dist/node/serve-0ffe109f.js

But, vue's package.json already has this wildcard export: "./dist/*": "./dist/*", I guess deno is not considering such exports?

@brc-dd would you opening a separate issue for this problem with a reproduction? I would love to include it as a test

brc-dd commented 2 years ago

@bartlomieju Add this in vite.config.js (rest of the steps were same as in your comment):

import { defineConfig } from 'npm:vite'
import vue from 'npm:@vitejs/plugin-vue'
import 'npm:vue@3.2.37/compiler-sfc'

import { createRequire } from 'https://deno.land/std@0.153.0/node/module.ts'

const require = createRequire(import.meta.url)
const vueRuntimePath = 'vue/dist/vue.runtime.esm-bundler.js'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: [
      {
        find: /^vue$/,
        replacement: require.resolve(vueRuntimePath)
      }
    ]
  }
})
mzaien commented 2 years ago
import "npm:vue@3.2.37/compiler-sfc"

Also true for react/preact, but to be clear I do not recall them having a compiler package, So I've tried adding react, and react dom

import "npm:react@18.2.0"
import "npm:react-dom@18.2.0"
ejsmith commented 2 years ago

@bartlomieju can you explain what the benefit of running Vite on deno is? Does Vite end up using the same resolution methods as Deno? Can we use VS code to edit both the front and backend code both with the deno language service and have everything work the same?

bartlomieju commented 2 years ago

@bartlomieju can you explain what the benefit of running Vite on deno is?

I'm not sure there's any particular benefit for using Deno over Node to run Vite. It is a quite complex project, which was a great testing ground for our Node compatibility which helped us uncover many bugs. But for Deno users being able to run Vite opens a whole frontend ecosystem and makes it more accessible.

Does Vite end up using the same resolution methods as Deno?

Currently not, but now that you can run Vite in Deno I see no reason why it wouldn't do so in the future.

Can we use VS code to edit both the front and backend code both with the deno language service and have everything work the same?

Yes, although Deno's LSP is still missing support for npm: specifiers that we intend to fix in the coming weeks.

bartlomieju commented 1 year ago

Deno v1.25.4 makes it much easier to run Vite in Deno, here's an example repo that you can give a try: https://github.com/bartlomieju/vite-deno-example

Keep in mind that for now we focused our efforts on the Vue template, so expect some bugs in other templates, but we're getting there! Feedback and bug reports are much appreciated so keep them coming.

Huge thanks to @dsherret for all the work that made it possible.

DefinitelyMaybe commented 1 year ago

Hey @bartlomieju

Great work so far! Have been watching this closely. I cloned the example repo and ran deno task dev but errored with:

PS C:\Users\rekke\Documents\vite-deno-example> deno task dev
Warning deno task is unstable and may drastically change in the future
Task dev deno run -A --unstable --node-modules-dir npm:vite
error: A required privilege is not held by the client. (os error 1314), symlink 'C:\Users\rekke\Documents\vite-deno-example\node_modules\.deno\esbuild-freebsd-arm64@0.15.8\node_modules\esbuild-freebsd-arm64' -> 'C:\Users\rekke\Documents\vite-deno-example\node_modules\.deno\esbuild@0.15.8\node_modules\esbuild-freebsd-arm64'

Was that a me thing or an almost there thing?

cjihrig commented 1 year ago

I believe your user account needs additional privileges at the operating system level to create symlinks on Windows.

DefinitelyMaybe commented 1 year ago

Ah, perfect. thank you will look into it.

dsherret commented 1 year ago

@DefinitelyMaybe I opened https://github.com/denoland/deno/issues/16006 to improve this error and maybe provide a better solution for Windows users who don't have symlinks enabled.

ar37-rs commented 1 year ago

npm:esbuild it downloading based on the whole OSes and whole architectures available on earth including the new loongsong arch, really weird.

dsherret commented 1 year ago

@ar37-rs we're aware. See #15544

brenelz commented 1 year ago

Wow this is pretty cool. Great work all!

DefinitelyMaybe commented 1 year ago

hey @dsherret, I got a part two of my windows saga. deno task dev starts up vite (success!) but upon opening http://localhost:5173/ the browser window is stalled waiting for the localhost connection.

What might be some things I could check out?

Extra info: Some refreshes will come through but don't display anything. I see hmr updates coming through but still dont display anything in the browser.

dsherret commented 1 year ago

@DefinitelyMaybe huh, yeah, the same thing happens to me on a Windows computer. We'll look into it.

brenelz commented 1 year ago

I'm testing this out with react and vite and getting this error. Could easily just not have things setup right:

failed to load config from /Users/brenelz/Desktop/Code/vite-deno-react-app/vite.config.mjs
error when starting dev server:
TypeError: Cannot read properties of null (reading 'main')
    at tryPackage (deno:ext/node/02_require.js:113:72)

Example repo: https://github.com/brenelz/deno-react-vite

bartlomieju commented 1 year ago

@DefinitelyMaybe I think the Windows problem is related to https://github.com/denoland/deno/issues/15549 - we'll fix it for v1.26.

@brenelz thanks for report, I'll debug it over the weekend.

ar37-rs commented 1 year ago

@ar37-rs we're aware. See #15544

@dsherret @bartlomieju, that's great, thanks.

bartlomieju commented 1 year ago

I'm testing this out with react and vite and getting this error. Could easily just not have things setup right:

failed to load config from /Users/brenelz/Desktop/Code/vite-deno-react-app/vite.config.mjs
error when starting dev server:
TypeError: Cannot read properties of null (reading 'main')
    at tryPackage (deno:ext/node/02_require.js:113:72)

Example repo: https://github.com/brenelz/deno-react-vite

Thanks for the repro @brenelz, I did a fix in https://github.com/denoland/deno/pull/16020

brenelz commented 1 year ago

Neat I was hoping it was something that simple

sithumonline commented 1 year ago

Hey @bartlomieju I tried https://github.com/brenelz/deno-react-vite with canary release of #16020 (075bdfd6213a532f1d5dc5381722cc534746e58d) and it gives this errors. Screenshot from 2022-09-27 06-13-55

Then I tried astro build. Screenshot from 2022-09-27 06-30-28

I hope this will help full.

brenelz commented 1 year ago

I couldn't replicate the vite react issue on a new machine. I did have to add the imports like you specified.

I am guessing a decent amount of work is involved in getting astro to work

bartlomieju commented 1 year ago

hey @dsherret, I got a part two of my windows saga. deno task dev starts up vite (success!) but upon opening http://localhost:5173/ the browser window is stalled waiting for the localhost connection.

What might be some things I could check out?

Extra info: Some refreshes will come through but don't display anything. I see hmr updates coming through but still dont display anything in the browser.

@DefinitelyMaybe this is now fixed by https://github.com/denoland/deno/pull/16076 and will be released in Deno v1.26.

@sithumonline I believe the problems stems from using babel though I haven't tried it. Also I haven't yet tried Astro, but it's something to look into after v1.26 is released.

sithumonline commented 1 year ago

I changed line 16 at node_modules/@babel/generator/lib/index.js from

const map = opts.sourceMaps ? _sourceMap.default(opts, code) : null; 

to

const map = null; 

then it started to working :exploding_head:

Deno currently worked seamlessly for the following template as well when I tried today.

Note: You have to edit vite.config.mjs and add papercuts.

bartlomieju commented 1 year ago

FYI I added several templates to create-vite-extra that you can use via following command:

$ deno run -A --unstable npm:create-vite-extra

and follow the prompts

gmosx commented 1 year ago

Unfortunately, create-vite-extra seems unusable on Fedora Linux, the arrow keys don't work, and I cannot select templates etc. Is there a workaround?

bartlomieju commented 1 year ago

Unfortunately, create-vite-extra seems unusable on Fedora Linux, the arrow keys don't work, and I cannot select templates etc. Is there a workaround?

That might be a regression in deno_std 0.158.0, which should be fixed this week. You can specify following env var and try again DENO_NODE_COMPAT_URL=https://deno.land/std@0.157.0/

njbraun commented 1 year ago

FYI, just tested this out on macOS (12.6) w/ apple silicon and I'm noticing that using vite dev server via deno task dev ends up hanging or not responding once it starts listening. For reference, vite build and vite preview work just fine.

vite (dev server) works just fine if I'm running on x86 Ubuntu

(using deno 1.26.1)

bartlomieju commented 1 year ago

@njbraun thanks for the report, we are aware of this issue - it is caused by recently landed NAPI support. Chokidar loads a .node file for FS events support and it seems we got a bug in our NAPI implementation. We will fix it in v1.26.2, but for now you can downgrade to v1.26.0 and everything will work fine 👍

reggi commented 1 year ago

Hey 👋 @bartlomieju thanks for working on vite support. 💪

I've been tinkering with the deno examples in deno run -A --unstable npm:create-vite-extra and it seems that the majority of them are designed to bundle client side js and serve a single HTML file. Many of the modern meta-frameworks however use vite-plugin-ssr under the hood with the vite dev server to form the running process that serves files. All of this is to say solid the web frameworks work, but I can't get solid start (npm init solid for the vite ssr template) the meta framework to work. There's a bunch of SSR templates in that command ssr-react, ssr-preact, ssr-svelte, ssr-solid some use vite and some use express for SSR. Am I doing something wrong to get SSR meta-frameworks that use Vite as their server, are we able to get this working today? Or will the SSR vite dev server never work on Deno / out of scope? Something like Qwik uses this as well, and I don't understand what's holding Qwik Deno support back now that we have this vite implementation and I was under the impression SRR still doesn't work. Any clarity would be great!

Another thing I couldn't wrap my head around was using deno-style url imports in what would be a client file, I tried to import something and the page went blank. I was curious if we need a vite-deno-url plugin to do this sort of thing?

reggi commented 1 year ago

I've been digging into this a bit more. Disregard my last comment. I think my lack in understand is around some support of these frameworks having deno adapters or default supporting node.

Solid Start in deno is here: https://github.com/solidjs/solid-start/blob/main/packages/start-deno/entry.js Astro has an adapter here: https://github.com/withastro/astro/tree/main/packages/integrations/deno

These are slightly different approaches but kind of demonstrate my confusion. The outcome of this is that as I understand it in the past frameworks would use node + vite to bundle the server code, now we can execute that bundle with deno + vite.

lubomirblazekcz commented 1 year ago

So now that the npm modules are stable, what is the correct or planned way to handle dependendies in Vite? In https://github.com/bluwy/create-vite-extra I see that deps are resolved via imports in vite.config.js, I would prefer to do this via import_map.json but that doesn't seem to work now. Or is it something on the vite / frameworks side that needs to be done?

benatkin commented 1 year ago

This probably should be closed now, because obviously vite will run, unless supporting npm packages is abandoned (unlikely). Whether vite should adapt to deno is a matter for vite.

I'm about to check if it runs on vite. What interests me most is running vite with low permissions.

Lesiuk commented 1 year ago

Vite is currently unusable with deno. Dev server hangs very often. It looks like some kind of deadlock.