kit icon indicating copy to clipboard operation
kit copied to clipboard

After upgrading to Vite 3 and with latest SvelteKit `process.env.NODE_ENV` is not replaced anymore

Open frederikhors opened this issue 3 years ago • 10 comments

Describe the bug

I was using "@sveltejs/kit": "1.0.0-next.370" and "vite": "2.9.14".

After the upgrade to "@sveltejs/kit": "1.0.0-next.391" and "vite": "3.0.2" I'm having issue with service-worker.ts which has this code in it:

/// <reference lib="webworker" />

import {
	precacheAndRoute,
	createHandlerBoundToURL,
	cleanupOutdatedCaches,
} from "workbox-precaching";
import { NavigationRoute, registerRoute } from "workbox-routing";

import { build, files, version } from "$service-worker";

const worker = self as unknown as ServiceWorkerGlobalScope;

cleanupOutdatedCaches();

precacheAndRoute([
	...build.map((f) => ({ url: f, revision: null })),
  /// more code
]);

// other workbox code

What is happening is that after npm run build (vite build) the service-worker.js in build directory contains code like:

....M="production"===process.env.NODE_ENV?K:A;class l extends Error{constructor(e,t).....

As you can see process.env.NODE_ENV is not replaced.

Reading on vitejs config I saw the define property which should do replacement like this:

define: {
  "process.env.NODE_ENV": '"production"',
  //"process.env.NODE_ENV": import.meta.env.MODE, // this doesn't work
},

I think this is not correct usage in SvelteKit.

I think SvelteKit should replace automagically that env because it's so common in the world.

System Info

System:
    OS: Windows 10 10.0.19044
  Binaries:
    Node: 16.16.0 - C:\Program Files\nodejs\node.EXE
    npm: 8.15.0 - C:\Program Files\nodejs\npm.CMD
  npmPackages:
    @sveltejs/adapter-static: 1.0.0-next.38 => 1.0.0-next.38
    @sveltejs/kit: 1.0.0-next.391 => 1.0.0-next.391
    svelte: 3.49.0 => 3.49.0
    vite: 3.0.2 => 3.0.2

Severity

blocking an upgrade

frederikhors avatar Jul 23 '22 11:07 frederikhors

I'm using this code right now:

import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";

export default defineConfig(({ mode }) => {
  return {
    plugins: [sveltekit()],

    define: {
      "process.env.NODE_ENV":
        mode === "production" ? '"production"' : '"development"',
    },

    //other configs...
  };
});

Wat do you think?

frederikhors avatar Jul 23 '22 11:07 frederikhors

SvelteKit was never handling process.env.NODE_ENV so I assume this is a change in Vite. I'd prefer that Vite be responsible for this sort of thing, but we need to figure out what changed between 2 and 3.

Rich-Harris avatar Jul 23 '22 12:07 Rich-Harris

Rich, what an honor your direct answer. You are a human example for me to follow.

I read that Vite doesn't want to replace these envs so I guess the only way is to do it by hand with the code I posted, if you think (rightly) it's not SvelteKit's job.

frederikhors avatar Jul 23 '22 12:07 frederikhors

If you change process.env.NODE_ENV to process.env['NODE_ENV'] does Vite's behavior change? I remember that in Vite v2 there was code that did an actual text search for process.env. (note trailing dot) followed by identifier characters, and replaced those with property accesses off of an object that contained only env vars with the "allowable" prefix (VITE_ by default), but that could be worked around by using process.env['NODE_ENV'] which would not match Vite's text search regex. I haven't had time to investigate whether this workaround still works in Vite v3, but it's probably worth a try.

rmunn avatar Jul 26 '22 06:07 rmunn

This is not possible to try for me because I'm importing workbox in service-worker.ts. And it uses a lot of process.env.*.

frederikhors avatar Jul 26 '22 09:07 frederikhors

I ran into this issue as well, just upgraded to the latest SvelteKit. I have code like this in my svelte.config.js to change the base path depending on if it's development or not. You might wonder why I need that though? It's because all my API calls are proxied via an /routes/api/[...rest]/+server.js catch all, which needs to live, relative to the routes, where it will in production (and my whole SvelteKit app is under a subfolder of the legacy app in production, using adapter-static).

const config = {
	kit: {
		paths: {
			base: process.env.NODE_ENV === 'development' ? undefined : '/v2'
       ...

A simple workaround is to just set it in my package.json scripts like this. I think I'll look for and/or file a bug Vite as well.

  "scripts": {
    "dev": "NODE_ENV=development vite dev"
  }

johnnysprinkles avatar Aug 17 '22 02:08 johnnysprinkles

I have the same problem. When I use workbox, many process.env.NODE_ENV are seen in the service-worker.js in build directory. It seems that vite.config.js configuration is not used to build service-worker. I used define and @rollup/plugin-replace but it didn't work.

madibaee avatar Aug 22 '22 08:08 madibaee

vite.config.ts is indeed ignored while building the service worker (see: build_service_worker.js)

As far as I'm aware process.env replacing in vite only worked through the define plugin. Which is used by everyone with large enough dependency graph, since too much of the ecosystem uses process.env.NODE_ENV checks.

Now, the behaviour was probably changed by this PR: https://github.com/sveltejs/kit/pull/5839/files#diff-435b0550c8431b095f93ce127dfa5bef62671c54f320f0aaaa44d3dfd7b332b1L67-R66
After this, sw build uses it's own config and no longer merges the default config, effectively making it impossible to use the define plugin (and any other plugins or configuration options, to be precise).

While I'm not sure we actually need to merge the default config (there might be some incompatible plugins and options), there should be a way to tweak the sw build configuration. We can probably add vite.service-worker.config.ts or provide configuration through kit.serviceWorker option in svelte.config.js

nulladdict avatar Aug 31 '22 06:08 nulladdict

If I'm reading correctly this issue should be resolved with #6329, which will allow the use of define again for the service worker. In the meantime, my workaround is basically a post-build sed script, heh...

dnotes avatar Sep 03 '22 10:09 dnotes

Yep, this should work now — we can probably close this issue. Any objections?

Rich-Harris avatar Sep 20 '22 19:09 Rich-Harris

Yep, this should work now — we can probably close this issue. Any objections?

No, it still doesn't work, so I implemented the Option 1 you proposed in #6329

This one is tricky as Vite doesn't have a concept of a 'service worker build', just SSR or not-SSR. Options:

  1. pass through certain properties from the main config (e.g. define)
  2. add an option to the plugin like sveltekit({ serviceWorkerConfig: vite.UserConfig })

Option 1 would be a breaking change. Option 2 is probably the better choice, and could be done in a non-breaking way, but I'm going to mark this as 'breaking' in case we decide the other way

guifesquet avatar Oct 04 '22 08:10 guifesquet

Confirmed that #7140 (which went live in @sveltejs/[email protected]) makes it possible to create a functional Workbox service worker.

If you are using Workbox to build your service worker, you will need to add the following configuration to your vite.config file. Note that this requires exporting a defineConfig function instead of a simple config object.

export default defineConfig(({ mode }) => {
    // ...the rest of your Vite configuration...
    define: {
        'process.env.NODE_ENV': mode === 'production' ? '"production"' : '"development"'
    },
}

I think this can be closed, but I wonder if a note about this should be included in 10_service_workers? Anyone who uses Workbox (or perhaps any other service worker library, I haven't tried) will have a failing service worker until they implement this configuration, and the console errors for that sort of thing are not very helpful.

dnotes avatar Oct 05 '22 16:10 dnotes

This may be implemented in Vite 4.2: https://github.com/vitejs/vite/blob/v4.2.0-beta.0/packages/vite/CHANGELOG.md#420-beta0-2023-02-27

benmccann avatar Feb 27 '23 18:02 benmccann

Is this still an issue with Vite 4? If not, closing.

dummdidumm avatar Dec 12 '23 19:12 dummdidumm

I think this is working right now. I'll re-open if not. Thank you all.

frederikhors avatar Dec 12 '23 20:12 frederikhors