mirror of https://github.com/docsifyjs/docsify.git
Chore: Clean up server implementation and update test docs (#2316)
- Replace live-server with existing Browsersync dependency as web server - Remove duplicate `index.html` file - Add `build:html` script to generate `/docs/preview.html`pull/2331/head
parent
cf61192f9a
commit
1c5a7013f1
@ -0,0 +1,42 @@
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import * as url from 'node:url';
|
||||
import prettier from 'prettier';
|
||||
import stripIndent from 'common-tags/lib/stripIndent/index.js';
|
||||
|
||||
const __filename = url.fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const prettierConfig = prettier.resolveConfig.sync(__dirname);
|
||||
|
||||
// Preview
|
||||
// =============================================================================
|
||||
function generatePreview() {
|
||||
const comment = stripIndent`
|
||||
<!--
|
||||
This file is generated by the build/html.js script.
|
||||
Do not edit this file directly.
|
||||
-->
|
||||
`;
|
||||
const srcFile = 'index.html';
|
||||
const srcPath = path.resolve(__dirname, '..', 'docs');
|
||||
const srcHTML = fs.readFileSync(path.resolve(srcPath, srcFile), 'utf8');
|
||||
const outFile = 'preview.html';
|
||||
const outPath = path.resolve(__dirname, '..', 'docs');
|
||||
const outHTML = srcHTML
|
||||
// Append comment
|
||||
.replace(/(<!DOCTYPE html>)/, `${comment}\n$1`)
|
||||
// Modify title
|
||||
.replace(/(<\/title>)/, ' (Preview)$1')
|
||||
// Replace CDN URLs with local paths
|
||||
.replace(/\/\/cdn.jsdelivr.net\/npm\/docsify@4\//g, '/');
|
||||
const formattedHTML = prettier.format(outHTML, {
|
||||
...prettierConfig,
|
||||
filepath: outFile,
|
||||
});
|
||||
|
||||
console.log(`\nBuilding ${outFile} in ${outPath}`);
|
||||
|
||||
fs.writeFileSync(path.resolve(outPath, outFile), formattedHTML);
|
||||
}
|
||||
|
||||
generatePreview();
|
@ -1,190 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>docsify</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<link rel="stylesheet" href="/themes/vue.css" title="vue" />
|
||||
<link rel="stylesheet" href="/themes/dark.css" title="dark" disabled />
|
||||
<link rel="stylesheet" href="/themes/buble.css" title="buble" disabled />
|
||||
<link rel="stylesheet" href="/themes/pure.css" title="pure" disabled />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/themes/dolphin.css"
|
||||
title="dolphin"
|
||||
disabled
|
||||
/>
|
||||
<style>
|
||||
nav.app-nav li ul {
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
#carbonads {
|
||||
box-shadow: none !important;
|
||||
width: auto !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-plugin-carbon@1"></script>
|
||||
<script>
|
||||
// Set html "lang" attribute based on URL
|
||||
const lang = location.hash.match(/#\/(de-de|es|ru-ru|zh-cn)\//);
|
||||
|
||||
if (lang) {
|
||||
document.documentElement.setAttribute('lang', lang[1]);
|
||||
}
|
||||
|
||||
// Docsify configuration
|
||||
window.$docsify = {
|
||||
alias: {
|
||||
'.*?/awesome':
|
||||
'https://raw.githubusercontent.com/docsifyjs/awesome-docsify/master/README.md',
|
||||
'.*?/changelog':
|
||||
'https://raw.githubusercontent.com/docsifyjs/docsify/master/CHANGELOG.md',
|
||||
'/.*/_navbar.md': '/_navbar.md',
|
||||
'/es/(.*)':
|
||||
'https://raw.githubusercontent.com/docsifyjs/docs-es/master/$1',
|
||||
'/de-de/(.*)':
|
||||
'https://raw.githubusercontent.com/docsifyjs/docs-de/master/$1',
|
||||
'/ru-ru/(.*)':
|
||||
'https://raw.githubusercontent.com/docsifyjs/docs-ru/master/$1',
|
||||
'/zh-cn/(.*)':
|
||||
'https://cdn.jsdelivr.net/gh/docsifyjs/docs-zh@master/$1',
|
||||
},
|
||||
auto2top: true,
|
||||
basePath: '/docs/',
|
||||
coverpage: true,
|
||||
executeScript: true,
|
||||
loadSidebar: true,
|
||||
loadNavbar: true,
|
||||
mergeNavbar: true,
|
||||
maxLevel: 4,
|
||||
subMaxLevel: 2,
|
||||
name: 'docsify',
|
||||
nameLink: {
|
||||
'/es/': '#/es/',
|
||||
'/de-de/': '#/de-de/',
|
||||
'/ru-ru/': '#/ru-ru/',
|
||||
'/zh-cn/': '#/zh-cn/',
|
||||
'/': '#/',
|
||||
},
|
||||
search: {
|
||||
noData: {
|
||||
'/es/': '¡No hay resultados!',
|
||||
'/de-de/': 'Keine Ergebnisse!',
|
||||
'/ru-ru/': 'Никаких результатов!',
|
||||
'/zh-cn/': '没有结果!',
|
||||
'/': 'No results!',
|
||||
},
|
||||
paths: 'auto',
|
||||
placeholder: {
|
||||
'/es/': 'Buscar',
|
||||
'/de-de/': 'Suche',
|
||||
'/ru-ru/': 'Поиск',
|
||||
'/zh-cn/': '搜索',
|
||||
'/': 'Search',
|
||||
},
|
||||
pathNamespaces: ['/es', '/de-de', '/ru-ru', '/zh-cn'],
|
||||
},
|
||||
skipLink: {
|
||||
'/es/': 'Saltar al contenido principal',
|
||||
'/de-de/': 'Ga naar de hoofdinhoud',
|
||||
'/ru-ru/': 'Перейти к основному содержанию',
|
||||
'/zh-cn/': '跳到主要内容',
|
||||
},
|
||||
vueComponents: {
|
||||
'button-counter': {
|
||||
template: /* html */ `<button @click="count += 1">You clicked me {{ count }} times</button>`,
|
||||
data() {
|
||||
return {
|
||||
count: 0,
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
vueGlobalOptions: {
|
||||
data() {
|
||||
return {
|
||||
count: 0,
|
||||
message: 'Hello, World!',
|
||||
// Fake API response
|
||||
images: [
|
||||
{ title: 'Image 1', url: 'https://picsum.photos/150?random=1' },
|
||||
{ title: 'Image 2', url: 'https://picsum.photos/150?random=2' },
|
||||
{ title: 'Image 3', url: 'https://picsum.photos/150?random=3' },
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
timeOfDay() {
|
||||
const date = new Date();
|
||||
const hours = date.getHours();
|
||||
|
||||
if (hours < 12) {
|
||||
return 'morning';
|
||||
} else if (hours < 18) {
|
||||
return 'afternoon';
|
||||
} else {
|
||||
return 'evening';
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
hello() {
|
||||
alert(this.message);
|
||||
},
|
||||
},
|
||||
},
|
||||
vueMounts: {
|
||||
'#counter': {
|
||||
data() {
|
||||
return {
|
||||
count: 0,
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
DocsifyCarbon.create('CEBI6KQE', 'docsifyjsorg'),
|
||||
function (hook, vm) {
|
||||
hook.beforeEach(html => {
|
||||
if (/githubusercontent\.com/.test(vm.route.file)) {
|
||||
url = vm.route.file
|
||||
.replace('raw.githubusercontent.com', 'github.com')
|
||||
.replace(/\/master/, '/blob/master');
|
||||
} else if (/jsdelivr\.net/.test(vm.route.file)) {
|
||||
url = vm.route.file
|
||||
.replace('cdn.jsdelivr.net/gh', 'github.com')
|
||||
.replace('@master', '/blob/master');
|
||||
} else {
|
||||
url =
|
||||
'https://github.com/docsifyjs/docsify/blob/develop/docs/' +
|
||||
vm.route.file;
|
||||
}
|
||||
const editHtml = '[:memo: Edit Document](' + url + ')\n';
|
||||
return (
|
||||
editHtml +
|
||||
html +
|
||||
'\n\n----\n\n' +
|
||||
'<a href="https://docsify.js.org" target="_blank" style="color: inherit; font-weight: normal; text-decoration: none;">Powered by docsify</a>\n\n' +
|
||||
'<a href="https://vercel.com/?utm_source=docsifyjs&utm_campaign=oss" target="_blank" title="Vercel has given us a Pro account"><img src="/docs/_media/powered-by-vercel.svg" alt="Vercel" width="150"></a>'
|
||||
);
|
||||
});
|
||||
},
|
||||
],
|
||||
};
|
||||
</script>
|
||||
<script src="/lib/docsify.js"></script>
|
||||
<script src="/lib/plugins/search.js"></script>
|
||||
<script src="/lib/plugins/front-matter.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs/components/prism-bash.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs/components/prism-markdown.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs/components/prism-nginx.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs/components/prism-php.min.js"></script>
|
||||
|
||||
<script src="//cdn.jsdelivr.net/npm/vue@2/dist/vue.min.js"></script>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,65 @@
|
||||
import * as path from 'node:path';
|
||||
import * as url from 'node:url';
|
||||
|
||||
const __filename = url.fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const defaults = {
|
||||
hostname: '127.0.0.1',
|
||||
notify: false,
|
||||
open: false,
|
||||
rewriteRules: [
|
||||
// Replace remote URLs with local paths
|
||||
{
|
||||
// Changelog
|
||||
match: /https?.*\/CHANGELOG.md/g,
|
||||
replace: '/CHANGELOG.md',
|
||||
},
|
||||
],
|
||||
server: {
|
||||
baseDir: 'docs',
|
||||
index: 'preview.html',
|
||||
routes: {
|
||||
'/changelog.md': path.resolve(__dirname, 'CHANGELOG.md'),
|
||||
'/lib': path.resolve(__dirname, 'lib'),
|
||||
'/node_modules': path.resolve(__dirname, 'node_modules'), // Required for automated Vue tests
|
||||
},
|
||||
},
|
||||
snippet: false,
|
||||
ui: false,
|
||||
};
|
||||
|
||||
export default {
|
||||
// Development (preview, local URLs, watch enabled)
|
||||
dev: {
|
||||
...defaults,
|
||||
files: ['CHANGELOG.md', 'docs/**/*', 'lib/**/*'],
|
||||
port: 3000,
|
||||
open: true,
|
||||
snippet: true,
|
||||
},
|
||||
// Production (index, CDN URLs, watch disabled)
|
||||
prod: {
|
||||
...defaults,
|
||||
port: 8080,
|
||||
server: {
|
||||
...defaults.server,
|
||||
index: 'index.html',
|
||||
},
|
||||
},
|
||||
// Test (preview, local URLs, watch disabled)
|
||||
test: {
|
||||
...defaults,
|
||||
middleware: [
|
||||
// Blank page required for test environment
|
||||
{
|
||||
route: '/_blank.html',
|
||||
handle(req, res, next) {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.end('');
|
||||
next();
|
||||
},
|
||||
},
|
||||
],
|
||||
port: 4000,
|
||||
},
|
||||
};
|
@ -1,10 +1,13 @@
|
||||
import liveServer from 'live-server';
|
||||
const middleware = [];
|
||||
import { create } from 'browser-sync';
|
||||
import serverConfigs from './server.config.js';
|
||||
|
||||
const params = {
|
||||
port: 3000,
|
||||
watch: ['lib', 'docs', 'themes'],
|
||||
middleware,
|
||||
};
|
||||
const bsServer = create();
|
||||
const args = process.argv.slice(2);
|
||||
const configName =
|
||||
Object.keys(serverConfigs).find(name => args.includes(`--${name}`)) || 'prod';
|
||||
const settings = serverConfigs[configName];
|
||||
|
||||
liveServer.start(params);
|
||||
// prettier-ignore
|
||||
console.log(`\nStarting ${configName} server (${settings.server.index}, watch: ${Boolean(settings.files)})\n`);
|
||||
|
||||
bsServer.init(settings);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import server from './server.js';
|
||||
import { startServer } from './server.js';
|
||||
|
||||
export default async () => {
|
||||
await server.startAsync();
|
||||
await startServer();
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import server from './server.js';
|
||||
import { stopServer } from './server.js';
|
||||
|
||||
export default async () => {
|
||||
server.stop();
|
||||
stopServer();
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import server from './server.js';
|
||||
import { startServer } from './server.js';
|
||||
|
||||
export default async config => {
|
||||
await server.startAsync();
|
||||
startServer();
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import server from './server.js';
|
||||
import { stopServer } from './server.js';
|
||||
|
||||
export default async config => {
|
||||
server.stop();
|
||||
stopServer();
|
||||
};
|
||||
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"redirects": [
|
||||
{
|
||||
"source": "/",
|
||||
"destination": "./docs/preview.html",
|
||||
"permanent": true
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue