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

base option does not support external URLs with the development server #2196

Closed
2 of 3 tasks
SirDavidLudwig opened this issue Feb 23, 2021 · 13 comments
Closed
2 of 3 tasks

Comments

@SirDavidLudwig
Copy link

⚠️ IMPORTANT ⚠️ Please check the following list before proceeding. If you ignore this issue template, your issue will be directly closed.

  • Read the docs.
  • Use Vite >=2.0. (1.x is no longer supported)
  • If the issue is related to 1.x -> 2.0 upgrade, read the Migration Guide first.

Describe the bug

The base option currently does not support the ability to specify external URLs when serving content through the development server. This greatly limits the incorporation of Vite into other backends (Laravel, etc.) as static assets can no longer be served since the assets are served on a different port than the web server. I explored this specific problem in more depth in a separate issue by attempting to integrate Vite into a Laravel project.

As a solution suggestion, I believe that this issue would be solved best by implementing an environment variable to specify a URL base for content served specifically through the dev server. This would resolve these issues with backend compatibility and allow for the most flexability in users' dev environments.

Reproduction

I'm not sure how worthwhile a reproduction guide is for this issue, but this should give you something to compare against.

  1. Create a vue-ts project using the @vitejs/app init script
npm init @vitejs/app
    # Project name: vite-static-assets
    # Select a template: vue-ts
cd vite-static-assets
npm install
  1. Set base property in vite.config.ts:
export default defineConfig({
  base: "http://localhost:3000/",
  server: {
    port: 3000 // Use the same port for dev and serve
  },
  // ...
})
  1. Compare the URL of the Vue logo in the inspector window between content served via npm run dev and npm run build && npm run serve. The src attribute of the <img> tag will only contain the base of http://localhost:3000/ on production builds.

System Info

  • vite version: 2.0.1
  • Operating System: Ubuntu 20.10
  • Node version: 14.15.4
  • Package manager (npm/yarn/pnpm) and version: npm

Logs (Optional if provided reproduction)

N/A

@yyx990803
Copy link
Member

The solution is to simply configure your Laravel app to serve the assets in vite directory. I personally don't know how to do that but this should be a common feature in all backend frameworks.

There are already integrations like https://github.com/innocenzi/laravel-vite so I'm pretty sure this is not a limitation.

@SirDavidLudwig
Copy link
Author

SirDavidLudwig commented Feb 24, 2021

@yyx990803
That integration is actually where we first come across this problem. At the moment we still don't have a proper solution. While I know I'm arguing only for a single backend here (Laravel), I believe this issue will apply to many other frameworks.

The backend can be configured easily to include the CSS/Js/Ts/etc. scripts/files based on the environment with no problem. However, the problem comes in with static assets (images, fonts, etc.) included from within these types of files, where a backend will have no control over the generated URLs. For example, a CSS file in Laravel would request assets from /resources/..., where resources is a non-public folder intended for uncompiled/unprocessed assets. It seems quite hacky/silly to require a backend framework to publicly serve assets from an intentionally non-public folder only in development environments. Whether this would be done through symlinking, or providing additional middleware, this does not seem like a proper solution to the problem.

@SirDavidLudwig
Copy link
Author

@yyx990803 Any possibility this issue could be reopened? More effort has been put into implementing workarounds in https://github.com/innocenzi/laravel-vite but the core problems still exists.

@innocenzi
Copy link
Contributor

innocenzi commented Feb 25, 2021

@yyx990803 I can confirm that this is an issue, and we don't have a proper solution yet. Other back-ends (Symfony, Ruby) have this issue too.

@ElMassimo has a workaround for his Ruby package, but this is mostly a hack and I think this should be handled on Vite's side. I think @SirDavidLudwig's idea of having an environment variable or configuration option would be a solid fix.

If I understand correctly, this environment variable (or configuration option) should be used there in order to handle everything properly?

EDIT: monkey-patching the return value of fileToDevUrl to prepend a BACKEND_BASE_URL seemed to work properly, but I didn't thoroughly test. I would have done a plugin, but the function is used individually by multiple plugins so this is not possible. :/

@khalwat
Copy link
Contributor

khalwat commented Apr 30, 2021

I'm too experiencing this issue (not with Laravel though, with Craft CMS as a backend). As @innocenzi has mentioned, I think this is a generic problem for server-side rendered backends that I'd love to see resolved.

@SirDavidLudwig
Copy link
Author

SirDavidLudwig commented Apr 30, 2021

@khalwat I posted a workaround that seems to work pretty well for me here that might help you out (at least until it's fixed).

@khalwat
Copy link
Contributor

khalwat commented May 1, 2021

@SirDavidLudwig I did see that... unfortunately this is a case where I can't really patch Vite itself because other people will be using the scaffolding I'm working on. Very much appreciate the pointer tho!

@SirDavidLudwig
Copy link
Author

@khalwat I see. Well, might I also suggest looking into generating patch files using something like patch-package. With it, it will apply these patches will automatically for everyone. Just wanted to throw that out there in case it might work for your needs

@ugrupp
Copy link

ugrupp commented May 10, 2021

Don't want to be pushy but could we at least reopen this issue? I'm trying to get Vite working with Craft, too, and this is the biggest blocker right now.

@khalwat
Copy link
Contributor

khalwat commented May 10, 2021

Agree, would love to see this re-opened, I referenced it here: https://nystudio107.com/blog/using-vite-js-next-generation-frontend-tooling-with-craft-cms#vite-processed-assets

...and it is still an issue, at least imo.

@tonychuuy
Copy link

I prefer a built-in solution, but for now I'm using a proxy as a work around, since I'm using docker for my backend development this is really easy, of course you can apply a similar fix to your needs.

# /etc/nginx/conf.d/default.conf
location ~* \.(png|jpe?g|gif|svg|ico|mp4)$ {
        proxy_pass https://host.docker.internal:${VITE_SERVER_PORT};
}

@haytor
Copy link

haytor commented Jun 7, 2021

如果使用laravel valet 可新增驱动,让驱动控制资源加载,具体如:

<?php

class ViteValetDriver extends ValetDriver
{
    /**
     * Determine if the driver serves the request.
     *
     * @param  string  $sitePath
     * @param  string  $siteName
     * @param  string  $uri
     * @return bool
     */
    public function serves($sitePath, $siteName, $uri)
    {
        return true;
    }
    /**
     * Determine if the incoming request is for a static file.
     *
     * @param  string  $sitePath
     * @param  string  $siteName
     * @param  string  $uri
     * @return string|false
     */
    public function isStaticFile($sitePath, $siteName, $uri)
    {  
        //应用根目录资源加载, node_modules中引用资源问题
        if (file_exists($staticFilePath = $sitePath . '/' . $uri)
            && is_file($staticFilePath)) {
            return $staticFilePath;
        }
        if (file_exists($staticFilePath = $sitePath . '/public' . $uri)
            && is_file($staticFilePath)) {
            return $staticFilePath;
        }
        return false;
    }
    /**
     * Get the fully resolved path to the application's front controller.
     *
     * @param  string  $sitePath
     * @param  string  $siteName
     * @param  string  $uri
     * @return string
     */
    public function frontControllerPath($sitePath, $siteName, $uri)
    {
        return $sitePath . '/public/index.php';
    }
}

@github-actions
Copy link

This issue has been locked since it has been closed for more than 14 days.

If you have found a concrete bug or regression related to it, please open a new bug report with a reproduction against the latest Vite version. If you have any other comments you should join the chat at Vite Land or create a new discussion.

@github-actions github-actions bot locked and limited conversation to collaborators Jul 15, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants