chore: Update local and Vercel preview. Fix CSS watch functionality. (#2348)

This commit is contained in:
John Hildenbiddle 2023-12-21 23:27:13 -06:00 committed by GitHub
parent 25e715b387
commit 167596be51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 106 additions and 98 deletions

2
.gitignore vendored
View File

@ -3,9 +3,9 @@
*.log
/_playwright-report
/_playwright-results
/docs/preview.html
/lib
/node_modules
# exceptions
!.gitkeep
.vercel

View File

@ -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();

View File

@ -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 sharedConfig = {
errorOnDeprecated: true,

53
middleware.js Normal file
View File

@ -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',
},
});
}

View File

@ -27,10 +27,9 @@
"build:css:min": "node build/mincss.js",
"build:css": "mkdirp lib/themes && node build/css -o lib/themes",
"build:emoji": "node ./build/emoji.js",
"build:html": "node ./build/html.js",
"build:js": "cross-env NODE_ENV=production node build/build.js",
"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:*",
"docker:build:test": "npm run docker:cli -- build:test",
"docker:build": "docker build -f Dockerfile -t docsify-test:local .",
@ -49,13 +48,13 @@
"prettier": "prettier . --write",
"pub:next": "cross-env RELEASE_TAG=next 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",
"test:e2e": "playwright test",
"test:integration": "npm run jest -- --selectProjects integration",
"test:unit": "npm run jest -- --selectProjects unit",
"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"
},
"husky": {

View File

@ -1,7 +1,7 @@
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}`;
process.env.TEST_HOST = TEST_HOST;

View File

@ -1,54 +1,46 @@
import * as path from 'node:path';
import * as url from 'node:url';
import { rewriteRules } from './middleware.js';
const __filename = url.fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const defaults = {
// Production (CDN URLs, watch disabled)
export const prodConfig = {
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',
},
],
port: 8080,
server: {
baseDir: 'docs',
index: 'preview.html',
baseDir: './docs',
},
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: {
'/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,
snippet: true,
};
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,
// Test (local URLs, watch disabled)
export const testConfig = {
...devConfig,
port: 4000,
server: {
...devConfig.server,
middleware: [
// Blank page required for test environment
{
@ -60,6 +52,7 @@ export default {
},
},
],
port: 4000,
},
snippet: false,
watch: false,
};

View File

@ -1,13 +1,14 @@
import { create } from 'browser-sync';
import serverConfigs from './server.config.js';
import { devConfig, prodConfig } from './server.configs.js';
const bsServer = create();
const args = process.argv.slice(2);
const configName =
Object.keys(serverConfigs).find(name => args.includes(`--${name}`)) || 'prod';
const settings = serverConfigs[configName];
const config = args.includes('--dev') ? devConfig : prodConfig;
const configName = config === devConfig ? 'development' : 'production';
const isWatch = Boolean(config.files) && config.watch !== false;
const urlType = config === devConfig ? 'local' : 'CDN';
// 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);

View File

@ -1,13 +1,13 @@
import * as process from 'node:process';
import { create } from 'browser-sync';
import config from '../../server.config.js';
import { testConfig } from '../../server.configs.js';
const bsServer = create();
export async function startServer() {
// Wait for server to start
return new Promise(resolve => {
const settings = config.test;
const settings = testConfig;
console.log('\n');

View File

@ -1,9 +1,13 @@
{
"redirects": [
"headers": [
{
"source": "/",
"destination": "./docs/preview.html",
"permanent": true
"source": "/(.*)",
"headers": [{ "key": "x-robots-tag", "value": "noindex" }]
}
],
"redirects": [{ "source": "/", "destination": "/preview/" }],
"rewrites": [
{ "source": "/preview/CHANGELOG.md", "destination": "/CHANGELOG.md" },
{ "source": "/preview/:path*", "destination": "/docs/:path*" }
]
}