Skip to content

fix #1101, #704 #1311

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

Closed
wants to merge 33 commits into from
Closed

fix #1101, #704 #1311

wants to merge 33 commits into from

Conversation

boxsnake
Copy link

@boxsnake boxsnake commented Jul 27, 2020

Summary
This fix solved:

  • The SSR does not work properly when fetching local markdown files
  • The SSR does not work properly for sidebars
  • The SSR can not map local files to url
  • Code bugs which makes SSR not work

This fix introduced:

  • baseUrl config entry to allow user override basePath when basePath is local location for SSR

What kind of change does this PR introduce? (check at least one)

  • Bugfix
  • Feature
  • Code style update
  • Refactor
  • Docs
  • Build-related changes
  • Repo settings
  • Other, please describe:

If changing the UI of default theme, please provide the before/after screenshot:

Does this PR introduce a breaking change? (check one)

  • Yes
  • No

If yes, please describe the impact and migration path for existing applications:

The PR fulfills these requirements:

  • When resolving a specific issue, it's referenced in the PR's title (e.g. fix #xxx[,#xxx], where "xxx" is the issue number)

You have tested in the following browsers: (Providing a detailed version will be better.)

  • Chrome
  • Firefox
  • Safari
  • Edge
  • IE

If adding a new feature, the PR's description includes:

  • A convincing reason for adding this feature
  • Related documents have been updated
  • Related tests have been updated

To avoid wasting your time, it's best to open a feature request issue first and wait for approval before working on it.

@vercel
Copy link

vercel bot commented Jul 27, 2020

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/docsify-core/docsify-preview/7pmavtza0
✅ Preview: https://docsify-preview-git-fork-boxsnake-fix-ssr.docsify-core.vercel.app

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jul 27, 2020

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 363548a:

Sandbox Source
docsify-template Configuration

@sy-records
Copy link
Member

image
You need a fix to pass ci

@sy-records
Copy link
Member

sy-records commented Jul 28, 2020

image
I've tested it and it still doesn't work. There's also an undefined.

use github.com/docsifyjs/docsify-ssr-demo

@boxsnake
Copy link
Author

boxsnake commented Jul 28, 2020

Known problem:

  • In the first time get into the SSR-ed page with history routerMode, the sidebar does not show proper active class for current route.

@boxsnake
Copy link
Author

New stuff added:

  • baseUrl for overriding basePath when basePath is local.
  • When baseUrl is used, the /xxx.md path should be avaiable over the server (eg. Use static to map .md files as static in expressjs)

@boxsnake
Copy link
Author

boxsnake commented Jul 28, 2020

A simple SSR using packages express and docsify-server-renderer:

const Express = require('express');
const Fs = require('fs');
const DocsifyServerRenderer = require('docsify-server-renderer');
const router = Express.Router();

const DocBase = '/tmp/doc';

// Expose `.md` file to server url for `history` mode loading
router.use('', Express.static(DocBase));

router.get('/:url(.{0,})', async function(req, res, next) {
   let url     = req.params.url || '';
   let renderConfig = {
        loadNavbar: false,
        loadSidebar: true,
        name: 'docsify',
        basePath: DocBase, // This is local server location, and will be replaced by `baseUrl` when SSR
        baseUrl: '' // This is for overriding `basePath` if `basePath` is local path in server
    };

    let tplContent  = Fs.readFileSync('./tpl.html', 'utf8');
    let tplConfig   = {template: tplContent, config: renderConfig};
    let tplRenderer = new DocsifyServerRenderer(tplConfig);
    let tplRendered = await tplRenderer.renderToString(url);
    return res.send(tplRendered);
});

module.exports = router;

@boxsnake
Copy link
Author

I do not think it is common procedure for an SSR engine to fetch Markdown (parsing resource) remotely via url.
For a more commonly SSR usage, people would want to fetch local files, and local templates, and the render them into one static page.

@boxsnake boxsnake changed the title Fix SSR #1101, #704 fix SSR #1101, #704 Jul 28, 2020
@boxsnake boxsnake changed the title fix SSR #1101, #704 fix #1101, #704 Jul 28, 2020
this.html = this.html.replace(new RegExp(`<!--${match}-->`, 'g'), content);
_getWebConfig() {
let config = Object.assign({}, this.config);
config.routerMode = 'abstract';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why assigning router to abstract ? is it for the default ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the page is rendered in the server-side, there is no need for web page javascripts to deal sidebar links as 'history' or 'hash' mode, it is directly an <a> link. Thus, I uses 'abstract' as the mode to avoid any js on- hooks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @docsifyjs/reviewers

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anikethsaha
I found that e2e tests runs through both hash and history modes. Thus, I am going to change this as following:

  1. Since SSR only goes an <a> link, and no need for onchange actions, I will use abstract as routerMode in injected config.
  2. Since SSR is in node, which does not have window object, I will use default getBasePath, getCurrentPath and normalize methods from History class.
  3. Since parse and toURL methods are required for generating links, I will use corresponding methods from either HashHistory or HTML5History class'es prototype.

Note: SSR config is slightly different from injected config. Injected one has routerMode 'abstract' to avoid onchange hooks. SSR config has routerMode 'hash' or 'history' to make sure the links are rendered correctly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not doing e2e for SSR I suppose, Also I would recommend to not change the current tests as it is being completely re-written #1276

@sy-records
Copy link
Member

Can you run npm run serve:ssr normally?
image

@boxsnake
Copy link
Author

boxsnake commented Aug 31, 2020

Can you run npm run serve:ssr normally?
image

Nope, but it is a problem in compiler lexer (from previous commits):
The line is

var linkRE = compile.Lexer.rules.inline.link;

I will look deep to fix this.

@trusktr
Copy link
Member

trusktr commented Feb 2, 2022

@boxsnake thanks for having attempted this. The SSR is too incomplete and experimental, as we recently added to README (plugins and various features of Docsify not working, etc).

I have a plan for a solid implementation of SSR that I will prototype soon, and it will remove SSR code from Docsify and delegate to a framework that specializes in SSR (Solid.js).

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 this pull request may close these issues.

4 participants