Open ghost opened 6 years ago
@ulivz I've already tried couple of base configs. And i tried again like yours. It doesn't work. Paths are still start with /. Can you open the issue again?
@atilkan Probably related to #387 (see https://github.com/vuejs/vuepress/issues/387#issuecomment-388082281), also https://github.com/vuejs/vuepress/issues/575 and https://github.com/vuejs/vuepress/issues/667 As i understand vuepress just cannot be used without a static server (see https://github.com/vuejs/vuepress/issues/667#issuecomment-407704352).
@petzerhub I changed paths manually and some of it worked.
Since ""
is negative, so ""
truly doesn't work for now (it will fallback to "/"
) ...
We need to enhance it.
What timeframe do you expect for this enhancement? I am about starting a new project and this is really required. (Manually changing the paths later is simply pita - but I'm sure, you guessed that already ;))
Any updates on this? Working on a project that would be perfect for VuePress, but need to build out with relative URLs as the deliverable will live on a Windows Filesystem.
It looks to me like this may be supported in html-webpack-plugin
4.0.0 https://github.com/jantimon/html-webpack-plugin/pull/1114
However, vuepress uses a fork https://github.com/vuejs/vuepress/commit/4816bef of that plugin (https://github.com/vuejs/vuepress/issues/1303), so we'd need to update the fork or switch back to html-webpack-plugin
Any more updates on this?
@BernardZhao @atilkan
I wrote a plugin which may satisfy your needs.
vuepress serve docs
And vuepress will build with absolute URLs and then serve them.
@BernardZhao @atilkan
I wrote a plugin which may satisfy your needs.
vuepress serve docs
And vuepress will build with absolute URLs and then serve them.
You would still need a server that serves the files though... OP wants to open the generated files straight from disk without any server. This can only be done when the urls are relative.
I agree with @Waterstraal, it's not a workaround in many cases, for example when using GitHub pages.
I agree with @Waterstraal, it's not a workaround in many cases, for example when using GitHub pages.
Since you are using GitHub pages, why do you need a relative URL? Can you provide a use case for me? I really would like to help but I am not so sure I understand your needs.
@Shigma we are deploying our docs in subfolders, per version. For example, v2.8.0 is located at https://www.chartjs.org/docs/2.8.0/, with a latest
symbolic link alias (https://www.chartjs.org/docs/latest/). Note that we are currently using GitBook but are considering to switch to VuePress.
Simple use-case: collect your pages on localhost without external ip... or in a subfolder on a shared space
@Shigma we are deploying our docs in subfolders, per version. For example, v2.8.0 is located at https://www.chartjs.org/docs/2.8.0/, with a
latest
symbolic link alias (https://www.chartjs.org/docs/latest/). Note that we are currently using GitBook but are considering to switch to VuePress.
And setting base
to /docs/2.8.0/
doesn't work?
I'm sure it works setting base
(though maybe not with the latest
alias), but base
can't be hard-coded in the repository since it depends of the current branch / tag (master
, 2.7.0
, 2.8.0
, etc...) and would break testing the docs locally. It can't be set at build time either, because the target sub-path is unknown at that time, the build process being different from the deploy one (and it would also break local builds).
@Shigma I don't understand what your problem with relative path is. Hardcoding something to get something else to work is always possible, but I can't imagine VuePress general aim is to hardcode simple things like that.
Posting to show interest in this enhancement.
Besides being useful for opening the site without a server it is also required to properly display websites on IPFS.
Interested in this enhancement as well, emphasizing on generating static files with relative paths for non-server file serving purpose.
Migrating out of gitbook (which is currently hosted in AWS S3) and would minimize the complexity/effort of the migration (e.g. effort on redoing the deployment pipeline)
I'm also highly interested in this enhancement. Are there any concrete plans for its implementation?
Any updates? This is also a strong need for our team because we want to host on our build server.
My usecase for this is Dash/Zeal/Velocity offline docs. It just renders from file URLs, but has a per-install random string at the start of the URI to separate each docset. It's per install so you can't predict it between systems. Using a base
of ./
doesn't work. Using a base
of /
doesn't work. Serving up the docs doesn't fix the offline portion of the usecase.
I hacked on this for a while, you can certainly get a decent amount of the docs working without JS enabled, but obviously any embedded Vue component won't render in that case.
We ran into the absolute base path as well. In our case, our needs in development can be partially satisfied by injecting the basename of the repo directory via a shell environment variable on the package.json script command line, and reading that via process.env
to set the dest and base settings in the .vuepress/config.js module. This assumes that the access path matches the path it is built under, which is just a little nuisance of re-building for each of a few different target locations. (This works for one fixed path per content build, but inhibits moving the static content elsewhere or accessing it through concurrent alternative paths.)
Same problem here. Why the heck you need a server to run simple HTML files with a bit of Javascript and Styles? I wrote a documentation for a project which should be shipped with the project and not being hosted somewhere, so the customer must be able to open the documentation without development skills.
https://github.com/vuejs/vuepress/blob/master/packages/%40vuepress/markdown/lib/link.js#L20 seems to suggest that the presence or absence of an absolute path (starting with the http protocol), is being used to infer whether or not the link is intended to be an internal (via vue router) or external link. This may not be the only place this assumption was made, and there may be other slightly tenuous inferences made about the absolute URL pattern - it could be somewhat difficult to allow for a relative URL base unless such inferences are removed. Seems also like that would come with some risk of breaking things elsewhere, but I don't know much about this codebase.
I sent https://github.com/yyx990803/html-webpack-plugin/pull/1, which I believe is necessary for fixing this issue
I took a look at using Docusaurus instead of Vuepress, but they don't support it either. They provided a much better explanation of why they don't support it though: https://github.com/facebook/docusaurus/issues/448#issuecomment-563973732
@benmccann That is a poor view rather than explanation. It is more like opening a pdf from your local machine. There are security holes in web too. Do you stop using it?
@benmccann I agree with @atilkan - that's not an explanation, but (very, very, outdated) paranoia ;)
@ulivz Would it be possible to re-fork html-webpack-plugin under the NPM @vuepress and the GH @vuepressjs namespaces?
Somewhat a solution vuepress-offlinify
@simonbrunel said:
@Shigma we are deploying our docs in subfolders, per version. For example, v2.8.0 is located at https://www.chartjs.org/docs/2.8.0/, with a
latest
symbolic link alias (https://www.chartjs.org/docs/latest/). Note that we are currently using GitBook but are considering to switch to VuePress.
I found this thread because I seem to have that problem, but I suggest changing the title of the issue to include "offline" and/or "no slash at beginning" so people aren't confused between the issue I solve there which is slashes after address (assets "relative" to .com) and "offline" (this issue--wanting to avoid the automatic the initial slash at the beginning of asset paths).
I think there is some confusion on this thread about "offline" (technically relative) and "subdirectory" (relative to .com). If I understand @simonbrunel, you are serving it online so having a "/" at the beginning is fine.
@simonbrunel Please let me know if this solves your issue without a plugin or patch: https://github.com/vuejs/vuepress/issues/1935#issuecomment-737614227
@poikilos your suggestion don't solve the problem: What problem does this feature solve? Run static files without a server.
Plese have some one found a trick to do that?
@poikilos your suggestion don't solve the problem: What problem does this feature solve? Run static files without a server.
Plese have some one found a trick to do that?
I've discovered that it's possible to run static vuepress files without a server by overwriting links to scripts, styles and pages inside html, and routing-related js code. I poked around vuepress output and did it, check out my project https://github.com/vuejs/vuepress/issues/796#issuecomment-644035856 It overwrites minified js code and this is bad, there should be more elegant solution by changing source files, but that sounds like much more effort to me.
@poikilos your suggestion don't solve the problem: What problem does this feature solve? Run static files without a server.
Plese have some one found a trick to do that?
My instructions allow you to save static html files. I have an article on doing it from a subdirectory and another article for doing it from the root of the domain. I'm not sure what you're asking--what did you think I meant? Don't be confused by the "Fix the nonworking..." issue, that has little to do with this one other than that my fix shows that issue is invalid and you can fix that with proper settings. :edit: You must mean without the leading slash for online use. My problem was that those were wrong even when running on a server and I solved that by not running via yarn/npm, which both change the current working directory and confuse vuepress so it doesn't find .vuepress and instead reverts to defaults including the site root setting. I remember now that I mentioned it because others may find this issue like I did when having that incorrect relative path for static html even though my fix doesn't solve the problem of the leading slash breaking offline use. That's why I said specifically that I had a different issue than the title, that the title of this issue is misleading, and suggested how to change or add to the issue title.
Tried with vuepress-next, now it throws an error when trying to build with base: ''
this all vuepress is just shit. I spent too much time struggling with it (making sidebar correct, changing favicon, etc.) and now it can not run without server.
@atilkan although they are rude by most people's standard, banning someone for a 'bad word' when voicing an opinion is a bit extreme; bad words are subjective and they didn't direct it towards any particular individual. But that's my 2 cents.
I think their comments come out of a sensible frustration. For what it's worth, vuepress team, I had the same issue as them, spent a bunch of personal time learning, configuring and exploring to only find out it does not create a usable local file out-of-box. Perhaps 'static site generator' is too loose of a term our industry is adopting? It sort of has multiple implicit meanings now apparently.
I think there are really 3 solutions to this problem
At minimum, I would encourage the team to at least continue explore this, as there clearly is a need for it. Whether you find it useful, or logical, or not as the core team developing of this, is irrelevant in my opinion - the fact is people want this feature, and if you don't find a reason to support it, consumers will move on to something that does support it. I have already done that and moved on to Hugo, which supports in natively, without plugin intervention, though I truly sincerely wish I didn't have to because I really like vuepress
Highly interested in this enhancement, here is why:
Any news on this? It seems multiple people have valid use cases, @simonbrunel explained one of them which is IMHO very reasonable when trying to actually ship versioned docs and make them available to whatever audience one needs, i.e. serving multiple versions of the same documentation and have a symbolic link to the "latest" version.
Sure, we can build the documentation multiple times, every time just changing the base
. But that seems very silly, it's 2022 after all ...
I'd be very much interested in an actual explanation as of why relative paths cannot be used and VuePress actively enforces absolute paths in "base".
Any news on this? It seems multiple people have valid use cases, @simonbrunel explained one of them which is IMHO very reasonable when trying to actually ship versioned docs and make them available to whatever audience one needs, i.e. serving multiple versions of the same documentation and have a symbolic link to the "latest" version.
Sure, we can build the documentation multiple times, every time just changing the
base
. But that seems very silly, it's 2022 after all ...I'd be very much interested in an actual explanation as of why relative paths cannot be used and VuePress actively enforces absolute paths in "base".
Probably, no one wanted to write this boring function for 2hrs :)
I wrote it today. The project can consider it a PR. If you commit this, please use (if making a commit with the git command or another program without a co-author feature, put two completely blank lines then): Co-authored-by: Poikilos <7557867+poikilos@users.noreply.github.com>
):
/**
* Convert a full path to a relative path.
* @param {string} fromPath - The absolute href of the current directory
* or file starting "/". If the leaf (part after last slash) has a "." it is
* assumed to be a file unless there is a slash after it (so if the
* leaf is a directory but contains a ".", put a slash after it).
* @param {string} toPath - The absolute href of the destination
* file or directory starting with "/".
*/
function getRelativePath(fromPath, toPath) {
if (!fromPath.startsWith('/')) {
console.log('Error: The fromPath "' + fromPath + '" given to getRelativePath is relative, preventing changing toPath.')
return toPath
}
if (!toPath.startsWith('/')) {
console.log('Error: The toPath "' + toPath + '" given to getRelativePath already appears relative, so it will not be changed.')
return toPath
}
var toLeafI = toPath.lastIndexOf('/')
var toLeaf = ''
var toDir = toPath
//if (toLeafI >= 0) { // always true since required to be absolute
toLeaf = toPath.substring(toLeafI + 1)
// ^ +1 to exclude the leading slash
toDir = toPath.substring(0, toLeafI + 1)
// ^ include the slash so there is always
// a slash (for easier calculation of return)
//}
var removeCount = 0
if (!toLeaf.includes(".")) {
// It is apparently not a file, so
// move the segment from the leaf
// to the dir.
if (toLeaf.length > 0) {
toDir += toLeaf + "/"
toLeaf = ""
removeCount = 1
// ^ The original didn't end in slash,
// so should be changed back (1
// character should be removed)
// before returning.
}
}
var fromLeafI = fromPath.lastIndexOf('/')
var fromLeaf = ''
if (fromLeafI >= 0) {
fromLeaf = fromPath.substring(fromLeafI+1)
}
var fromDir = fromPath
if (fromLeaf.includes(".")) {
// It is apparently a file.
fromDir = fromPath.substring(0, fromLeafI)
}
if (!fromDir.endsWith('/')) {
// It must be a directory at this point
// so add the '/' so all directories have
// / (for easier calculation of return).
fromDir += '/'
}
// console.log(' fromDir='+fromDir)
// console.log(' fromLeaf='+fromLeaf)
// console.log(' toDir='+toDir)
// console.log(' toLeaf='+toLeaf)
// console.log(' removeCount='+removeCount)
// Both fromDir and toDir end with '/' at this point.
if (toDir.startsWith(fromDir)) {
toPath = toDir.substring(fromDir.length) + toLeaf;
// The deeper path is now relative.
// This will also remove the leading slash because
// fromDir always has a slash by now.
}
else if (fromDir.startsWith(toDir)) {
// It is a shallower path, so repeat .. as necessary.
var uncommonSide = fromDir.substring(0, fromDir.length-toDir.length)
var uncommonSlashCount = uncommonSide.split("/").length
// console.log(' uncommonSide='+uncommonSide)
// console.log(' uncommonSlashCount='+uncommonSlashCount)
var trail = "../".repeat(uncommonSlashCount-1)
// trail.substring(0, trail.length-1)
toPath = trail + toLeaf
}
toPath = toPath.substring(0, toPath.length-removeCount)
return toPath
}
console.log('Test shallower dir (next 3 should be: ".."):')
console.log(getRelativePath("/services/design/", "/services"))
console.log(getRelativePath("/services/design/index.html", "/services"))
console.log(getRelativePath("/services/design", "/services"))
console.log()
console.log('Test shallower file (next 3 should be: "../index.html"):')
console.log(getRelativePath("/services/design/", "/services/index.html"))
console.log(getRelativePath("/services/design/index.html", "/services/index.html"))
console.log(getRelativePath("/services/design", "/services/index.html"))
console.log()
console.log('Test shallower root (should be "../../"):')
console.log(getRelativePath("/services/design/index.html", "/"))
console.log('Test file in shallower root (should be "../../index.html"):')
console.log(getRelativePath("/services/design/index.html", "/index.html"))
console.log('Test shallower directory (should be "../"):')
console.log(getRelativePath("/services/design/index.html", "/services/"))
console.log('Test deeper directory without slash (next 3 should be "design"):')
console.log(getRelativePath("/services/", "/services/design"))
console.log(getRelativePath("/services/index.php", "/services/design"))
console.log(getRelativePath("/services", "/services/design"))
// ^ expected output is: 'design'
console.log()
console.log('Test to ensure errors happen on incorrect input (next 2 should be "services"):')
// Incorrect input tests:
console.log(getRelativePath("/services/design", "services"))
// ^ should have an error since not absolute
console.log(getRelativePath("services/design", "services"))
// ^ should have an error since not absolute
I don't know all of the places in the code to use the function because I've never looked at the code of vuepress itself, or not enough to recall. Therefore, please take a look at this issue again and maybe you can make the change far more quickly than I can. If you use my function to do so please use the co-author information I supplied.
Caveats:
.includes('.')
for both toPath and fromPath. However, that would make the function slightly less versatile. You would either have to say isdirectory or isfile, else error. If neither exists, it wouldn't be known!Highly interested in this enhancement, I'd like to ship our vuepress doc to my users.
I just tried the vuepress successor vitepress. Sadly, it has this exact same issue.
It's not possible to build with an empty base url.
Setting base
in config.ts
to ''
will prepend paths with /
, resulting in this:
<link rel="preload stylesheet" href="/assets/style.0e94836e.css" as="style">
<script type="module" src="/assets/app.6a80f313.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.2ed14f66.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/assets/chunks/framework.e3082fbd.js">
<link rel="modulepreload" href="/assets/chunks/theme.ba0b17c6.js">
<link rel="modulepreload" href="/assets/index.md.d37213a0.lean.js">
Jeez 6 years after and still not possible to use relative urls 😅
vuepress 1, edit your .vuepress/config.js
:
class ReplaceHistoryToHashWebpackPlugin {
apply(compiler) {
compiler.hooks.emit.tap("ReplaceHistoryToHash", (compilation) => {
Object.keys(compilation.assets)
.filter((c) => c.endsWith(".js"))
.forEach((key) => {
if (compilation.assets[key] && compilation.assets[key]._value) {
const start =
compilation.assets[key]._value.indexOf('mode:"history"');
if (start > -1) {
compilation.assets[key]._value =
compilation.assets[key]._value.slice(0, start + 6) +
"hash" +
compilation.assets[key]._value.slice(start + 13);
}
}
});
});
}
}
module.exports = {
base: process.env.NODE_ENV === "production" ? __dirname + "/dist/" : "/",
configureWebpack: (config, isServer) => {
config.plugins.push(new ReplaceHistoryToHashWebpackPlugin());
},
};
Well, we have since moved to JetBrains WriterSide.
Feature request
If there was a feature to build with relative urls, we could run the files without opening a server. Might be something like:
vuepress build --relative
And urls would be like:
assets/js/5.3ca37a5b.js
instead of:/assets/js/5.3ca37a5b.js
What problem does this feature solve?
Run static files without a server.
Are you willing to work on this yourself?**
Sure.