-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
adapter-node doesn't work correctly with paths.base #3726
Comments
Same issue. Software is not usable for now. |
Similar issues with adapter-static - see #3620 Incorrect build path for prerendered endpoints when setting a basepath |
I actually question the reason for hard-coding the base path in a folder structure like this. If I run the app behind a reverse proxy I'd like to dynamically provide the prefix its listening to (through the x-forwaded-prefix header for example). The workaround of fixing the build folder seems to solve the issue for the moment however |
I've had a closer look at how the copy occurs. If you're simply wanting to copy to the correct folders then a small modification of the following to include the base could be done. kit/packages/adapter-node/index.js Lines 33 to 36 in 3d728d2
This is probably the easiest way to solve both the static and node adapters though presumably the static adapter would place it in the root (as you would copy it into the correct base subfolder when deploying it, so the problem is actually the reverse of the node adapter) whereas the node adapter one needs to EITHER translate base on the fly (which means it could support an environment variable defining the base at runtime, which is supported by the override method exported from Server allowing you to override this at runtime, I think) OR it can just serve it from the hard coded compile time base folder. I don't really know which way is preferred so can't provide a PR and may need some discussion. |
Instead of having to modify the source code as @bundabrg mentions, I am just using an |
* Add `base` to builder * Prepend `builder.base` when copying Client, Static and Prerendered assets in adapter-node Fixes sveltejs#3726 Related sveltejs#3620
I personally think that this is actually part of a bigger issue and simply copying to the correct folder whilst a quick fix is not a "good fix". I've added changes to my branch that does the quick fix but I don't like it. When generating a static site we ultimately will be placing it either in the correct folder OR preferably behind a load-balancing reverse proxy that strips off the prefix and have it served from the root. So the prefix should not exist in the build folder at all but the code will need to know to add the prefix when referring to assets. When generating a dynamic site it can be passed environment variables (or perhaps read a config file) where it gets its base prefix. In the same way the site could exist behind a reverse proxy that strips off the prefix OR it'll handle the prefix itself. It matters not as this is an implementation detail of the adapter. The code needs to know to add the prefix when referring to assets and presumably when doing SSR fetching it'll need to know to add/remove the prefix as necessary.
const server = polka().use(
// https://github.com/lukeed/polka/issues/173
// @ts-ignore - nothing we can do about so just ignore it
compression$1({ threshold: 0 }),
handler
);
const handler = sequence(
[
serve(path.join(__dirname, '/client'), 31536000, true),
serve(path.join(__dirname, '/static'), 0),
serve(path.join(__dirname, '/prerendered'), 0),
ssr
].filter(Boolean)
); The issue is that const server = polka().use(
BASE_PATH,
// https://github.com/lukeed/polka/issues/173
// @ts-ignore - nothing we can do about so just ignore it
compression$1({ threshold: 0 }),
handler
); where This way if I have a reverse proxy that strips prefixes I can have If I don't strip the prefix, then I can set Anyway, that's my 2c. |
This bug still exists in the current version. The workaround of moving both the client/_app folder and the contents of the client/static folder to the right place works though. |
As already mentioned, there is a related issue with the static adapter - #4528. The workaround of adjusting the directories didn't work for me but I found a workaround with the following. <script>
import { base } from '$app/paths';
</script>
<a href="{base}/">Home</a>
<a href="{base}/about">About</a> |
@TheFoolishPupil - I tried your trick but I get links like /%7Bbase%7D/about - may be because I'm using a component to render nav and it is passed an array with href properties? If I switch to |
@jcallaha, if I understand you correctly, you pass hrefs as a property to you nav component? In some sub-component where you actually render the tags you should be able to take whichever path was passed as a prop and prepend |
my workaround. it seems 'just moving the _app folder' will not work. $ npx svelte-kit build
$ mkdir build/client/$base
$ ln -s ../_app build/client/$base
$ node build/index.js |
afaik
what i do is to set a temporary base-path in the vite config, and use a custom node script that replaces the occurences of the temporary base path in all the files of the build folder in addition to moving the _app (and static) folders into the directory structure that represents the basepath -> since i am using a docker container/kubernetes deployment scenario this works "fine" for my purposes |
Not sure how everyone got it to work by moving As @bundabrg suggested, I had to move quite a few folders.
Warning: I'm not sure the server folder should move though 🤔 |
This is what I am doing to automate the directory structure updates. I chain this script onto my build command. This works for me and I am using this approach for all my Svelte Kit apps (for now). @seanlail, I think I may still be importing base in my components too. I'll have to check if that is a necessary step or not. My script doesn't move server, and I'm pretty sure the server directory has nothing to do with this issue. import { base } from '$app/paths'
<a href="{base}/about">About</a> // snippet from svelte.config.js
kit: {
adapter: adapter(),
paths: {
base: isDev ? '' : '/root-path',
}
} // snippet from package.json
"scripts": {
"dev": "svelte-kit dev",
"build": "svelte-kit build && node path_fix.js",
} // path_fix.js
import fs from 'fs-extra'
import CONFIG from './svelte.config.js'
const appRoot = CONFIG.kit.paths.base // something like '/root-path'
const clientSrc = `./build/client/_app`
const clientDest = `./build/client${appRoot}/_app` // appRoot leads with a slash
if (fs.exists(clientDest)) {
fs.removeSync(clientDest)
}
fs.moveSync(clientSrc, clientDest)
const staticSrc = `./build/static`
const staticDest = `./build/static${appRoot}`
if (fs.exists(staticDest)) {
fs.removeSync(staticDest)
}
fs.mkdirsSync(staticDest)
const contents = fs.readdirSync(staticSrc)
contents
.filter(entry => entry !== '.DS_Store')
.forEach(entry => {
fs.moveSync(`${staticSrc}/${entry}`, `${staticDest}/${entry}`)
}) |
@joelhickok Thanks this works great! I had to swap two lines to avoid
|
Whoops... yes, I had that problem too but corrected it. I thought I copied and pasted the corrected code, but maybe not. I'll check and update when I get a chance soon. |
Oh, I really need this to be fixed. I cannot use the workaround mentioned earlier because my case is one level more complex as I need to use the generated middleware handler in another express server (directus). I cannot control exactly when to
|
if (options.paths.base && !state.prerendering?.fallback) { | |
if (!decoded.startsWith(options.paths.base)) { | |
return new Response('Not found', { status: 404 }); | |
} | |
decoded = decoded.slice(options.paths.base.length) || '/'; | |
} |
Now everything works as expected (i.e.
/dashboard
and /dashboard/about
) at least with my minimal testing.
This is surely not the final solution as the dev server needs those lines and I guess the other adapters need them as well...
I got one step further by adding the base url to the request before passing it to the handler
:
app.use('/dashboard', (req, res, next) => {
let requestProxy = new Proxy(req, {
get(target, property) {
if (property === 'url') {
return target.baseUrl + (target.url === '/' ? '' : target.url);
}
return target[property];
},
});
handler(requestProxy, res, next);
});
Now the ssr
function works correctly (because it strips the basepath we just added) but the static files are not correctly served (because sirv does not strip the basepath) as @bundabrg also noted in #3726 (comment)
Two comments:
|
I think I figured out where the change needs to happen. In builder.writeClient(`${out}/client`); should change to builder.writeClient(`${out}/client${builder.config.kit.paths.base}`); I suspect the I also suspect their is a similar change in |
This works, but you still need to specifically set otherwise you stil get this
with sveltekig.config.js set like this
Makes me wonder. base should ALWAYS be a variable, defaulting to "/" maybe yes, but never assume it's not there. |
Any updates here? I am currently evaluating using Svelte(Kit) in our new app and this would be a showstopper. |
The bug the majority in this issue have is fixed now, the base path is taken into account when writing the files to disk. This doesn't suffice for people with reserved proxies which strip the base path or something related. #7242 tracks that. |
Describe the bug
Basically, we have this
svelte.config.js
.When we now run
svelte-kit build
, it produces this folder structure (partly):the problem now is that the browser is not able to fetch the files in
client
andstatic
. The node server returns status code404
for these files.The browser requests the files like this:
http://localhost:3000/basepath/_app/...
.If we manually modify the folder structure to this (manually add a
basepath
folder inclient
andstatic
) it works fine.It seems that the
adapter-node
forgets to takepaths.base
into account for the static files.By the way: If I start the build with
svelte-kit preview
, it works fine. Just starting it withnode build
does not work.Reproduction
I created a simple demo app based on the
npm init svelte@next
command.https://github.com/vekunz/svelte-paths-base-demo
Logs
System Info
Severity
blocking all usage of SvelteKit
Additional Information
It seems that in my example app moving the static files in a
basepath
subdirectory does not work also.The text was updated successfully, but these errors were encountered: