mirror of
https://github.com/modernweb-dev/rocket.git
synced 2026-03-21 15:54:57 +00:00
Compare commits
15 Commits
@rocket/en
...
@rocket/cl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b48fb9760 | ||
|
|
39206a1738 | ||
|
|
cbfb0f91e2 | ||
|
|
58692147e9 | ||
|
|
8dedc56afa | ||
|
|
bcbfae332d | ||
|
|
0fae0037d8 | ||
|
|
390335da18 | ||
|
|
6d2f469d26 | ||
|
|
94a6f54585 | ||
|
|
ff8b4c5cd5 | ||
|
|
5122ea8639 | ||
|
|
3032ba9b82 | ||
|
|
93503ed309 | ||
|
|
77646abbee |
@@ -28,7 +28,7 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://rocket.modern-web.dev">Website</a>
|
<a href="https://rocket.modern-web.dev">Website</a>
|
||||||
·
|
·
|
||||||
<a href="https://rocket.modern-web.dev/doc/">Documentation</a>
|
<a href="https://rocket.modern-web.dev/docs/">Documentation</a>
|
||||||
·
|
·
|
||||||
<a href="https://rocket.modern-web.dev/chat">Discord Community</a>
|
<a href="https://rocket.modern-web.dev/chat">Discord Community</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -35,8 +35,9 @@
|
|||||||
"setup:ts-configs": "node scripts/generate-ts-configs.mjs",
|
"setup:ts-configs": "node scripts/generate-ts-configs.mjs",
|
||||||
"start:experimental": "NODE_DEBUG=engine:rendering node --no-warnings --experimental-loader ./packages/engine/src/litCssLoader.js packages/cli/src/cli.js start --open",
|
"start:experimental": "NODE_DEBUG=engine:rendering node --no-warnings --experimental-loader ./packages/engine/src/litCssLoader.js packages/cli/src/cli.js start --open",
|
||||||
"start": "NODE_DEBUG=engine:rendering node --trace-warnings packages/cli/src/cli.js start --open",
|
"start": "NODE_DEBUG=engine:rendering node --trace-warnings packages/cli/src/cli.js start --open",
|
||||||
|
"preview": "node packages/cli/src/cli.js preview --open",
|
||||||
"test": "yarn test:node && yarn test:web",
|
"test": "yarn test:node && yarn test:web",
|
||||||
"test:integration": "playwright test packages/*/test-node/*.spec.js",
|
"test:integration": "playwright test packages/*/test-node/*.spec.js --retries=3",
|
||||||
"test:node": "yarn test:unit && yarn test:integration",
|
"test:node": "yarn test:unit && yarn test:integration",
|
||||||
"test:unit": "node --trace-warnings ./node_modules/.bin/mocha --require ./scripts/testMochaGlobalHooks.js \"packages/*/test-node/**/*.test.{ts,js,mjs,cjs}\" -- --timeout 8000 --reporter dot --exit",
|
"test:unit": "node --trace-warnings ./node_modules/.bin/mocha --require ./scripts/testMochaGlobalHooks.js \"packages/*/test-node/**/*.test.{ts,js,mjs,cjs}\" -- --timeout 8000 --reporter dot --exit",
|
||||||
"test:web": "web-test-runner",
|
"test:web": "web-test-runner",
|
||||||
|
|||||||
@@ -1,5 +1,30 @@
|
|||||||
# @rocket/cli
|
# @rocket/cli
|
||||||
|
|
||||||
|
## 0.20.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 39206a1: `rocket start` now outputs to `_site-dev` instead of `_site`.
|
||||||
|
- 39206a1: `rocket start` clears only its output folder (defaults to `_site-dev`)
|
||||||
|
- cbfb0f9: Add `rocket preview` command to enable fast checking of the production build
|
||||||
|
|
||||||
|
## 0.20.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 8dedc56: Add start message for `rocket start`
|
||||||
|
|
||||||
|
```
|
||||||
|
🚀 Rocket Engine v0.2.5
|
||||||
|
|
||||||
|
🚧 Local: http://localhost:8000/
|
||||||
|
🌐 Network: http://xxx.xxx.xxx.xxx:8000/
|
||||||
|
```
|
||||||
|
|
||||||
|
- Updated dependencies [8dedc56]
|
||||||
|
- Updated dependencies [390335d]
|
||||||
|
- @rocket/engine@0.2.6
|
||||||
|
|
||||||
## 0.20.0
|
## 0.20.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/cli",
|
"name": "@rocket/cli",
|
||||||
"version": "0.20.0",
|
"version": "0.20.2",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -53,16 +53,18 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rocket/building-rollup": "^0.4.0",
|
"@rocket/building-rollup": "^0.4.0",
|
||||||
"@rocket/engine": "^0.2.0",
|
"@rocket/engine": "^0.2.6",
|
||||||
"@web/rollup-plugin-copy": "^0.3.0",
|
"@web/rollup-plugin-copy": "^0.3.0",
|
||||||
"colorette": "^2.0.16",
|
"colorette": "^2.0.16",
|
||||||
"commander": "^9.0.0",
|
"commander": "^9.0.0",
|
||||||
"fs-extra": "^9.0.1",
|
"fs-extra": "^9.0.1",
|
||||||
"gray-matter": "^4.0.3",
|
"gray-matter": "^4.0.3",
|
||||||
|
"ip": "^1.1.5",
|
||||||
"plugins-manager": "^0.3.0",
|
"plugins-manager": "^0.3.0",
|
||||||
"puppeteer": "^13.0.0"
|
"puppeteer": "^13.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/ip": "^1.1.0",
|
||||||
"koa-proxy": "^1.0.0-alpha.3"
|
"koa-proxy": "^1.0.0-alpha.3"
|
||||||
},
|
},
|
||||||
"types": "./dist-types/src/index.d.ts",
|
"types": "./dist-types/src/index.d.ts",
|
||||||
|
|||||||
@@ -88,6 +88,8 @@ export class RocketBuild {
|
|||||||
|
|
||||||
async build() {
|
async build() {
|
||||||
await this.cli.events.dispatchEventDone('build-start');
|
await this.cli.events.dispatchEventDone('build-start');
|
||||||
|
await this.cli.clearOutputDir();
|
||||||
|
await this.cli.clearOutputDevDir();
|
||||||
|
|
||||||
this.engine = new Engine();
|
this.engine = new Engine();
|
||||||
this.engine.setOptions({
|
this.engine.setOptions({
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { RocketStart } from './RocketStart.js';
|
|||||||
import { RocketBuild } from './RocketBuild.js';
|
import { RocketBuild } from './RocketBuild.js';
|
||||||
import { RocketInit } from './RocketInit.js';
|
import { RocketInit } from './RocketInit.js';
|
||||||
import { RocketUpgrade } from './RocketUpgrade.js';
|
import { RocketUpgrade } from './RocketUpgrade.js';
|
||||||
|
import { RocketPreview } from './RocketPreview.js';
|
||||||
// import { ignore } from './images/ignore.js';
|
// import { ignore } from './images/ignore.js';
|
||||||
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
@@ -34,7 +35,7 @@ export class RocketCli {
|
|||||||
open: false,
|
open: false,
|
||||||
cwd: process.cwd(),
|
cwd: process.cwd(),
|
||||||
inputDir: 'FALLBACK',
|
inputDir: 'FALLBACK',
|
||||||
outputDir: '_site',
|
outputDir: 'FALLBACK',
|
||||||
outputDevDir: '_site-dev',
|
outputDevDir: '_site-dev',
|
||||||
|
|
||||||
serviceWorkerSourcePath: '',
|
serviceWorkerSourcePath: '',
|
||||||
@@ -93,6 +94,9 @@ export class RocketCli {
|
|||||||
if (this.options.inputDir === 'FALLBACK') {
|
if (this.options.inputDir === 'FALLBACK') {
|
||||||
this.options.inputDir = path.join(this.options.cwd, 'site', 'pages');
|
this.options.inputDir = path.join(this.options.cwd, 'site', 'pages');
|
||||||
}
|
}
|
||||||
|
if (this.options.outputDir === 'FALLBACK') {
|
||||||
|
this.options.outputDir = path.join(this.options.cwd, '_site');
|
||||||
|
}
|
||||||
if (this.options.inputDir instanceof URL) {
|
if (this.options.inputDir instanceof URL) {
|
||||||
this.options.inputDir = this.options.inputDir.pathname;
|
this.options.inputDir = this.options.inputDir.pathname;
|
||||||
}
|
}
|
||||||
@@ -122,7 +126,6 @@ export class RocketCli {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async prepare() {
|
async prepare() {
|
||||||
await this.clearOutputDirs();
|
|
||||||
if (!this.options.presets) {
|
if (!this.options.presets) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -180,6 +183,7 @@ export class RocketCli {
|
|||||||
{ plugin: RocketInit, options: {} },
|
{ plugin: RocketInit, options: {} },
|
||||||
// { plugin: RocketLint },
|
// { plugin: RocketLint },
|
||||||
{ plugin: RocketUpgrade, options: {} },
|
{ plugin: RocketUpgrade, options: {} },
|
||||||
|
{ plugin: RocketPreview, options: {} },
|
||||||
];
|
];
|
||||||
|
|
||||||
if (Array.isArray(this.options.setupCliPlugins)) {
|
if (Array.isArray(this.options.setupCliPlugins)) {
|
||||||
@@ -230,10 +234,13 @@ export class RocketCli {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async clearOutputDirs() {
|
async clearOutputDir() {
|
||||||
if (this.options.outputDir && existsSync(this.options.outputDir)) {
|
if (this.options.outputDir && existsSync(this.options.outputDir)) {
|
||||||
await rm(this.options.outputDir, { recursive: true, force: true });
|
await rm(this.options.outputDir, { recursive: true, force: true });
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async clearOutputDevDir() {
|
||||||
if (this.options.outputDevDir && existsSync(this.options.outputDevDir)) {
|
if (this.options.outputDevDir && existsSync(this.options.outputDevDir)) {
|
||||||
await rm(this.options.outputDevDir, { recursive: true, force: true });
|
await rm(this.options.outputDevDir, { recursive: true, force: true });
|
||||||
}
|
}
|
||||||
|
|||||||
79
packages/cli/src/RocketPreview.js
Executable file
79
packages/cli/src/RocketPreview.js
Executable file
@@ -0,0 +1,79 @@
|
|||||||
|
import { logPreviewMessage } from './preview/logPreviewMessage.js';
|
||||||
|
import { startDevServer } from '@web/dev-server';
|
||||||
|
import path from 'path';
|
||||||
|
import { existsSync } from 'fs';
|
||||||
|
import { gray, bold } from 'colorette';
|
||||||
|
|
||||||
|
export class RocketPreview {
|
||||||
|
/**
|
||||||
|
* @param {import('commander').Command} program
|
||||||
|
* @param {import('./RocketCli.js').RocketCli} cli
|
||||||
|
*/
|
||||||
|
async setupCommand(program, cli) {
|
||||||
|
this.cli = cli;
|
||||||
|
this.active = true;
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('preview')
|
||||||
|
.option('-i, --input-dir <path>', 'path to the folder with the build html files')
|
||||||
|
.option('-o, --open', 'automatically open the browser')
|
||||||
|
.action(async cliOptions => {
|
||||||
|
cli.setOptions(cliOptions);
|
||||||
|
cli.activePlugin = this;
|
||||||
|
|
||||||
|
await this.preview();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async preview() {
|
||||||
|
if (!this.cli) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for typescript as `this.cli.options.outputDir` supports other inputs as well
|
||||||
|
// but the cli will normalize it to a string before calling plugins
|
||||||
|
if (
|
||||||
|
typeof this.cli.options.inputDir !== 'string' ||
|
||||||
|
typeof this.cli.options.outputDir !== 'string'
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rootIndexHtml = path.join(this.cli.options.outputDir, 'index.html');
|
||||||
|
if (!existsSync(rootIndexHtml)) {
|
||||||
|
console.log(`${bold(`👀 Previewing Production Build`)}`);
|
||||||
|
console.log('');
|
||||||
|
console.log(` 🛑 No index.html found in the build directory ${gray(`${rootIndexHtml}`)}`);
|
||||||
|
console.log(' 🤔 Did you forget to run `rocket build` before?');
|
||||||
|
console.log('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {import('@web/dev-server').DevServerConfig} */
|
||||||
|
const config = {
|
||||||
|
open: this.cli.options.open,
|
||||||
|
rootDir: this.cli.options.outputDir,
|
||||||
|
clearTerminalOnReload: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.devServer = await startDevServer({
|
||||||
|
config,
|
||||||
|
logStartMessage: false,
|
||||||
|
readCliArgs: false,
|
||||||
|
readFileConfig: false,
|
||||||
|
// argv: this.__argv,
|
||||||
|
});
|
||||||
|
logPreviewMessage({ devServerOptions: this.devServer.config }, console);
|
||||||
|
} catch (e) {
|
||||||
|
console.log('🛑 Starting preview server failed');
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async stop() {
|
||||||
|
if (this.devServer) {
|
||||||
|
await this.devServer.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { fromRollup } from '@web/dev-server-rollup';
|
import { fromRollup } from '@web/dev-server-rollup';
|
||||||
|
|
||||||
import { Engine } from '@rocket/engine/server';
|
import { Engine } from '@rocket/engine/server';
|
||||||
|
import { logStartMessage } from './start/logStartMessage.js';
|
||||||
|
|
||||||
export class RocketStart {
|
export class RocketStart {
|
||||||
/** @type {Engine | undefined} */
|
/** @type {Engine | undefined} */
|
||||||
@@ -30,11 +31,12 @@ export class RocketStart {
|
|||||||
if (!this.cli) {
|
if (!this.cli) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
await this.cli.clearOutputDevDir();
|
||||||
|
|
||||||
// TODO: enable URL support in the Engine and remove this "workaround"
|
// TODO: enable URL support in the Engine and remove this "workaround"
|
||||||
if (
|
if (
|
||||||
typeof this.cli.options.inputDir !== 'string' ||
|
typeof this.cli.options.inputDir !== 'string' ||
|
||||||
typeof this.cli.options.outputDir !== 'string'
|
typeof this.cli.options.outputDevDir !== 'string'
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -49,7 +51,7 @@ export class RocketStart {
|
|||||||
this.engine = new Engine();
|
this.engine = new Engine();
|
||||||
this.engine.setOptions({
|
this.engine.setOptions({
|
||||||
docsDir: this.cli.options.inputDir,
|
docsDir: this.cli.options.inputDir,
|
||||||
outputDir: this.cli.options.outputDir,
|
outputDir: this.cli.options.outputDevDir,
|
||||||
setupPlugins: this.cli.options.setupEnginePlugins,
|
setupPlugins: this.cli.options.setupEnginePlugins,
|
||||||
open: this.cli.options.open,
|
open: this.cli.options.open,
|
||||||
longFileHeaderWidth: this.cli.options.longFileHeaderWidth,
|
longFileHeaderWidth: this.cli.options.longFileHeaderWidth,
|
||||||
@@ -60,7 +62,14 @@ export class RocketStart {
|
|||||||
setupDevServerPlugins: [...this.cli.options.setupDevServerPlugins, ...withWrap],
|
setupDevServerPlugins: [...this.cli.options.setupDevServerPlugins, ...withWrap],
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
console.log('🚀 Engines online');
|
this.engine.events.on('devServerStarted', () => {
|
||||||
|
if (this.engine?.devServer) {
|
||||||
|
logStartMessage(
|
||||||
|
{ devServerOptions: this.engine.devServer?.config, engine: this.engine },
|
||||||
|
console,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
await this.engine.start();
|
await this.engine.start();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('Engine start errored');
|
console.log('Engine start errored');
|
||||||
@@ -71,7 +80,6 @@ export class RocketStart {
|
|||||||
async stop({ hard = true } = {}) {
|
async stop({ hard = true } = {}) {
|
||||||
if (this.engine) {
|
if (this.engine) {
|
||||||
await this.engine.stop({ hard });
|
await this.engine.stop({ hard });
|
||||||
console.log('🚀 Engines offline');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
34
packages/cli/src/helpers/infoMessages.js
Normal file
34
packages/cli/src/helpers/infoMessages.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import ip from 'ip';
|
||||||
|
import { white, cyan } from 'colorette';
|
||||||
|
|
||||||
|
/** @typedef {import('@web/dev-server').DevServerConfig} DevServerConfig */
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {DevServerConfig} devServerOptions
|
||||||
|
* @param {string} host
|
||||||
|
* @param {string} path
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export function createAddress(devServerOptions, host, path) {
|
||||||
|
return `http${devServerOptions.http2 ? 's' : ''}://${host}:${devServerOptions.port}${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {DevServerConfig} devServerOptions
|
||||||
|
* @param {console} logger
|
||||||
|
* @param {string} openPath
|
||||||
|
*/
|
||||||
|
export function logNetworkAddress(devServerOptions, logger, openPath) {
|
||||||
|
try {
|
||||||
|
const address = ip.address();
|
||||||
|
if (typeof address === 'string') {
|
||||||
|
logger.log(
|
||||||
|
`${white(' 🌐 Network:')} ${cyan(createAddress(devServerOptions, address, openPath))}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (_a) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
33
packages/cli/src/preview/logPreviewMessage.js
Normal file
33
packages/cli/src/preview/logPreviewMessage.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { white, bold, cyan, gray } from 'colorette';
|
||||||
|
import { createAddress, logNetworkAddress } from '../helpers/infoMessages.js';
|
||||||
|
|
||||||
|
/** @typedef {import('@web/dev-server').DevServerConfig} DevServerConfig */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{ devServerOptions: DevServerConfig}} options
|
||||||
|
* @param {console} logger
|
||||||
|
*/
|
||||||
|
export function logPreviewMessage({ devServerOptions }, logger) {
|
||||||
|
const prettyHost = devServerOptions.hostname ?? 'localhost';
|
||||||
|
let openPath = typeof devServerOptions.open === 'string' ? devServerOptions.open : '/';
|
||||||
|
if (!openPath.startsWith('/')) {
|
||||||
|
openPath = `/${openPath}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.log(`${bold(`👀 Previewing Production Build`)}`);
|
||||||
|
logger.log('');
|
||||||
|
logger.log(
|
||||||
|
`${white(' 🚧 Local:')} ${cyan(createAddress(devServerOptions, prettyHost, openPath))}`,
|
||||||
|
);
|
||||||
|
logNetworkAddress(devServerOptions, logger, openPath);
|
||||||
|
const sourceDir = devServerOptions.rootDir;
|
||||||
|
if (sourceDir) {
|
||||||
|
logger.log(`${white(' 📝 Source:')} ${cyan(sourceDir)}`);
|
||||||
|
}
|
||||||
|
logger.log('');
|
||||||
|
logger.log(
|
||||||
|
gray(
|
||||||
|
'If what you see works as expected then you can upload "source" to your production web server.',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
24
packages/cli/src/start/logStartMessage.js
Normal file
24
packages/cli/src/start/logStartMessage.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { white, bold, cyan, gray } from 'colorette';
|
||||||
|
import { createAddress, logNetworkAddress } from '../helpers/infoMessages.js';
|
||||||
|
|
||||||
|
/** @typedef {import('@web/dev-server').DevServerConfig} DevServerConfig */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{ devServerOptions: DevServerConfig, engine: import('@rocket/engine/server').Engine}} options
|
||||||
|
* @param {console} logger
|
||||||
|
*/
|
||||||
|
export function logStartMessage({ devServerOptions, engine }, logger) {
|
||||||
|
const prettyHost = devServerOptions.hostname ?? 'localhost';
|
||||||
|
let openPath = typeof devServerOptions.open === 'string' ? devServerOptions.open : '/';
|
||||||
|
if (!openPath.startsWith('/')) {
|
||||||
|
openPath = `/${openPath}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.log(`${bold(`🚀 Rocket Engine`)} ${gray(`v${engine.getVersion()}`)}`);
|
||||||
|
logger.log('');
|
||||||
|
logger.log(
|
||||||
|
`${white(' 🚧 Local:')} ${cyan(createAddress(devServerOptions, prettyHost, openPath))}`,
|
||||||
|
);
|
||||||
|
logNetworkAddress(devServerOptions, logger, openPath);
|
||||||
|
logger.log('');
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ import { setupTestCli } from './test-helpers.js';
|
|||||||
|
|
||||||
export function prepareTestCli(importMetaUrl) {
|
export function prepareTestCli(importMetaUrl) {
|
||||||
const dir = path.dirname(fileURLToPath(importMetaUrl));
|
const dir = path.dirname(fileURLToPath(importMetaUrl));
|
||||||
return (cwd, cliOptions = ['build'], options = {}) => setupTestCli(cwd, cliOptions, options, dir);
|
return fullOptions => setupTestCli({ dir, ...fullOptions });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|||||||
@@ -60,7 +60,13 @@ function cleanupLitMarkersFn(text) {
|
|||||||
return newText;
|
return newText;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setupTestCli(cwd, cliOptions = ['build'], options = {}, dir) {
|
export async function setupTestCli({
|
||||||
|
cwd,
|
||||||
|
cliOptions = ['build'],
|
||||||
|
options = {},
|
||||||
|
testOptions = {},
|
||||||
|
dir,
|
||||||
|
}) {
|
||||||
const resolvedCwd = path.join(dir, cwd.split('/').join(path.sep));
|
const resolvedCwd = path.join(dir, cwd.split('/').join(path.sep));
|
||||||
const useOptions = { buildOptimize: false, buildAutoStop: false, ...options, cwd: resolvedCwd };
|
const useOptions = { buildOptimize: false, buildAutoStop: false, ...options, cwd: resolvedCwd };
|
||||||
if (useOptions.inputDir) {
|
if (useOptions.inputDir) {
|
||||||
@@ -69,6 +75,18 @@ export async function setupTestCli(cwd, cliOptions = ['build'], options = {}, di
|
|||||||
useOptions.outputDir = path.join(resolvedCwd, '__output');
|
useOptions.outputDir = path.join(resolvedCwd, '__output');
|
||||||
useOptions.outputDevDir = path.join(resolvedCwd, '__output-dev');
|
useOptions.outputDevDir = path.join(resolvedCwd, '__output-dev');
|
||||||
|
|
||||||
|
const capturedLogs = [];
|
||||||
|
const origLog = console.log;
|
||||||
|
const origError = console.error;
|
||||||
|
if (testOptions.captureLogs) {
|
||||||
|
console.log = msg => {
|
||||||
|
capturedLogs.push(msg);
|
||||||
|
};
|
||||||
|
console.error = msg => {
|
||||||
|
capturedLogs.push(msg);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const cli = new RocketCli({
|
const cli = new RocketCli({
|
||||||
argv: [process.argv[0], new URL('../src/cli.js', import.meta.url).pathname, ...cliOptions],
|
argv: [process.argv[0], new URL('../src/cli.js', import.meta.url).pathname, ...cliOptions],
|
||||||
});
|
});
|
||||||
@@ -184,6 +202,10 @@ export async function setupTestCli(cwd, cliOptions = ['build'], options = {}, di
|
|||||||
|
|
||||||
async function cleanup() {
|
async function cleanup() {
|
||||||
await cli.stop({ hard: false });
|
await cli.stop({ hard: false });
|
||||||
|
if (testOptions.captureLogs) {
|
||||||
|
console.log = origLog;
|
||||||
|
console.error = origError;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function build() {
|
async function build() {
|
||||||
@@ -243,5 +265,6 @@ export async function setupTestCli(cwd, cliOptions = ['build'], options = {}, di
|
|||||||
renameSource,
|
renameSource,
|
||||||
backupOrRestoreSource,
|
backupOrRestoreSource,
|
||||||
restoreSource,
|
restoreSource,
|
||||||
|
capturedLogs,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ const { expect } = chai;
|
|||||||
|
|
||||||
describe('Config', () => {
|
describe('Config', () => {
|
||||||
it('01: no config file', async () => {
|
it('01: no config file', async () => {
|
||||||
const { build, readOutput, readDevOutput } = await setupTestCli(
|
const { build, readOutput, readDevOutput } = await setupTestCli({
|
||||||
'fixtures/01-config/01-no-config/',
|
cwd: 'fixtures/01-config/01-no-config/',
|
||||||
undefined,
|
options: { buildOptimize: true },
|
||||||
{ buildOptimize: true },
|
testOptions: { captureLogs: true },
|
||||||
);
|
});
|
||||||
await build();
|
await build();
|
||||||
|
|
||||||
expect(readOutput('index.html')).to.equal(
|
expect(readOutput('index.html')).to.equal(
|
||||||
@@ -31,14 +31,21 @@ describe('Config', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('02: change input dir', async () => {
|
it('02: change input dir', async () => {
|
||||||
const { build, readDevOutput } = await setupTestCli('fixtures/01-config/02-change-input-dir/');
|
const { build, readDevOutput } = await setupTestCli({
|
||||||
|
cwd: 'fixtures/01-config/02-change-input-dir/',
|
||||||
|
testOptions: { captureLogs: true },
|
||||||
|
});
|
||||||
await build();
|
await build();
|
||||||
|
|
||||||
expect(readDevOutput('index.html')).to.equal(['Hello World!'].join('\n'));
|
expect(readDevOutput('index.html')).to.equal(['Hello World!'].join('\n'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('03: can add a middleware (api proxy) to the dev server', async () => {
|
it('03: can add a middleware (api proxy) to the dev server', async () => {
|
||||||
const { cleanup, cli } = await setupTestCli('fixtures/01-config/03-add-middleware/', ['start']);
|
const { cleanup, cli } = await setupTestCli({
|
||||||
|
cwd: 'fixtures/01-config/03-add-middleware/',
|
||||||
|
cliOptions: ['start'],
|
||||||
|
testOptions: { captureLogs: true },
|
||||||
|
});
|
||||||
const apiServer = http.createServer((request, response) => {
|
const apiServer = http.createServer((request, response) => {
|
||||||
if (request.url === '/api/message') {
|
if (request.url === '/api/message') {
|
||||||
response.writeHead(200);
|
response.writeHead(200);
|
||||||
@@ -61,20 +68,22 @@ describe('Config', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('04: can add a rollup plugin via setupDevServerAndBuildPlugins to build', async () => {
|
it('04: can add a rollup plugin via setupDevServerAndBuildPlugins to build', async () => {
|
||||||
const { build, readOutput } = await setupTestCli(
|
const { build, readOutput } = await setupTestCli({
|
||||||
'fixtures/01-config/04-add-rollup-plugin/',
|
cwd: 'fixtures/01-config/04-add-rollup-plugin/',
|
||||||
undefined,
|
options: { buildOptimize: true },
|
||||||
{ buildOptimize: true },
|
testOptions: { captureLogs: true },
|
||||||
);
|
});
|
||||||
await build();
|
await build();
|
||||||
const inlineModule = await readOutput('e97af63d.js', { format: false });
|
const inlineModule = await readOutput('e97af63d.js', { format: false });
|
||||||
expect(inlineModule).to.equal('var a={test:"data"};console.log(a);\n');
|
expect(inlineModule).to.equal('var a={test:"data"};console.log(a);\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('04a: can add a rollup plugin via setupDevServerAndBuildPlugins to start', async () => {
|
it('04a: can add a rollup plugin via setupDevServerAndBuildPlugins to start', async () => {
|
||||||
const { cli, cleanup } = await setupTestCli('fixtures/01-config/04-add-rollup-plugin/', [
|
const { cli, cleanup } = await setupTestCli({
|
||||||
'start',
|
cwd: 'fixtures/01-config/04-add-rollup-plugin/',
|
||||||
]);
|
cliOptions: ['start'],
|
||||||
|
testOptions: { captureLogs: true },
|
||||||
|
});
|
||||||
await cli.start();
|
await cli.start();
|
||||||
const { port } = cli?.activePlugin?.engine.devServer.config;
|
const { port } = cli?.activePlugin?.engine.devServer.config;
|
||||||
|
|
||||||
@@ -88,9 +97,10 @@ describe('Config', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('05: long file header comments', async () => {
|
it('05: long file header comments', async () => {
|
||||||
const { build, readSource } = await setupTestCli(
|
const { build, readSource } = await setupTestCli({
|
||||||
'fixtures/01-config/05-long-file-header-comment/',
|
cwd: 'fixtures/01-config/05-long-file-header-comment/',
|
||||||
);
|
testOptions: { captureLogs: true },
|
||||||
|
});
|
||||||
await build();
|
await build();
|
||||||
|
|
||||||
expect(readSource('index.rocket.js', { format: false })).to.equal(
|
expect(readSource('index.rocket.js', { format: false })).to.equal(
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ const { expect } = chai;
|
|||||||
|
|
||||||
describe('Build', () => {
|
describe('Build', () => {
|
||||||
it('01: copy public files', async () => {
|
it('01: copy public files', async () => {
|
||||||
const { build, readOutput, outputExists, readDevOutput } = await setupTestCli(
|
const { build, readOutput, outputExists, readDevOutput } = await setupTestCli({
|
||||||
'fixtures/02-build/01-copy-public-files/',
|
cwd: 'fixtures/02-build/01-copy-public-files/',
|
||||||
undefined,
|
options: {
|
||||||
{
|
|
||||||
buildOptimize: true,
|
buildOptimize: true,
|
||||||
},
|
},
|
||||||
);
|
testOptions: { captureLogs: true },
|
||||||
|
});
|
||||||
await build();
|
await build();
|
||||||
|
|
||||||
expect(readOutput('index.html')).to.equal(
|
expect(readOutput('index.html')).to.equal(
|
||||||
|
|||||||
@@ -6,7 +6,11 @@ const { expect } = chai;
|
|||||||
describe('Upgrade System', () => {
|
describe('Upgrade System', () => {
|
||||||
it('2021-09-menu', async () => {
|
it('2021-09-menu', async () => {
|
||||||
const { build, sourceExists, readSource, backupOrRestoreSource, restoreSource } =
|
const { build, sourceExists, readSource, backupOrRestoreSource, restoreSource } =
|
||||||
await setupTestCli('fixtures/03-upgrade/2022-03-menu', ['upgrade']);
|
await setupTestCli({
|
||||||
|
cwd: 'fixtures/03-upgrade/2022-03-menu',
|
||||||
|
cliOptions: ['upgrade'],
|
||||||
|
testOptions: { captureLogs: true },
|
||||||
|
});
|
||||||
await backupOrRestoreSource();
|
await backupOrRestoreSource();
|
||||||
|
|
||||||
await build();
|
await build();
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ const { expect } = chai;
|
|||||||
|
|
||||||
describe('Open Graph', () => {
|
describe('Open Graph', () => {
|
||||||
it('generates the image and adds the meta tags', async () => {
|
it('generates the image and adds the meta tags', async () => {
|
||||||
const { build, readOutput, outputExists } = await setupTestCli(
|
const { build, readOutput, outputExists } = await setupTestCli({
|
||||||
'fixtures/04-open-graph/01-generate-image-and-inject-meta',
|
cwd: 'fixtures/04-open-graph/01-generate-image-and-inject-meta',
|
||||||
undefined,
|
options: {
|
||||||
{
|
|
||||||
buildOptimize: true,
|
buildOptimize: true,
|
||||||
},
|
},
|
||||||
);
|
testOptions: { captureLogs: true },
|
||||||
|
});
|
||||||
await build();
|
await build();
|
||||||
|
|
||||||
expect(readOutput('index.html', { replaceImageHashes: true })).to.equal(
|
expect(readOutput('index.html', { replaceImageHashes: true })).to.equal(
|
||||||
@@ -35,13 +35,13 @@ describe('Open Graph', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('handles multiple pages', async () => {
|
it('handles multiple pages', async () => {
|
||||||
const { build, readOutput } = await setupTestCli(
|
const { build, readOutput } = await setupTestCli({
|
||||||
'fixtures/04-open-graph/02-multiple-pages',
|
cwd: 'fixtures/04-open-graph/02-multiple-pages',
|
||||||
undefined,
|
options: {
|
||||||
{
|
|
||||||
buildOptimize: true,
|
buildOptimize: true,
|
||||||
},
|
},
|
||||||
);
|
testOptions: { captureLogs: true },
|
||||||
|
});
|
||||||
await build();
|
await build();
|
||||||
|
|
||||||
expect(readOutput('index.html', { replaceImageHashes: true })).to.equal(
|
expect(readOutput('index.html', { replaceImageHashes: true })).to.equal(
|
||||||
|
|||||||
25
packages/cli/test-node/05-start.test.js
Normal file
25
packages/cli/test-node/05-start.test.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import chai from 'chai';
|
||||||
|
import { white, bold } from 'colorette';
|
||||||
|
|
||||||
|
import { setupTestCli } from './test-helpers.js';
|
||||||
|
|
||||||
|
const { expect } = chai;
|
||||||
|
|
||||||
|
describe('Start', () => {
|
||||||
|
it('Start Message', async () => {
|
||||||
|
const { cli, capturedLogs, cleanup } = await setupTestCli({
|
||||||
|
cwd: 'fixtures/05-start/01-start-message',
|
||||||
|
cliOptions: ['start'],
|
||||||
|
testOptions: { captureLogs: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
await cli.start();
|
||||||
|
await cleanup();
|
||||||
|
|
||||||
|
expect(capturedLogs[0].startsWith(`${bold(`🚀 Rocket Engine`)} `)).to.be.true;
|
||||||
|
expect(capturedLogs[1]).to.equal('');
|
||||||
|
expect(capturedLogs[2].startsWith(`${white(' 🚧 Local:')}`)).to.be.true;
|
||||||
|
expect(capturedLogs[3].startsWith(`${white(' 🌐 Network:')}`)).to.be.true;
|
||||||
|
expect(capturedLogs[4]).to.equal('');
|
||||||
|
});
|
||||||
|
});
|
||||||
49
packages/cli/test-node/06-preview.test.js
Normal file
49
packages/cli/test-node/06-preview.test.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import chai from 'chai';
|
||||||
|
import { white, bold, gray } from 'colorette';
|
||||||
|
|
||||||
|
import { setupTestCli } from './test-helpers.js';
|
||||||
|
|
||||||
|
const { expect } = chai;
|
||||||
|
|
||||||
|
describe('Preview', () => {
|
||||||
|
it('01: Preview Message', async () => {
|
||||||
|
const { cli, capturedLogs, cleanup } = await setupTestCli({
|
||||||
|
cwd: 'fixtures/06-preview/01-preview-message',
|
||||||
|
cliOptions: ['preview'],
|
||||||
|
testOptions: { captureLogs: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
await cli.start();
|
||||||
|
await cleanup();
|
||||||
|
|
||||||
|
expect(capturedLogs[0]).to.equal(`${bold(`👀 Previewing Production Build`)}`);
|
||||||
|
expect(capturedLogs[1]).to.equal('');
|
||||||
|
expect(capturedLogs[2].startsWith(`${white(' 🚧 Local:')}`)).to.be.true;
|
||||||
|
expect(capturedLogs[3].startsWith(`${white(' 🌐 Network:')}`)).to.be.true;
|
||||||
|
expect(capturedLogs[4].startsWith(`${white(' 📝 Source:')}`)).to.be.true;
|
||||||
|
expect(capturedLogs[5]).to.equal('');
|
||||||
|
expect(capturedLogs[6]).to.equal(
|
||||||
|
`${gray(
|
||||||
|
'If what you see works as expected then you can upload "source" to your production web server.',
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('02: Error Message if there is no build output', async () => {
|
||||||
|
const { cli, capturedLogs, cleanup } = await setupTestCli({
|
||||||
|
cwd: 'fixtures/06-preview/02-error-no-build',
|
||||||
|
cliOptions: ['preview'],
|
||||||
|
testOptions: { captureLogs: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
await cli.start();
|
||||||
|
await cleanup();
|
||||||
|
|
||||||
|
expect(capturedLogs[0]).to.equal(`${bold(`👀 Previewing Production Build`)}`);
|
||||||
|
expect(capturedLogs[1]).to.equal('');
|
||||||
|
expect(capturedLogs[2].startsWith(` 🛑 No index.html found in the build directory`)).to.be
|
||||||
|
.true;
|
||||||
|
expect(capturedLogs[3]).to.equal(' 🤔 Did you forget to run `rocket build` before?');
|
||||||
|
expect(capturedLogs[4]).to.equal('');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
/* START - Rocket auto generated - do not touch */
|
||||||
|
export const sourceRelativeFilePath = 'index.rocket.js';
|
||||||
|
/* END - Rocket auto generated - do not touch */
|
||||||
|
|
||||||
|
export default () => 'Hello World!';
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "index.rocket.js",
|
||||||
|
"menuLinkText": "index.rocket.js",
|
||||||
|
"url": "/",
|
||||||
|
"outputRelativeFilePath": "index.html",
|
||||||
|
"sourceRelativeFilePath": "index.rocket.js",
|
||||||
|
"level": 0
|
||||||
|
}
|
||||||
1
packages/cli/test-node/fixtures/06-preview/01-preview-message/.gitignore
vendored
Normal file
1
packages/cli/test-node/fixtures/06-preview/01-preview-message/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!__output
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
so preview does not stop
|
||||||
@@ -1,5 +1,32 @@
|
|||||||
# @rocket/engine
|
# @rocket/engine
|
||||||
|
|
||||||
|
## 0.2.6
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 8dedc56: Add `engine.getVersion()` method
|
||||||
|
- 390335d: Improve title tag handling
|
||||||
|
|
||||||
|
## 0.2.5
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 93503ed: HTML in headings will be ignored for the menu
|
||||||
|
Some examples:
|
||||||
|
|
||||||
|
- `<h1>Hello <em>Word</em></h1>` => `Hello Word`
|
||||||
|
- `<h1>Hello <strong>World</strong> of <span>JS <em>(JavaScript)</em></span>!</h1>` => `Hello World of JS (JavaScript)!`
|
||||||
|
|
||||||
|
- 3032ba9: Menus now support special characters in markdown headings.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```md
|
||||||
|
# Fun Errors & Feedback
|
||||||
|
|
||||||
|
# <some-button>
|
||||||
|
```
|
||||||
|
|
||||||
## 0.2.4
|
## 0.2.4
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/engine",
|
"name": "@rocket/engine",
|
||||||
"version": "0.2.4",
|
"version": "0.2.6",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"debug": "DEBUG=engine:rendering yarn test",
|
"debug": "DEBUG=engine:rendering yarn test",
|
||||||
"debug:integration": "PWDEBUG=1 yarn test:integration",
|
"debug:integration": "PWDEBUG=1 yarn test:integration",
|
||||||
"test": "mocha --require ../../scripts/testMochaGlobalHooks.js --timeout 8000 test-node/**/*.test.js test-node/*.test.js",
|
"test": "mocha --require ../../scripts/testMochaGlobalHooks.js --timeout 8000 test-node/**/*.test.js test-node/*.test.js",
|
||||||
"test:integration": "playwright test test-node/*.spec.js",
|
"test:integration": "playwright test test-node/*.spec.js --retries=3",
|
||||||
"test:watch": "onchange 'src/**/*.js' 'test-node/**/*.js' -- npm test",
|
"test:watch": "onchange 'src/**/*.js' 'test-node/**/*.js' -- npm test",
|
||||||
"types:copy": "copyfiles \"./types/**/*.d.ts\" dist-types/"
|
"types:copy": "copyfiles \"./types/**/*.d.ts\" dist-types/"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
// TODO: implement copy without extra dependency => node 16.7.0 copy has recursive
|
// TODO: implement copy without extra dependency => node 16.7.0 copy has recursive
|
||||||
import fse from 'fs-extra';
|
import fse from 'fs-extra';
|
||||||
import { mkdir, rm } from 'fs/promises';
|
import { mkdir, readFile, rm } from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { startDevServer } from '@web/dev-server';
|
import { startDevServer } from '@web/dev-server';
|
||||||
@@ -32,6 +32,8 @@ import { RocketHeader } from './file-header/RocketHeader.js';
|
|||||||
|
|
||||||
const logRendering = debuglog('engine:rendering');
|
const logRendering = debuglog('engine:rendering');
|
||||||
|
|
||||||
|
const pkgJson = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8'));
|
||||||
|
|
||||||
export class Engine {
|
export class Engine {
|
||||||
/** @type {EngineOptions} */
|
/** @type {EngineOptions} */
|
||||||
options = {
|
options = {
|
||||||
@@ -121,8 +123,10 @@ export class Engine {
|
|||||||
if (pageTree.pageTreeChangedOnSave) {
|
if (pageTree.pageTreeChangedOnSave) {
|
||||||
for (const sourceFilePath of sourceFiles) {
|
for (const sourceFilePath of sourceFiles) {
|
||||||
const result = await this.renderFile({ sourceFilePath, throwOnError: true });
|
const result = await this.renderFile({ sourceFilePath, throwOnError: true });
|
||||||
|
await pageTree.add(result.sourceRelativeFilePath);
|
||||||
await cleanupAutoGeneratedFiles(result);
|
await cleanupAutoGeneratedFiles(result);
|
||||||
}
|
}
|
||||||
|
await pageTree.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,6 +269,7 @@ export class Engine {
|
|||||||
readFileConfig: false,
|
readFileConfig: false,
|
||||||
// argv: this.__argv,
|
// argv: this.__argv,
|
||||||
});
|
});
|
||||||
|
this.events.emit('devServerStarted');
|
||||||
|
|
||||||
this.devServer.webSockets.on(
|
this.devServer.webSockets.on(
|
||||||
'message',
|
'message',
|
||||||
@@ -467,4 +472,8 @@ export class Engine {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getVersion() {
|
||||||
|
return pkgJson.version;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,10 +28,28 @@ export function getHtmlMetaData(htmlFilePath) {
|
|||||||
const metaData = {
|
const metaData = {
|
||||||
// headlinesWithId: [],
|
// headlinesWithId: [],
|
||||||
};
|
};
|
||||||
|
/** @type {string | undefined} */
|
||||||
|
let capturedHeadlineText = undefined;
|
||||||
|
let withinHTMLHead = false;
|
||||||
parser.eventHandler = (ev, _data) => {
|
parser.eventHandler = (ev, _data) => {
|
||||||
|
if (ev === SaxEventType.OpenTag) {
|
||||||
|
const data = /** @type {Tag} */ (/** @type {any} */ (_data));
|
||||||
|
if (isHeadline(data)) {
|
||||||
|
capturedHeadlineText = '';
|
||||||
|
}
|
||||||
|
if (data.name === 'head') {
|
||||||
|
withinHTMLHead = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (capturedHeadlineText !== undefined && ev === SaxEventType.Text) {
|
||||||
|
const data = /** @type {Text} */ (/** @type {any} */ (_data));
|
||||||
|
capturedHeadlineText += data.value;
|
||||||
|
}
|
||||||
|
|
||||||
if (ev === SaxEventType.CloseTag) {
|
if (ev === SaxEventType.CloseTag) {
|
||||||
const data = /** @type {Tag} */ (/** @type {any} */ (_data));
|
const data = /** @type {Tag} */ (/** @type {any} */ (_data));
|
||||||
|
// ********** <meta name="*" content="*">
|
||||||
if (data.name === 'meta') {
|
if (data.name === 'meta') {
|
||||||
const metaName = getAttribute(data, 'name');
|
const metaName = getAttribute(data, 'name');
|
||||||
if (metaName === 'menu:link.text') {
|
if (metaName === 'menu:link.text') {
|
||||||
@@ -60,29 +78,39 @@ export function getHtmlMetaData(htmlFilePath) {
|
|||||||
metaData.menuNoLink = getAttribute(data, 'content') !== 'false';
|
metaData.menuNoLink = getAttribute(data, 'content') !== 'false';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!metaData.title && data.name === 'title') {
|
if (withinHTMLHead && data.name === 'title') {
|
||||||
metaData.title = getText(data);
|
metaData.title = getText(data);
|
||||||
}
|
}
|
||||||
if (!metaData.h1 && data.name === 'h1') {
|
|
||||||
metaData.h1 = getText(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// ********** <h1> - <h6>
|
||||||
if (isHeadline(data)) {
|
if (isHeadline(data)) {
|
||||||
const id = getAttribute(data, 'id');
|
const id = getAttribute(data, 'id');
|
||||||
const rawText = getText(data);
|
|
||||||
const linkText = getAttribute(data, 'link-text');
|
const linkText = getAttribute(data, 'link-text');
|
||||||
if (id && rawText) {
|
const processedCapturedHeadlineText = capturedHeadlineText
|
||||||
|
?.replace(/</g, '<')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.trim();
|
||||||
|
const text = linkText || processedCapturedHeadlineText || '';
|
||||||
|
if (!metaData.h1 && data.name === 'h1') {
|
||||||
|
metaData.h1 = text;
|
||||||
|
}
|
||||||
|
if (id && text) {
|
||||||
if (!metaData.headlinesWithId) {
|
if (!metaData.headlinesWithId) {
|
||||||
metaData.headlinesWithId = [];
|
metaData.headlinesWithId = [];
|
||||||
}
|
}
|
||||||
const rawTextObj = linkText ? { rawText } : {};
|
const rawTextObj = linkText ? { rawText: processedCapturedHeadlineText } : {};
|
||||||
metaData.headlinesWithId.push({
|
metaData.headlinesWithId.push({
|
||||||
text: linkText || rawText,
|
text,
|
||||||
id,
|
id,
|
||||||
level: parseInt(data.name[1], 10),
|
level: parseInt(data.name[1], 10),
|
||||||
...rawTextObj,
|
...rawTextObj,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
capturedHeadlineText = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.name === 'head') {
|
||||||
|
withinHTMLHead = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -97,6 +125,7 @@ export function getHtmlMetaData(htmlFilePath) {
|
|||||||
});
|
});
|
||||||
readable.on('end', () => {
|
readable.on('end', () => {
|
||||||
parser.end();
|
parser.end();
|
||||||
|
capturedHeadlineText = undefined;
|
||||||
|
|
||||||
resolve(metaData);
|
resolve(metaData);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ const require = createRequire(import.meta.url);
|
|||||||
export const streamOptions = { highWaterMark: 128 * 1024 };
|
export const streamOptions = { highWaterMark: 128 * 1024 };
|
||||||
const saxPath = require.resolve('sax-wasm/lib/sax-wasm.wasm');
|
const saxPath = require.resolve('sax-wasm/lib/sax-wasm.wasm');
|
||||||
const saxWasmBuffer = await readFile(saxPath);
|
const saxWasmBuffer = await readFile(saxPath);
|
||||||
export const parser = new SAXParser(SaxEventType.CloseTag, streamOptions);
|
export const parser = new SAXParser(
|
||||||
|
SaxEventType.OpenTag | SaxEventType.CloseTag | SaxEventType.Text,
|
||||||
|
streamOptions,
|
||||||
|
);
|
||||||
|
|
||||||
await parser.prepareWasm(saxWasmBuffer);
|
await parser.prepareWasm(saxWasmBuffer);
|
||||||
|
|||||||
@@ -834,4 +834,118 @@ describe('Engine menus', () => {
|
|||||||
|
|
||||||
await cleanup();
|
await cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('14: get-all-text-but-strip-html', async () => {
|
||||||
|
const { build, readSource } = await setupTestEngine(
|
||||||
|
'fixtures/05-menu/14-get-all-text-but-strip-html/docs',
|
||||||
|
);
|
||||||
|
await build();
|
||||||
|
|
||||||
|
expect(JSON.parse(readSource('pageTreeData.rocketGenerated.json'))).to.deep.equal({
|
||||||
|
h1: 'Hello World of JS (JavaScript)!',
|
||||||
|
name: 'Hello World of JS (JavaScript)!',
|
||||||
|
menuLinkText: 'Hello World of JS (JavaScript)!',
|
||||||
|
url: '/',
|
||||||
|
outputRelativeFilePath: 'index.html',
|
||||||
|
sourceRelativeFilePath: 'index.rocket.js',
|
||||||
|
level: 0,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('15: markdown special characters', async () => {
|
||||||
|
const { build, readSource } = await setupTestEngine(
|
||||||
|
'fixtures/05-menu/15-md-special-characters/docs',
|
||||||
|
);
|
||||||
|
await build();
|
||||||
|
|
||||||
|
expect(JSON.parse(readSource('pageTreeData.rocketGenerated.json'))).to.deep.equal({
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
h1: '<some-button>',
|
||||||
|
headlinesWithId: [
|
||||||
|
{
|
||||||
|
id: 'some-button',
|
||||||
|
level: 1,
|
||||||
|
text: '<some-button>',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
level: 1,
|
||||||
|
menuLinkText: '<some-button>',
|
||||||
|
name: '<some-button>',
|
||||||
|
outputRelativeFilePath: 'component/index.html',
|
||||||
|
sourceRelativeFilePath: 'component.rocket.md',
|
||||||
|
url: '/component/',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
h1: 'Fun Errors & Feedback',
|
||||||
|
headlinesWithId: [
|
||||||
|
{
|
||||||
|
id: 'fun-errors--feedback',
|
||||||
|
level: 1,
|
||||||
|
text: 'Fun Errors & Feedback',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
level: 0,
|
||||||
|
menuLinkText: 'Fun Errors & Feedback',
|
||||||
|
name: 'Fun Errors & Feedback',
|
||||||
|
outputRelativeFilePath: 'index.html',
|
||||||
|
sourceRelativeFilePath: 'index.rocket.md',
|
||||||
|
url: '/',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('16: link-text attribute', async () => {
|
||||||
|
const { build, readSource } = await setupTestEngine(
|
||||||
|
'fixtures/05-menu/16-link-text-attribute/docs',
|
||||||
|
);
|
||||||
|
await build();
|
||||||
|
|
||||||
|
expect(JSON.parse(readSource('pageTreeData.rocketGenerated.json'))).to.deep.equal({
|
||||||
|
h1: 'Home',
|
||||||
|
headlinesWithId: [
|
||||||
|
{
|
||||||
|
id: 'home',
|
||||||
|
level: 1,
|
||||||
|
rawText: 'Welcome to Rocket',
|
||||||
|
text: 'Home',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'first',
|
||||||
|
level: 2,
|
||||||
|
text: 'First',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'second',
|
||||||
|
level: 2,
|
||||||
|
rawText: 'Second is best',
|
||||||
|
text: 'Second',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
level: 0,
|
||||||
|
menuLinkText: 'Home',
|
||||||
|
name: 'Home',
|
||||||
|
outputRelativeFilePath: 'index.html',
|
||||||
|
sourceRelativeFilePath: 'index.rocket.js',
|
||||||
|
url: '/',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('17: title-tag', async () => {
|
||||||
|
const { build, readSource, deleteSource } = await setupTestEngine(
|
||||||
|
'fixtures/05-menu/17-title-tag/docs',
|
||||||
|
);
|
||||||
|
await deleteSource('pageTreeData.rocketGenerated.json');
|
||||||
|
await build();
|
||||||
|
|
||||||
|
expect(JSON.parse(readSource('pageTreeData.rocketGenerated.json'))).to.deep.equal({
|
||||||
|
h1: 'Welcome to Rocket',
|
||||||
|
level: 0,
|
||||||
|
menuLinkText: 'Welcome to Rocket',
|
||||||
|
name: 'Welcome to Rocket',
|
||||||
|
outputRelativeFilePath: 'index.html',
|
||||||
|
sourceRelativeFilePath: 'index.rocket.js',
|
||||||
|
title: 'Welcome to Rocket | Rocket',
|
||||||
|
url: '/',
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -116,10 +116,21 @@ describe('Engine start error handling', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('04: update-header-while-rendering', async () => {
|
it('04: update-header-while-rendering', async () => {
|
||||||
const { readOutput, writeSource, cleanup, engine, setAsOpenedInBrowser, outputExists } =
|
const {
|
||||||
await setupTestEngine(
|
readOutput,
|
||||||
|
writeSource,
|
||||||
|
cleanup,
|
||||||
|
engine,
|
||||||
|
setAsOpenedInBrowser,
|
||||||
|
outputExists,
|
||||||
|
anEngineEvent,
|
||||||
|
} = await setupTestEngine(
|
||||||
'fixtures/09b-watch-error-handling/04-update-header-while-rendering/docs',
|
'fixtures/09b-watch-error-handling/04-update-header-while-rendering/docs',
|
||||||
);
|
);
|
||||||
|
expect(outputExists('index.html')).to.be.false;
|
||||||
|
|
||||||
|
await engine.start();
|
||||||
|
setAsOpenedInBrowser('index.rocket.js');
|
||||||
await writeSource(
|
await writeSource(
|
||||||
'index.rocket.js',
|
'index.rocket.js',
|
||||||
[
|
[
|
||||||
@@ -140,13 +151,7 @@ describe('Engine start error handling', () => {
|
|||||||
'`;',
|
'`;',
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
);
|
);
|
||||||
|
await anEngineEvent('rocketUpdated');
|
||||||
await engine.start();
|
|
||||||
setAsOpenedInBrowser('index.rocket.js');
|
|
||||||
|
|
||||||
const { port } = engine.devServer.config;
|
|
||||||
expect(outputExists('index.html')).to.be.false;
|
|
||||||
await fetch(`http://localhost:${port}/`);
|
|
||||||
|
|
||||||
expect(readOutput('index.html')).to.equal(
|
expect(readOutput('index.html')).to.equal(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"title": "Fixed Title",
|
"title": "Fixed Title",
|
||||||
"h1": "\n Welcome Members:\n ",
|
"h1": "Welcome Members:",
|
||||||
"headlinesWithId": [
|
"headlinesWithId": [
|
||||||
{
|
{
|
||||||
"text": "\n Welcome Members:\n ",
|
"text": "Welcome Members:",
|
||||||
"id": "welcome-members",
|
"id": "welcome-members",
|
||||||
"level": 1
|
"level": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "Fixed Title",
|
"name": "Fixed Title",
|
||||||
"menuLinkText": "\n Welcome Members:\n ",
|
"menuLinkText": "Welcome Members:",
|
||||||
"url": "/",
|
"url": "/",
|
||||||
"outputRelativeFilePath": "index.html",
|
"outputRelativeFilePath": "index.html",
|
||||||
"sourceRelativeFilePath": "index.rocket.js",
|
"sourceRelativeFilePath": "index.rocket.js",
|
||||||
|
|||||||
@@ -6,7 +6,13 @@ export { layout };
|
|||||||
|
|
||||||
import { html } from 'lit';
|
import { html } from 'lit';
|
||||||
export default () => html`
|
export default () => html`
|
||||||
<meta name="menu:link.text" content="About" />
|
<html>
|
||||||
|
<head>
|
||||||
<title>About | MyPage</title>
|
<title>About | MyPage</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<meta name="menu:link.text" content="About" />
|
||||||
<h1>This is About</h1>
|
<h1>This is About</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
"level": 0,
|
"level": 0,
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"menuLinkText": "About",
|
|
||||||
"title": "About | MyPage",
|
"title": "About | MyPage",
|
||||||
|
"menuLinkText": "About",
|
||||||
"h1": "This is About",
|
"h1": "This is About",
|
||||||
"name": "This is About",
|
"name": "This is About",
|
||||||
"url": "/about/",
|
"url": "/about/",
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/* START - Rocket auto generated - do not touch */
|
||||||
|
export const sourceRelativeFilePath = 'index.rocket.js';
|
||||||
|
import { layout, html } from './recursive.data.js';
|
||||||
|
export { layout, html };
|
||||||
|
/* END - Rocket auto generated - do not touch */
|
||||||
|
|
||||||
|
export default () =>
|
||||||
|
html`<h1>
|
||||||
|
Hello <strong>World</strong> of <span>JS <em>(JavaScript)</em></span
|
||||||
|
>!
|
||||||
|
</h1>`;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"h1": "Hello World of JS (JavaScript)!",
|
||||||
|
"name": "Hello World of JS (JavaScript)!",
|
||||||
|
"menuLinkText": "Hello World of JS (JavaScript)!",
|
||||||
|
"url": "/",
|
||||||
|
"outputRelativeFilePath": "index.html",
|
||||||
|
"sourceRelativeFilePath": "index.rocket.js",
|
||||||
|
"level": 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { PageTree, SiteMenu } from '@rocket/engine';
|
||||||
|
import { html } from 'lit';
|
||||||
|
|
||||||
|
const pageTree = new PageTree({
|
||||||
|
inputDir: new URL('./', import.meta.url),
|
||||||
|
outputDir: new URL('../__output', import.meta.url),
|
||||||
|
});
|
||||||
|
|
||||||
|
await pageTree.restore();
|
||||||
|
|
||||||
|
export const layout = data => {
|
||||||
|
return html`
|
||||||
|
${pageTree.renderMenu(new SiteMenu(), data.sourceRelativeFilePath)}
|
||||||
|
<main>${data.content()}</main>
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { html };
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
```js server
|
||||||
|
/* START - Rocket auto generated - do not touch */
|
||||||
|
export const sourceRelativeFilePath = 'component.rocket.md';
|
||||||
|
import { layout, html } from './recursive.data.js';
|
||||||
|
export { layout, html };
|
||||||
|
/* END - Rocket auto generated - do not touch */
|
||||||
|
```
|
||||||
|
|
||||||
|
# <some-button>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
```js server
|
||||||
|
/* START - Rocket auto generated - do not touch */
|
||||||
|
export const sourceRelativeFilePath = 'index.rocket.md';
|
||||||
|
import { layout, html } from './recursive.data.js';
|
||||||
|
export { layout, html };
|
||||||
|
/* END - Rocket auto generated - do not touch */
|
||||||
|
```
|
||||||
|
|
||||||
|
# Fun Errors & Feedback
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"h1": "Fun Errors & Feedback",
|
||||||
|
"headlinesWithId": [
|
||||||
|
{
|
||||||
|
"text": "Fun Errors & Feedback",
|
||||||
|
"id": "fun-errors--feedback",
|
||||||
|
"level": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Fun Errors & Feedback",
|
||||||
|
"menuLinkText": "Fun Errors & Feedback",
|
||||||
|
"url": "/",
|
||||||
|
"outputRelativeFilePath": "index.html",
|
||||||
|
"sourceRelativeFilePath": "index.rocket.md",
|
||||||
|
"level": 0,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"h1": "<some-button>",
|
||||||
|
"headlinesWithId": [
|
||||||
|
{
|
||||||
|
"text": "<some-button>",
|
||||||
|
"id": "some-button",
|
||||||
|
"level": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "<some-button>",
|
||||||
|
"menuLinkText": "<some-button>",
|
||||||
|
"url": "/component/",
|
||||||
|
"outputRelativeFilePath": "component/index.html",
|
||||||
|
"sourceRelativeFilePath": "component.rocket.md",
|
||||||
|
"level": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { PageTree, SiteMenu } from '@rocket/engine';
|
||||||
|
import { html } from 'lit';
|
||||||
|
|
||||||
|
const pageTree = new PageTree({
|
||||||
|
inputDir: new URL('./', import.meta.url),
|
||||||
|
outputDir: new URL('../__output', import.meta.url),
|
||||||
|
});
|
||||||
|
|
||||||
|
await pageTree.restore();
|
||||||
|
|
||||||
|
export const layout = data => {
|
||||||
|
return html`
|
||||||
|
${pageTree.renderMenu(new SiteMenu(), data.sourceRelativeFilePath)}
|
||||||
|
<main>${data.content()}</main>
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { html };
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/* START - Rocket auto generated - do not touch */
|
||||||
|
export const sourceRelativeFilePath = 'index.rocket.js';
|
||||||
|
import { layout, html } from './recursive.data.js';
|
||||||
|
export { layout, html };
|
||||||
|
/* END - Rocket auto generated - do not touch */
|
||||||
|
|
||||||
|
export default () => html`
|
||||||
|
<h1 id="home" link-text="Home">Welcome to Rocket</h1>
|
||||||
|
<h2 id="first">First</h2>
|
||||||
|
<h2 link-text="Second" id="second">Second is best</h2>
|
||||||
|
`;
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"h1": "Home",
|
||||||
|
"headlinesWithId": [
|
||||||
|
{
|
||||||
|
"text": "Home",
|
||||||
|
"id": "home",
|
||||||
|
"level": 1,
|
||||||
|
"rawText": "Welcome to Rocket"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "First",
|
||||||
|
"id": "first",
|
||||||
|
"level": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Second",
|
||||||
|
"id": "second",
|
||||||
|
"level": 2,
|
||||||
|
"rawText": "Second is best"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Home",
|
||||||
|
"menuLinkText": "Home",
|
||||||
|
"url": "/",
|
||||||
|
"outputRelativeFilePath": "index.html",
|
||||||
|
"sourceRelativeFilePath": "index.rocket.js",
|
||||||
|
"level": 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { PageTree, SiteMenu } from '@rocket/engine';
|
||||||
|
import { html } from 'lit';
|
||||||
|
|
||||||
|
const pageTree = new PageTree({
|
||||||
|
inputDir: new URL('./', import.meta.url),
|
||||||
|
outputDir: new URL('../__output', import.meta.url),
|
||||||
|
});
|
||||||
|
|
||||||
|
await pageTree.restore();
|
||||||
|
|
||||||
|
export const layout = data => {
|
||||||
|
return html`
|
||||||
|
${pageTree.renderMenu(new SiteMenu(), data.sourceRelativeFilePath)}
|
||||||
|
<main>${data.content()}</main>
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { html };
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
/* START - Rocket auto generated - do not touch */
|
||||||
|
export const sourceRelativeFilePath = 'index.rocket.js';
|
||||||
|
import { layout, html } from './recursive.data.js';
|
||||||
|
export { layout, html };
|
||||||
|
/* END - Rocket auto generated - do not touch */
|
||||||
|
|
||||||
|
export default () => html` <h1>Welcome to Rocket</h1> `;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"title": "Welcome to Rocket | Rocket",
|
||||||
|
"h1": "Welcome to Rocket",
|
||||||
|
"name": "Welcome to Rocket",
|
||||||
|
"menuLinkText": "Welcome to Rocket",
|
||||||
|
"url": "/",
|
||||||
|
"outputRelativeFilePath": "index.html",
|
||||||
|
"sourceRelativeFilePath": "index.rocket.js",
|
||||||
|
"level": 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { PageTree } from '@rocket/engine';
|
||||||
|
import { html } from 'lit';
|
||||||
|
|
||||||
|
const pageTree = new PageTree({
|
||||||
|
inputDir: new URL('./', import.meta.url),
|
||||||
|
outputDir: new URL('../__output', import.meta.url),
|
||||||
|
});
|
||||||
|
|
||||||
|
await pageTree.restore();
|
||||||
|
|
||||||
|
const titleWrapperFn = title => (title ? `${title} | Rocket` : '');
|
||||||
|
|
||||||
|
export const layout = data => {
|
||||||
|
const title = titleWrapperFn(pageTree.getPage(data.sourceRelativeFilePath)?.model?.name);
|
||||||
|
return html`
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title-server-only>${title}</title-server-only>
|
||||||
|
</head>
|
||||||
|
</html>
|
||||||
|
<body>
|
||||||
|
<main>${data.content()}</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { html };
|
||||||
@@ -1,5 +1,16 @@
|
|||||||
# @rocket/launch
|
# @rocket/launch
|
||||||
|
|
||||||
|
## 0.21.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 390335d: Improve title tag handling
|
||||||
|
- Updated dependencies [8dedc56]
|
||||||
|
- Updated dependencies [390335d]
|
||||||
|
- Updated dependencies [8dedc56]
|
||||||
|
- @rocket/engine@0.2.6
|
||||||
|
- @rocket/cli@0.20.1
|
||||||
|
|
||||||
## 0.21.0
|
## 0.21.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/launch",
|
"name": "@rocket/launch",
|
||||||
"version": "0.21.0",
|
"version": "0.21.1",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -46,9 +46,9 @@
|
|||||||
"preset"
|
"preset"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rocket/cli": "^0.20.0",
|
"@rocket/cli": "^0.20.1",
|
||||||
"@rocket/components": "^0.2.0",
|
"@rocket/components": "^0.2.0",
|
||||||
"@rocket/engine": "^0.2.0",
|
"@rocket/engine": "^0.2.6",
|
||||||
"@webcomponents/template-shadowroot": "^0.1.0",
|
"@webcomponents/template-shadowroot": "^0.1.0",
|
||||||
"lit": "^2.3.0",
|
"lit": "^2.3.0",
|
||||||
"workbox-window": "^6.1.5"
|
"workbox-window": "^6.1.5"
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export class LayoutMain extends Layout {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
footerMenu: [],
|
footerMenu: [],
|
||||||
titleWrapperFn: title => `${title} | ${this.options.siteName}`,
|
titleWrapperFn: title => (title ? `${title} | ${this.options.siteName}` : ''),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ const { expect } = chai;
|
|||||||
|
|
||||||
describe('Search', () => {
|
describe('Search', () => {
|
||||||
it('01: writes the search index', async () => {
|
it('01: writes the search index', async () => {
|
||||||
const { build, readOutput, readPublic } = await setupTestCli(
|
const { build, readOutput, readPublic } = await setupTestCli({
|
||||||
'fixtures/01-single-page/',
|
cwd: 'fixtures/01-single-page/',
|
||||||
undefined,
|
options: {
|
||||||
{
|
|
||||||
buildOptimize: true,
|
buildOptimize: true,
|
||||||
},
|
},
|
||||||
);
|
testOptions: { captureLogs: true },
|
||||||
|
});
|
||||||
await build();
|
await build();
|
||||||
|
|
||||||
const indexString =
|
const indexString =
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
# @rocket/spark
|
# @rocket/spark
|
||||||
|
|
||||||
|
## 0.2.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 390335d: Improve title tag handling
|
||||||
|
- Updated dependencies [8dedc56]
|
||||||
|
- Updated dependencies [390335d]
|
||||||
|
- @rocket/engine@0.2.6
|
||||||
|
|
||||||
## 0.2.0
|
## 0.2.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/spark",
|
"name": "@rocket/spark",
|
||||||
"version": "0.2.0",
|
"version": "0.2.1",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rocket/components": "^0.2.0",
|
"@rocket/components": "^0.2.0",
|
||||||
"@rocket/engine": "^0.2.0",
|
"@rocket/engine": "^0.2.6",
|
||||||
"lit": "^2.3.0"
|
"lit": "^2.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export class LayoutHome extends Layout {
|
|||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
const page = this.options.pageTree.getPage(data.sourceRelativeFilePath);
|
const page = this.options.pageTree.getPage(data.sourceRelativeFilePath);
|
||||||
if (page.model.headlinesWithId) {
|
if (page?.model?.headlinesWithId) {
|
||||||
return html`
|
return html`
|
||||||
${page.model.headlinesWithId.map(
|
${page.model.headlinesWithId.map(
|
||||||
headline => html`
|
headline => html`
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ Like any unfamiliar technology, Rocket comes with a slight learning curve. Howev
|
|||||||
|
|
||||||
### Example Projects
|
### Example Projects
|
||||||
|
|
||||||
If you prefer to learn Rocket by example, check out our [examples](https://github.com/modernweb-dev/rocket/tree/next/examples) on GitHub.
|
If you prefer to learn Rocket by example, check out our [examples](https://github.com/modernweb-dev/rocket/tree/main/examples) on GitHub.
|
||||||
|
|
||||||
You locally install any of these examples by running `npx @rocket/create@latest` and selecting it within the wizard.
|
You locally install any of these examples by running `npx @rocket/create@latest` and selecting it within the wizard.
|
||||||
|
|
||||||
|
|||||||
@@ -48,11 +48,11 @@ This with start rocket in development mode and you will see your site running in
|
|||||||
|
|
||||||
## What is a page?
|
## What is a page?
|
||||||
|
|
||||||
A page is a file that ends either with `*.rocket.js`, `*.rocket.md` or `*.rocket.html` and is located in the input directory (`docs` by default). Pages will make up the majority or your website.
|
A page is a file that ends either with `*.rocket.js`, `*.rocket.md` or `*.rocket.html` and is located in the input directory (`site/pages` by default). Pages will make up the majority or your website.
|
||||||
|
|
||||||
The simplest way to get started is to create a file
|
The simplest way to get started is to create a file
|
||||||
|
|
||||||
👉 `docs/index.rocket.md`
|
👉 `site/pages/index.rocket.md`
|
||||||
|
|
||||||
```md
|
```md
|
||||||
# Hello World
|
# Hello World
|
||||||
@@ -78,15 +78,23 @@ This section will be used to auto inject settings and data via a data cascade.
|
|||||||
|
|
||||||
To test it you can create a file
|
To test it you can create a file
|
||||||
|
|
||||||
👉 `docs/recursive.data.js`
|
👉 `site/pages/recursive.data.js`
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { html } from 'lit';
|
import { html } from 'lit';
|
||||||
|
|
||||||
export const layout = data => html`<div>${data.content()}</div>`;
|
export const layout = data => html`
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<header>My Website</header>
|
||||||
|
<div>${data.content()}</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
```
|
```
|
||||||
|
|
||||||
Now if you go back to your `docs/index.rocket.md` you will see that `layout` got automatically injected.
|
Now if you go back to your `site/pages/index.rocket.md` you will see that `layout` got automatically injected.
|
||||||
|
|
||||||
````md
|
````md
|
||||||
```js server
|
```js server
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export const description = 'Learn how to structure a project with Rocket.';
|
|||||||
# Project Structure
|
# Project Structure
|
||||||
|
|
||||||
Rocket works with one input folder for all your pages that defaults to `site/pages`.
|
Rocket works with one input folder for all your pages that defaults to `site/pages`.
|
||||||
Within `pages` there is a `__public` folder that will be copied as is to the output folder.
|
Within `pages` there is a `public` folder that will be copied as is to the output folder.
|
||||||
|
|
||||||
All other files like `layouts`, `css`, `data`, ... can be placed anywhere in your project.
|
All other files like `layouts`, `css`, `data`, ... can be placed anywhere in your project.
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ export async function registerCustomElements() {
|
|||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
customElements.define('rocket-header', await import('@rocket/components/header.js').then(m => m.RocketHeader));
|
customElements.define('rocket-header', await import('@rocket/components/header.js').then(m => m.RocketHeader));
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
|
customElements.define('inline-notification', await import('@rocket/components/inline-notification.js').then(m => m.InlineNotification));
|
||||||
|
// prettier-ignore
|
||||||
customElements.define('rocket-main-docs', await import('@rocket/components/main-docs.js').then(m => m.RocketMainDocs));
|
customElements.define('rocket-main-docs', await import('@rocket/components/main-docs.js').then(m => m.RocketMainDocs));
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
customElements.define('rocket-content-area', await import('@rocket/components/content-area.js').then(m => m.RocketContentArea));
|
customElements.define('rocket-content-area', await import('@rocket/components/content-area.js').then(m => m.RocketContentArea));
|
||||||
@@ -85,22 +87,22 @@ In most cases you probably will not need to do anything as it will take the text
|
|||||||
So if you have a page like this:
|
So if you have a page like this:
|
||||||
|
|
||||||
```md
|
```md
|
||||||
# Hello World
|
# Learning Rocket
|
||||||
```
|
```
|
||||||
|
|
||||||
then it will be called "Hello World" in the menu.
|
then it will be called "Learning Rocket" in the menu.
|
||||||
|
|
||||||
You can overwrite that by using the property `menuLinkText`;
|
You can overwrite that by using the property `menuLinkText`;
|
||||||
|
|
||||||
````md
|
````md
|
||||||
```js server
|
```js server
|
||||||
export const menuLinkText = 'Hello';
|
export const menuLinkText = 'Docs';
|
||||||
```
|
```
|
||||||
|
|
||||||
# Hello World
|
# Learning Rocket
|
||||||
````
|
````
|
||||||
|
|
||||||
Now the menu will be called "Hello".
|
Now the menu will be called "Docs".
|
||||||
|
|
||||||
Within a menu the text of the links is defined by the following priority:
|
Within a menu the text of the links is defined by the following priority:
|
||||||
|
|
||||||
@@ -111,6 +113,32 @@ Within a menu the text of the links is defined by the following priority:
|
|||||||
|
|
||||||
You can influence that data that gets provided to the menu by setting exports.
|
You can influence that data that gets provided to the menu by setting exports.
|
||||||
|
|
||||||
|
### link-text="..."
|
||||||
|
|
||||||
|
If you want to rename the menu text you can use the attribute `link-text`.
|
||||||
|
It works on your h1 for the page title as well as on your h2-h6 for a table of contents menu.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h1 link-text="Docs">Learning Rocket</h1>
|
||||||
|
|
||||||
|
<h2 link-text="Contact">Write us a message</h2>
|
||||||
|
```
|
||||||
|
|
||||||
|
<inline-notification>
|
||||||
|
You can use HTML within markdown too!
|
||||||
|
</inline-notification>
|
||||||
|
|
||||||
|
## Headings with HTML
|
||||||
|
|
||||||
|
HTML in headings will be ignored for the menu
|
||||||
|
|
||||||
|
Some examples:
|
||||||
|
|
||||||
|
- `<h1>Hello <em>Word</em></h1>` => `Hello Word`
|
||||||
|
- `<h1>Hello <strong>World</strong> of <span>JS <em>(JavaScript)</em></span>!</h1>` => `Hello World of JS (JavaScript)!`
|
||||||
|
|
||||||
## Menu No Link
|
## Menu No Link
|
||||||
|
|
||||||
Often you have sections or groups of pages which you want to provide a heading for.
|
Often you have sections or groups of pages which you want to provide a heading for.
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ export async function registerCustomElements() {
|
|||||||
}
|
}
|
||||||
export const needsLoader = true;
|
export const needsLoader = true;
|
||||||
/* END - Rocket auto generated - do not touch */
|
/* END - Rocket auto generated - do not touch */
|
||||||
|
export const title = 'Plugins Manager';
|
||||||
|
export const subTitle = 'Enable fully customizable options for your plugin system';
|
||||||
```
|
```
|
||||||
|
|
||||||
# Overview
|
# Overview
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ export async function registerCustomElements() {
|
|||||||
}
|
}
|
||||||
export const needsLoader = true;
|
export const needsLoader = true;
|
||||||
/* END - Rocket auto generated - do not touch */
|
/* END - Rocket auto generated - do not touch */
|
||||||
|
|
||||||
|
export const title = 'Markdown JavaScript';
|
||||||
|
export const subTitle = 'Executable JavaScript in markdown by annotating code blocks';
|
||||||
```
|
```
|
||||||
|
|
||||||
# Overview
|
# Overview
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ export async function registerCustomElements() {
|
|||||||
}
|
}
|
||||||
export const needsLoader = true;
|
export const needsLoader = true;
|
||||||
/* END - Rocket auto generated - do not touch */
|
/* END - Rocket auto generated - do not touch */
|
||||||
|
|
||||||
|
export const title = 'Rocket Rollup Config';
|
||||||
|
export const subTitle =
|
||||||
|
'A ready to use and customizable rollup config for web sites, MPAs and SPAs';
|
||||||
```
|
```
|
||||||
|
|
||||||
# Overview
|
# Overview
|
||||||
|
|||||||
@@ -24,11 +24,14 @@ export async function registerCustomElements() {
|
|||||||
}
|
}
|
||||||
export const needsLoader = true;
|
export const needsLoader = true;
|
||||||
/* END - Rocket auto generated - do not touch */
|
/* END - Rocket auto generated - do not touch */
|
||||||
|
|
||||||
|
export const title = 'Check HTML links';
|
||||||
|
export const subTitle = 'A fast checker for broken links/references in HTML files';
|
||||||
```
|
```
|
||||||
|
|
||||||
# Overview
|
# Overview
|
||||||
|
|
||||||
A fast checker for broken links/references in HTML.
|
A fast checker for broken links/references in HTML files.
|
||||||
|
|
||||||
<inline-notification type="tip">
|
<inline-notification type="tip">
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"title": "Welcome to Rocket",
|
"title": "Welcome to Rocket",
|
||||||
"h1": "\n \n ",
|
"h1": "",
|
||||||
"name": "\n \n ",
|
"name": "Welcome to Rocket",
|
||||||
"menuLinkText": "\n \n ",
|
"menuLinkText": "Welcome to Rocket",
|
||||||
"url": "/",
|
"url": "/",
|
||||||
"outputRelativeFilePath": "index.html",
|
"outputRelativeFilePath": "index.html",
|
||||||
"sourceRelativeFilePath": "index.rocket.js",
|
"sourceRelativeFilePath": "index.rocket.js",
|
||||||
@@ -386,6 +386,31 @@
|
|||||||
"text": "Recommended Project Structure",
|
"text": "Recommended Project Structure",
|
||||||
"id": "recommended-project-structure",
|
"id": "recommended-project-structure",
|
||||||
"level": 2
|
"level": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "site/pages/",
|
||||||
|
"id": "sitepages",
|
||||||
|
"level": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "site/src/",
|
||||||
|
"id": "sitesrc",
|
||||||
|
"level": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "site/src/components",
|
||||||
|
"id": "sitesrccomponents",
|
||||||
|
"level": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "site/src/layouts",
|
||||||
|
"id": "sitesrclayouts",
|
||||||
|
"level": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "site/public/",
|
||||||
|
"id": "sitepublic",
|
||||||
|
"level": 3
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "Project Structure",
|
"name": "Project Structure",
|
||||||
@@ -758,6 +783,16 @@
|
|||||||
"id": "menu-link-text",
|
"id": "menu-link-text",
|
||||||
"level": 3
|
"level": 3
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"text": "link-text=\"...\"",
|
||||||
|
"id": "link-text",
|
||||||
|
"level": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Headings with HTML",
|
||||||
|
"id": "headings-with-html",
|
||||||
|
"level": 2
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"text": "Menu No Link",
|
"text": "Menu No Link",
|
||||||
"id": "menu-no-link",
|
"id": "menu-no-link",
|
||||||
@@ -937,7 +972,7 @@
|
|||||||
"level": 2
|
"level": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "The Function",
|
"text": "The :resolve Function",
|
||||||
"id": "the-resolve-function",
|
"id": "the-resolve-function",
|
||||||
"level": 2
|
"level": 2
|
||||||
},
|
},
|
||||||
@@ -1432,7 +1467,7 @@
|
|||||||
"level": 2
|
"level": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "1. Simple Tags and External Files",
|
"text": "1. Simple <link> Tags and External Files",
|
||||||
"id": "1-simple-link-tags-and-external-files",
|
"id": "1-simple-link-tags-and-external-files",
|
||||||
"level": 3
|
"level": 3
|
||||||
},
|
},
|
||||||
@@ -1447,7 +1482,7 @@
|
|||||||
"level": 3
|
"level": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "Recommendations & Best Practices",
|
"text": "Recommendations & Best Practices",
|
||||||
"id": "recommendations--best-practices",
|
"id": "recommendations--best-practices",
|
||||||
"level": 2
|
"level": 2
|
||||||
},
|
},
|
||||||
@@ -2239,7 +2274,7 @@
|
|||||||
"needsLoader": true,
|
"needsLoader": true,
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"title": "Overview | Rocket",
|
"title": "Plugins Manager",
|
||||||
"h1": "Overview",
|
"h1": "Overview",
|
||||||
"headlinesWithId": [
|
"headlinesWithId": [
|
||||||
{
|
{
|
||||||
@@ -2313,7 +2348,7 @@
|
|||||||
"level": 2
|
"level": 2
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "Overview",
|
"name": "Plugins Manager",
|
||||||
"menuLinkText": "Overview",
|
"menuLinkText": "Overview",
|
||||||
"url": "/tools/plugins-manager/overview/",
|
"url": "/tools/plugins-manager/overview/",
|
||||||
"outputRelativeFilePath": "tools/plugins-manager/overview/index.html",
|
"outputRelativeFilePath": "tools/plugins-manager/overview/index.html",
|
||||||
@@ -2345,7 +2380,8 @@
|
|||||||
"launch-blog-details": "@rocket/launch/blog-details.js::LaunchBlogDetails",
|
"launch-blog-details": "@rocket/launch/blog-details.js::LaunchBlogDetails",
|
||||||
"my-counter": "#src/components/MyCounter.js::MyCounter"
|
"my-counter": "#src/components/MyCounter.js::MyCounter"
|
||||||
},
|
},
|
||||||
"needsLoader": true
|
"needsLoader": true,
|
||||||
|
"subTitle": "Enable fully customizable options for your plugin system"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -2388,7 +2424,7 @@
|
|||||||
"needsLoader": true,
|
"needsLoader": true,
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"title": "Overview | Rocket",
|
"title": "Markdown JavaScript",
|
||||||
"h1": "Overview",
|
"h1": "Overview",
|
||||||
"headlinesWithId": [
|
"headlinesWithId": [
|
||||||
{
|
{
|
||||||
@@ -2451,13 +2487,23 @@
|
|||||||
"id": "basic",
|
"id": "basic",
|
||||||
"level": 3
|
"level": 3
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"text": "mdjsDocPage",
|
||||||
|
"id": "mdjsdocpage",
|
||||||
|
"level": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "mdjsProcess",
|
||||||
|
"id": "mdjsprocess",
|
||||||
|
"level": 4
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"text": "Advanced",
|
"text": "Advanced",
|
||||||
"id": "advanced",
|
"id": "advanced",
|
||||||
"level": 3
|
"level": 3
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "Overview",
|
"name": "Markdown JavaScript",
|
||||||
"menuLinkText": "Overview",
|
"menuLinkText": "Overview",
|
||||||
"url": "/tools/markdown-javascript/overview/",
|
"url": "/tools/markdown-javascript/overview/",
|
||||||
"outputRelativeFilePath": "tools/markdown-javascript/overview/index.html",
|
"outputRelativeFilePath": "tools/markdown-javascript/overview/index.html",
|
||||||
@@ -2489,7 +2535,8 @@
|
|||||||
"launch-blog-details": "@rocket/launch/blog-details.js::LaunchBlogDetails",
|
"launch-blog-details": "@rocket/launch/blog-details.js::LaunchBlogDetails",
|
||||||
"my-counter": "#src/components/MyCounter.js::MyCounter"
|
"my-counter": "#src/components/MyCounter.js::MyCounter"
|
||||||
},
|
},
|
||||||
"needsLoader": true
|
"needsLoader": true,
|
||||||
|
"subTitle": "Executable JavaScript in markdown by annotating code blocks"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Preview | Rocket",
|
"title": "Preview | Rocket",
|
||||||
@@ -2655,7 +2702,7 @@
|
|||||||
"needsLoader": true,
|
"needsLoader": true,
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"title": "Overview | Rocket",
|
"title": "Rocket Rollup Config",
|
||||||
"h1": "Overview",
|
"h1": "Overview",
|
||||||
"headlinesWithId": [
|
"headlinesWithId": [
|
||||||
{
|
{
|
||||||
@@ -2689,7 +2736,7 @@
|
|||||||
"level": 3
|
"level": 3
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "Overview",
|
"name": "Rocket Rollup Config",
|
||||||
"menuLinkText": "Overview",
|
"menuLinkText": "Overview",
|
||||||
"url": "/tools/rollup-config/overview/",
|
"url": "/tools/rollup-config/overview/",
|
||||||
"outputRelativeFilePath": "tools/rollup-config/overview/index.html",
|
"outputRelativeFilePath": "tools/rollup-config/overview/index.html",
|
||||||
@@ -2721,7 +2768,8 @@
|
|||||||
"launch-blog-details": "@rocket/launch/blog-details.js::LaunchBlogDetails",
|
"launch-blog-details": "@rocket/launch/blog-details.js::LaunchBlogDetails",
|
||||||
"my-counter": "#src/components/MyCounter.js::MyCounter"
|
"my-counter": "#src/components/MyCounter.js::MyCounter"
|
||||||
},
|
},
|
||||||
"needsLoader": true
|
"needsLoader": true,
|
||||||
|
"subTitle": "A ready to use and customizable rollup config for web sites, MPAs and SPAs"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -2764,7 +2812,7 @@
|
|||||||
"needsLoader": true,
|
"needsLoader": true,
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"title": "Overview | Rocket",
|
"title": "Check HTML links",
|
||||||
"h1": "Overview",
|
"h1": "Overview",
|
||||||
"headlinesWithId": [
|
"headlinesWithId": [
|
||||||
{
|
{
|
||||||
@@ -2803,7 +2851,7 @@
|
|||||||
"level": 2
|
"level": 2
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "Overview",
|
"name": "Check HTML links",
|
||||||
"menuLinkText": "Overview",
|
"menuLinkText": "Overview",
|
||||||
"url": "/tools/check-html-links/overview/",
|
"url": "/tools/check-html-links/overview/",
|
||||||
"outputRelativeFilePath": "tools/check-html-links/overview/index.html",
|
"outputRelativeFilePath": "tools/check-html-links/overview/index.html",
|
||||||
@@ -2835,7 +2883,8 @@
|
|||||||
"launch-blog-details": "@rocket/launch/blog-details.js::LaunchBlogDetails",
|
"launch-blog-details": "@rocket/launch/blog-details.js::LaunchBlogDetails",
|
||||||
"my-counter": "#src/components/MyCounter.js::MyCounter"
|
"my-counter": "#src/components/MyCounter.js::MyCounter"
|
||||||
},
|
},
|
||||||
"needsLoader": true
|
"needsLoader": true,
|
||||||
|
"subTitle": "A fast checker for broken links/references in HTML files"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
13
yarn.lock
13
yarn.lock
@@ -1656,6 +1656,13 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-1.8.2.tgz#7315b4c4c54f82d13fa61c228ec5c2ea5cc9e0e1"
|
resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-1.8.2.tgz#7315b4c4c54f82d13fa61c228ec5c2ea5cc9e0e1"
|
||||||
integrity sha512-EqX+YQxINb+MeXaIqYDASb6U6FCHbWjkj4a1CKDBks3d/QiB2+PqBLyO72vLDgAO1wUI4O+9gweRcQK11bTL/w==
|
integrity sha512-EqX+YQxINb+MeXaIqYDASb6U6FCHbWjkj4a1CKDBks3d/QiB2+PqBLyO72vLDgAO1wUI4O+9gweRcQK11bTL/w==
|
||||||
|
|
||||||
|
"@types/ip@^1.1.0":
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/ip/-/ip-1.1.0.tgz#aec4f5bfd49e4a4c53b590d88c36eb078827a7c0"
|
||||||
|
integrity sha512-dwNe8gOoF70VdL6WJBwVHtQmAX4RMd62M+mAB9HQFjG1/qiCLM/meRy95Pd14FYBbEDwCq7jgJs89cHpLBu4HQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/is-ci@^3.0.0":
|
"@types/is-ci@^3.0.0":
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/is-ci/-/is-ci-3.0.0.tgz#7e8910af6857601315592436f030aaa3ed9783c3"
|
resolved "https://registry.yarnpkg.com/@types/is-ci/-/is-ci-3.0.0.tgz#7e8910af6857601315592436f030aaa3ed9783c3"
|
||||||
@@ -2085,9 +2092,9 @@
|
|||||||
glob "^7.1.6"
|
glob "^7.1.6"
|
||||||
|
|
||||||
"@web/rollup-plugin-html@^1.8.0":
|
"@web/rollup-plugin-html@^1.8.0":
|
||||||
version "1.10.3"
|
version "1.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/@web/rollup-plugin-html/-/rollup-plugin-html-1.10.3.tgz#78fa06a9a7f2ec6973a12bd1000b900c1fd4e4eb"
|
resolved "https://registry.yarnpkg.com/@web/rollup-plugin-html/-/rollup-plugin-html-1.11.0.tgz#46c2bcb3a3b9db55d53b897ffc7e7ef2f618a052"
|
||||||
integrity sha512-2RMIeKxpGtrcXiqPTgMVq5neGa5xa69MfNK860BHVMEO2N/MrHFuQNr1eNLsspcq2DL/xnymwC3w5hgjtlgxag==
|
integrity sha512-EqUcV5plGYTV/utdbX8g5t8Yq/z6VfFuQuPD39ckOQuRj7Rj6HD15FHwLHpFAWOR0+GrDnNzR74RvI4ipGm0qQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@web/parse5-utils" "^1.3.0"
|
"@web/parse5-utils" "^1.3.0"
|
||||||
glob "^7.1.6"
|
glob "^7.1.6"
|
||||||
|
|||||||
Reference in New Issue
Block a user