Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify vite.php config (look into CORs issues too) #80

Open
joshuapease opened this issue Feb 18, 2025 · 17 comments · May be fixed by #88
Open

Simplify vite.php config (look into CORs issues too) #80

joshuapease opened this issue Feb 18, 2025 · 17 comments · May be fixed by #88

Comments

@joshuapease
Copy link
Contributor

While Slacking with @maxfenton it seems like this:

$host = Craft::$app->getRequest()->getIsConsoleRequest()
    ? App::env('PRIMARY_SITE_URL')
    : Craft::$app->getRequest()->getHostInfo();

Can be simplified to

$host = App::env('PRIMARY_SITE_URL');

Max also noted some potential CORs issues (that may or may not be related to this change)

Blocked request. This host ("parents-fentanyl-awareness.ddev.site") is not allowed.
To allow this host, add "parents-fentanyl-awareness.ddev.site" to `server.allowedHosts` in vite.config.js.
@joshuapease joshuapease added this to the Smokey Bear Ready milestone Feb 18, 2025
@maxfenton
Copy link
Contributor

I may have been wrong about the change to $host — when I restarted this morning I ran into CORS issues like you thought I would.

This allowedHosts seems like a good and safe addition to our vite.config.js files:

server: {
      host: '0.0.0.0',
      cors: true,
      strictPort: true,
      port: HTTP_PORT,
      allowedHosts: ['.ddev.site'],
      origin: env.PRIMARY_SITE_URL + ':' + originPort
    },

@maxfenton
Copy link
Contributor

I didn't get a chance to test this other way out
Image

@robzor
Copy link

robzor commented Feb 25, 2025

Not sure if this is the right ticket but I was using your great blog article to dip my toes into using Vite inside the DDEV container and fell into a CORS issue.

See this article for info: https://dev.to/mandrasch/vite-is-suddenly-not-working-anymore-due-to-cors-error-ddev-3673

But it seems like there was a security issue with Vite before and so now you need to add:

cors: {
        origin: /https?:\/\/([A-Za-z0-9\-\.]+)?(\.ddev\.site)(?::\d+)?$/,
      },

into your server bit in the vite.config.js

I also changed to using the simplified $host as specified up there as I'm currently using DDEV with a custom port and the previous version would try and add 2 ports to the end of the URL :)

@maxfenton
Copy link
Contributor

maxfenton commented Feb 25, 2025

Thank you @robzor

@joshuapease I just checked out the Craft Vite docs and Andrew Welch has updated the ports and config to include that change but also that the ports in ddev/config are flipped from these ones. https://nystudio107.com/docs/vite/#using-ddev


.ddev/config.yaml

web_extra_exposed_ports:
    - name: craft-vite
      container_port: 3000
      http_port: 3001
      https_port: 3000

(note https and container_port are the same)

vite.config.js

server: {
  host: '0.0.0.0',
  port: 3000, 
  strictPort: true,
  origin: `${process.env.DDEV_PRIMARY_URL.replace(/:\d+$/, "")}:3000`,
  cors: {
    origin: /https?:\/\/([A-Za-z0-9\-\.]+)?(\.ddev\.site)(?::\d+)?$/,
  },
}

(again here the ports are the https and container_port values, not http and container_port)

config/vite.php

<?php

use craft\helpers\App;

return [
	'checkDevServer' => true,
	'devServerInternal' => 'http://localhost:3000',
	'devServerPublic' => preg_replace('/:\d+$/', '', App::env('PRIMARY_SITE_URL')) . ':3000',
	'serverPublic' => App::env('PRIMARY_SITE_URL') . '/dist/',
	'useDevServer' => App::env('ENVIRONMENT') === 'dev' || App::env('CRAFT_ENVIRONMENT') === 'dev',
	'manifestPath' => '@webroot/dist/.vite/manifest.json'
];

@robzor
Copy link

robzor commented Feb 25, 2025

Yeah his example didn't work for me until I changed the port to match yours (e.g. Use the HTTPS one for the dev server)

joshuapease added a commit that referenced this issue Feb 27, 2025
Run `ddev install` with the @latest flag on all dependencies.
joshuapease added a commit that referenced this issue Feb 27, 2025
The config can be way simpler if you only allow access from https
@joshuapease joshuapease linked a pull request Feb 28, 2025 that will close this issue
1 task
@joshuapease joshuapease linked a pull request Feb 28, 2025 that will close this issue
1 task
@joshuapease
Copy link
Contributor Author

Thanks for all your notes @robzor and @maxfenton

Here's where I've landed with a PR.

@robzor
Copy link

robzor commented Feb 28, 2025

One thing to add to this, because I am running DDEV on a custom port, I have both regex things in the JS config and Plugin config:

