mirror of
https://github.com/docsifyjs/docsify.git
synced 2026-10-16 20:21:38 +08:00
chore: Update local and Vercel preview. Fix CSS watch functionality. (#2348)
This commit is contained in:
committed by
GitHub
parent
25e715b387
commit
167596be51
+1
-1
@@ -3,9 +3,9 @@
|
|||||||
*.log
|
*.log
|
||||||
/_playwright-report
|
/_playwright-report
|
||||||
/_playwright-results
|
/_playwright-results
|
||||||
/docs/preview.html
|
|
||||||
/lib
|
/lib
|
||||||
/node_modules
|
/node_modules
|
||||||
|
|
||||||
# exceptions
|
# exceptions
|
||||||
!.gitkeep
|
!.gitkeep
|
||||||
|
.vercel
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
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();
|
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
import serverConfig from './server.config.js';
|
import { testConfig } from './server.configs.js';
|
||||||
|
|
||||||
const { hostname, port } = serverConfig.test;
|
const { hostname, port } = testConfig;
|
||||||
const TEST_HOST = `http://${hostname}:${port}`;
|
const TEST_HOST = `http://${hostname}:${port}`;
|
||||||
const sharedConfig = {
|
const sharedConfig = {
|
||||||
errorOnDeprecated: true,
|
errorOnDeprecated: true,
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
// Exports
|
||||||
|
// =============================================================================
|
||||||
|
export const config = {
|
||||||
|
matcher: ['/preview/(index.html)?'],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Rewrite rules shared with local server configurations
|
||||||
|
export const rewriteRules = [
|
||||||
|
// Replace CDN URLs with local paths
|
||||||
|
{
|
||||||
|
match: /https?.*\/CHANGELOG.md/g,
|
||||||
|
replace: '/CHANGELOG.md',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// CDN versioned default
|
||||||
|
// Ex1: //cdn.com/package-name
|
||||||
|
// Ex2: http://cdn.com/package-name@1.0.0
|
||||||
|
// Ex3: https://cdn.com/package-name@latest
|
||||||
|
match: /(?:https?:)*\/\/.*cdn.*docsify[@\d.latest]*(?=["'])/g,
|
||||||
|
replace: '/lib/docsify.min.js',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// CDN paths to local paths
|
||||||
|
// Ex1: //cdn.com/package-name/path/file.js => /path/file.js
|
||||||
|
// Ex2: http://cdn.com/package-name@1.0.0/dist/file.js => /dist/file.js
|
||||||
|
// Ex3: https://cdn.com/package-name@latest/dist/file.js => /dist/file.js
|
||||||
|
match: /(?:https?:)*\/\/.*cdn.*docsify[@\d.latest]*\/(?:lib\/)/g,
|
||||||
|
replace: '/lib/',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// Serve virtual /preview/index.html
|
||||||
|
// Note: See vercel.json for preview routing configuration
|
||||||
|
// 1. Fetch index.html from /docs/ directory
|
||||||
|
// 2. Replace CDN URLs with local paths (see rewriteRules)
|
||||||
|
// 3. Return preview HTML
|
||||||
|
export default async function middleware(request) {
|
||||||
|
const { origin } = new URL(request.url);
|
||||||
|
const indexURL = `${origin}/docs/index.html`;
|
||||||
|
const indexHTML = await fetch(indexURL).then(res => res.text());
|
||||||
|
const previewHTML = rewriteRules.reduce(
|
||||||
|
(html, rule) => html.replace(rule.match, rule.replace),
|
||||||
|
indexHTML
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Response(previewHTML, {
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
'content-type': 'text/html',
|
||||||
|
'x-robots-tag': 'noindex',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
+3
-4
@@ -27,10 +27,9 @@
|
|||||||
"build:css:min": "node build/mincss.js",
|
"build:css:min": "node build/mincss.js",
|
||||||
"build:css": "mkdirp lib/themes && node build/css -o lib/themes",
|
"build:css": "mkdirp lib/themes && node build/css -o lib/themes",
|
||||||
"build:emoji": "node ./build/emoji.js",
|
"build:emoji": "node ./build/emoji.js",
|
||||||
"build:html": "node ./build/html.js",
|
|
||||||
"build:js": "cross-env NODE_ENV=production node build/build.js",
|
"build:js": "cross-env NODE_ENV=production node build/build.js",
|
||||||
"build:test": "npm run build && npm test",
|
"build:test": "npm run build && npm test",
|
||||||
"build": "rimraf lib themes && run-s build:js build:css build:css:min build:cover build:emoji build:html",
|
"build": "rimraf lib themes && run-s build:js build:css build:css:min build:cover build:emoji",
|
||||||
"dev": "run-p serve:dev watch:*",
|
"dev": "run-p serve:dev watch:*",
|
||||||
"docker:build:test": "npm run docker:cli -- build:test",
|
"docker:build:test": "npm run docker:cli -- build:test",
|
||||||
"docker:build": "docker build -f Dockerfile -t docsify-test:local .",
|
"docker:build": "docker build -f Dockerfile -t docsify-test:local .",
|
||||||
@@ -49,13 +48,13 @@
|
|||||||
"prettier": "prettier . --write",
|
"prettier": "prettier . --write",
|
||||||
"pub:next": "cross-env RELEASE_TAG=next sh build/release.sh",
|
"pub:next": "cross-env RELEASE_TAG=next sh build/release.sh",
|
||||||
"pub": "sh build/release.sh",
|
"pub": "sh build/release.sh",
|
||||||
"serve:dev": "npm run build:html && npm run serve -- --dev",
|
"serve:dev": "npm run serve -- --dev",
|
||||||
"serve": "node server",
|
"serve": "node server",
|
||||||
"test:e2e": "playwright test",
|
"test:e2e": "playwright test",
|
||||||
"test:integration": "npm run jest -- --selectProjects integration",
|
"test:integration": "npm run jest -- --selectProjects integration",
|
||||||
"test:unit": "npm run jest -- --selectProjects unit",
|
"test:unit": "npm run jest -- --selectProjects unit",
|
||||||
"test": "npm run jest && run-s test:e2e",
|
"test": "npm run jest && run-s test:e2e",
|
||||||
"watch:css": "npm run css -- -o themes -w",
|
"watch:css": "npm run build:css -- -w",
|
||||||
"watch:js": "node build/build.js"
|
"watch:js": "node build/build.js"
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { devices } from '@playwright/test';
|
import { devices } from '@playwright/test';
|
||||||
import serverConfig from './server.config.js';
|
import { testConfig } from './server.configs.js';
|
||||||
|
|
||||||
const { hostname, port } = serverConfig.test;
|
const { hostname, port } = testConfig;
|
||||||
const TEST_HOST = `http://${hostname}:${port}`;
|
const TEST_HOST = `http://${hostname}:${port}`;
|
||||||
|
|
||||||
process.env.TEST_HOST = TEST_HOST;
|
process.env.TEST_HOST = TEST_HOST;
|
||||||
|
|||||||
@@ -1,54 +1,46 @@
|
|||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
import * as url from 'node:url';
|
import * as url from 'node:url';
|
||||||
|
import { rewriteRules } from './middleware.js';
|
||||||
|
|
||||||
const __filename = url.fileURLToPath(import.meta.url);
|
const __filename = url.fileURLToPath(import.meta.url);
|
||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
const defaults = {
|
|
||||||
|
// Production (CDN URLs, watch disabled)
|
||||||
|
export const prodConfig = {
|
||||||
hostname: '127.0.0.1',
|
hostname: '127.0.0.1',
|
||||||
notify: false,
|
notify: false,
|
||||||
open: false,
|
open: false,
|
||||||
rewriteRules: [
|
port: 8080,
|
||||||
// Replace remote URLs with local paths
|
|
||||||
{
|
|
||||||
// Changelog
|
|
||||||
match: /https?.*\/CHANGELOG.md/g,
|
|
||||||
replace: '/CHANGELOG.md',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
server: {
|
server: {
|
||||||
baseDir: 'docs',
|
baseDir: './docs',
|
||||||
index: 'preview.html',
|
},
|
||||||
|
snippet: false,
|
||||||
|
ui: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Development (local URLs, watch enabled)
|
||||||
|
export const devConfig = {
|
||||||
|
...prodConfig,
|
||||||
|
files: ['CHANGELOG.md', 'docs/**/*', 'lib/**/*'],
|
||||||
|
port: 3000,
|
||||||
|
rewriteRules,
|
||||||
|
server: {
|
||||||
|
...prodConfig.server,
|
||||||
routes: {
|
routes: {
|
||||||
'/changelog.md': path.resolve(__dirname, 'CHANGELOG.md'),
|
'/changelog.md': path.resolve(__dirname, 'CHANGELOG.md'),
|
||||||
'/lib': path.resolve(__dirname, 'lib'),
|
'/lib': path.resolve(__dirname, 'lib'),
|
||||||
'/node_modules': path.resolve(__dirname, 'node_modules'), // Required for automated Vue tests
|
'/node_modules': path.resolve(__dirname, 'node_modules'), // Required for automated Vue tests
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
snippet: false,
|
snippet: true,
|
||||||
ui: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
// Test (local URLs, watch disabled)
|
||||||
// Development (preview, local URLs, watch enabled)
|
export const testConfig = {
|
||||||
dev: {
|
...devConfig,
|
||||||
...defaults,
|
port: 4000,
|
||||||
files: ['CHANGELOG.md', 'docs/**/*', 'lib/**/*'],
|
server: {
|
||||||
port: 3000,
|
...devConfig.server,
|
||||||
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: [
|
middleware: [
|
||||||
// Blank page required for test environment
|
// Blank page required for test environment
|
||||||
{
|
{
|
||||||
@@ -60,6 +52,7 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
port: 4000,
|
|
||||||
},
|
},
|
||||||
|
snippet: false,
|
||||||
|
watch: false,
|
||||||
};
|
};
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
import { create } from 'browser-sync';
|
import { create } from 'browser-sync';
|
||||||
import serverConfigs from './server.config.js';
|
import { devConfig, prodConfig } from './server.configs.js';
|
||||||
|
|
||||||
const bsServer = create();
|
const bsServer = create();
|
||||||
const args = process.argv.slice(2);
|
const args = process.argv.slice(2);
|
||||||
const configName =
|
const config = args.includes('--dev') ? devConfig : prodConfig;
|
||||||
Object.keys(serverConfigs).find(name => args.includes(`--${name}`)) || 'prod';
|
const configName = config === devConfig ? 'development' : 'production';
|
||||||
const settings = serverConfigs[configName];
|
const isWatch = Boolean(config.files) && config.watch !== false;
|
||||||
|
const urlType = config === devConfig ? 'local' : 'CDN';
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
console.log(`\nStarting ${configName} server (${settings.server.index}, watch: ${Boolean(settings.files)})\n`);
|
console.log(`\nStarting ${configName} server (${urlType} URLs, watch: ${isWatch})\n`);
|
||||||
|
|
||||||
bsServer.init(settings);
|
bsServer.init(config);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import * as process from 'node:process';
|
import * as process from 'node:process';
|
||||||
import { create } from 'browser-sync';
|
import { create } from 'browser-sync';
|
||||||
import config from '../../server.config.js';
|
import { testConfig } from '../../server.configs.js';
|
||||||
|
|
||||||
const bsServer = create();
|
const bsServer = create();
|
||||||
|
|
||||||
export async function startServer() {
|
export async function startServer() {
|
||||||
// Wait for server to start
|
// Wait for server to start
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const settings = config.test;
|
const settings = testConfig;
|
||||||
|
|
||||||
console.log('\n');
|
console.log('\n');
|
||||||
|
|
||||||
|
|||||||
+8
-4
@@ -1,9 +1,13 @@
|
|||||||
{
|
{
|
||||||
"redirects": [
|
"headers": [
|
||||||
{
|
{
|
||||||
"source": "/",
|
"source": "/(.*)",
|
||||||
"destination": "./docs/preview.html",
|
"headers": [{ "key": "x-robots-tag", "value": "noindex" }]
|
||||||
"permanent": true
|
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"redirects": [{ "source": "/", "destination": "/preview/" }],
|
||||||
|
"rewrites": [
|
||||||
|
{ "source": "/preview/CHANGELOG.md", "destination": "/CHANGELOG.md" },
|
||||||
|
{ "source": "/preview/:path*", "destination": "/docs/:path*" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user