origin: `${process.env.DDEV_PRIMARY_URL.replace(/:\d+$/, "")}:` + HTTPS_PORT,`

and

'devServerPublic' => preg_replace('/:\d+$/', '', App::env('PRIMARY_SITE_URL')) . ':3001', // Matches https_port in .ddev/config.yaml

Might be worth adding those? :)

@maxfenton
Copy link
Contributor

@robzor I had a deploy error when I tried something that included ${process.env.DDEV_PRIMARY_URL.replace(...)} because DDEV_PRIMARY_URL wasn't present on the production server .env — needed to use optional chaining (?.): DDEV_PRIMARY_URL?.replace

@robzor
Copy link

robzor commented Mar 3, 2025

Hm, that's interesting, I would've thought that on the production environment it should ignore that whole server section, maybe that's a FR for the Vite guys.

@joshuapease
Copy link
Contributor Author

@robzor I think that's just an error that's inherent to the order that JavaScript executes.

${process.env.DDEV_PRIMARY_URL.replace(/:\d+$/, "")}: + HTTPS_PORT,` gets called before Vite even reads the config file.

Optional chaining is a good fix.

I've never needed to run DDEV in a custom port. Does that port show up in your PRIMARY_SITE_URL?

Would it work to use the PRIMARY_SITE_URL .env var in both cases?

@robzor
Copy link

robzor commented Mar 4, 2025

hi @joshuapease yeah, DDEV populates the .env with the custom port which is nice.

I tried changing DDEV_PRIMARY_URL to the primary site url .env var but it didn't work, I'm not using the loadEnv method from the Viget config though, as I was trying to make the vite config as small as possible :D

joshuapease added a commit that referenced this issue Mar 4, 2025
- Add regex replacmenets to allow for custom DDEV ports
- Switch port numbers to match nystudio docs.
  - https://nystudio107.com/docs/vite/#using-ddev
- Use DDEV_PRIMARY_URL in vite.config.js
  - We don't need loadEnv anymore
@joshuapease
Copy link
Contributor Author

@robzor Gotcha... those ports are immediately removed by the regex right?

Seems like the main benefit is that you don't need to use loadEnv?

I think that's benefit is worthwhile. I also like being aligned with the nystudio docs wherever possible.

@maxfenton @robzor I made a few tweaks to that PR to account for your feedback

  • Add regex replacements to allow for custom DDEV ports
  • Switch port numbers to match nystudio docs (I don't know why I made mine different, but aligning with nystudio is better)
  • Use DDEV_PRIMARY_URL in vite.config.js
    • We don't need loadEnv anymore

@robzor
Copy link

robzor commented Mar 4, 2025

Mine is an ongoing concern, as this is my first project properly diving into Vite, but my config is currently looking like this:

import { defineConfig } from 'vite';
import ViteRestart from 'vite-plugin-restart';

// Match ports in .ddev/config.yaml and config/vite.php
const HTTP_PORT = 3000;
const HTTPS_PORT = 3001;

export default defineConfig(({ command }) => {

  return {
    base: command === 'serve' ? '' : '/dist/',
    build: {
      manifest: true,
      outDir: './web/dist/',
      rollupOptions: {
        input: {
          app: 'src/js/app.js',
        },
      },
    },
    plugins: [
      ViteRestart({
        reload: [
          'templates/**/*',
        ],
      }),
    ],
    publicDir: 'src/public',
    server: {
      host: "0.0.0.0",
      port: HTTP_PORT,
      strictPort: true,
      origin: `${process.env.DDEV_PRIMARY_URL.replace(/:\d+$/, "")}:` + HTTPS_PORT,
      cors: {
        origin: /https?:\/\/([A-Za-z0-9\-\.]+)?(\.ddev\.site)(?::\d+)?$/,
      },
    },
  }
});

@robzor
Copy link

robzor commented Mar 5, 2025

Just to add to this, I've tried to deploy this to Servd and I'm getting an error with process I believe - is this what happened to you @maxfenton ?

@robzor
Copy link

robzor commented Mar 5, 2025

Ah, got it working by adding this:

 const primaryUrl = process.env.DDEV_PRIMARY_URL ? process.env.DDEV_PRIMARY_URL.replace(/:\d+$/, "") : '';

and changing the origin line to:

      origin: `${primaryUrl}:` + HTTPS_PORT,

@maxfenton
Copy link
Contributor

maxfenton commented Mar 5, 2025

@robzor I think that's equivalent to:

origin: `${process.env.DDEV_PRIMARY_URL?.replace(/:\d+$/, '')}:${HTTPS_PORT}`,

where the optional chaining is doing the same as your ternary logic.

@robzor
Copy link

robzor commented Mar 5, 2025

I tried that a few days ago and it didn't work for some reason

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants