mirror of
https://github.com/modernweb-dev/rocket.git
synced 2026-03-21 15:54:57 +00:00
Compare commits
144 Commits
@mdjs/core
...
@rocket/cl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c009801164 | ||
|
|
60310ab3dd | ||
|
|
db03f69210 | ||
|
|
e6c3d274cf | ||
|
|
f9014c15a6 | ||
|
|
7e277cd88f | ||
|
|
bc6106381c | ||
|
|
00bf3882f6 | ||
|
|
543e297c5b | ||
|
|
70b0ce8e1c | ||
|
|
9f8785a885 | ||
|
|
62637a829e | ||
|
|
81c4d7bf3c | ||
|
|
08181194e2 | ||
|
|
97cb38ccb8 | ||
|
|
26d3de1444 | ||
|
|
1f141058c1 | ||
|
|
08574c9b31 | ||
|
|
e81b77f236 | ||
|
|
456b8e78f0 | ||
|
|
0d7ea015af | ||
|
|
445b02872f | ||
|
|
1a599db3ed | ||
|
|
6b6bed5391 | ||
|
|
30eb822151 | ||
|
|
15a82c0e4d | ||
|
|
0197bee621 | ||
|
|
5c6b9c91eb | ||
|
|
6221e5f9ea | ||
|
|
06741ed729 | ||
|
|
23c164c822 | ||
|
|
c2a76c3f53 | ||
|
|
70bb7a128e | ||
|
|
3c342473d7 | ||
|
|
9e0579ab19 | ||
|
|
de202da0a5 | ||
|
|
509a8d9115 | ||
|
|
42418f2c00 | ||
|
|
cadd8588b0 | ||
|
|
aabe011427 | ||
|
|
e1089c5701 | ||
|
|
9f10386eb2 | ||
|
|
0987a41620 | ||
|
|
7301a0f354 | ||
|
|
5ac6aa6693 | ||
|
|
9f1633cccc | ||
|
|
00f4a91550 | ||
|
|
eb62dd9fd5 | ||
|
|
bb07267289 | ||
|
|
738941afdd | ||
|
|
ef086c7aa3 | ||
|
|
3d22fbb72e | ||
|
|
adf0f1d88f | ||
|
|
4145031162 | ||
|
|
ac58953527 | ||
|
|
7dc3e0f9b0 | ||
|
|
305a657ff5 | ||
|
|
8585e2ad66 | ||
|
|
4585675b00 | ||
|
|
39f4fa7050 | ||
|
|
ccdd4d077e | ||
|
|
a5661b85c2 | ||
|
|
99b12c7c9e | ||
|
|
61bb700c3e | ||
|
|
aa93c2ad89 | ||
|
|
8e9c0a3106 | ||
|
|
1c68a95c3c | ||
|
|
c1876da2ff | ||
|
|
3dde0ab096 | ||
|
|
09caa4bcef | ||
|
|
ddc89e05bb | ||
|
|
7e70d8a327 | ||
|
|
fc8b3a2944 | ||
|
|
ee20047305 | ||
|
|
48dcdd7d6d | ||
|
|
03e15051be | ||
|
|
312d5bec81 | ||
|
|
e31e8be75b | ||
|
|
9978ea7eda | ||
|
|
d91e46b867 | ||
|
|
174217180b | ||
|
|
f6aa1872c2 | ||
|
|
f5a6cbfb97 | ||
|
|
989758ce03 | ||
|
|
fbcedde7a0 | ||
|
|
d72427d889 | ||
|
|
b7d5cbacf3 | ||
|
|
8d8c756607 | ||
|
|
3750c4e7a2 | ||
|
|
5c3eda35a9 | ||
|
|
6910d50bf5 | ||
|
|
a2dc8656db | ||
|
|
e778cd8a3c | ||
|
|
9e3c2f52d9 | ||
|
|
579e8e72a2 | ||
|
|
06ae8693b2 | ||
|
|
cee2b7b04c | ||
|
|
9625b94d39 | ||
|
|
1f79d7a047 | ||
|
|
bf99541951 | ||
|
|
8df9a3e9c3 | ||
|
|
1b9559f2a5 | ||
|
|
8eede4b16b | ||
|
|
2294ccf4a2 | ||
|
|
3b1a0cf26a | ||
|
|
cf442215a9 | ||
|
|
41049f3908 | ||
|
|
2b5c61d19c | ||
|
|
f5d349e256 | ||
|
|
ce0b00e7a1 | ||
|
|
83286a99de | ||
|
|
6cabdba5f6 | ||
|
|
f5f2d69d0c | ||
|
|
795a3613af | ||
|
|
bcf8f4fe83 | ||
|
|
5330740cb3 | ||
|
|
2edd61beaa | ||
|
|
2a5fc08f35 | ||
|
|
43a7ca10c3 | ||
|
|
da39fa72f3 | ||
|
|
a0e8edfbb9 | ||
|
|
50434293bb | ||
|
|
f08f92615b | ||
|
|
1949b1e1cb | ||
|
|
340bf8e653 | ||
|
|
eae200708d | ||
|
|
f707f636fa | ||
|
|
814b5d29ad | ||
|
|
e1e96acceb | ||
|
|
7543a129cf | ||
|
|
60e85a17a7 | ||
|
|
fd8f97859a | ||
|
|
56fdb0cbd4 | ||
|
|
e6d9c74510 | ||
|
|
c338696482 | ||
|
|
2ff4b4c542 | ||
|
|
ba64b45ebf | ||
|
|
e437e02cb9 | ||
|
|
ce9b12edd4 | ||
|
|
d034f799c0 | ||
|
|
8bba4a88c8 | ||
|
|
c7261aa2b0 | ||
|
|
690075d335 | ||
|
|
2724f073fc |
@@ -10,3 +10,5 @@ _site
|
|||||||
_site-dev
|
_site-dev
|
||||||
__output
|
__output
|
||||||
__output-dev
|
__output-dev
|
||||||
|
|
||||||
|
docs/_merged*
|
||||||
|
|||||||
@@ -8,25 +8,25 @@ First, create a fork of the [modernweb-dev/rocket](https://github.com/modernweb-
|
|||||||
|
|
||||||
Next, clone our repository onto your computer.
|
Next, clone our repository onto your computer.
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
git clone git@github.com:modernweb-dev/rocket.git
|
git clone git@github.com:modernweb-dev/rocket.git
|
||||||
```
|
```
|
||||||
|
|
||||||
Once cloning is complete, change directory to the repository.
|
Once cloning is complete, change directory to the repository.
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
cd rocket
|
cd rocket
|
||||||
```
|
```
|
||||||
|
|
||||||
Now add your fork as a remote (replacing YOUR_USERNAME with your GitHub username).
|
Now add your fork as a remote (replacing YOUR_USERNAME with your GitHub username).
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
git remote add fork git@github.com:<YOUR_USERNAME>/rocket.git
|
git remote add fork git@github.com:<YOUR_USERNAME>/rocket.git
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a new local branch.
|
Create a new local branch.
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
git checkout -b my-awesome-fix
|
git checkout -b my-awesome-fix
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ git checkout -b my-awesome-fix
|
|||||||
|
|
||||||
Now that you have cloned the repository, ensure you have [yarn](https://classic.yarnpkg.com/lang/en/) installed, then run the following commands to set up the development environment.
|
Now that you have cloned the repository, ensure you have [yarn](https://classic.yarnpkg.com/lang/en/) installed, then run the following commands to set up the development environment.
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
yarn install
|
yarn install
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ This documents your intent to release, and allows you to specify a message that
|
|||||||
|
|
||||||
Run
|
Run
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
yarn changeset
|
yarn changeset
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ Exceptions:
|
|||||||
Commit messages must follow the [conventional commit format](https://www.conventionalcommits.org/en/v1.0.0/)
|
Commit messages must follow the [conventional commit format](https://www.conventionalcommits.org/en/v1.0.0/)
|
||||||
Modern-web uses package name as scope. So for example if you fix a _terrible bug_ in the package `@web/test-runner`, the commit message should look like this:
|
Modern-web uses package name as scope. So for example if you fix a _terrible bug_ in the package `@web/test-runner`, the commit message should look like this:
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
fix(test-runner): fix terrible bug
|
fix(test-runner): fix terrible bug
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ fix(test-runner): fix terrible bug
|
|||||||
|
|
||||||
Now it's time to push your branch that contains your committed changes to your fork.
|
Now it's time to push your branch that contains your committed changes to your fork.
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
git push -u fork my-awesome-fix
|
git push -u fork my-awesome-fix
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,11 @@
|
|||||||
src="https://img.shields.io/badge/twitter-@modern_web_dev-1DA1F3?style=flat-square"
|
src="https://img.shields.io/badge/twitter-@modern_web_dev-1DA1F3?style=flat-square"
|
||||||
alt="Follow @modern_web_dev on Twitter"
|
alt="Follow @modern_web_dev on Twitter"
|
||||||
/></a>
|
/></a>
|
||||||
|
<a href="https://open.vscode.dev/modernweb-dev/rocket"
|
||||||
|
><img
|
||||||
|
src="https://open.vscode.dev/badges/open-in-vscode.svg"
|
||||||
|
alt="Open in VS Code"
|
||||||
|
/></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
|||||||
1
docs/.eleventyignore
Normal file
1
docs/.eleventyignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.docs.md
|
||||||
1
docs/_assets/_static/logos/npm.svg
Normal file
1
docs/_assets/_static/logos/npm.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg id="n" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#c12127;}.cls-2{fill:#fff;}</style></defs><title>n</title><path class="cls-1" d="M0,16V0H16V16ZM3,3V13H8V5h3v8h2V3Z"/><path class="cls-2" d="M3,3H13V13H11V5H8v8H3Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 287 B |
3
docs/_assets/_static/logos/pnpm.svg
Normal file
3
docs/_assets/_static/logos/pnpm.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="76.58987244897958 44 164.00775510204068 164" width="160.01" height="160"><defs><path d="M237.6 95L187.6 95L187.6 45L237.6 45L237.6 95Z" id="arNRoK435"></path><path d="M182.59 95L132.59 95L132.59 45L182.59 45L182.59 95Z" id="a3H2WU7Px"></path><path d="M127.59 95L77.59 95L77.59 45L127.59 45L127.59 95Z" id="b1DInM56vl"></path><path d="M237.6 150L187.6 150L187.6 100L237.6 100L237.6 150Z" id="a7LFlgQIwu"></path><path d="M182.59 150L132.59 150L132.59 100L182.59 100L182.59 150Z" id="amwLiZcuo"></path><path d="M182.59 205L132.59 205L132.59 155L182.59 155L182.59 205Z" id="f3Peu5RWan"></path><path d="M237.6 205L187.6 205L187.6 155L237.6 155L237.6 205Z" id="a6DXBfqPa"></path><path d="M127.59 205L77.59 205L77.59 155L127.59 155L127.59 205Z" id="c1GWSTH1z7"></path></defs><g><g><use xlink:href="#arNRoK435" opacity="1" fill="#f9ad00" fill-opacity="1"></use></g><g><use xlink:href="#a3H2WU7Px" opacity="1" fill="#f9ad00" fill-opacity="1"></use></g><g><use xlink:href="#b1DInM56vl" opacity="1" fill="#f9ad00" fill-opacity="1"></use></g><g><use xlink:href="#a7LFlgQIwu" opacity="1" fill="#f9ad00" fill-opacity="1"></use></g><g><use xlink:href="#amwLiZcuo" opacity="1" fill="#4e4e4e" fill-opacity="1"></use></g><g><use xlink:href="#f3Peu5RWan" opacity="1" fill="#4e4e4e" fill-opacity="1"></use></g><g><use xlink:href="#a6DXBfqPa" opacity="1" fill="#4e4e4e" fill-opacity="1"></use></g><g><use xlink:href="#c1GWSTH1z7" opacity="1" fill="#4e4e4e" fill-opacity="1"></use></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
1
docs/_assets/_static/logos/yarn.svg
Normal file
1
docs/_assets/_static/logos/yarn.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 518 518"><style>.st0{fill:#2c8ebb}.st1{fill:#fff}</style><path class="st0" d="M259 0c143 0 259 116 259 259S402 518 259 518 0 402 0 259 116 0 259 0z"/><path class="st1" d="M435.2 337.5c-1.8-14.2-13.8-24-29.2-23.8-23 .3-42.3 12.2-55.1 20.1-5 3.1-9.3 5.4-13 7.1.8-11.6.1-26.8-5.9-43.5-7.3-20-17.1-32.3-24.1-39.4 8.1-11.8 19.2-29 24.4-55.6 4.5-22.7 3.1-58-7.2-77.8-2.1-4-5.6-6.9-10-8.1-1.8-.5-5.2-1.5-11.9.4C293.1 96 289.6 93.8 286.9 92c-5.6-3.6-12.2-4.4-18.4-2.1-8.3 3-15.4 11-22.1 25.2-1 2.1-1.9 4.1-2.7 6.1-12.7.9-32.7 5.5-49.6 23.8-2.1 2.3-6.2 4-10.5 5.6h.1c-8.8 3.1-12.8 10.3-17.7 23.3-6.8 18.2.2 36.1 7.1 47.7-9.4 8.4-21.9 21.8-28.5 37.5-8.2 19.4-9.1 38.4-8.8 48.7-7 7.4-17.8 21.3-19 36.9-1.6 21.8 6.3 36.6 9.8 42 1 1.6 2.1 2.9 3.3 4.2-.4 2.7-.5 5.6.1 8.6 1.3 7 5.7 12.7 12.4 16.3 13.2 7 31.6 10 45.8 2.9 5.1 5.4 14.4 10.6 31.3 10.6h1c4.3 0 58.9-2.9 74.8-6.8 7.1-1.7 12-4.7 15.2-7.4 10.2-3.2 38.4-12.8 65-30 18.8-12.2 25.3-14.8 39.3-18.2 13.6-3.3 22.1-15.7 20.4-29.4zm-23.8 14.7c-16 3.8-24.1 7.3-43.9 20.2-30.9 20-64.7 29.3-64.7 29.3s-2.8 4.2-10.9 6.1c-14 3.4-66.7 6.3-71.5 6.4-12.9.1-20.8-3.3-23-8.6-6.7-16 9.6-23 9.6-23s-3.6-2.2-5.7-4.2c-1.9-1.9-3.9-5.7-4.5-4.3-2.5 6.1-3.8 21-10.5 27.7-9.2 9.3-26.6 6.2-36.9.8-11.3-6 .8-20.1.8-20.1s-6.1 3.6-11-3.8c-4.4-6.8-8.5-18.4-7.4-32.7 1.2-16.3 19.4-32.1 19.4-32.1s-3.2-24.1 7.3-48.8c9.5-22.5 35.1-40.6 35.1-40.6s-21.5-23.8-13.5-45.2c5.2-14 7.3-13.9 9-14.5 6-2.3 11.8-4.8 16.1-9.5 21.5-23.2 48.9-18.8 48.9-18.8s13-39.5 25-31.8c3.7 2.4 17 32 17 32s14.2-8.3 15.8-5.2c8.6 16.7 9.6 48.6 5.8 68-6.4 32-22.4 49.2-28.8 60-1.5 2.5 17.2 10.4 29 43.1 10.9 29.9 1.2 55 2.9 57.8.3.5.4.7.4.7s12.5 1 37.6-14.5c13.4-8.3 29.3-17.6 47.4-17.8 17.5-.3 18.4 20.2 5.2 23.4z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -1,3 +1,41 @@
|
|||||||
|
:not(rocket-navigation):not(:defined) {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rocket-navigation,
|
||||||
|
header {
|
||||||
|
font-family: 'Montserrat', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
code-tabs[collection="package-managers"] {
|
||||||
|
--code-tabs-icon-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call-to-action {
|
||||||
|
background: var(--button-one) !important;
|
||||||
|
text-shadow: none !important;
|
||||||
|
border-radius: 5px !important;
|
||||||
|
padding-top: 15px !important;
|
||||||
|
padding-bottom: 15px !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call-to-action:hover,
|
||||||
|
.call-to-action:focus,
|
||||||
|
.call-to-action:active {
|
||||||
|
background: var(--button-one-hover) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call-to-action:nth-child(2) {
|
||||||
|
background: var(--button-two) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call-to-action:nth-child(2):hover,
|
||||||
|
.call-to-action:nth-child(2):focus,
|
||||||
|
.call-to-action:nth-child(2):active {
|
||||||
|
background: var(--button-two-hover) !important;
|
||||||
|
}
|
||||||
|
|
||||||
body[layout^='layout-home'] .markdown-body .call-to-action:nth-of-type(2) {
|
body[layout^='layout-home'] .markdown-body .call-to-action:nth-of-type(2) {
|
||||||
--primary-color: #222;
|
--primary-color: #222;
|
||||||
--primary-color-lighter: #333;
|
--primary-color-lighter: #333;
|
||||||
@@ -11,11 +49,3 @@ body[layout^='layout-home'] .markdown-body .call-to-action:nth-of-type(2) {
|
|||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rocket-navigation {
|
|
||||||
font-family: 'Montserrat', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
font-family: 'Montserrat', sans-serif;
|
|
||||||
}
|
|
||||||
|
|||||||
141
docs/_assets/theme.css
Normal file
141
docs/_assets/theme.css
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
html {
|
||||||
|
--button-one-hover: #436eff;
|
||||||
|
--button-one: #2758ff;
|
||||||
|
--button-two-hover: #444;
|
||||||
|
--button-two: black;
|
||||||
|
--contrast-color-dark: #1d3557;
|
||||||
|
--contrast-color-light: #fff;
|
||||||
|
--footer-background: rgba(0, 0, 0, 0.02);
|
||||||
|
--header-color: white;
|
||||||
|
--markdown-link-color: #2758ff;
|
||||||
|
--markdown-syntax-background-color: #f9f9f9;
|
||||||
|
--markdown-table-row-odd-background-color: #efefef;
|
||||||
|
--owc-active-color: #2758ff;
|
||||||
|
--owc-hover-color: #436eff;
|
||||||
|
--page-background: white;
|
||||||
|
--primary-color-accent: #cee5f6;
|
||||||
|
--primary-color-darker: #1a5285;
|
||||||
|
--primary-color-lighter: #449ad7;
|
||||||
|
--primary-color: rgb(44, 62, 80);
|
||||||
|
--primary-lines-color: #ccc;
|
||||||
|
--primary-text-color: #2c3e50;
|
||||||
|
--primary-text-inverse-color: #eee;
|
||||||
|
--switch-unselected-color: #808080;
|
||||||
|
--switch-selected-color: #42b983;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
html {
|
||||||
|
--header-color: #2f3136;
|
||||||
|
--footer-background: rgba(255, 255, 255, 0.1);
|
||||||
|
--page-background: #36393e;
|
||||||
|
--text-color: #eee;
|
||||||
|
--primary-text-color: #eee;
|
||||||
|
--primary-color: white;
|
||||||
|
--primary-color-lighter: #449ad7;
|
||||||
|
--primary-color-darker: #1a5285;
|
||||||
|
--primary-color-accent: #cee5f6;
|
||||||
|
--contrast-color-light: #fff;
|
||||||
|
--contrast-color-dark: #1d3557;
|
||||||
|
--primary-lines-color: #333;
|
||||||
|
--owc-active-color: #41ffb0;
|
||||||
|
--owc-hover-color: #6dffc2;
|
||||||
|
--button-one: #9b03fe;
|
||||||
|
--button-one-hover: #a724ff;
|
||||||
|
--button-two: black;
|
||||||
|
--button-two-hover: rgb(36, 36, 36);
|
||||||
|
--rocket-search-background-color: #4a4d52;
|
||||||
|
--rocket-search-highlight-color: #41ffb0;
|
||||||
|
--rocket-search-hover-background-color: #6b717a;
|
||||||
|
--rocket-search-fill-color: #fff;
|
||||||
|
--primary-text-inverse-color: #2c3e50;
|
||||||
|
--switch-unselected-color: #808080;
|
||||||
|
--switch-selected-color: #42b983;
|
||||||
|
|
||||||
|
/* Markdown */
|
||||||
|
--markdown-octicon-link: var(--primary-text-color);
|
||||||
|
--markdown-link-color: #41ffb0;
|
||||||
|
--markdown-divider-color: #e1e4e8;
|
||||||
|
--markdown-blockquote-border-color: #dfe2e5;
|
||||||
|
--markdown-blockquote-color: #90aac7;
|
||||||
|
--markdown-kbd-background-color: #fafbfc;
|
||||||
|
--markdown-kbd-border-color: #c6cbd1;
|
||||||
|
--markdown-kbd-border-bottom-color: #959da5;
|
||||||
|
--markdown-kbd-color: #444d56;
|
||||||
|
--markdown-heading-color-6: #6a737d;
|
||||||
|
--markdown-table-background-color: var(--markdown-syntax-background-color);
|
||||||
|
--markdown-table-row-odd-background-color: var(--markdown-kbd-color);
|
||||||
|
--markdown-table-border-color: transparent;
|
||||||
|
--markdown-code-background-color: rgba(27, 31, 35, 0.05);
|
||||||
|
--markdown-pre-background-color: rgb(49, 49, 49);
|
||||||
|
|
||||||
|
/* syntax */
|
||||||
|
--markdown-syntax-color: #f8f8f2;
|
||||||
|
--markdown-syntax-background-color: #2e3440;
|
||||||
|
--markdown-syntax-atrule-color: #88c0d0;
|
||||||
|
--markdown-syntax-attr-name-color: #a3be8c;
|
||||||
|
--markdown-syntax-attr-value-color: #88c0d0;
|
||||||
|
--markdown-syntax-builtin-color: #a3be8c;
|
||||||
|
--markdown-syntax-boolean-color: #81a1c1;
|
||||||
|
--markdown-syntax-class-name-color: #88c0d0;
|
||||||
|
--markdown-syntax-constant-color: #81a1c1;
|
||||||
|
--markdown-syntax-char-color: #a3be8c;
|
||||||
|
--markdown-syntax-deleted-color: #81a1c1;
|
||||||
|
--markdown-syntax-entity-color: #81a1c1;
|
||||||
|
--markdown-syntax-function-color: #88c0d0;
|
||||||
|
--markdown-syntax-inserted-color: #a3be8c;
|
||||||
|
--markdown-syntax-keyword-color: #81a1c1;
|
||||||
|
--markdown-syntax-number-color: #b48ead;
|
||||||
|
--markdown-syntax-operator-color: #81a1c1;
|
||||||
|
--markdown-syntax-property-color: #81a1c1;
|
||||||
|
--markdown-syntax-punctuation-color: #81a1c1;
|
||||||
|
--markdown-syntax-regex-color: #81a1c1;
|
||||||
|
--markdown-syntax-important-color: #81a1c1;
|
||||||
|
--markdown-syntax-selector-color: #a3be8c;
|
||||||
|
--markdown-syntax-symbol-color: #81a1c1;
|
||||||
|
--markdown-syntax-string-color: #a3be8c;
|
||||||
|
--markdown-syntax-tag-color: #81a1c1;
|
||||||
|
--markdown-syntax-url-color: #81a1c1;
|
||||||
|
--markdown-syntax-variable-color: #81a1c1;
|
||||||
|
--markdown-syntax-hotkey-selector-color: #d73a49;
|
||||||
|
--markdown-syntax-keyword-color: #22863a;
|
||||||
|
--markdown-syntax-background-color: rgb(27, 29, 35);
|
||||||
|
--markdown-syntax-atrule-color: rgb(198, 120, 221);
|
||||||
|
--markdown-syntax-attr-name-color: rgb(198, 120, 221);
|
||||||
|
--markdown-syntax-boolean-color: rgb(209, 154, 102);
|
||||||
|
--markdown-syntax-class-name-color: rgb(97, 175, 239);
|
||||||
|
--markdown-syntax-constant-color: rgb(220, 220, 170);
|
||||||
|
--markdown-syntax-entity-color: rgb(220, 220, 170);
|
||||||
|
--markdown-syntax-function-color: rgb(97, 175, 239);
|
||||||
|
--markdown-syntax-inserted-color: rgb(220, 220, 170);
|
||||||
|
--markdown-syntax-keyword-color: rgb(198, 120, 221);
|
||||||
|
--markdown-syntax-number-color: rgb(220, 220, 170);
|
||||||
|
--markdown-syntax-operator-color: rgb(220, 220, 170);
|
||||||
|
--markdown-syntax-property-color: rgb(220, 220, 170);
|
||||||
|
--markdown-syntax-punctuation-color: white;
|
||||||
|
--markdown-syntax-regex-color: rgb(209, 154, 102);
|
||||||
|
--markdown-syntax-selector-color: rgb(86, 156, 214);
|
||||||
|
--markdown-syntax-symbol-color: rgb(220, 220, 170);
|
||||||
|
--markdown-syntax-tag-color: rgb(86, 156, 214);
|
||||||
|
--markdown-syntax-url-color: rgb(220, 220, 170);
|
||||||
|
--markdown-syntax-variable-color: rgb(220, 220, 170);
|
||||||
|
}
|
||||||
|
|
||||||
|
.string {
|
||||||
|
color: rgb(152, 195, 121);
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment {
|
||||||
|
color: #7d7d7d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.language-css {
|
||||||
|
--markdown-syntax-string-color: #81a1c1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body[layout='home'] .markdown-body .call-to-action:nth-of-type(2) {
|
||||||
|
--primary-color: #222;
|
||||||
|
--primary-color-lighter: #333;
|
||||||
|
--primary-color-darker: #000;
|
||||||
|
}
|
||||||
@@ -9,6 +9,11 @@ module.exports = async function () {
|
|||||||
name: 'GitHub',
|
name: 'GitHub',
|
||||||
url: 'https://github.com/modernweb-dev/rocket',
|
url: 'https://github.com/modernweb-dev/rocket',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Slack',
|
||||||
|
url:
|
||||||
|
'https://join.slack.com/t/lit-and-friends/shared_invite/zt-llwznvsy-LZwT13R66gOgnrg12PUGqw',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
gitSiteUrl: 'https://github.com/modernweb-dev/rocket',
|
gitSiteUrl: 'https://github.com/modernweb-dev/rocket',
|
||||||
gitBranch: 'main',
|
gitBranch: 'main',
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<link rel="stylesheet" href="{{ '/_assets/theme.css' | asset | url }}">
|
||||||
@@ -1,11 +1,3 @@
|
|||||||
<link
|
|
||||||
href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&display=swap"
|
|
||||||
rel="stylesheet"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap"
|
|
||||||
rel="stylesheet"
|
|
||||||
/>
|
|
||||||
<meta name="twitter:creator" content="@modern_web_dev" />
|
<meta name="twitter:creator" content="@modern_web_dev" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{ '/_assets/body.css' | asset | url }}" mdjs-use>
|
<link rel="stylesheet" href="{{ '/_assets/body.css' | asset | url }}" mdjs-use>
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ The features so far are:
|
|||||||
|
|
||||||
It checks your final HTML output so you need to execute it after your Static Site Generator.
|
It checks your final HTML output so you need to execute it after your Static Site Generator.
|
||||||
|
|
||||||
```
|
```shell
|
||||||
npx check-html-links _site
|
npx check-html-links _site
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Configuration >> Computed Config ||20
|
# Configuration >> Computed Config || 20
|
||||||
|
|
||||||
If you want to add data that depends on other data then you can do it via [Eleventy's computed data](https://www.11ty.dev/docs/data-computed/).
|
If you want to add data that depends on other data then you can do it via [Eleventy's computed data](https://www.11ty.dev/docs/data-computed/).
|
||||||
|
|
||||||
@@ -8,25 +8,23 @@ Rocket exposes it via `setupEleventyComputedConfig`.
|
|||||||
|
|
||||||
Let's say you want to add a `Welcome to the contact page` everywhere. (A filter might be a better choice, but it's a good example of the concept.)
|
Let's say you want to add a `Welcome to the contact page` everywhere. (A filter might be a better choice, but it's a good example of the concept.)
|
||||||
|
|
||||||
👉 `rocket.config.mjs` (or your theme config file)
|
👉 `rocket.config.js` (or your theme config file)
|
||||||
|
|
||||||
```js
|
<!-- prettier-ignore-start -->
|
||||||
|
```js copy
|
||||||
import { addPlugin } from 'plugins-manager';
|
import { addPlugin } from 'plugins-manager';
|
||||||
|
|
||||||
/** @type {Partial<import("../../../types/main").RocketCliOptions>} */
|
/** @type {import('@rocket/cli').RocketCliOptions} */
|
||||||
const config = {
|
export default ({
|
||||||
setupEleventyComputedConfig: [
|
setupEleventyComputedConfig: [
|
||||||
addPlugin({ name: 'greeting', plugin: data => `Welcome to the ${data.title} page.` }),
|
addPlugin({ name: 'greeting', plugin: data => `Welcome to the ${data.title} page.` }),
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
export default config;
|
|
||||||
```
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
{% raw %}
|
Now you can use {% raw %}{{ greeting }}{% endraw %} everywhere,
|
||||||
Now you can use {{ greeting }} everywhere.
|
and it will be correctly replaced with a Welcome and the page title.
|
||||||
{% endraw %}
|
|
||||||
And it will be correctly replaced with a Welcome and the page title.
|
|
||||||
|
|
||||||
## Default Available Configs
|
## Default Available Configs
|
||||||
|
|
||||||
|
|||||||
314
docs/docs/configuration/images.md
Normal file
314
docs/docs/configuration/images.md
Normal file
@@ -0,0 +1,314 @@
|
|||||||
|
# Configuration >> Images ||40
|
||||||
|
|
||||||
|
Rocket does handle content images automatically by
|
||||||
|
|
||||||
|
- producing multiple sizes so users download images that are meant for their resolution
|
||||||
|
- outputting multiple formats so the device can choose the best image format it supports
|
||||||
|
|
||||||
|
And the best thing about is you don't need to do anything.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
If you are using markdown images you are good to go.
|
||||||
|
|
||||||
|
```md
|
||||||
|

|
||||||
|
```
|
||||||
|
|
||||||
|
will result in
|
||||||
|
|
||||||
|
```html
|
||||||
|
<picture>
|
||||||
|
<source
|
||||||
|
type="image/avif"
|
||||||
|
srcset="/images/5f03d82-300.avif 300w, /images/5f03d82-820.avif 820w"
|
||||||
|
sizes="(min-width: 1024px) 820px, calc(100vw - 20px)"
|
||||||
|
/>
|
||||||
|
<source
|
||||||
|
type="image/jpeg"
|
||||||
|
srcset="/images/5f03d82-300.jpeg 300w, /images/5f03d82-820.jpeg 820w"
|
||||||
|
sizes="(min-width: 1024px) 820px, calc(100vw - 20px)"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt="My Image"
|
||||||
|
rocket-image="responsive"
|
||||||
|
src="/images/5f03d82-300.jpeg"
|
||||||
|
width="300"
|
||||||
|
height="158"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
</picture>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Benefits
|
||||||
|
|
||||||
|
The main benefit is that we can serve the correct size and optimal image format depending on the browser capabilities leading to optimal loading times on different systems.
|
||||||
|
|
||||||
|
- Smaller images for smaller screens
|
||||||
|
|
||||||
|
When providing `srcset` and `sizes` the browser can decide which image makes the most sense to download.
|
||||||
|
This will lead to much faster websites especially on mobile where smaller images can be served.
|
||||||
|
If you wanna know more check out [The anatomy of responsive images](https://jakearchibald.com/2015/anatomy-of-responsive-images/).
|
||||||
|
|
||||||
|
- Serve the best/smallest image format the browser understands
|
||||||
|
|
||||||
|
There are currently ~3 formats you may want to consider `avif`, `webp` and `jpg`. The improvements are huge [webp is ~30% and avif ~50%](https://www.ctrl.blog/entry/webp-avif-comparison.html) smaller then the original jpg.
|
||||||
|
|
||||||
|
## Adding a caption
|
||||||
|
|
||||||
|
If you want to describe your image in more detail you can add a caption
|
||||||
|
|
||||||
|
```md
|
||||||
|

|
||||||
|
```
|
||||||
|
|
||||||
|
will result in
|
||||||
|
|
||||||
|
```html
|
||||||
|
<figure>
|
||||||
|
<picture>
|
||||||
|
<!-- picture code the same as above -->
|
||||||
|
</picture>
|
||||||
|
<figcaption>My caption text</figcaption>
|
||||||
|
</figure>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adjusting options
|
||||||
|
|
||||||
|
Under the hood it is using [11ty/image](https://www.11ty.dev/docs/plugins/image/) and all it's options are available.
|
||||||
|
|
||||||
|
<inline-notification type="tip">
|
||||||
|
|
||||||
|
If you are using a layout preset like `@rocket/launch` then you probably don't want to touch/change these options as the preset will set it for you accordion to its layout needs.
|
||||||
|
|
||||||
|
The default preset for regular markdown content is available as `responsive`.
|
||||||
|
|
||||||
|
</inline-notification>
|
||||||
|
|
||||||
|
👉 `rocket.config.js`
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
|
imagePresets: {
|
||||||
|
responsive: {
|
||||||
|
widths: [300, 820],
|
||||||
|
formats: ['avif', 'jpeg'],
|
||||||
|
sizes: '(min-width: 1024px) 820px, calc(100vw - 20px)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
## Ignoring Images
|
||||||
|
|
||||||
|
Files ending in `.svg` or that include `rocket-ignore.` will remain untouched.
|
||||||
|
|
||||||
|
For example
|
||||||
|
|
||||||
|
```md
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
```
|
||||||
|
|
||||||
|
becomes
|
||||||
|
|
||||||
|
```html
|
||||||
|
<img src="logo.svg" alt="Logo stays svg" rocket-image="responsive" />
|
||||||
|
<img src="my-image.rocket-unresponsive.jpg" alt="Ignore by file name" rocket-image="responsive" />
|
||||||
|
<picture>[...] </picture>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adjusting ignore function
|
||||||
|
|
||||||
|
The default ignore function looks like this
|
||||||
|
|
||||||
|
```js
|
||||||
|
/**
|
||||||
|
* The default responsive ignore function will ignore files
|
||||||
|
* - ending in `.svg`
|
||||||
|
* - containing `rocket-unresponsive.`
|
||||||
|
*
|
||||||
|
* @param {object} opts
|
||||||
|
* @param {string} opts.src
|
||||||
|
* @param {string} opts.title
|
||||||
|
* @param {string} opts.alt
|
||||||
|
* @param {{name: string, value: string}[]} opts.attributes
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function ignore({ src }) {
|
||||||
|
return src.endsWith('svg') || src.includes('rocket-unresponsive.');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
and you can adjust it by setting it via the `imagePreset`.
|
||||||
|
|
||||||
|
For this example we want to also ignore `.jpeg` files.
|
||||||
|
|
||||||
|
👉 `rocket.config.js`
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
|
imagePresets: {
|
||||||
|
responsive: {
|
||||||
|
// ...
|
||||||
|
ignore: ({ src }) =>
|
||||||
|
src.endsWith('.jpeg') || src.endsWith('svg') || src.includes('rocket-unresponsive.'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
With that setting we get the following behavior
|
||||||
|
|
||||||
|
```md
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
```
|
||||||
|
|
||||||
|
becomes
|
||||||
|
|
||||||
|
```html
|
||||||
|
<img src="logo.svg" alt="Logo stays svg" rocket-image="responsive" />
|
||||||
|
<img src="my-image.rocket-unresponsive.jpg" alt="Ignore by file name" rocket-image="responsive" />
|
||||||
|
<img src="my-image.jpeg" alt="My Image Alternative Text" rocket-image="responsive" />
|
||||||
|
```
|
||||||
|
|
||||||
|
## Defining your own presets
|
||||||
|
|
||||||
|
You can add your own image preset like so
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
|
imagePresets: {
|
||||||
|
'my-image-preset': {
|
||||||
|
widths: [30, 60],
|
||||||
|
formats: ['avif', 'jpeg'],
|
||||||
|
sizes: '(min-width: 1024px) 30px, 60px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
Once that `imagePreset` is defined you can use it by adding it to any `img` tag.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<img src="./path/to/image.jpg" alt="my alt" rocket-image="my-image-preset" />
|
||||||
|
```
|
||||||
|
|
||||||
|
## How does it work?
|
||||||
|
|
||||||
|
1. Each markdown image `` gets rendered as `<img src="path/to/image.jpg" alt="my image" rocket-image="responsive">`
|
||||||
|
2. We parse the html output and process every image which has `rocket-image`
|
||||||
|
3. Get the image preset settings from the name e.g. `rocket-image="my-image-preset"` reads `imagePreset['my-image-preset']`
|
||||||
|
4. Pass the settings onto `@11ty/image` to generate the image sizes and formats
|
||||||
|
5. With the metadata we render the html
|
||||||
|
|
||||||
|
## Default Formats
|
||||||
|
|
||||||
|
An [image file format](https://en.wikipedia.org/wiki/Image_file_formats) is a way of storing common image formats. Each format varies in capabilities like compression algorithm, availability, progressive rendering, encode and decode time, ...
|
||||||
|
Ultimately newer formats are usually smaller while retaining image quality which leads to faster websites.
|
||||||
|
|
||||||
|
By default, we generate `avif` and `jpg` because
|
||||||
|
|
||||||
|
- we only want to generate two versions to limit CI time and html size
|
||||||
|
- `avif` is significantly smaller than `webp`
|
||||||
|
- `avif` is available in
|
||||||
|
- Chrome since August 2020
|
||||||
|
- Firefox since June 2021
|
||||||
|
- `jpg` as a fallback for Edge, Safari, IE11
|
||||||
|
- `webp` would only help a small percentage of Edge & Safari on macOS 11 (Big Sur) users
|
||||||
|
|
||||||
|
This leads to the following situation:
|
||||||
|
|
||||||
|
- Chrome, Firefox gets the small `avif`
|
||||||
|
- Edge, Safari, IE11 gets the bigger `jpg`
|
||||||
|
|
||||||
|
To learn more about `avif` take a look at [AVIF has landed](https://jakearchibald.com/2020/avif-has-landed/).
|
||||||
|
|
||||||
|
If you want to add `webp` (or replace `avif` with it) you can do so by setting the formats
|
||||||
|
|
||||||
|
👉 `rocket.config.js`
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
|
imagePresets: {
|
||||||
|
responsive: {
|
||||||
|
formats: ['avif', 'webp', 'jpeg'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
## Default widths
|
||||||
|
|
||||||
|
In order to understand the need for having a single image in multiple resolutions we need to understand the our website is served to many different environments and each may come with its own specific device pixel ratio (DPR). The device pixel ratio is the ratio between physical pixels and logical pixels. For instance, the Galaxy S20 report a device pixel ratio of 3, because the physical linear resolution is triple the logical linear resolution.
|
||||||
|
|
||||||
|
Physical resolution: 1440 x 3200
|
||||||
|
Logical resolution: 480 x 1067
|
||||||
|
|
||||||
|
And 1440 / 480 = 3.
|
||||||
|
|
||||||
|
By default, we generate the following widths `600`, `900` and `1640` because
|
||||||
|
|
||||||
|
- we only want to generate a small amount of widths to limit CI time and service worker cache size
|
||||||
|
- `600` is good for mobile with DRP 2
|
||||||
|
- `900` is good for mobile with DRP 3 and desktop with DPR of 1
|
||||||
|
- `1640` is good for desktop with DPR of 2
|
||||||
|
|
||||||
|
If you want to add more widths you can add them to `widths`.
|
||||||
|
|
||||||
|
👉 `rocket.config.js`
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
|
imagePresets: {
|
||||||
|
responsive: {
|
||||||
|
widths: [300, 600, 900, 1200, 1640],
|
||||||
|
sizes: '(min-width: 1024px) 820px, calc(100vw - 20px)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
<inline-notification type="tip">
|
||||||
|
|
||||||
|
As an end user in most cases you don't want to mess with this as a layout preset should set this for you. If you are building your own layout preset then be sure to set `widths` and `sizes` via `adjustImagePresets`
|
||||||
|
|
||||||
|
```js
|
||||||
|
export function myPreset() {
|
||||||
|
return {
|
||||||
|
adjustImagePresets: imagePresets => ({
|
||||||
|
...imagePresets,
|
||||||
|
responsive: {
|
||||||
|
...imagePresets.responsive,
|
||||||
|
widths: [600, 900, 1640],
|
||||||
|
sizes: '(min-width: 1024px) 820px, calc(100vw - 40px)',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</inline-notification>
|
||||||
|
|
||||||
|
```js script
|
||||||
|
import '@rocket/launch/inline-notification/inline-notification.js';
|
||||||
|
```
|
||||||
@@ -1,25 +1,30 @@
|
|||||||
# Configuration >> Overview ||10
|
# Configuration >> Overview || 10
|
||||||
|
|
||||||
The configuration file is `rocket.config.js` or `rocket.config.mjs`.
|
The configuration file is `rocket.config.js` or `rocket.config.mjs`.
|
||||||
|
|
||||||
The config files consist of the following parts:
|
The config files consist of the following parts:
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
```js
|
```js
|
||||||
import { rocketLaunch } from '@rocket/launch';
|
import { rocketLaunch } from '@rocket/launch';
|
||||||
|
|
||||||
export default {
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
presets: [rocketLaunch()],
|
presets: [rocketLaunch()],
|
||||||
emptyOutputDir: true,
|
emptyOutputDir: true,
|
||||||
pathPrefix: 'subfolder-only-for-build',
|
pathPrefix: 'subfolder-only-for-build',
|
||||||
};
|
});
|
||||||
```
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
Rocket is primarily build around plugins for each of its systems.
|
Rocket is primarily build around plugins for each of its systems.
|
||||||
|
|
||||||
New plugins can be added and all default plugins can be adjusted or even removed by using the following functions.
|
New plugins can be added and all default plugins can be adjusted or even removed by using the following functions.
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
```js
|
```js
|
||||||
export default {
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
// add remark/unified plugin to the Markdown processing (e.g. enable special code blocks)
|
// add remark/unified plugin to the Markdown processing (e.g. enable special code blocks)
|
||||||
setupUnifiedPlugins: [],
|
setupUnifiedPlugins: [],
|
||||||
|
|
||||||
@@ -40,8 +45,9 @@ export default {
|
|||||||
|
|
||||||
// add a plugin to the cli (e.g. a new command like "rocket my-command")
|
// add a plugin to the cli (e.g. a new command like "rocket my-command")
|
||||||
setupCliPlugins: [],
|
setupCliPlugins: [],
|
||||||
};
|
});
|
||||||
```
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
## Adding Rollup Plugins
|
## Adding Rollup Plugins
|
||||||
|
|
||||||
@@ -55,19 +61,19 @@ You can accomplish this with Rollup and dev server plugins. Make sure to add bot
|
|||||||
|
|
||||||
For these cases you can use `setupDevAndBuildPlugins`, which will automatically add the plugin for you to both Rollup and dev-server:
|
For these cases you can use `setupDevAndBuildPlugins`, which will automatically add the plugin for you to both Rollup and dev-server:
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
```js
|
```js
|
||||||
import json from '@rollup/plugin-json';
|
import json from '@rollup/plugin-json';
|
||||||
import { addPlugin } from 'plugins-manager';
|
import { addPlugin } from 'plugins-manager';
|
||||||
|
|
||||||
/** @type {Partial<import("@rocket/cli").RocketCliOptions>} */
|
/** @type {import('@rocket/cli').RocketCliOptions} */
|
||||||
const config = {
|
export default ({
|
||||||
setupDevAndBuildPlugins: [
|
setupDevAndBuildPlugins: [
|
||||||
addPlugin({ name: 'json', plugin: json, location: 'top', options: { my: 'settings' } }),
|
addPlugin({ name: 'json', plugin: json, location: 'top', options: { my: 'settings' } }),
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
export default config;
|
|
||||||
```
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
This will add the Rollup plugin `json` with the id `json` at the top of the plugin list of Rollup and the dev server. It needs to be at the top so further plugins down the line can work with JSON imports.
|
This will add the Rollup plugin `json` with the id `json` at the top of the plugin list of Rollup and the dev server. It needs to be at the top so further plugins down the line can work with JSON imports.
|
||||||
For the Dev Server the plugins are automatically wrapped by `@web/dev-server-rollup`. Note that [not all Rollup plugins](https://modern-web.dev/docs/dev-server/plugins/rollup/#compatibility-with-rollup-plugins) will work with the dev-server.
|
For the Dev Server the plugins are automatically wrapped by `@web/dev-server-rollup`. Note that [not all Rollup plugins](https://modern-web.dev/docs/dev-server/plugins/rollup/#compatibility-with-rollup-plugins) will work with the dev-server.
|
||||||
@@ -76,13 +82,85 @@ For the Dev Server the plugins are automatically wrapped by `@web/dev-server-rol
|
|||||||
|
|
||||||
All plugins which are either default or are added via a preset can still be adjusted by using `adjustPluginOptions`.
|
All plugins which are either default or are added via a preset can still be adjusted by using `adjustPluginOptions`.
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
```js
|
```js
|
||||||
import { adjustPluginOptions } from 'plugins-manager';
|
import { adjustPluginOptions } from 'plugins-manager';
|
||||||
|
|
||||||
/** @type {Partial<import("@rocket/cli").RocketCliOptions>} */
|
/** @type {import('@rocket/cli').RocketCliOptions} */
|
||||||
const config = {
|
export default ({
|
||||||
setupDevAndBuildPlugins: [adjustPluginOptions('json', { my: 'overwrite settings' })],
|
setupDevAndBuildPlugins: [adjustPluginOptions('json', { my: 'overwrite settings' })],
|
||||||
};
|
});
|
||||||
|
|
||||||
export default config;
|
|
||||||
```
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
## Lifecycle
|
||||||
|
|
||||||
|
You can hook into the rocket lifecycle by specifying a function for `before11ty`. This function runs before 11ty calls it's write method. If it is an async function, Rocket will await it's promise.
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
|
async before11ty() {
|
||||||
|
await copyDataFiles();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
## Advanced
|
||||||
|
|
||||||
|
Sometimes you need even more control over specific settings.
|
||||||
|
|
||||||
|
### Rollup
|
||||||
|
|
||||||
|
For example if you wanna add an `acron` plugin to rollup
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
import { importAssertions } from 'acorn-import-assertions';
|
||||||
|
|
||||||
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
|
rollup: config => ({
|
||||||
|
...config,
|
||||||
|
acornInjectPlugins: [importAssertions],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
### Eleventy
|
||||||
|
|
||||||
|
For example to add custom filter you can access the eleventy config directly
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
|
eleventy: eleventyConfig => {
|
||||||
|
eleventyConfig.addFilter('value', value => `prefix${value}`);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
You even have access to the full rocketConfig if you for example want to create filters that behave differently during start/build.
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
|
eleventy: (config, rocketConfig) => {
|
||||||
|
config.addFilter('conditional-resolve', value => {
|
||||||
|
if (rocketConfig.command === 'build') {
|
||||||
|
return `build:${value}`;
|
||||||
|
}
|
||||||
|
if (rocketConfig.command === 'start') {
|
||||||
|
return `start:${value}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|||||||
48
docs/docs/configuration/service-worker.md
Normal file
48
docs/docs/configuration/service-worker.md
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# Configuration >> Service Worker ||30
|
||||||
|
|
||||||
|
Rocket does come with a default service worker that will
|
||||||
|
|
||||||
|
- cache already visited pages
|
||||||
|
- cache assets of visited pages (up to 100 files then it replaces older entries)
|
||||||
|
- reload the page if a newer html page version is available on service worker activation
|
||||||
|
|
||||||
|
## Adjusting the file name
|
||||||
|
|
||||||
|
Changing the service worker file name can be quite a hassle so you can adjust generate file name via a config.
|
||||||
|
|
||||||
|
👉 `rocket.config.js`
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
|
serviceWorkerName: 'my-service-worker-name.js',
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
## Meet the Service Worker
|
||||||
|
|
||||||
|
The default service worker will work for many scenarios however your needs my vary.
|
||||||
|
To enable different service worker strategies you can replace the default service worker code by providing a file at `_assets/service-worker.js`.
|
||||||
|
This file will be auto transformed and generated in the root of the website using the defined `serviceWorkerName`.
|
||||||
|
|
||||||
|
For inspiration, you can take a look at the default config.
|
||||||
|
|
||||||
|
[https://github.com/modernweb-dev/rocket/blob/main/packages/cli/preset/\_assets/service-worker.js](https://github.com/modernweb-dev/rocket/blob/main/packages/cli/preset/_assets/service-worker.js)
|
||||||
|
|
||||||
|
Be sure to check out [workbox](https://developers.google.com/web/tools/workbox) for more service worker magic.
|
||||||
|
|
||||||
|
And if you wanna have a 30 minutes crash course we highly recommend the talk [Service Workers For The Rest Of Us](https://vimeo.com/362260166) by [Philip Walton](https://twitter.com/philwalton).
|
||||||
|
|
||||||
|
## Registration
|
||||||
|
|
||||||
|
The registration happens via another file that you can also overwrite at `_assets/scripts/registerServiceWorker.js`.
|
||||||
|
|
||||||
|
Below you find the default implementation.
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
{{ '/_assets/scripts/registerServiceWorker.js' | asset | toAbsPath | inlineFilePath; }}
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
@@ -4,7 +4,7 @@ Use mdjs in your Eleventy site.
|
|||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
```
|
```shell
|
||||||
npm install @rocket/eleventy-plugin-mdjs
|
npm install @rocket/eleventy-plugin-mdjs
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,25 @@ eleventyNavigation:
|
|||||||
|
|
||||||
Here you will find all the details for each of the packages/systems we offer.
|
Here you will find all the details for each of the packages/systems we offer.
|
||||||
|
|
||||||
You should check out:
|
## Contents
|
||||||
|
|
||||||
- [@rocket/launch](./presets/launch.md) which is our default preset
|
- [Configuration](./configuration/)
|
||||||
|
- [Overview](./configuration/overview/)
|
||||||
|
- [Computed Config](./configuration/computed-config/)
|
||||||
|
- [Service Worker](./configuration/service-worker/)
|
||||||
|
- [Images](./configuration/images/)
|
||||||
|
- [Presets](./presets/)
|
||||||
|
- [Joining Blocks](./presets/joining-blocks/)
|
||||||
|
- [`@rocket/launch`](./presets/launch/)
|
||||||
|
- [`@rocket/search`](./presets/search/)
|
||||||
|
- [`@rocket/blog`](./presets/blog/)
|
||||||
|
- [Markdown JavaScript](./markdown-javascript/)
|
||||||
|
- [Overview](./markdown-javascript/overview/)
|
||||||
|
- [Preview](./markdown-javascript/preview/)
|
||||||
|
- [Story](./markdown-javascript/story/)
|
||||||
|
- [Eleventy Plugins](./eleventy-plugins/)
|
||||||
|
- [Markdown JavaScript (mdjs)](./eleventy-plugins/mdjs-unified/)
|
||||||
|
- [Tools](./tools/)
|
||||||
|
- [Plugins Manager](./tools/plugins-manager/)
|
||||||
|
- [Rollup Config](./tools/rollup-config/)
|
||||||
|
- [Check HTML Links ](./tools/check-html-links/)
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# Markdown JavaScript >> Overview || 10
|
# Markdown JavaScript >> Overview || 10
|
||||||
|
|
||||||
|
```js script
|
||||||
|
import '@mdjs/mdjs-story/define';
|
||||||
|
import '@mdjs/mdjs-preview/define';
|
||||||
|
import { html } from '@mdjs/mdjs-story';
|
||||||
|
```
|
||||||
|
|
||||||
Markdown JavaScript (mdjs) is a format that allows you to use JavaScript with Markdown, to create interactive demos. It does so by "annotating" JavaScript that should be executed in Markdown.
|
Markdown JavaScript (mdjs) is a format that allows you to use JavaScript with Markdown, to create interactive demos. It does so by "annotating" JavaScript that should be executed in Markdown.
|
||||||
|
|
||||||
To annotate we use a code block with `js script`.
|
To annotate we use a code block with `js script`.
|
||||||
@@ -63,13 +69,6 @@ import '@mdjs/mdjs-preview/define';
|
|||||||
|
|
||||||
Once loaded you can use them like so:
|
Once loaded you can use them like so:
|
||||||
|
|
||||||
````md
|
|
||||||
```js script
|
|
||||||
import '@mdjs/mdjs-story/define';
|
|
||||||
import '@mdjs/mdjs-preview/define';
|
|
||||||
```
|
|
||||||
````
|
|
||||||
|
|
||||||
### Story
|
### Story
|
||||||
|
|
||||||
The code snippet will actually get executed at that place and you will have a live demo
|
The code snippet will actually get executed at that place and you will have a live demo
|
||||||
@@ -117,12 +116,6 @@ export const JsPreviewStory = () => html` <demo-wc-card>JS Preview Story</demo-w
|
|||||||
|
|
||||||
Here is a live example from [demo-wc-card](https://www.npmjs.com/package/demo-wc-card).
|
Here is a live example from [demo-wc-card](https://www.npmjs.com/package/demo-wc-card).
|
||||||
|
|
||||||
```js script
|
|
||||||
import '@mdjs/mdjs-story/define';
|
|
||||||
import '@mdjs/mdjs-preview/define';
|
|
||||||
import { html } from 'lit-html';
|
|
||||||
```
|
|
||||||
|
|
||||||
```js preview-story
|
```js preview-story
|
||||||
import 'demo-wc-card/demo-wc-card.js';
|
import 'demo-wc-card/demo-wc-card.js';
|
||||||
export const header = () => {
|
export const header = () => {
|
||||||
@@ -130,6 +123,68 @@ export const header = () => {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```js story-code
|
||||||
|
// not defined for android
|
||||||
|
```
|
||||||
|
|
||||||
|
```js story-code
|
||||||
|
// not defined for ios
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Story Code
|
||||||
|
|
||||||
|
If your preview is followed by a code blocks marked as `story-code` then those will be shown when switching between multiple platforms
|
||||||
|
|
||||||
|
````md
|
||||||
|
```js preview-story
|
||||||
|
// will be visible when platform web is selected
|
||||||
|
export const JsPreviewStory = () => html` <demo-wc-card>JS Preview Story</demo-wc-card> `;
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml story-code
|
||||||
|
<!-- will be visible when platform android is selected -->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/demoWcCard"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Android Code"
|
||||||
|
style="@style/Widget.FooComponents.Demo.Wc.Card"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift story-code
|
||||||
|
// will be visible when platform ios is selected
|
||||||
|
import DemoWc.Card
|
||||||
|
|
||||||
|
let card = DemoWcButton()
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
See it in action by opening up the code block and switching platforms
|
||||||
|
|
||||||
|
```js preview-story
|
||||||
|
// will be visible when platform web is selected
|
||||||
|
export const JsPreviewStory = () => html` <demo-wc-card>JS Preview Story</demo-wc-card> `;
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml story-code
|
||||||
|
<!-- will be visible when platform android is selected -->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/demoWcCard"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Android Code"
|
||||||
|
style="@style/Widget.FooComponents.Demo.Wc.Card"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift story-code
|
||||||
|
// will be visible when platform ios is selected
|
||||||
|
import DemoWc.Card
|
||||||
|
|
||||||
|
let card = DemoWcButton()
|
||||||
|
```
|
||||||
|
|
||||||
## Supported Systems
|
## Supported Systems
|
||||||
|
|
||||||
### Storybook
|
### Storybook
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ You can showcase live running code by annotating a code block with `js preview-s
|
|||||||
- Settings can be remembered for other pages / return visits
|
- Settings can be remembered for other pages / return visits
|
||||||
|
|
||||||
```js script
|
```js script
|
||||||
import { html } from 'lit-html';
|
import { html } from '@mdjs/mdjs-preview';
|
||||||
import './assets/demo-element.js';
|
import './assets/demo-element.js';
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ import './assets/demo-element.js';
|
|||||||
|
|
||||||
````md
|
````md
|
||||||
```js script
|
```js script
|
||||||
import { html } from 'lit-html';
|
import { html } from '@mdjs/mdjs-preview';
|
||||||
import './assets/demo-element.js';
|
import './assets/demo-element.js';
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -40,6 +40,68 @@ will result in
|
|||||||
export const foo = () => html` <demo-element></demo-element> `;
|
export const foo = () => html` <demo-element></demo-element> `;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```js story-code
|
||||||
|
// not defined for android
|
||||||
|
```
|
||||||
|
|
||||||
|
```js story-code
|
||||||
|
// not defined for ios
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Story Code
|
||||||
|
|
||||||
|
If your preview is followed by a code blocks marked as `story-code` then those will be shown when switching between multiple platforms
|
||||||
|
|
||||||
|
````md
|
||||||
|
```js preview-story
|
||||||
|
// will be visible when platform web is selected
|
||||||
|
export const JsPreviewStory = () => html` <demo-element></demo-element> `;
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml story-code
|
||||||
|
<!-- will be visible when platform android is selected -->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/demoElement"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Android Code"
|
||||||
|
style="@style/Widget.Demo.Element"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift story-code
|
||||||
|
// will be visible when platform ios is selected
|
||||||
|
import Demo.Element
|
||||||
|
|
||||||
|
let card = DemoElement()
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
See it in action by opening up the code block and switching platforms
|
||||||
|
|
||||||
|
```js preview-story
|
||||||
|
// will be visible when platform web is selected
|
||||||
|
export const JsPreviewStory = () => html` <demo-element></demo-element> `;
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml story-code
|
||||||
|
<!-- will be visible when platform android is selected -->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/demoElement"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Android Code"
|
||||||
|
style="@style/Widget.Demo.Element"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift story-code
|
||||||
|
// will be visible when platform ios is selected
|
||||||
|
import Demo.Element
|
||||||
|
|
||||||
|
let card = DemoElement()
|
||||||
|
```
|
||||||
|
|
||||||
## HTML Story
|
## HTML Story
|
||||||
|
|
||||||
````md
|
````md
|
||||||
@@ -72,15 +134,18 @@ excludeFromSearch: true
|
|||||||
|
|
||||||
Once you have that you need to configure it for the story renderer by setting it in your `rocket.config.js`.
|
Once you have that you need to configure it for the story renderer by setting it in your `rocket.config.js`.
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
```js
|
```js
|
||||||
export default {
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
setupUnifiedPlugins: [
|
setupUnifiedPlugins: [
|
||||||
adjustPluginOptions('mdjsSetupCode', {
|
adjustPluginOptions('mdjsSetupCode', {
|
||||||
simulationSettings: { simulatorUrl: '/simulator/' },
|
simulationSettings: { simulatorUrl: '/simulator/' },
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
```
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
<inline-notification type="tip">
|
<inline-notification type="tip">
|
||||||
|
|
||||||
@@ -111,7 +176,7 @@ We can simulate the following settings
|
|||||||
<html theme="dark"></html>
|
<html theme="dark"></html>
|
||||||
```
|
```
|
||||||
3. `language`
|
3. `language`
|
||||||
Best to relay on `data-lang` and `lang` often gets changes by translations services which may interfere with you translation loading system.
|
Best to relay on `data-lang` as `lang` often gets changes by translations services which may interfere with your translation loading system.
|
||||||
```html
|
```html
|
||||||
<html lang="en-US" data-lang="en-US"></html>
|
<html lang="en-US" data-lang="en-US"></html>
|
||||||
<html lang="de-DE" data-lang="de-DE"></html>
|
<html lang="de-DE" data-lang="de-DE"></html>
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
You can showcase live running code by annotating a code block with `js story`.
|
You can showcase live running code by annotating a code block with `js story`.
|
||||||
|
|
||||||
```js script
|
```js script
|
||||||
import { html } from 'lit-html';
|
import { html } from '@mdjs/mdjs-story';
|
||||||
```
|
```
|
||||||
|
|
||||||
````md
|
````md
|
||||||
```js script
|
```js script
|
||||||
import { html } from 'lit-html';
|
import { html } from '@mdjs/mdjs-story';
|
||||||
```
|
```
|
||||||
|
|
||||||
```js story
|
```js story
|
||||||
|
|||||||
@@ -1,21 +1,36 @@
|
|||||||
# Presets >> Blog ||40
|
# Presets >> Blog || 40
|
||||||
|
|
||||||
Enable writing blog posts within your Rocket site.
|
Enable writing blog posts within your Rocket site.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
<code-tabs collection="package-managers" default-tab="npm" align="end">
|
||||||
|
|
||||||
|
```bash tab npm
|
||||||
npm i @rocket/blog
|
npm i @rocket/blog
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```bash tab yarn
|
||||||
|
yarn add @rocket/blog
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab pnpm
|
||||||
|
pnpm add @rocket/blog
|
||||||
|
```
|
||||||
|
|
||||||
|
</code-tabs>
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
👉 `rocket.config.mjs`
|
👉 `rocket.config.js`
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
```js
|
```js
|
||||||
import { rocketBlog } from '@rocket/blog';
|
import { rocketBlog } from '@rocket/blog';
|
||||||
|
|
||||||
export default {
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
presets: [rocketBlog()],
|
presets: [rocketBlog()],
|
||||||
};
|
});
|
||||||
```
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Presets >> Joining Blocks ||10
|
# Presets >> Joining Blocks || 10
|
||||||
|
|
||||||
The template system allows for a very granular control of how individual parts will be merged, overwritten or reorderd.
|
The template system allows for a very granular control of how individual parts will be merged, overwritten or reorderd.
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ As a preset you may want to add this to your layout.
|
|||||||
|
|
||||||
{% raw %}
|
{% raw %}
|
||||||
|
|
||||||
```
|
```jinja2
|
||||||
<footer id="main-footer">
|
<footer id="main-footer">
|
||||||
{% for blockName, blockPath in _joiningBlocks.footer %}
|
{% for blockName, blockPath in _joiningBlocks.footer %}
|
||||||
{% include blockPath %}
|
{% include blockPath %}
|
||||||
@@ -22,11 +22,15 @@ This will now render all templates within `_includes/_joiningBlocks/footer/*`.
|
|||||||
|
|
||||||
Let's assume we have a preset with the following files
|
Let's assume we have a preset with the following files
|
||||||
|
|
||||||
```html
|
👉 `_includes/_joiningBlocks/footer/10-first.njk`
|
||||||
<!-- usedPreset/_includes/_joiningBlocks/footer/10-first.njk -->
|
|
||||||
<p>first</p>
|
|
||||||
|
|
||||||
<!-- usedPreset/_includes/_joiningBlocks/footer/20-second.njk -->
|
```html
|
||||||
|
<p>first</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
👉 `_includes/_joiningBlocks/footer/20-second.njk`
|
||||||
|
|
||||||
|
```html
|
||||||
<p>second</p>
|
<p>second</p>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -41,8 +45,9 @@ And it produces this in your website
|
|||||||
|
|
||||||
Now we can add a file which will insert content without needing to overwrite any of the preset file.
|
Now we can add a file which will insert content without needing to overwrite any of the preset file.
|
||||||
|
|
||||||
|
👉 `docs/_includes/_joiningBlocks/footer/15-in-between.njk`
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- docs/_includes/_joiningBlocks/footer/15-in-between.njk -->
|
|
||||||
<p>in-between</p>
|
<p>in-between</p>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -60,8 +65,9 @@ the final output will be
|
|||||||
|
|
||||||
Now if you want to overwrite you can use the same filename.
|
Now if you want to overwrite you can use the same filename.
|
||||||
|
|
||||||
|
👉 `docs/_includes/_joiningBlocks/footer/10-first.njk`
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- docs/_includes/_joiningBlocks/footer/10-first.njk -->
|
|
||||||
<p>updated first</p>
|
<p>updated first</p>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -78,8 +84,9 @@ the final output will be
|
|||||||
|
|
||||||
Sometimes you wanna reorder when you overwrite as well
|
Sometimes you wanna reorder when you overwrite as well
|
||||||
|
|
||||||
|
👉 `docs/_includes/_joiningBlocks/footer/30-first.njk`
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- docs/_includes/_joiningBlocks/footer/30-first.njk -->
|
|
||||||
<p>first</p>
|
<p>first</p>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,119 +0,0 @@
|
|||||||
# Presets >> Launch ||20
|
|
||||||
|
|
||||||
Rocket comes with a preset you will love. Simple, responsive and behaving like native, it sure is going to be a hit among your users.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm i @rocket/launch
|
|
||||||
```
|
|
||||||
|
|
||||||
👉 `rocket.config.mjs`
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { rocketLaunch } from '@rocket/launch';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
presets: [rocketLaunch()],
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## Data
|
|
||||||
|
|
||||||
Most data comes from `site.cjs`.
|
|
||||||
|
|
||||||
There is also a specific `rocketLaunch.json`.
|
|
||||||
|
|
||||||
The footer data comes from `footer.json`
|
|
||||||
|
|
||||||
## Inline Notification
|
|
||||||
|
|
||||||
Notification are web components that bring in some styles.
|
|
||||||
|
|
||||||
To use them in Markdown you need to write the HTML tag and have it separated by an empty line.
|
|
||||||
|
|
||||||
```js script
|
|
||||||
import '@rocket/launch/inline-notification/inline-notification.js';
|
|
||||||
```
|
|
||||||
|
|
||||||
First you need to import the script
|
|
||||||
|
|
||||||
````
|
|
||||||
```js script
|
|
||||||
import '@rocket/launch/inline-notification/inline-notification.js';
|
|
||||||
```
|
|
||||||
````
|
|
||||||
|
|
||||||
### Tip
|
|
||||||
|
|
||||||
<inline-notification type="tip">
|
|
||||||
|
|
||||||
I am a tip
|
|
||||||
|
|
||||||
</inline-notification>
|
|
||||||
|
|
||||||
**Usage**
|
|
||||||
|
|
||||||
```md
|
|
||||||
<inline-notification type="tip">
|
|
||||||
|
|
||||||
I am a tip
|
|
||||||
|
|
||||||
</inline-notification>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Modify the Title
|
|
||||||
|
|
||||||
To override the title you can provide a property success.
|
|
||||||
|
|
||||||
<inline-notification type="tip" title="success">
|
|
||||||
|
|
||||||
I am a success message
|
|
||||||
|
|
||||||
</inline-notification>
|
|
||||||
|
|
||||||
**Usage**
|
|
||||||
|
|
||||||
```md
|
|
||||||
<inline-notification type="tip" title="success">
|
|
||||||
|
|
||||||
I am a success message
|
|
||||||
|
|
||||||
</inline-notification>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Warning
|
|
||||||
|
|
||||||
<inline-notification type="warning">
|
|
||||||
|
|
||||||
I am a warning
|
|
||||||
|
|
||||||
</inline-notification>
|
|
||||||
|
|
||||||
**Usage**
|
|
||||||
|
|
||||||
```md
|
|
||||||
<inline-notification type="warning">
|
|
||||||
|
|
||||||
I am a warning
|
|
||||||
|
|
||||||
</inline-notification>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Danger
|
|
||||||
|
|
||||||
<inline-notification type="danger">
|
|
||||||
|
|
||||||
I am a dangerous message
|
|
||||||
|
|
||||||
</inline-notification>
|
|
||||||
|
|
||||||
**Usage**
|
|
||||||
|
|
||||||
```md
|
|
||||||
<inline-notification type="danger">
|
|
||||||
|
|
||||||
I am a dangerous message
|
|
||||||
|
|
||||||
</inline-notification>
|
|
||||||
```
|
|
||||||
7
docs/docs/presets/launch/custom-elements.txt
Normal file
7
docs/docs/presets/launch/custom-elements.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
layout: layout-api
|
||||||
|
package: '@rocket/launch'
|
||||||
|
module: inline-notification/index.js
|
||||||
|
---
|
||||||
|
|
||||||
|
# Presets >> Launch >> Custom Elements || 20
|
||||||
3
docs/docs/presets/launch/index.md
Normal file
3
docs/docs/presets/launch/index.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Presets >> Launch || 20
|
||||||
|
|
||||||
|
- [Preset](./preset/)
|
||||||
145
docs/docs/presets/launch/preset.md
Normal file
145
docs/docs/presets/launch/preset.md
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
---
|
||||||
|
alerts:
|
||||||
|
- type: tip
|
||||||
|
content: Take a tip from me
|
||||||
|
- type: warning
|
||||||
|
content: Be *sure* about this...
|
||||||
|
- type: danger
|
||||||
|
content: You **really** shouldn't!
|
||||||
|
---
|
||||||
|
|
||||||
|
# Presets >> Launch >> Preset || 10
|
||||||
|
|
||||||
|
Rocket comes with a preset you will love. Simple, responsive and behaving like native, it sure is going to be a hit among your users.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Install `@rocket/launch` from the NPM repository using your favourite package manager.
|
||||||
|
|
||||||
|
<code-tabs collection="package-managers" default-tab="npm" align="end">
|
||||||
|
|
||||||
|
```bash tab npm
|
||||||
|
npm i @rocket/launch
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab yarn
|
||||||
|
yarn add @rocket/launch
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab pnpm
|
||||||
|
pnpm add @rocket/launch
|
||||||
|
```
|
||||||
|
|
||||||
|
</code-tabs>
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
👉 `rocket.config.js`
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
import { rocketLaunch } from '@rocket/launch';
|
||||||
|
|
||||||
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
|
presets: [rocketLaunch()],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
## Data
|
||||||
|
|
||||||
|
The launch preset configures [11ty data](https://www.11ty.dev/docs/data/) using a few overridable files:
|
||||||
|
|
||||||
|
- `site.cjs`: Responsible for most of the site-wide config
|
||||||
|
- `rocketLaunch.json`: configures the homepage layout
|
||||||
|
- `footer.json`: Configures the content of the footer
|
||||||
|
|
||||||
|
## Inline Notification
|
||||||
|
|
||||||
|
```js script
|
||||||
|
import '@rocket/launch/inline-notification/inline-notification.js';
|
||||||
|
```
|
||||||
|
|
||||||
|
Launch ships with `<inline-notification>`, a custom element that applies some styles similar to "info boxes". The element works for `<noscript>` users as well, as long as you don't [override](/guides/presets/overriding/) the default `noscript.css` file.
|
||||||
|
|
||||||
|
To add an inline notification you need to remember to import the element definition:
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
~~~markdown
|
||||||
|
```js script
|
||||||
|
import '@rocket/launch/inline-notification/inline-notification.js';
|
||||||
|
```
|
||||||
|
~~~
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
Then you can add your notification to the page. If you want to write the notification's content using markdown, just pad the opening and closing tags with empty lines.
|
||||||
|
|
||||||
|
There are three varieties of `<inline-notification>`, "tip", "warning", and "danger"
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#inline-notifications::part(tab) {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
#inline-notifications code-tab::part(content) {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
#inline-notifications code-copy::part(copy-button) {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid var(--primary-lines-color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<code-tabs id="inline-notifications" default-tab="tip">
|
||||||
|
|
||||||
|
{%for alert in alerts%}
|
||||||
|
|
||||||
|
<code-tab data-label="{{ alert.type }}" data-id="{{ alert.type }}" no-copy>
|
||||||
|
|
||||||
|
```md copy
|
||||||
|
<inline-notification type="{{ alert.type }}">
|
||||||
|
|
||||||
|
{{ alert.content | safe }}
|
||||||
|
|
||||||
|
</inline-notification>
|
||||||
|
```
|
||||||
|
|
||||||
|
<inline-notification type="{{ alert.type }}">
|
||||||
|
|
||||||
|
{{ alert.content | safe }}
|
||||||
|
|
||||||
|
</inline-notification>
|
||||||
|
|
||||||
|
</code-tab>
|
||||||
|
|
||||||
|
{%endfor%}
|
||||||
|
|
||||||
|
</code-tabs>
|
||||||
|
|
||||||
|
### Modify the Title
|
||||||
|
|
||||||
|
The notification title defautls to it's type. You can write a custom title with the `title` attribute.
|
||||||
|
|
||||||
|
<inline-notification type="tip" title="success">
|
||||||
|
|
||||||
|
I am a success message
|
||||||
|
|
||||||
|
</inline-notification>
|
||||||
|
|
||||||
|
```md
|
||||||
|
<inline-notification type="tip" title="success">
|
||||||
|
|
||||||
|
I am a success message
|
||||||
|
|
||||||
|
</inline-notification>
|
||||||
|
```
|
||||||
|
|
||||||
|
<inline-notification type="warning">
|
||||||
|
|
||||||
|
The `title` attribute does not change the title for `<noscript>` users, so don't include any critical information in it.
|
||||||
|
|
||||||
|
</inline-notification>
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# Presets >> Search ||30
|
|
||||||
|
|
||||||
Add a search for all your static content.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm i @rocket/search
|
|
||||||
```
|
|
||||||
|
|
||||||
👉 `rocket.config.mjs`
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { rocketSearch } from '@rocket/search';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
presets: [rocketSearch()],
|
|
||||||
};
|
|
||||||
```
|
|
||||||
9
docs/docs/presets/search/custom-elements.txt
Normal file
9
docs/docs/presets/search/custom-elements.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
layout: layout-api
|
||||||
|
package: '@rocket/search'
|
||||||
|
modules:
|
||||||
|
- src/RocketSearch.js
|
||||||
|
- src/RocketSearchCombobox.js
|
||||||
|
---
|
||||||
|
|
||||||
|
# Presets >> Search >> Custom Elements || 20
|
||||||
3
docs/docs/presets/search/index.md
Normal file
3
docs/docs/presets/search/index.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Presets >> Search || 10
|
||||||
|
|
||||||
|
- [Preset](./preset/)
|
||||||
36
docs/docs/presets/search/preset.md
Normal file
36
docs/docs/presets/search/preset.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Presets >> Search >> Preset || 10
|
||||||
|
|
||||||
|
Add a search for all your static content.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
<code-tabs collection="package-managers" default-tab="npm" align="end">
|
||||||
|
|
||||||
|
```bash tab npm
|
||||||
|
npm i @rocket/search
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab yarn
|
||||||
|
yarn add @rocket/search
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab pnpm
|
||||||
|
pnpm add @rocket/search
|
||||||
|
```
|
||||||
|
|
||||||
|
</code-tabs>
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
👉 `rocket.config.js`
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
import { rocketSearch } from '@rocket/search';
|
||||||
|
|
||||||
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
|
presets: [rocketSearch()],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Tools >> Check HTML Links ||30
|
# Tools >> Check HTML Links ||30
|
||||||
|
|
||||||
```js
|
```js script
|
||||||
import '@rocket/launch/inline-notification/inline-notification.js';
|
import '@rocket/launch/inline-notification/inline-notification.js';
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ Read the [Introducing Check HTMl Links - no more bad links](../../blog/introduci
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```
|
```shell
|
||||||
npm i -D check-html-links
|
npm i -D check-html-links
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -3,15 +3,121 @@
|
|||||||
The Plugins Manager replaces the specific registration/execution (with options) in a given plugin system by an intend to use a plugin (with these options).
|
The Plugins Manager replaces the specific registration/execution (with options) in a given plugin system by an intend to use a plugin (with these options).
|
||||||
This allows your users to adjust the options before actually applying the plugins.
|
This allows your users to adjust the options before actually applying the plugins.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
1. Install npm package
|
||||||
|
```bash
|
||||||
|
npm i plugins-manager
|
||||||
|
```
|
||||||
|
2. Change your public API from an array of plugin "instances" to an array of setup functions
|
||||||
|
```diff
|
||||||
|
import myPlugin from 'my-plugin';
|
||||||
|
+ import { addPlugin } from 'plugins-manager';
|
||||||
|
export default {
|
||||||
|
- plugins: [myPlugin],
|
||||||
|
+ setupPlugins: [addPlugin(myPlugin)]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
3. Convert setup function to plugins
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { applyPlugins } from 'plugins-manager';
|
||||||
|
|
||||||
|
const finalConfig = applyPlugins(config); // "converts" setupPlugins to plugins
|
||||||
|
|
||||||
|
// work with plugins or pass it on to another tool
|
||||||
|
const bundle = await rollup(finalConfig);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
As you users in most cases you will need to either add or adjust a given plugin in a config file.
|
||||||
|
|
||||||
|
👉 `my-tool.config.js`
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { addPlugin, adjustPluginOptions } from 'plugins-manager';
|
||||||
|
import json from '@rollup/plugin-json';
|
||||||
|
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setupPlugins: [
|
||||||
|
// add a new plugin with optional plugin options
|
||||||
|
addPlugin(json, {
|
||||||
|
/* ... */
|
||||||
|
}),
|
||||||
|
|
||||||
|
// adjust the options of a plugin that is already registered
|
||||||
|
adjustPluginOptions(nodeResolve, {
|
||||||
|
/* ... */
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Plugins can be functions or classes
|
||||||
|
|
||||||
|
### Function Plugins
|
||||||
|
|
||||||
|
```js
|
||||||
|
function myPlugin({ lastName: 'initial-second' }) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setupPlugins: [addPlugin(myPlugin)],
|
||||||
|
};
|
||||||
|
|
||||||
|
// function parameters are type safe
|
||||||
|
addPlugin(myPlugin, { lastName: 'new name' }); // ts ok
|
||||||
|
addPlugin(myPlugin, { otherProp: 'new name' }); // ts error
|
||||||
|
```
|
||||||
|
|
||||||
|
### Class Plugins
|
||||||
|
|
||||||
|
The options are passed to the constructor.
|
||||||
|
|
||||||
|
```js
|
||||||
|
/**
|
||||||
|
* @typedef {object} MyClassOptions
|
||||||
|
* @property {string} lastName
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MyClass {
|
||||||
|
/** @type {MyClassOptions} */
|
||||||
|
options = {
|
||||||
|
lastName: 'initial-second',
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Partial<MyClassOptions>} options
|
||||||
|
*/
|
||||||
|
constructor(options = {}) {
|
||||||
|
this.options = { ...this.options, ...options };
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setupPlugins: [addPlugin(MyClass)],
|
||||||
|
};
|
||||||
|
|
||||||
|
// constructor parameters are type safe
|
||||||
|
addPlugin(MyClass, { lastName: 'new name' }); // ts ok
|
||||||
|
addPlugin(MyClass, { otherProp: 'new name' }); // ts error
|
||||||
|
```
|
||||||
|
|
||||||
## Problem
|
## Problem
|
||||||
|
|
||||||
Many plugin systems require you to either execute a plugin function like in `rollup`.
|
Many plugin systems require you to either execute a plugin function like in `rollup`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import json from '@rollup/plugin-json';
|
import json from '@rollup/plugin-json';
|
||||||
export default {
|
|
||||||
|
export default /** @type {import('rocket/cli').RocketCliConfig} */ ({
|
||||||
plugins: [json({ preferConst: true })],
|
plugins: [json({ preferConst: true })],
|
||||||
};
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
or add it in a special way like in `eleventy`
|
or add it in a special way like in `eleventy`
|
||||||
@@ -44,18 +150,14 @@ This means if you wish to define default plugins and allow your user to override
|
|||||||
|
|
||||||
The plugins manager lets you orchestrate a set of "meta plugins" which are defined by
|
The plugins manager lets you orchestrate a set of "meta plugins" which are defined by
|
||||||
|
|
||||||
- name
|
- plugin (class or function)
|
||||||
- plugin
|
- it's options
|
||||||
- options
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import beep from '@rollup/plugin-beep';
|
import beep from '@rollup/plugin-beep';
|
||||||
import url from '@rollup/plugin-url';
|
import url from '@rollup/plugin-url';
|
||||||
|
|
||||||
let metaPlugins = [
|
let metaPlugins = [{ plugin: beep }, { plugin: url, options: { limit: 10000 } }];
|
||||||
{ name: 'beep', plugin: beep },
|
|
||||||
{ name: 'url', plugin: url, options: { limit: 10000 } },
|
|
||||||
];
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This array can be modified by adding/removing or adjusting options.
|
This array can be modified by adding/removing or adjusting options.
|
||||||
@@ -90,16 +192,13 @@ export default {
|
|||||||
|
|
||||||
### Adding Helpers
|
### Adding Helpers
|
||||||
|
|
||||||
Doing array manipulations is kinda error-prone so we offer encourage to use an array of setup function. Where as each setup function can either add a new plugin (with a unique name) or adjust an already existing plugin.
|
Doing array manipulations is kinda error-prone so we encourage to use an array of setup function. Where as each setup function can either add a new plugin (with a unique name) or adjust an already existing plugin.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { addPlugin, adjustPluginOptions } from 'plugins-manager';
|
import { addPlugin, adjustPluginOptions } from 'plugins-manager';
|
||||||
|
|
||||||
const systemSetupFunctions = [
|
const systemSetupFunctions = [addPlugin(first), addPlugin(second)];
|
||||||
addPlugin({ name: 'first', plugin: first }),
|
const userSetupFunctions = [adjustPluginOptions(first, { my: 'options' })];
|
||||||
addPlugin({ name: 'second', plugin: second }),
|
|
||||||
];
|
|
||||||
const userSetupFunctions = [adjustPluginOptions('first', { my: 'options' })];
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Arrays of functions can by merged like so
|
Arrays of functions can by merged like so
|
||||||
@@ -111,9 +210,9 @@ const finalSetupFunctions = [...systemSetupFunctions, ...userSetupFunctions];
|
|||||||
and then converted to the final output.
|
and then converted to the final output.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { metaPluginsToRollupPlugins } from 'plugins-manager';
|
import { applyPlugins } from 'plugins-manager';
|
||||||
|
|
||||||
const plugins = metaPluginsToRollupPlugins(finalSetupFunctions, metaPlugins);
|
const plugins = applyPlugins(finalSetupFunctions, metaPlugins);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Adding a Plugin
|
## Adding a Plugin
|
||||||
@@ -129,18 +228,39 @@ By default it adds at the bottom.
|
|||||||
import json from '@rollup/plugin-json';
|
import json from '@rollup/plugin-json';
|
||||||
import { addPlugin } from 'plugins-manager';
|
import { addPlugin } from 'plugins-manager';
|
||||||
|
|
||||||
const userSetupFunctions = [
|
const userSetupFunctions = [addPlugin(json, { preferConst: true })];
|
||||||
addPlugin({ name: 'json', plugin: json, options: { preferConst: true } }),
|
|
||||||
];
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
addPlugin({ name: 'json', plugin: json }); // Add at the bottom (default)
|
addPlugin(json); // Add at the bottom (default)
|
||||||
addPlugin({ name: 'json', plugin: json, location: 'top' }); // Add at the top/beginning of the array
|
addPlugin(json, {}, { location: 'top' }); // Add at the top/beginning of the array
|
||||||
addPlugin({ name: 'json', plugin: json, location: 'beep' }); // Add after (default) plugin 'beep'
|
addPlugin(json, {}, { location: beep }); // Add after (default) plugin 'beep'
|
||||||
addPlugin({ name: 'json', plugin: json, location: 'beep', how: 'before' }); // Add before plugin 'beep'
|
addPlugin(json, {}, { location: beep, how: 'before' }); // Add before plugin 'beep'
|
||||||
|
```
|
||||||
|
|
||||||
|
This is type safe and typescript will throw an error if you pass the wrong type.
|
||||||
|
|
||||||
|
```js
|
||||||
|
function myPlugin({ myFlag = false } = {}) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
addPlugin(myPlugin, { myFlag: true }); // ts ok
|
||||||
|
addPlugin(myPlugin, { notExisting: true }); // ts error
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: There is a "hidden" feature in addPlugin that if you attach a `wrapPlugin` property to the returning function it will call `wrapPlugin` on the plugin before adding it.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// example auto wrap rollup plugins for @web/dev-server
|
||||||
|
import { fromRollup } from '@web/dev-server-rollup';
|
||||||
|
|
||||||
|
const userSetupFunctions = [addPlugin(json)].map(mod => {
|
||||||
|
mod.wrapPlugin = fromRollup;
|
||||||
|
return mod;
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
## Adjusting Plugin Options
|
## Adjusting Plugin Options
|
||||||
@@ -150,12 +270,14 @@ Adjusting options means to either
|
|||||||
- flatly merge objects (e.g. only the first level will be preserved)
|
- flatly merge objects (e.g. only the first level will be preserved)
|
||||||
- calling a function to do the merge yourself
|
- calling a function to do the merge yourself
|
||||||
- setting the raw value (if not an object or function)
|
- setting the raw value (if not an object or function)
|
||||||
|
- you need to have a reference to the plugin (which is used to auto complete the available options via typescript)
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
import json from '@rollup/plugin-json';
|
||||||
import { adjustPluginOptions } from 'plugins-manager';
|
import { adjustPluginOptions } from 'plugins-manager';
|
||||||
|
|
||||||
const userSetupFunctions = [
|
const userSetupFunctions = [
|
||||||
adjustPluginOptions('json', { preferConst: false, anotherOption: 'format' }),
|
adjustPluginOptions(json, { preferConst: false, anotherOption: 'format' }),
|
||||||
];
|
];
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -163,36 +285,53 @@ Example usage:
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
// given
|
// given
|
||||||
addPlugin({
|
addPlugin(json, {
|
||||||
name: 'json',
|
other: {
|
||||||
plugin: json,
|
nested: 'other.nested',
|
||||||
options: {
|
nested2: 'other.nested2',
|
||||||
other: {
|
|
||||||
nested: 'other.nested',
|
|
||||||
nested2: 'other.nested2',
|
|
||||||
},
|
|
||||||
main: true,
|
|
||||||
},
|
},
|
||||||
|
main: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// merge objects flately
|
// merge objects flately
|
||||||
adjustPluginOptions('json', { other: { nested: '--overwritten--' } });
|
adjustPluginOptions(json, { other: { nested: '--overwritten--' } });
|
||||||
// resulting options = { other: { nested: '--overwritten--' }, main: true }
|
// resulting options = { other: { nested: '--overwritten--' }, main: true }
|
||||||
// NOTE: nested2 is removed
|
// NOTE: nested2 is removed
|
||||||
|
|
||||||
// merge via function
|
// merge via function
|
||||||
adjustPluginOptions('json', config => ({ other: { ...config.other, nested: '--overwritten--' } }));
|
adjustPluginOptions(json, config => ({ other: { ...config.other, nested: '--overwritten--' } }));
|
||||||
// resulting options = { other: { nested: '--overwritten--', nested2: 'other.nested2' }, main: true }
|
// resulting options = { other: { nested: '--overwritten--', nested2: 'other.nested2' }, main: true }
|
||||||
|
|
||||||
// merge via function to override full options
|
// merge via function to override full options
|
||||||
adjustPluginOptions('json', config => ({ only: 'this' }));
|
adjustPluginOptions(json, config => ({ only: 'this' }));
|
||||||
// resulting options = { only: 'this' }
|
// resulting options = { only: 'this' }
|
||||||
|
|
||||||
// setting a raw value
|
// setting a raw value
|
||||||
adjustPluginOptions('json', false);
|
adjustPluginOptions(json, false);
|
||||||
// resulting options = false
|
// resulting options = false
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This is type safe and typescript will throw an error if you pass the wrong type.
|
||||||
|
|
||||||
|
```js
|
||||||
|
function myPlugin({ myFlag = false } = {}) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
adjustPluginOptions(myPlugin, { myFlag: true }); // ts ok
|
||||||
|
adjustPluginOptions(myPlugin, { notExisting: true }); // ts error
|
||||||
|
```
|
||||||
|
|
||||||
|
## Remove Plugin
|
||||||
|
|
||||||
|
Sometimes you would like to remove a default plugin from the config.
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
setupPlugins: [removePlugin(json)],
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## Converting metaPlugins to an Actual Plugin
|
## Converting metaPlugins to an Actual Plugin
|
||||||
|
|
||||||
To execute all setup function you can use this little helper
|
To execute all setup function you can use this little helper
|
||||||
@@ -223,25 +362,9 @@ Rollup has a more specific helper that handles
|
|||||||
Note: if you provide `config.plugins` then it will return that directly ignoring `setupPlugins`
|
Note: if you provide `config.plugins` then it will return that directly ignoring `setupPlugins`
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { metaConfigToRollupConfig } from 'plugins-manager';
|
import { applyPlugins } from 'plugins-manager';
|
||||||
|
|
||||||
const finalConfig = metaConfigToRollupConfig(currentConfig, defaultMetaPlugins);
|
const finalConfig = applyPlugins(currentConfig, defaultMetaPlugins);
|
||||||
```
|
|
||||||
|
|
||||||
Web Dev Server has a more specific helper that handles
|
|
||||||
|
|
||||||
- `config.setupPlugins`
|
|
||||||
- `config.setupRollupPlugins`
|
|
||||||
|
|
||||||
Note: if you provide `config.plugins` then it will return that directly ignoring `setupPlugins` and `setupRollupPlugins`
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { metaConfigToWebDevServerConfig } from 'plugins-manager';
|
|
||||||
import { fromRollup } from '@web/dev-server-rollup';
|
|
||||||
|
|
||||||
const finalConfig = metaConfigToWebDevServerConfig(currentConfig, defaultMetaPlugins, {
|
|
||||||
rollupWrapperFunction: fromRollup,
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Eleventy
|
Eleventy
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ You write modern JavaScript using the latest browser features. Rollup will optim
|
|||||||
- Set HTML or JavaScript as input and/or output
|
- Set HTML or JavaScript as input and/or output
|
||||||
- Optimized for browsers which support modules
|
- Optimized for browsers which support modules
|
||||||
- Loads polyfills using feature detection
|
- Loads polyfills using feature detection
|
||||||
- Generates a service worker
|
|
||||||
- Minifies JavaScript
|
- Minifies JavaScript
|
||||||
- Minifies lit-html templates
|
- Minifies lit-html templates
|
||||||
|
|
||||||
|
|||||||
@@ -20,19 +20,19 @@ The Plugins Manager helps you register and execute your plugins across the vario
|
|||||||
|
|
||||||
## Adding Remark/Unified Plugins
|
## Adding Remark/Unified Plugins
|
||||||
|
|
||||||
If you want to a plugin to the Markdown processing you can use `setupUnifiedPlugins`.
|
If you want to add a plugin to the Markdown processing you can use `setupUnifiedPlugins`.
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
```js
|
```js
|
||||||
import emoji from 'remark-emoji';
|
import emoji from 'remark-emoji';
|
||||||
import { addPlugin } from 'plugins-manager';
|
import { addPlugin } from 'plugins-manager';
|
||||||
|
|
||||||
/** @type {Partial<import('@rocket/cli').RocketCliOptions>} */
|
/** @type {Partial<import('@rocket/cli').RocketCliOptions>} */
|
||||||
const config = {
|
export default ({
|
||||||
setupUnifiedPlugins: [addPlugin({ location: 'markdown', name: 'emoji', plugin: emoji })],
|
setupUnifiedPlugins: [addPlugin({ location: 'markdown', name: 'emoji', plugin: emoji })],
|
||||||
};
|
});
|
||||||
|
|
||||||
export default config;
|
|
||||||
```
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
For plugins that should handle the Markdown <abbr title="Abstract Syntax Tree">AST</abbr> you should use `addPlugin({ location: 'markdown', name: 'my-plugin', plugin: MyPlugin})`. <br>
|
For plugins that should handle the Markdown <abbr title="Abstract Syntax Tree">AST</abbr> you should use `addPlugin({ location: 'markdown', name: 'my-plugin', plugin: MyPlugin})`. <br>
|
||||||
While for the rehype AST you should use `addPlugin({ location: 'remark2rehype', name: 'my-plugin', plugin: MyPlugin})`.
|
While for the rehype AST you should use `addPlugin({ location: 'remark2rehype', name: 'my-plugin', plugin: MyPlugin})`.
|
||||||
|
|||||||
@@ -10,94 +10,160 @@ Make sure they are installed before proceeding.
|
|||||||
|
|
||||||
The fastest way to get started is by using an existing preset like the launch preset.
|
The fastest way to get started is by using an existing preset like the launch preset.
|
||||||
|
|
||||||
1. Start with an empty new folder
|
### Step 1. Initialize the Project Package
|
||||||
|
|
||||||
```
|
Start by creating an empty folder for your project
|
||||||
mkdir my-project
|
|
||||||
cd my-project
|
|
||||||
npm init -y
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Install dependencies
|
```bash copy
|
||||||
|
mkdir my-project
|
||||||
|
cd my-project
|
||||||
|
```
|
||||||
|
|
||||||
```
|
Then initialize a package.json file
|
||||||
npm install --save-dev @rocket/cli @rocket/launch
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Add to your .gitignore
|
<code-tabs collection="package-managers" default-tab="npm" align="end">
|
||||||
|
|
||||||
```
|
```bash tab npm
|
||||||
## Rocket ignore files (need to be the full relative path to the folders)
|
npm init -y
|
||||||
docs/_merged_data/
|
```
|
||||||
docs/_merged_assets/
|
|
||||||
docs/_merged_includes/
|
|
||||||
```
|
|
||||||
|
|
||||||
<inline-notification type="danger">
|
```bash tab yarn
|
||||||
|
yarn init -y
|
||||||
|
```
|
||||||
|
|
||||||
You may be tempted to skip the step above, because you're not ready to commit to git yet!
|
```bash tab pnpm
|
||||||
|
pnpm init -y
|
||||||
|
```
|
||||||
|
|
||||||
Rocket uses the .gitignore file to manage its requirements. If you skip this step, Rocket will fail to deploy!
|
</code-tabs>
|
||||||
|
|
||||||
|
### Step 2. Install dependencies
|
||||||
|
|
||||||
|
<code-tabs collection="package-managers" default-tab="npm" align="end">
|
||||||
|
|
||||||
|
```bash tab npm
|
||||||
|
npm install --save-dev @rocket/cli @rocket/launch
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab yarn
|
||||||
|
yarn add -D @rocket/cli @rocket/launch
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab pnpm
|
||||||
|
pnpm add -D @rocket/cli @rocket/launch
|
||||||
|
```
|
||||||
|
|
||||||
|
</code-tabs>
|
||||||
|
|
||||||
|
### Step 3. Bootstrap the project
|
||||||
|
|
||||||
|
<code-tabs collection="package-managers" default-tab="npm" align="end">
|
||||||
|
|
||||||
|
```bash tab npm
|
||||||
|
npx rocket bootstrap
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab yarn
|
||||||
|
yarn rocket bootstrap
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab pnpm
|
||||||
|
pnpx rocket bootstrap
|
||||||
|
```
|
||||||
|
|
||||||
|
</code-tabs>
|
||||||
|
|
||||||
|
The `bootstrap` command creates four files in your repo:
|
||||||
|
|
||||||
|
- `.gitignore` containing rocket's build artifacts
|
||||||
|
- `rocket.config.js` containing a minimal rocket config
|
||||||
|
- `docs/.eleventyignore` required to allow you to [override templates](/guides/presets/overriding/)
|
||||||
|
- `docs/index.md` your first page
|
||||||
|
|
||||||
|
It also set the package `type` to `"module"` and adds a `start` and `docs` package scripts.
|
||||||
|
|
||||||
|
<inline-notification type="warning">
|
||||||
|
|
||||||
|
If you don't want to use the `module` package type, make sure to rename the generated config file to `rocket.config.mjs`.
|
||||||
|
|
||||||
</inline-notification>
|
</inline-notification>
|
||||||
|
|
||||||
4. Create a `rocket.config.mjs` (or `.js` if you have type: "module" in you package.json)
|
<details><summary>Default Files Contents</summary>
|
||||||
|
|
||||||
```js
|
<code-tabs default-tab="rocket.config.js">
|
||||||
import { rocketLaunch } from '@rocket/launch';
|
|
||||||
|
|
||||||
export default {
|
<!-- prettier-ignore-start -->
|
||||||
presets: [rocketLaunch()],
|
```js tab rocket.config.js
|
||||||
};
|
import { rocketLaunch } from '@rocket/launch';
|
||||||
```
|
|
||||||
|
|
||||||
5. (optionally) Create a file `.eleventyignore` (this file will be needed once you start customizing presets)
|
/** @type {import('rocket/cli').RocketCliConfig} */
|
||||||
|
export default ({
|
||||||
|
presets: [rocketLaunch()],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
```
|
```md tab docs/index.md
|
||||||
node_modules/**
|
# Welcome to Your Rocket Site
|
||||||
/docs/_assets
|
|
||||||
/docs/_includes
|
|
||||||
/docs/_data
|
|
||||||
```
|
|
||||||
|
|
||||||
<inline-notification type="warning" title="note">
|
Add your markdown content here.
|
||||||
|
```
|
||||||
|
|
||||||
All further paths are relative to your project root (my-project in this case).
|
<!-- prettier-ignore-start -->
|
||||||
|
|
||||||
</inline-notification>
|
```html tab docs/.eleventyignore
|
||||||
|
_assets
|
||||||
|
_includes
|
||||||
|
_data
|
||||||
|
```
|
||||||
|
|
||||||
|
```html tab .gitignore
|
||||||
|
## Rocket ignore files (need to be the full relative path to the folders)
|
||||||
|
docs/_merged_data/
|
||||||
|
docs/_merged_assets/
|
||||||
|
docs/_merged_includes/
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
</code-tabs>
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
## Add your First Page
|
## Add your First Page
|
||||||
|
|
||||||
👉 `docs/index.md`
|
Bootstrap created the file `docs/index.md`. Open it in your editor and change it to suit your needs.
|
||||||
|
|
||||||
|
<small>NOTE: This tutorial assumes you are familiar with Markdown, for page authoring.</small>
|
||||||
|
|
||||||
```md
|
```md
|
||||||
# Welcome to Your Rocket Site
|
# Welcome to Your Rocket Site
|
||||||
|
|
||||||
Text here, like any Markdown file.
|
Add your markdown content here.
|
||||||
```
|
```
|
||||||
|
|
||||||
This tutorial assumes you are familiar with Markdown, for page authoring.
|
|
||||||
|
|
||||||
Please note that the heading - text prefixed with `#` or `##` - is not optional for each page in this tutorial. Everything below that first line is optional Markdown text.
|
Please note that the heading - text prefixed with `#` or `##` - is not optional for each page in this tutorial. Everything below that first line is optional Markdown text.
|
||||||
|
|
||||||
## Startup:
|
## Startup
|
||||||
|
|
||||||
👉 `package.json`
|
|
||||||
|
|
||||||
Add `"start": "rocket start"` to your package.json
|
|
||||||
|
|
||||||
```json
|
|
||||||
"scripts": {
|
|
||||||
"start": "rocket start"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Now you can launch your site locally with
|
Now you can launch your site locally with
|
||||||
|
|
||||||
```bash
|
<code-tabs collection="package-managers" default-tab="npm" align="end">
|
||||||
npm run start
|
|
||||||
|
```bash tab npm
|
||||||
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```bash tab yarn
|
||||||
|
yarn start
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab pnpm
|
||||||
|
pnpx start
|
||||||
|
```
|
||||||
|
|
||||||
|
</code-tabs>
|
||||||
|
|
||||||
## Taking Inventory Before Adding Pages:
|
## Taking Inventory Before Adding Pages:
|
||||||
|
|
||||||
We're about to add both content and navigation at the same time.
|
We're about to add both content and navigation at the same time.
|
||||||
@@ -107,11 +173,16 @@ It can be helpful to take an inventory, before we start, to separate basic setup
|
|||||||
- We built the project with basic npm commands
|
- We built the project with basic npm commands
|
||||||
- Added a couple required files manually
|
- Added a couple required files manually
|
||||||
- Adjusted package.json
|
- Adjusted package.json
|
||||||
- **doc/index.md** to seed the content
|
- **docs/index.md** to seed the content
|
||||||
- Launches with `npm start`
|
- Launches with `npm start`
|
||||||
|
|
||||||
That's all it takes to get a new super-fast and powerful site, complete with a service worker, default styling, navigation, and ready to deploy as a plain old static files.
|
That's all it takes to get a new super-fast and powerful site, complete with a service worker, default styling, navigation, and ready to deploy as a plain old static files.
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
- [Adding Pages](../adding-pages/)
|
||||||
|
- [Using Presets](../../presets/getting-started/)
|
||||||
|
|
||||||
```js script
|
```js script
|
||||||
import '@rocket/launch/inline-notification/inline-notification.js';
|
import '@rocket/launch/inline-notification/inline-notification.js';
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# First Pages >> Managing sidebar ||30
|
# First Pages >> Managing sidebar || 30
|
||||||
|
|
||||||
The sidebar will show all the content of the current section.
|
The sidebar will show all the content of the current section.
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ Will be ordered as `First`, `Second`,
|
|||||||
|
|
||||||
Internally `# Foo >> Bar >> Baz ||20` gets converted to.
|
Internally `# Foo >> Bar >> Baz ||20` gets converted to.
|
||||||
|
|
||||||
```
|
```yml
|
||||||
---
|
---
|
||||||
title: Bar: Baz
|
title: Bar: Baz
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
@@ -33,10 +33,11 @@ eleventyNavigation:
|
|||||||
---
|
---
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<!--
|
||||||
You can also look at this live playground:
|
You can also look at this live playground:
|
||||||
|
|
||||||
```js story
|
```js story
|
||||||
import { html } from 'lit-html';
|
import { html } from '@mdjs/mdjs-preview';
|
||||||
|
|
||||||
export const headlineConverter = () => html`
|
export const headlineConverter = () => html`
|
||||||
<p>
|
<p>
|
||||||
@@ -45,6 +46,7 @@ export const headlineConverter = () => html`
|
|||||||
</p>
|
</p>
|
||||||
`;
|
`;
|
||||||
```
|
```
|
||||||
|
-->
|
||||||
|
|
||||||
How it then works is very similar to https://www.11ty.dev/docs/plugins/navigation/
|
How it then works is very similar to https://www.11ty.dev/docs/plugins/navigation/
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,49 @@
|
|||||||
# First Pages >> Use JavaScript ||40
|
# First Pages >> Use JavaScript || 40
|
||||||
|
|
||||||
You can use `js script` to execute JavaScript (`type="module"`).
|
If you would like to add JavaScript to a page, you can do it inline using the `script` markdown directive. The script you write runs on the page as a module.
|
||||||
|
|
||||||
````
|
<!-- prettier-ignore-start -->
|
||||||
|
~~~markdown
|
||||||
```js script
|
```js script
|
||||||
console.log('foo');
|
const message = 'Hello, World!';
|
||||||
|
console.log(message);
|
||||||
```
|
```
|
||||||
````
|
~~~
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
This can be useful for importing web components and using them in Markdown.
|
Adding the above will log `Hello, World!` to the console without adding a global `message` variable.
|
||||||
|
|
||||||
````
|
This can be useful for importing web components and using them in Markdown. Imagine you had some `magic-reveal` element that you wanted to use on a page:
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
~~~markdown
|
||||||
```js script
|
```js script
|
||||||
import 'magic-reveal/magic-reveal.js';
|
import 'magic-reveal/magic-reveal.js';
|
||||||
|
```
|
||||||
|
|
||||||
<magic-reveal>
|
<magic-reveal>
|
||||||
|
|
||||||
This text will get magically revealed. I can **still** use Markdown as long as there is an empty line between the opening/closing tags and my text.
|
This text will get magically revealed.
|
||||||
|
|
||||||
|
I can **still** use Markdown as long as there is an empty line
|
||||||
|
between the opening/closing tags and my text.
|
||||||
|
|
||||||
</magic-reveal>
|
</magic-reveal>
|
||||||
```
|
~~~
|
||||||
````
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
or you can use `js story`, `js preview-story`, ...
|
## Component Story Format
|
||||||
|
|
||||||
|
You can also add storybook-style CSF (v2 only) stories to a page using `js story` or `js preview-story`, just make sure to import `html` from `@mdjs/mdjs-preview` instead of from `lit` or `lit-html`.
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
~~~markdown
|
||||||
|
```js story
|
||||||
|
import { html } from '@mdjs/mdjs-preview';
|
||||||
|
|
||||||
|
export const StoryPreview = () => html`
|
||||||
|
<p>Use stories in Rocket!</p>
|
||||||
|
`;
|
||||||
|
```
|
||||||
|
~~~
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
# Go Live ||40
|
# Go Live || 40
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Go Live >> Overview ||10
|
# Go Live >> Overview || 10
|
||||||
|
|
||||||
A few things are usually needed before going live "for real".
|
A few things are usually needed before going live "for real".
|
||||||
|
|
||||||
@@ -9,17 +9,21 @@ Many servers are configured to handle this automatically and to serve a 404.html
|
|||||||
|
|
||||||
The [Rocket Launch preset](../../docs/presets/launch.md) ships a default 404 template you can use.
|
The [Rocket Launch preset](../../docs/presets/launch.md) ships a default 404 template you can use.
|
||||||
|
|
||||||
To enable it, you need to create a 404.md and use the 404 layout.
|
To enable it, you need to create a `404.md` and use the 404 layout.
|
||||||
|
|
||||||
👉 `docs/404.md`
|
👉 `docs/404.md`
|
||||||
|
|
||||||
```
|
```markdown copy
|
||||||
---
|
---
|
||||||
layout: layout-404
|
layout: layout-404
|
||||||
permalink: 404.html
|
permalink: 404.html
|
||||||
---
|
---
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This results in a `404.html` page, which will do nothing by itself. But many hosting services like netlify or firebase, for example will redirect 404s to this `404.html` by default.
|
||||||
|
|
||||||
|
If the hosting provider doesn't already do this, then you may be able to accomplish it via some settings for example by using a `.htaccess` file in case of an apache server.
|
||||||
|
|
||||||
## Add a Sitemap
|
## Add a Sitemap
|
||||||
|
|
||||||
A sitemap can be used to inform search engines or services about the pages your site has.
|
A sitemap can be used to inform search engines or services about the pages your site has.
|
||||||
@@ -28,24 +32,23 @@ You can create one by adding this file:
|
|||||||
|
|
||||||
👉 `docs/sitemap.njk`
|
👉 `docs/sitemap.njk`
|
||||||
|
|
||||||
{% raw %}
|
```markdown copy
|
||||||
|
|
||||||
```
|
|
||||||
---
|
---
|
||||||
layout: layout-raw
|
layout: layout-raw
|
||||||
permalink: /sitemap.xml
|
permalink: /sitemap.xml
|
||||||
eleventyExcludeFromCollections: true
|
eleventyExcludeFromCollections: true
|
||||||
---
|
---
|
||||||
|
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
{% for page in collections.all %}
|
{% raw %}{% for page in collections.all %}
|
||||||
|
{%- if page.url !== '/404.html' -%}
|
||||||
<url>
|
<url>
|
||||||
<loc>{{ rocketConfig.absoluteBaseUrl }}{{ page.url | url }}</loc>
|
<loc>{{ rocketConfig.absoluteBaseUrl }}{{ page.url | url }}</loc>
|
||||||
<lastmod>{{ page.date.toISOString() }}</lastmod>
|
<lastmod>{{ page.date.toISOString() }}</lastmod>
|
||||||
<changefreq>{{ page.data.changeFreq if page.data.changeFreq else "monthly" }}</changefreq>
|
<changefreq>{{ page.data.changeFreq if page.data.changeFreq else "monthly" }}</changefreq>
|
||||||
</url>
|
</url>
|
||||||
{% endfor %}
|
{%- endif -%}
|
||||||
|
{% endfor %}{% endraw %}
|
||||||
</urlset>
|
</urlset>
|
||||||
```
|
```
|
||||||
|
|
||||||
{% endraw %}
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Go Live >> Social Media ||20
|
# Go Live >> Social Media || 20
|
||||||
|
|
||||||
Having a nice preview image for social media can be very helpful.
|
Having a nice preview image for social media can be very helpful.
|
||||||
For that reason Rocket creates those automatically with the title, parent title, section and your logo.
|
For that reason Rocket creates those automatically with the title, parent title, section and your logo.
|
||||||
@@ -15,7 +15,7 @@ Note: If your logo has an `<?xml>` tag it will throw an error as it will be inli
|
|||||||
|
|
||||||
You can create your own image and link it with something like this
|
You can create your own image and link it with something like this
|
||||||
|
|
||||||
```
|
```markdown copy
|
||||||
---
|
---
|
||||||
socialMediaImage: path/to/my/image.png
|
socialMediaImage: path/to/my/image.png
|
||||||
---
|
---
|
||||||
@@ -29,7 +29,7 @@ You can create an `11tydata.cjs` file next to your page. If your page is `docs/g
|
|||||||
|
|
||||||
In there you can use the default `createSocialImage` but provide your own values.
|
In there you can use the default `createSocialImage` but provide your own values.
|
||||||
|
|
||||||
```js
|
```js copy
|
||||||
const { createSocialImage } = require('@rocket/cli');
|
const { createSocialImage } = require('@rocket/cli');
|
||||||
|
|
||||||
module.exports = async function () {
|
module.exports = async function () {
|
||||||
@@ -39,7 +39,7 @@ module.exports = async function () {
|
|||||||
subTitle2: 'in 5 Minutes',
|
subTitle2: 'in 5 Minutes',
|
||||||
footer: 'Rocket Guides',
|
footer: 'Rocket Guides',
|
||||||
// you can also override the svg only for this page by providing
|
// you can also override the svg only for this page by providing
|
||||||
// createSocialImageSvg: async () => '<svg>...</svg>'
|
// createSocialImageSvg: async () => '{%raw%}<svg>...</svg>{%endraw%}'
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
socialMediaImage,
|
socialMediaImage,
|
||||||
@@ -52,13 +52,14 @@ module.exports = async function () {
|
|||||||
Often you want to have a unique style for your social media images.
|
Often you want to have a unique style for your social media images.
|
||||||
For that you can provide your own function which returns a string of an SVG to render the image.
|
For that you can provide your own function which returns a string of an SVG to render the image.
|
||||||
|
|
||||||
👉 `rocket.config.mjs`
|
👉 `rocket.config.js`
|
||||||
|
|
||||||
```js
|
<!-- prettier-ignore-start -->
|
||||||
|
```js copy
|
||||||
import { adjustPluginOptions } from 'plugins-manager';
|
import { adjustPluginOptions } from 'plugins-manager';
|
||||||
|
|
||||||
/** @type {Partial<import("@rocket/cli").RocketCliOptions>} */
|
/** @type {import('@rocket/cli').RocketCliOptions} */
|
||||||
const config = {
|
export default ({
|
||||||
setupEleventyComputedConfig: [
|
setupEleventyComputedConfig: [
|
||||||
adjustPluginOptions('socialMediaImage', {
|
adjustPluginOptions('socialMediaImage', {
|
||||||
createSocialImageSvg: async ({
|
createSocialImageSvg: async ({
|
||||||
@@ -95,59 +96,69 @@ const config = {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
export default config;
|
|
||||||
```
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
## Using an SVG File as a src with Nunjucks
|
## Using an SVG File as a src with Nunjucks
|
||||||
|
|
||||||
If you have multiple variations it may be easier to save them as SVG files and use a template system.
|
If you have multiple variations it may be easier to save them as SVG files and use a template system.
|
||||||
|
|
||||||
WARNING: Untested example
|
<!-- prettier-ignore-start -->
|
||||||
|
<code-tabs default-tab="rocket.config.js">
|
||||||
|
|
||||||
👉 `rocket.config.mjs`
|
```js tab rocket.config.js
|
||||||
|
|
||||||
{% raw %}
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { adjustPluginOptions } from 'plugins-manager';
|
import { adjustPluginOptions } from 'plugins-manager';
|
||||||
|
|
||||||
/** @type {Partial<import("@rocket/cli").RocketCliOptions>} */
|
/** @type {import('@rocket/cli').RocketCliOptions} */
|
||||||
const config = {
|
export default ({
|
||||||
setupEleventyComputedConfig: [
|
setupEleventyComputedConfig: [
|
||||||
adjustPluginOptions('socialMediaImage', {
|
adjustPluginOptions('socialMediaImage', {
|
||||||
createSocialImageSvg: async (args = {}) => {
|
createSocialImageSvg: async (args = {}) => {
|
||||||
// inside of the svg you can use {{ title }}
|
const svgBuffer = await fs.promises.readFile('/path/to/your/template.svg');
|
||||||
const svgBuffer = await fs.promises.readFile('/path/to/your/svg/file');
|
|
||||||
const svg = logoBuffer.toString();
|
const svg = logoBuffer.toString();
|
||||||
return nunjucks.renderString(svg, args);
|
return nunjucks.renderString(svg, args);
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
{% endraw %}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```svg tab /path/to/your/template.svg
|
||||||
|
{%raw%}<svg xmlns="http://www.w3.org/2000/svg" fill="#e63946" viewBox="0 0 511.998 511.998">
|
||||||
|
<text font-family="'Open Sans', sans-serif" font-size="39" transform="translate(422.99 408.53)">
|
||||||
|
<tspan x="-89.26" y="12.25">{{ title }}</tspan>
|
||||||
|
</text>
|
||||||
|
<path d="M98.649 430.256c-46.365 28.67-71.17 30.939-78.916 23.51-7.75-7.433-6.519-32.307 20.182-79.832 24.953-44.412 65.374-96.693 113.818-147.211l-11.279-10.817c-49.33 51.442-90.583 104.845-116.163 150.373-19.228 34.22-37.848 79.134-17.375 98.766 5.84 5.6 13.599 7.935 22.484 7.935 22.269 0 51.606-14.677 75.469-29.432 44.416-27.464 96.044-70.919 145.373-122.362l-11.279-10.817c-48.446 50.519-98.987 93.095-142.314 119.887zM254.734 294.95l-18.47-17.71 10.816-11.281 18.47 17.71zM285.516 324.473l-18.47-17.71 10.816-11.28 18.47 17.71zM315.543 317.807l-73.886-70.847 10.816-11.28 73.886 70.846zM500.916 41.287c-7.769 1.59-76.412 16.062-93.897 34.294l-50.728 52.899-114.703-3.629-39.198 40.876 79.28 40.569-21.755 22.687 72.848 69.858 21.755-22.687 43.857 77.51 39.197-40.876-8.433-114.451 50.727-52.899c17.485-18.234 29.067-87.422 30.331-95.251l1.801-11.169-11.082 2.269zM228.209 161.383l19.842-20.692 93.688 2.964-48.775 50.864-64.755-33.136zm173.423 166.303l-35.822-63.308 48.776-50.865 6.886 93.482-19.84 20.691zm-69.334-50.943l-50.287-48.223L412.89 92.037l50.288 48.223-130.88 136.483zm140.711-148.707l-48.316-46.334c14.54-8.427 44.787-17.217 68.076-22.632-4.433 23.497-11.949 54.085-19.76 68.966z"/>
|
||||||
|
<path d="M326.335 257.25l-24.628-23.614 10.816-11.28 24.628 23.615zM431.385 134.414l-11.808 12.315-11.28-10.816 11.808-12.315zM401.838 165.183l-11.28-10.816 11.807-12.314 11.28 10.816zM384.121 183.66l-11.28-10.816 11.807-12.314 11.28 10.816zM175.19 184.515l11.051 11.05-23.582 23.582-11.05-11.05zM190.903 168.796l11.05 11.052-7.863 7.86-11.05-11.052z"/>
|
||||||
|
</svg>{%endraw%}
|
||||||
|
```
|
||||||
|
|
||||||
|
</code-tabs>
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
## Enabling / Disabling
|
## Enabling / Disabling
|
||||||
|
|
||||||
Generating images from SVG is quite fast but it can still add that's why by default during `rocket start` there will be no social media images created.
|
Generating images from SVG is quite fast but it can still add that's why by default during `rocket start` there will be no social media images created.
|
||||||
|
|
||||||
If you with so create them also during start you can
|
If you with so create them also during start you can
|
||||||
|
|
||||||
```js
|
<!-- prettier-ignore-start -->
|
||||||
const config = {
|
```js copy
|
||||||
|
export default ({
|
||||||
start: {
|
start: {
|
||||||
createSocialMediaImages: true,
|
createSocialMediaImages: true,
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
```
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
Similarly, if you never want to create social media images even during build then you can globally disable it via
|
Similarly, if you never want to create social media images even during build then you can globally disable it via
|
||||||
|
|
||||||
```js
|
<!-- prettier-ignore-start -->
|
||||||
const config = {
|
```js copy
|
||||||
|
export default ({
|
||||||
createSocialMediaImages: true,
|
createSocialMediaImages: true,
|
||||||
};
|
});
|
||||||
```
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|||||||
@@ -5,4 +5,19 @@ eleventyNavigation:
|
|||||||
order: 10
|
order: 10
|
||||||
---
|
---
|
||||||
|
|
||||||
Rocket is a fundamentally straight forward way to generate static pages while still allowing to sprinkle in some JavaScript where needed.
|
Rocket helps you generate static pages from Markdown files while giving you the flexibility to sprinkle in some JavaScript where needed.
|
||||||
|
|
||||||
|
- [First Pages](./first-pages/getting-started/) Learn how to bootstrap and run a Rocket site
|
||||||
|
- [Adding Pages](./first-pages/adding-pages/) Create your own content pages
|
||||||
|
- [Linking](./first-pages/link-to-other-pages/) Link between yuor markdown pages
|
||||||
|
- [Managing Sidebar](./first-pages/manage-sidebar/) Customize your site's navigation
|
||||||
|
- [Use JavaScript](./first-pages/use-javascript/) Write inline scripts in markdown
|
||||||
|
- [URLs](./first-pages/urls/) Customize your pages' permalinks
|
||||||
|
- [Layouts](./first-pages/layouts/) Give your page a custom layout
|
||||||
|
- [Presets](./presets/getting-started/) Customize Rocket with config presets
|
||||||
|
- [Overriding](./presets/overriding/) Override preset templates
|
||||||
|
- [Using Templates](./presets/using-templates/) Make use of preset templates
|
||||||
|
- [Create Your Own](./presets/create-your-own/getting-started/) Write and publish your own presets
|
||||||
|
- [Configuration](./configuration/getting-started/) Make Rocket your own
|
||||||
|
- [Go Live](./go-live/overview/) Publish your site
|
||||||
|
- [Social Media](./go-live/social-media/) Generate social images
|
||||||
|
|||||||
@@ -1,106 +0,0 @@
|
|||||||
# Presets >> Create your own || 90
|
|
||||||
|
|
||||||
A preset is a setup function and a folder including `_assets`, `_data` and `_includes` (all optional).
|
|
||||||
|
|
||||||
To play around with a preset you can create a folder `fire-theme`.
|
|
||||||
|
|
||||||
You then create the setup function for it with only one property called `path` which will allow Rocket to properly resolve it.
|
|
||||||
|
|
||||||
## Create a Preset Config File
|
|
||||||
|
|
||||||
👉 `fire-theme/fireTheme.js`
|
|
||||||
|
|
||||||
```js
|
|
||||||
import path from 'path';
|
|
||||||
import { fileURLToPath } from 'url';
|
|
||||||
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
||||||
|
|
||||||
export function fireTheme() {
|
|
||||||
return {
|
|
||||||
path: path.resolve(__dirname),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Once you have that you can start filling in content you need.
|
|
||||||
|
|
||||||
For example a we could override the full `layout.css` by adding a it like so
|
|
||||||
|
|
||||||
👉 `fire-theme/layout.css`
|
|
||||||
|
|
||||||
```css
|
|
||||||
body {
|
|
||||||
background: hotpink;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Once you have that you can add it to your Rocket config.
|
|
||||||
|
|
||||||
NOTE: The order of presets is important, as for example in this case we take everything from `rocketLaunch` but later override via `fireTheme`.
|
|
||||||
|
|
||||||
👉 `rocket-config.js`
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { rocketLaunch } from '@rocket/launch';
|
|
||||||
import { fireTheme } from 'path/to/fire-theme/fireTheme.js';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
presets: [rocketLaunch(), fireTheme()],
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## Publish a Preset
|
|
||||||
|
|
||||||
If you would like to publish a preset to use it on multiple websites or share it with your friends you can do like so.
|
|
||||||
|
|
||||||
1. Pick a name for the package => for this example we take `fire-theme`.
|
|
||||||
2. Create a new folder `fire-theme`
|
|
||||||
3. Create a folder `fire-theme/preset` copy `fireTheme.js` from [above](#create-a-preset-config-file) into `preset/fireTheme.js`
|
|
||||||
4. Add a 👉 `package.json`
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "fire-theme",
|
|
||||||
"version": "0.3.0",
|
|
||||||
"description": "Fire Theme for Rocket",
|
|
||||||
"license": "MIT",
|
|
||||||
"type": "module",
|
|
||||||
"exports": {
|
|
||||||
".": "./index.js",
|
|
||||||
"./preset/": "./preset/"
|
|
||||||
},
|
|
||||||
"files": ["*.js", "preset"],
|
|
||||||
"keywords": ["rocket", "preset"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
5. Add a 👉 `index.js`
|
|
||||||
|
|
||||||
```js
|
|
||||||
export { fireTheme } from './preset/fireTheme.js';
|
|
||||||
```
|
|
||||||
|
|
||||||
6. Add a 👉 `README.md`
|
|
||||||
|
|
||||||
````
|
|
||||||
# FireTheme
|
|
||||||
|
|
||||||
This is a theme/preset for [Rocket](https://rocket.modern-web.dev/).
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```
|
|
||||||
npm i -D fire-theme
|
|
||||||
```
|
|
||||||
|
|
||||||
Add it to your 👉 `rocket.config.js`
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { fireTheme } from 'fire-theme';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
presets: [fireTheme()],
|
|
||||||
};
|
|
||||||
```
|
|
||||||
````
|
|
||||||
54
docs/guides/presets/create-your-own/getting-started.md
Normal file
54
docs/guides/presets/create-your-own/getting-started.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Presets >> Create your Own >> Getting Started || 10
|
||||||
|
|
||||||
|
A preset is a setup function and a folder including `_assets`, `_data` and `_includes` (all optional).
|
||||||
|
|
||||||
|
To play around with a preset you can create a folder `fire-theme`.
|
||||||
|
|
||||||
|
You then create the setup function for it with only one property called `path` which will allow Rocket to properly resolve it.
|
||||||
|
|
||||||
|
## Create a Preset Config File
|
||||||
|
|
||||||
|
👉 `fire-theme/fireTheme.js`
|
||||||
|
|
||||||
|
```js copy
|
||||||
|
import path from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
|
export function fireTheme() {
|
||||||
|
return {
|
||||||
|
path: path.resolve(__dirname),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you have that you can start filling in content you need.
|
||||||
|
|
||||||
|
For example we could override the full `layout.css` by adding it like so
|
||||||
|
|
||||||
|
👉 `fire-theme/layout.css`
|
||||||
|
|
||||||
|
```css copy
|
||||||
|
body {
|
||||||
|
background: hotpink;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you have that you can add it to your Rocket config.
|
||||||
|
|
||||||
|
NOTE: The order of presets is important, as for example in this case we take everything from `rocketLaunch` but later override via `fireTheme`.
|
||||||
|
|
||||||
|
👉 `rocket.config.js`
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js copy
|
||||||
|
import { rocketLaunch } from '@rocket/launch';
|
||||||
|
import { fireTheme } from 'path/to/fire-theme/fireTheme.js';
|
||||||
|
|
||||||
|
/** @type {import('@rocket/cli').RocketCliOptions} */
|
||||||
|
export default ({
|
||||||
|
presets: [rocketLaunch(), fireTheme()],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
22
docs/guides/presets/create-your-own/hooks.md
Normal file
22
docs/guides/presets/create-your-own/hooks.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Presets >> Create your Own >> Hooks || 20
|
||||||
|
|
||||||
|
Your preset can hook into the rocket lifecycle by specifying a function for `before11ty`. This function runs before 11ty calls it's write method. If it is an async function, Rocket will await it's promise.
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
```js
|
||||||
|
/** @type {import('@rocket/cli').RocketPreset} */
|
||||||
|
export default ({
|
||||||
|
async before11ty() {
|
||||||
|
await copyDataFiles();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
## Preset Interface
|
||||||
|
|
||||||
|
The full preset interface is copied below for your reference.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
{% include ../../../../packages/cli/types/preset.d.ts %}
|
||||||
|
```
|
||||||
7
docs/guides/presets/create-your-own/index.md
Normal file
7
docs/guides/presets/create-your-own/index.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Presets >> Create your Own || 40
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
- [Getting Started](./getting-started/)
|
||||||
|
- [Hooks](./hooks/)
|
||||||
|
- [Publishing your Preset](./publishing/)
|
||||||
60
docs/guides/presets/create-your-own/publishing.md
Normal file
60
docs/guides/presets/create-your-own/publishing.md
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# Presets >> Create your Own >> Publishing || 100
|
||||||
|
|
||||||
|
If you would like to publish a preset to use it on multiple websites or share it with your friends you can do like so.
|
||||||
|
|
||||||
|
1. Pick a name for the package
|
||||||
|
- use the convention `rocket-preset-${name}`
|
||||||
|
- for this example we use `rocket-preset-fire-theme`.
|
||||||
|
2. Create a new folder `fire-theme`
|
||||||
|
3. Create a folder `fire-theme/preset` copy `fireTheme.js` from [above](../getting-started/) into `preset/fireTheme.js`
|
||||||
|
4. Add a 👉 `package.json`
|
||||||
|
|
||||||
|
```json copy
|
||||||
|
{
|
||||||
|
"name": "rocket-preset-fire-theme",
|
||||||
|
"version": "0.3.0",
|
||||||
|
"description": "Fire Theme for Rocket",
|
||||||
|
"license": "MIT",
|
||||||
|
"type": "module",
|
||||||
|
"exports": {
|
||||||
|
".": "./index.js",
|
||||||
|
"./preset/": "./preset/"
|
||||||
|
},
|
||||||
|
"files": ["*.js", "preset"],
|
||||||
|
"keywords": ["rocket", "preset"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Add a 👉 `index.js`
|
||||||
|
|
||||||
|
```js copy
|
||||||
|
export { fireTheme } from './preset/fireTheme.js';
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
6. Add a 👉 `README.md`
|
||||||
|
|
||||||
|
~~~markdown copy
|
||||||
|
# FireTheme
|
||||||
|
|
||||||
|
This is a theme/preset for [Rocket](https://rocket.modern-web.dev/).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```
|
||||||
|
npm i -D fire-theme
|
||||||
|
```
|
||||||
|
|
||||||
|
Add it to your 👉 `rocket.config.js`
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { fireTheme } from 'fire-theme';
|
||||||
|
|
||||||
|
/** @type {import('@rocket/cli').RocketCliOptions} */
|
||||||
|
export default ({
|
||||||
|
presets: [rocketLaunch(), fireTheme()],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
~~~
|
||||||
|
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
@@ -1,7 +1,36 @@
|
|||||||
# Presets >> Getting Started ||10
|
# Presets >> Getting Started || 10
|
||||||
|
|
||||||
Presets are ...
|
Presets are partial rocket configs that combine any number of plugins to add specific features. Rocket is built on these presets, like `rocketLaunch`, `rocketBlog`, and `rocketSearch`
|
||||||
|
|
||||||
You can use a preset via the config...
|
You can use a preset via the config by adding it to the `presets` array
|
||||||
|
|
||||||
You can load multiple presets.
|
<!-- prettier-ignore-start -->
|
||||||
|
```js copy
|
||||||
|
import { rocketLaunch } from '@rocket/launch';
|
||||||
|
import { rocketBlog } from '@rocket/blog';
|
||||||
|
import { rocketSearch } from '@rocket/search';
|
||||||
|
|
||||||
|
/** @type {import('@rocket/cli').RocketCliOptions} */
|
||||||
|
export default ({
|
||||||
|
presets: [rocketLaunch(), rocketBlog(), rocketSearch()],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
## Community Presets
|
||||||
|
|
||||||
|
There are a number of community-made presets available:
|
||||||
|
|
||||||
|
<!--
|
||||||
|
-- Thank you for your interest in rocket. To add your preset,
|
||||||
|
-- follow the format below. Please add your preset in alphabetical order.
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [rocket-preset-code-tabs](https://www.npmjs.com/package/rocket-preset-code-tabs) - Add tab elements for code blocks
|
||||||
|
- [rocket-preset-custom-elements-manifest](https://www.npmjs.com/package/rocket-preset-custom-elements-manifest) - Documents code generation for JavaScript libraries, particularly custom elements.
|
||||||
|
- [rocket-preset-markdown-directive](https://www.npmjs.com/package/rocket-preset-markdown-directive) - Add your own custom md code block directives
|
||||||
|
- [rocket-preset-playground-elements](https://www.npmjs.com/package/rocket-preset-playground-elements) - Live code editors that run in-browser
|
||||||
|
- [rocket-preset-slide-decks](https://www.npmjs.com/package/rocket-preset-slide-decks) - Slide decks in Markdown and HTML
|
||||||
|
- [rocket-preset-webcomponents-dev](https://www.npmjs.com/package/rocket-preset-webcomponents-dev) - Live code editors that run on webcomponents.dev
|
||||||
|
|
||||||
|
> Want your plugin listed here? Please [create a PR](https://github.com/modernweb-dev/rocket/edit/main/docs/guides/presets/getting-started.md)!
|
||||||
|
|||||||
@@ -1 +1,6 @@
|
|||||||
# Presets || 20
|
# Presets || 20
|
||||||
|
|
||||||
|
- [Getting Started](./getting-started/)
|
||||||
|
- [Overriding](./overriding/)
|
||||||
|
- [Using Templates](./using-templates/)
|
||||||
|
- [Create Your Own](./create-your-own/getting-started/)
|
||||||
|
|||||||
@@ -4,4 +4,23 @@ All loaded presets will be combined but you can override each file.
|
|||||||
|
|
||||||
Take a look at `docs/_merged_includes` and override what you want to override by placing the same filename into `_includes`.
|
Take a look at `docs/_merged_includes` and override what you want to override by placing the same filename into `_includes`.
|
||||||
|
|
||||||
|
For example, to override the css files loaded in the `<head>`,
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp docs/_merged_includes/_joiningBlocks/head/40-stylesheets.njk \
|
||||||
|
docs/_includes/_joiningBlocks/head/40-stylesheets.njk
|
||||||
|
```
|
||||||
|
|
||||||
|
then edit the file to suit your needs.
|
||||||
|
|
||||||
Also works for `_assets`, `_data` ...
|
Also works for `_assets`, `_data` ...
|
||||||
|
|
||||||
|
<inline-notification type="warning">
|
||||||
|
|
||||||
|
If you don't [add `.eleventyignore`](/guides/first-pages/getting-started/#setup), you may receive error messages when running `rocket build`.
|
||||||
|
|
||||||
|
</inline-notification>
|
||||||
|
|
||||||
|
```js script
|
||||||
|
import '@rocket/launch/inline-notification/inline-notification.js';
|
||||||
|
```
|
||||||
|
|||||||
@@ -37,6 +37,14 @@ If you look into `docs/_merged_includes/_joiningBlocks/bottom/` you will see a f
|
|||||||
- `190-google-analytics.njk`
|
- `190-google-analytics.njk`
|
||||||
- `my-script.njk`
|
- `my-script.njk`
|
||||||
|
|
||||||
|
<inline-notification type="tip">
|
||||||
|
|
||||||
|
File names without an order/number in front are considered with the order number `10 000` so the generally end up at the bottom. If you need something even below unordered items you can use numbers that are greater then `10 000`.
|
||||||
|
|
||||||
|
_Note: For unordered files there is no guarantee of any order._
|
||||||
|
|
||||||
|
</inline-notification>
|
||||||
|
|
||||||
## Controlling the order
|
## Controlling the order
|
||||||
|
|
||||||
In the html `<head>` order is usually not that important but when adding script it does.
|
In the html `<head>` order is usually not that important but when adding script it does.
|
||||||
@@ -57,3 +65,7 @@ which brings the order to
|
|||||||
## More information
|
## More information
|
||||||
|
|
||||||
For more details please see the [Joining Blocks Docs](../../docs/presets/joining-blocks.md)
|
For more details please see the [Joining Blocks Docs](../../docs/presets/joining-blocks.md)
|
||||||
|
|
||||||
|
```js script
|
||||||
|
import '@rocket/launch/inline-notification/inline-notification.js';
|
||||||
|
```
|
||||||
|
|||||||
4
netlify.toml
Normal file
4
netlify.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[[headers]]
|
||||||
|
for = "/*"
|
||||||
|
[headers.values]
|
||||||
|
Content-Security-Policy = "default-src 'self'; script-src 'self' www.googletagmanager.com 'sha256-W6Gq+BvrdAAMbF8E7WHA7UPQxuUOfJM8E9mpKD0oihA=' 'sha256-vFU+IJ5dUUukI5Varwy49dN2d89DmFj7UNewqQv88sw='; style-src 'self' 'unsafe-inline' fonts.googleapis.com; font-src 'self' data: fonts.gstatic.com;"
|
||||||
28
package.json
28
package.json
@@ -8,16 +8,18 @@
|
|||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"analyze": "run-s analyze:* format:*",
|
||||||
|
"analyze:analyze": "node scripts/workspaces-scripts-bin.mjs analyze",
|
||||||
"build": "npm run build:packages && npm run build:site",
|
"build": "npm run build:packages && npm run build:site",
|
||||||
"build:packages": "node scripts/workspaces-scripts-bin.mjs build:package",
|
"build:packages": "node scripts/workspaces-scripts-bin.mjs build:package",
|
||||||
"build:site": "npm run rocket:build",
|
"build:site": "run-s analyze:* rocket:build",
|
||||||
"changeset": "changeset",
|
"changeset": "changeset",
|
||||||
"debug": "web-test-runner --watch --config web-test-runner-chrome.config.mjs",
|
"debug": "web-test-runner --watch --config web-test-runner-chrome.config.mjs",
|
||||||
"debug:firefox": "web-test-runner --watch --config web-test-runner-firefox.config.mjs",
|
"debug:firefox": "web-test-runner --watch --config web-test-runner-firefox.config.mjs",
|
||||||
"debug:webkit": "web-test-runner --watch --config web-test-runner-webkit.config.mjs",
|
"debug:webkit": "web-test-runner --watch --config web-test-runner-webkit.config.mjs",
|
||||||
"format": "npm run format:eslint && npm run format:prettier",
|
"format": "run-s format:*",
|
||||||
"format:eslint": "eslint --ext .ts,.js,.mjs,.cjs . --fix",
|
"format:eslint": "eslint --ext .ts,.js,.mjs,.cjs . --fix",
|
||||||
"format:prettier": "node node_modules/prettier/bin-prettier.js \"**/*.{ts,js,mjs,cjs,md}\" \"**/package.json\" --write --ignore-path .eslintignore",
|
"format:prettier": "node node_modules/prettier/bin-prettier.js \"**/*.{ts,js,mjs,cjs,md}\" \"**/!(expected)/package.json\" --write --ignore-path .eslintignore",
|
||||||
"lint": "run-p lint:*",
|
"lint": "run-p lint:*",
|
||||||
"lint:eslint": "eslint --ext .ts,.js,.mjs,.cjs .",
|
"lint:eslint": "eslint --ext .ts,.js,.mjs,.cjs .",
|
||||||
"lint:prettier": "node node_modules/prettier/bin-prettier.js \"**/*.{ts,js,mjs,cjs,md}\" --check --ignore-path .eslintignore",
|
"lint:prettier": "node node_modules/prettier/bin-prettier.js \"**/*.{ts,js,mjs,cjs,md}\" --check --ignore-path .eslintignore",
|
||||||
@@ -31,7 +33,8 @@
|
|||||||
"setup": "npm run setup:ts-configs && npm run build:packages",
|
"setup": "npm run setup:ts-configs && npm run build:packages",
|
||||||
"setup:patches": "npx patch-package",
|
"setup:patches": "npx patch-package",
|
||||||
"setup:ts-configs": "node scripts/generate-ts-configs.mjs",
|
"setup:ts-configs": "node scripts/generate-ts-configs.mjs",
|
||||||
"start": "node packages/cli/src/cli.js start",
|
"xprestart": "yarn analyze",
|
||||||
|
"start": "node --trace-warnings packages/cli/src/cli.js start",
|
||||||
"test": "yarn test:node && yarn test:web",
|
"test": "yarn test:node && yarn test:web",
|
||||||
"test:node": "mocha \"packages/*/test-node/**/*.test.{ts,js,mjs,cjs}\" --timeout 5000 --reporter dot --exit",
|
"test:node": "mocha \"packages/*/test-node/**/*.test.{ts,js,mjs,cjs}\" --timeout 5000 --reporter dot --exit",
|
||||||
"test:web": "web-test-runner",
|
"test:web": "web-test-runner",
|
||||||
@@ -44,8 +47,9 @@
|
|||||||
"update-package-configs": "node scripts/update-package-configs.mjs && yarn format"
|
"update-package-configs": "node scripts/update-package-configs.mjs && yarn format"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@changesets/cli": "^2.12.0",
|
"@changesets/cli": "^2.20.0",
|
||||||
"@open-wc/testing": "^2.5.32",
|
"@custom-elements-manifest/analyzer": "^0.4.12",
|
||||||
|
"@open-wc/testing": "^3.0.0-next.1",
|
||||||
"@rollup/plugin-commonjs": "^17.0.0",
|
"@rollup/plugin-commonjs": "^17.0.0",
|
||||||
"@rollup/plugin-json": "^4.1.0",
|
"@rollup/plugin-json": "^4.1.0",
|
||||||
"@rollup/plugin-typescript": "^8.1.0",
|
"@rollup/plugin-typescript": "^8.1.0",
|
||||||
@@ -58,31 +62,33 @@
|
|||||||
"@typescript-eslint/parser": "^4.13.0",
|
"@typescript-eslint/parser": "^4.13.0",
|
||||||
"@web/test-runner": "^0.12.2",
|
"@web/test-runner": "^0.12.2",
|
||||||
"@web/test-runner-commands": "^0.4.0",
|
"@web/test-runner-commands": "^0.4.0",
|
||||||
"@web/test-runner-playwright": "^0.8.0",
|
"@web/test-runner-playwright": "^0.8.8",
|
||||||
|
"cem-plugin-readme": "^0.1.3",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"concurrently": "^5.3.0",
|
"concurrently": "^5.3.0",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"deepmerge": "^4.2.2",
|
"deepmerge": "^4.2.2",
|
||||||
"esbuild": "^0.8.31",
|
"esbuild": "^0.12.15",
|
||||||
"eslint": "^7.17.0",
|
"eslint": "^7.17.0",
|
||||||
"eslint-config-prettier": "^7.1.0",
|
"eslint-config-prettier": "^7.1.0",
|
||||||
"hanbi": "^0.4.1",
|
"hanbi": "^0.4.1",
|
||||||
"husky": "^4.3.7",
|
"husky": "^4.3.7",
|
||||||
"lint-staged": "^10.5.3",
|
"lint-staged": "^10.5.3",
|
||||||
"mocha": "^8.2.1",
|
"mocha": "^8.2.1",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.7",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"onchange": "^7.1.0",
|
"onchange": "^7.1.0",
|
||||||
"prettier": "^2.2.1",
|
"prettier": "^2.2.1",
|
||||||
"prettier-plugin-package": "^1.3.0",
|
"prettier-plugin-package": "^1.3.0",
|
||||||
"puppeteer": "^5.5.0",
|
"publish-docs": "^0.1.2",
|
||||||
|
"puppeteer": "^9.0.0",
|
||||||
"remark-emoji": "^2.1.0",
|
"remark-emoji": "^2.1.0",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rollup": "^2.36.1",
|
"rollup": "^2.36.1",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"sinon": "^9.2.3",
|
"sinon": "^9.2.3",
|
||||||
"ts-node": "^9.1.1",
|
"ts-node": "^9.1.1",
|
||||||
"typescript": "^4.1.3"
|
"typescript": "^4.3.2"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"parser": "@typescript-eslint/parser",
|
"parser": "@typescript-eslint/parser",
|
||||||
|
|||||||
@@ -1,5 +1,50 @@
|
|||||||
# @rocket/blog
|
# @rocket/blog
|
||||||
|
|
||||||
|
## 0.4.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 70bb7a1: BREAKING CHANGE: Update to latest plugins manager to get type safe options
|
||||||
|
|
||||||
|
There is no longer a name string as a key for a plugin. It is identified by it's function/class. You will need to adjust your code if you are adding or adjusting plugins.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- addPlugin({ name: 'my-plugin', plugin: myPlugin, options: { myFlag: true }, location: 'top' });
|
||||||
|
+ addPlugin(myPlugin, { myFlag: true }, { location: 'top' });
|
||||||
|
- adjustPluginOptions('my-plugin', { myFlag: true });
|
||||||
|
+ adjustPluginOptions(myPlugin, { myFlag: true });
|
||||||
|
```
|
||||||
|
|
||||||
|
For more details please see the [Changelog](https://github.com/modernweb-dev/rocket/blob/main/packages/plugins-manager/CHANGELOG.md#030) of the plugins-manager package.
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- plugins-manager@0.3.0
|
||||||
|
|
||||||
|
## 0.3.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- e1089c5: add title to blog page
|
||||||
|
|
||||||
|
## 0.3.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 00f4a91: alignment + spacings for article grids
|
||||||
|
|
||||||
|
## 0.3.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- a5661b8: Updates dependencies
|
||||||
|
|
||||||
## 0.3.0
|
## 0.3.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/blog",
|
"name": "@rocket/blog",
|
||||||
"version": "0.3.0",
|
"version": "0.4.0",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -38,6 +38,6 @@
|
|||||||
"testing"
|
"testing"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"plugins-manager": "^0.2.1"
|
"plugins-manager": "^0.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ body[layout='layout-blog-details'] #sidebar-nav li.anchor a:hover::before {
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
margin: calc(-1 * var(--gap)) 0 0 calc(-1 * var(--gap));
|
margin: calc(-1 * var(--gap)) 0 0 calc(-1 * var(--gap));
|
||||||
width: calc(100% + var(--gap));
|
width: calc(100% + var(--gap));
|
||||||
|
|
||||||
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.articles article {
|
.articles article {
|
||||||
@@ -32,6 +34,12 @@ body[layout='layout-blog-details'] #sidebar-nav li.anchor a:hover::before {
|
|||||||
.articles article h2 {
|
.articles article h2 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border: none;
|
border: none;
|
||||||
|
padding-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.articles article .thumbnail {
|
||||||
|
display: block;
|
||||||
|
height: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.articles article .read {
|
.articles article .read {
|
||||||
@@ -48,7 +56,7 @@ body[layout='layout-blog-details'] #sidebar-nav li.anchor a:hover::before {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 1024px) {
|
@media screen and (min-width: 1024px) {
|
||||||
body[layout='layout-blog-details'] #sidebar {
|
body[layout='layout-blog-details'] #sidebar {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
{% if title %}
|
||||||
|
<h1>{{title}}</h1>
|
||||||
|
{% endif %}
|
||||||
{% if cover_image %}
|
{% if cover_image %}
|
||||||
<img src="{{ cover_image | url }}" alt="">
|
<img src="{{ cover_image | url }}" alt="">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
{% if post.data.published %}
|
{% if post.data.published %}
|
||||||
<article>
|
<article>
|
||||||
{% if post.data.cover_image %}
|
{% if post.data.cover_image %}
|
||||||
<a href="{{ post.url | url }}">
|
<a href="{{ post.url | url }}" class="thumbnail" style="background-image: url({{ post.data.cover_image | url }});">
|
||||||
<img src="{{ post.data.cover_image | url }}" alt="">
|
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
|||||||
@@ -1 +1,9 @@
|
|||||||
<link rel="stylesheet" href="{{ '/_assets/rocket-blog.css' | asset | url }}">
|
<link rel="stylesheet" href="{{ '/_assets/rocket-blog.css' | asset | url }}">
|
||||||
|
{%- if layout == 'layout-blog-overview' -%}
|
||||||
|
<style>
|
||||||
|
.articles article .thumbnail {
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{%- endif -%}
|
||||||
|
|||||||
@@ -47,6 +47,6 @@ export function rocketBlog({ section = SECTION, postCollection = POST_COLLECTION
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
path: path.resolve(__dirname),
|
path: path.resolve(__dirname),
|
||||||
setupEleventyPlugins: [addPlugin({ name: 'rocket-blog', plugin: eleventyPluginRocketBlog })],
|
setupEleventyPlugins: [addPlugin(eleventyPluginRocketBlog)],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,34 @@
|
|||||||
# @rocket/building-rollup
|
# @rocket/building-rollup
|
||||||
|
|
||||||
|
## 0.4.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 70bb7a1: BREAKING CHANGE: Update to latest plugins manager to get type safe options
|
||||||
|
|
||||||
|
There is no longer a name string as a key for a plugin. It is identified by it's function/class. You will need to adjust your code if you are adding or adjusting plugins.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- addPlugin({ name: 'my-plugin', plugin: myPlugin, options: { myFlag: true }, location: 'top' });
|
||||||
|
+ addPlugin(myPlugin, { myFlag: true }, { location: 'top' });
|
||||||
|
- adjustPluginOptions('my-plugin', { myFlag: true });
|
||||||
|
+ adjustPluginOptions(myPlugin, { myFlag: true });
|
||||||
|
```
|
||||||
|
|
||||||
|
For more details please see the [Changelog](https://github.com/modernweb-dev/rocket/blob/main/packages/plugins-manager/CHANGELOG.md#030) of the plugins-manager package.
|
||||||
|
|
||||||
|
## 0.3.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 60e85a1: Support `picture` tags by handling `source` tags with `srcset` attributes in the rollup asset gathering build phase.
|
||||||
|
|
||||||
|
## 0.3.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 2724f07: Stop auto generating a service worker from a template. Setup your own and then bundle via `createServiceWorkerConfig`.
|
||||||
|
|
||||||
## 0.2.0
|
## 0.2.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|||||||
@@ -6,3 +6,7 @@
|
|||||||
export { createBasicConfig, createBasicMetaConfig } from './src/createBasicConfig.js';
|
export { createBasicConfig, createBasicMetaConfig } from './src/createBasicConfig.js';
|
||||||
export { createSpaConfig, createSpaMetaConfig } from './src/createSpaConfig.js';
|
export { createSpaConfig, createSpaMetaConfig } from './src/createSpaConfig.js';
|
||||||
export { createMpaConfig, createMpaMetaConfig } from './src/createMpaConfig.js';
|
export { createMpaConfig, createMpaMetaConfig } from './src/createMpaConfig.js';
|
||||||
|
export {
|
||||||
|
createServiceWorkerConfig,
|
||||||
|
createServiceWorkerMetaConfig,
|
||||||
|
} from './src/createServiceWorkerConfig.js';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/building-rollup",
|
"name": "@rocket/building-rollup",
|
||||||
"version": "0.2.0",
|
"version": "0.4.0",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -55,11 +55,16 @@
|
|||||||
"@babel/preset-env": "^7.12.11",
|
"@babel/preset-env": "^7.12.11",
|
||||||
"@rollup/plugin-babel": "^5.2.2",
|
"@rollup/plugin-babel": "^5.2.2",
|
||||||
"@rollup/plugin-node-resolve": "^11.0.1",
|
"@rollup/plugin-node-resolve": "^11.0.1",
|
||||||
"@web/rollup-plugin-html": "^1.6.0",
|
"@rollup/plugin-replace": "^2.4.2",
|
||||||
|
"@web/rollup-plugin-html": "^1.8.0",
|
||||||
"@web/rollup-plugin-import-meta-assets": "^1.0.4",
|
"@web/rollup-plugin-import-meta-assets": "^1.0.4",
|
||||||
"@web/rollup-plugin-polyfills-loader": "^1.1.0",
|
"@web/rollup-plugin-polyfills-loader": "^1.1.0",
|
||||||
"browserslist": "^4.16.1",
|
"browserslist": "^4.16.1",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"rollup-plugin-workbox": "^6.1.0"
|
"workbox-broadcast-update": "^6.1.5",
|
||||||
|
"workbox-cacheable-response": "^6.1.5",
|
||||||
|
"workbox-expiration": "^6.1.5",
|
||||||
|
"workbox-routing": "^6.1.5",
|
||||||
|
"workbox-strategies": "^6.1.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import resolve from '@rollup/plugin-node-resolve';
|
|||||||
import { terser } from 'rollup-plugin-terser';
|
import { terser } from 'rollup-plugin-terser';
|
||||||
import babelPkg from '@rollup/plugin-babel';
|
import babelPkg from '@rollup/plugin-babel';
|
||||||
|
|
||||||
import { metaConfigToRollupConfig } from 'plugins-manager';
|
import { applyPlugins } from 'plugins-manager';
|
||||||
|
|
||||||
const { babel } = babelPkg;
|
const { babel } = babelPkg;
|
||||||
|
|
||||||
export function createBasicConfig(userConfig) {
|
export function createBasicConfig(userConfig) {
|
||||||
const { config, metaPlugins } = createBasicMetaConfig(userConfig);
|
const { config, metaPlugins } = createBasicMetaConfig(userConfig);
|
||||||
return metaConfigToRollupConfig(config, metaPlugins);
|
return applyPlugins(config, metaPlugins);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBasicMetaConfig(userConfig = { output: {} }) {
|
export function createBasicMetaConfig(userConfig = { output: {} }) {
|
||||||
@@ -39,14 +39,12 @@ export function createBasicMetaConfig(userConfig = { output: {} }) {
|
|||||||
|
|
||||||
let metaPlugins = [
|
let metaPlugins = [
|
||||||
{
|
{
|
||||||
name: 'node-resolve',
|
|
||||||
plugin: resolve,
|
plugin: resolve,
|
||||||
options: {
|
options: {
|
||||||
moduleDirectories: ['node_modules', 'web_modules'],
|
moduleDirectories: ['node_modules', 'web_modules'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'babel',
|
|
||||||
plugin: babel,
|
plugin: babel,
|
||||||
options: {
|
options: {
|
||||||
babelHelpers: 'bundled',
|
babelHelpers: 'bundled',
|
||||||
@@ -73,7 +71,6 @@ export function createBasicMetaConfig(userConfig = { output: {} }) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'terser',
|
|
||||||
plugin: terser,
|
plugin: terser,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { createSpaMetaConfig } from './createSpaConfig.js';
|
import { createSpaMetaConfig } from './createSpaConfig.js';
|
||||||
import { adjustPluginOptions, metaConfigToRollupConfig } from 'plugins-manager';
|
import { adjustPluginOptions, applyPlugins } from 'plugins-manager';
|
||||||
|
import { rollupPluginHTML } from '@web/rollup-plugin-html';
|
||||||
|
|
||||||
export function createMpaConfig(userConfig) {
|
export function createMpaConfig(userConfig) {
|
||||||
const { config, metaPlugins } = createMpaMetaConfig(userConfig);
|
const { config, metaPlugins } = createMpaMetaConfig(userConfig);
|
||||||
|
|
||||||
const final = metaConfigToRollupConfig(config, metaPlugins);
|
const final = applyPlugins(config, metaPlugins);
|
||||||
return final;
|
return final;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,13 +13,9 @@ export function createMpaMetaConfig(userConfig = { output: {}, setupPlugins: []
|
|||||||
const { config, metaPlugins } = createSpaMetaConfig(userConfig);
|
const { config, metaPlugins } = createSpaMetaConfig(userConfig);
|
||||||
|
|
||||||
config.setupPlugins = [
|
config.setupPlugins = [
|
||||||
adjustPluginOptions('html', {
|
adjustPluginOptions(rollupPluginHTML, {
|
||||||
flattenOutput: false,
|
flattenOutput: false,
|
||||||
}),
|
}),
|
||||||
adjustPluginOptions('workbox', config => {
|
|
||||||
delete config.navigateFallback;
|
|
||||||
return config;
|
|
||||||
}),
|
|
||||||
...config.setupPlugins,
|
...config.setupPlugins,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
88
packages/building-rollup/src/createServiceWorkerConfig.js
Normal file
88
packages/building-rollup/src/createServiceWorkerConfig.js
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
import resolve from '@rollup/plugin-node-resolve';
|
||||||
|
import { terser } from 'rollup-plugin-terser';
|
||||||
|
import babelPkg from '@rollup/plugin-babel';
|
||||||
|
import replace from '@rollup/plugin-replace';
|
||||||
|
|
||||||
|
import { applyPlugins } from 'plugins-manager';
|
||||||
|
|
||||||
|
const { babel } = babelPkg;
|
||||||
|
|
||||||
|
export function createServiceWorkerConfig(userConfig) {
|
||||||
|
const { config, metaPlugins } = createServiceWorkerMetaConfig(userConfig);
|
||||||
|
return applyPlugins(config, metaPlugins);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createServiceWorkerMetaConfig(userConfig = { output: {} }) {
|
||||||
|
const developmentMode =
|
||||||
|
typeof userConfig.developmentMode !== undefined
|
||||||
|
? userConfig.developmentMode
|
||||||
|
: !!process.env.ROLLUP_WATCH;
|
||||||
|
delete userConfig.developmentMode;
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
treeshake: !developmentMode,
|
||||||
|
setupPlugins: [],
|
||||||
|
...userConfig,
|
||||||
|
|
||||||
|
output: {
|
||||||
|
format: 'iife',
|
||||||
|
file: 'service-worker.js',
|
||||||
|
...userConfig.output,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let metaPlugins = [
|
||||||
|
{
|
||||||
|
plugin: resolve,
|
||||||
|
options: {
|
||||||
|
moduleDirectories: ['node_modules', 'web_modules'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plugin: replace,
|
||||||
|
options: {
|
||||||
|
'process.env.NODE_ENV': JSON.stringify(developmentMode ? 'development' : 'production'),
|
||||||
|
preventAssignment: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plugin: babel,
|
||||||
|
options: {
|
||||||
|
babelHelpers: 'bundled',
|
||||||
|
compact: true,
|
||||||
|
presets: [
|
||||||
|
[
|
||||||
|
'@babel/preset-env',
|
||||||
|
{
|
||||||
|
targets: [
|
||||||
|
'last 3 Chrome major versions',
|
||||||
|
'last 3 ChromeAndroid major versions',
|
||||||
|
'last 3 Firefox major versions',
|
||||||
|
'last 3 Edge major versions',
|
||||||
|
'last 3 Safari major versions',
|
||||||
|
'last 3 iOS major versions',
|
||||||
|
],
|
||||||
|
useBuiltIns: false,
|
||||||
|
shippedProposals: true,
|
||||||
|
modules: false,
|
||||||
|
bugfixes: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plugin: terser,
|
||||||
|
options: {
|
||||||
|
mangle: {
|
||||||
|
toplevel: true,
|
||||||
|
properties: {
|
||||||
|
regex: /(^_|_$)/,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return { config, metaPlugins, developmentMode };
|
||||||
|
}
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
import path from 'path';
|
|
||||||
import { rollupPluginHTML } from '@web/rollup-plugin-html';
|
import { rollupPluginHTML } from '@web/rollup-plugin-html';
|
||||||
import { generateSW } from 'rollup-plugin-workbox';
|
|
||||||
import { importMetaAssets } from '@web/rollup-plugin-import-meta-assets';
|
import { importMetaAssets } from '@web/rollup-plugin-import-meta-assets';
|
||||||
import { polyfillsLoader } from '@web/rollup-plugin-polyfills-loader';
|
import { polyfillsLoader } from '@web/rollup-plugin-polyfills-loader';
|
||||||
import { metaConfigToRollupConfig } from 'plugins-manager';
|
import { applyPlugins } from 'plugins-manager';
|
||||||
|
|
||||||
import { createBasicMetaConfig } from './createBasicConfig.js';
|
import { createBasicMetaConfig } from './createBasicConfig.js';
|
||||||
|
|
||||||
export function createSpaConfig(userConfig) {
|
export function createSpaConfig(userConfig) {
|
||||||
const { config, metaPlugins } = createSpaMetaConfig(userConfig);
|
const { config, metaPlugins } = createSpaMetaConfig(userConfig);
|
||||||
return metaConfigToRollupConfig(config, metaPlugins);
|
return applyPlugins(config, metaPlugins);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSpaMetaConfig(userConfig = { output: {} }) {
|
export function createSpaMetaConfig(userConfig = { output: {} }) {
|
||||||
@@ -32,44 +30,16 @@ export function createSpaMetaConfig(userConfig = { output: {} }) {
|
|||||||
const spaMetaPlugins = [
|
const spaMetaPlugins = [
|
||||||
...metaPlugins,
|
...metaPlugins,
|
||||||
{
|
{
|
||||||
name: 'html',
|
|
||||||
plugin: rollupPluginHTML,
|
plugin: rollupPluginHTML,
|
||||||
options: {
|
options: {
|
||||||
rootDir,
|
rootDir,
|
||||||
absoluteBaseUrl,
|
absoluteBaseUrl,
|
||||||
injectServiceWorker: true,
|
|
||||||
serviceWorkerPath: path.join(config.output.dir, 'service-worker.js'),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'workbox',
|
|
||||||
plugin: generateSW,
|
|
||||||
options: {
|
|
||||||
// Keep 'legacy-*.js' just for retro compatibility
|
|
||||||
globIgnores: ['polyfills/*.js', 'legacy-*.js', 'nomodule-*.js'],
|
|
||||||
navigateFallback: '/index.html',
|
|
||||||
// where to output the generated sw
|
|
||||||
swDest: path.join(config.output.dir, 'service-worker.js'),
|
|
||||||
// directory to match patterns against to be precached
|
|
||||||
globDirectory: path.join(config.output.dir),
|
|
||||||
// cache any html js and css by default
|
|
||||||
globPatterns: ['**/*.{html,js,css,webmanifest}', '**/*-search-index.json'],
|
|
||||||
skipWaiting: true,
|
|
||||||
clientsClaim: true,
|
|
||||||
runtimeCaching: [
|
|
||||||
{
|
|
||||||
urlPattern: 'polyfills/*.js',
|
|
||||||
handler: 'CacheFirst',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'import-meta-assets',
|
|
||||||
plugin: importMetaAssets,
|
plugin: importMetaAssets,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'polyfills-loader',
|
|
||||||
plugin: polyfillsLoader,
|
plugin: polyfillsLoader,
|
||||||
options: {
|
options: {
|
||||||
polyfills: {},
|
polyfills: {},
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ describe('plugin count', () => {
|
|||||||
expect(config.plugins.length).to.equal(3);
|
expect(config.plugins.length).to.equal(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('createSpaConfig has 7 plugins', () => {
|
it('createSpaConfig has 6 plugins', () => {
|
||||||
const config = createSpaConfig();
|
const config = createSpaConfig();
|
||||||
expect(config.plugins.length).to.equal(7);
|
expect(config.plugins.length).to.equal(6);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('createMpaConfig has 7 plugins', () => {
|
it('createMpaConfig has 6 plugins', () => {
|
||||||
const config = createMpaConfig();
|
const config = createMpaConfig();
|
||||||
expect(config.plugins.length).to.equal(7);
|
expect(config.plugins.length).to.equal(6);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -26,10 +26,7 @@ async function execute(configString) {
|
|||||||
const config = (await import(configPath)).default;
|
const config = (await import(configPath)).default;
|
||||||
await buildAndWrite(config);
|
await buildAndWrite(config);
|
||||||
|
|
||||||
return async (
|
return async (fileName, { stripToBody = false, stripStartEndWhitespace = true } = {}) => {
|
||||||
fileName,
|
|
||||||
{ stripServiceWorker = false, stripToBody = false, stripStartEndWhitespace = true } = {},
|
|
||||||
) => {
|
|
||||||
let text = await fs.promises.readFile(
|
let text = await fs.promises.readFile(
|
||||||
path.join(config.output.dir, fileName.split('/').join(path.sep)),
|
path.join(config.output.dir, fileName.split('/').join(path.sep)),
|
||||||
);
|
);
|
||||||
@@ -39,11 +36,6 @@ async function execute(configString) {
|
|||||||
const bodyCloseTagStart = text.indexOf('</body>');
|
const bodyCloseTagStart = text.indexOf('</body>');
|
||||||
text = text.substring(bodyOpenTagEnd, bodyCloseTagStart);
|
text = text.substring(bodyOpenTagEnd, bodyCloseTagStart);
|
||||||
}
|
}
|
||||||
if (stripServiceWorker) {
|
|
||||||
const scriptOpenTagEnd = text.indexOf('<script inject-service-worker');
|
|
||||||
const scriptCloseTagStart = text.indexOf('</script>', scriptOpenTagEnd) + 9;
|
|
||||||
text = text.substring(0, scriptOpenTagEnd) + text.substring(scriptCloseTagStart);
|
|
||||||
}
|
|
||||||
if (stripStartEndWhitespace) {
|
if (stripStartEndWhitespace) {
|
||||||
text = text.trim();
|
text = text.trim();
|
||||||
}
|
}
|
||||||
@@ -57,19 +49,16 @@ describe('createMapConfig', () => {
|
|||||||
|
|
||||||
const indexHtml = await readOutput('index.html', {
|
const indexHtml = await readOutput('index.html', {
|
||||||
stripToBody: true,
|
stripToBody: true,
|
||||||
stripServiceWorker: true,
|
|
||||||
});
|
});
|
||||||
expect(indexHtml).to.equal('<h1>Only static HTML content in index.html</h1>');
|
expect(indexHtml).to.equal('<h1>Only static HTML content in index.html</h1>');
|
||||||
|
|
||||||
const subHtmlIndexHtml = await readOutput('sub-html/index.html', {
|
const subHtmlIndexHtml = await readOutput('sub-html/index.html', {
|
||||||
stripToBody: true,
|
stripToBody: true,
|
||||||
stripServiceWorker: true,
|
|
||||||
});
|
});
|
||||||
expect(subHtmlIndexHtml).to.equal('<h1>Only static HTML content in sub-html/index.html</h1>');
|
expect(subHtmlIndexHtml).to.equal('<h1>Only static HTML content in sub-html/index.html</h1>');
|
||||||
|
|
||||||
const subJsIndexHtml = await readOutput('sub-js/index.html', {
|
const subJsIndexHtml = await readOutput('sub-js/index.html', {
|
||||||
stripToBody: true,
|
stripToBody: true,
|
||||||
stripServiceWorker: true,
|
|
||||||
});
|
});
|
||||||
expect(subJsIndexHtml).to.equal(
|
expect(subJsIndexHtml).to.equal(
|
||||||
'<h1>Has js in sub-js/index.html</h1>\n\n\n<script type="module" src="../sub-js.js"></script>',
|
'<h1>Has js in sub-js/index.html</h1>\n\n\n<script type="module" src="../sub-js.js"></script>',
|
||||||
@@ -77,13 +66,9 @@ describe('createMapConfig', () => {
|
|||||||
|
|
||||||
const subJsAbsoluteIndexHtml = await readOutput('sub-js-absolute/index.html', {
|
const subJsAbsoluteIndexHtml = await readOutput('sub-js-absolute/index.html', {
|
||||||
stripToBody: true,
|
stripToBody: true,
|
||||||
stripServiceWorker: true,
|
|
||||||
});
|
});
|
||||||
expect(subJsAbsoluteIndexHtml).to.equal(
|
expect(subJsAbsoluteIndexHtml).to.equal(
|
||||||
'<h1>Has js in sub-js-absolute/index.html</h1>\n\n\n<script type="module" src="../sub-js-absolute.js"></script>',
|
'<h1>Has js in sub-js-absolute/index.html</h1>\n\n\n<script type="module" src="../sub-js-absolute.js"></script>',
|
||||||
);
|
);
|
||||||
|
|
||||||
const serviceWorkerJs = await readOutput('service-worker.js');
|
|
||||||
expect(serviceWorkerJs).to.include('Promise'); // not empty string might be enough...
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,31 @@
|
|||||||
# check-html-links
|
# check-html-links
|
||||||
|
|
||||||
|
## 0.2.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 5043429: Ignore `<a href="tel:9999">` links
|
||||||
|
- f08f926: Add missing `slash` dependency
|
||||||
|
- a0e8edf: Ignore links containing not http schema urls like `sketch://`, `vscode://`, ...
|
||||||
|
|
||||||
|
```html
|
||||||
|
<a href="sketch://add-library?url=https%3A%2F%2Fmyexample.com%2Fdesign%2Fui-kit.xml"></a>
|
||||||
|
<a href="vscode://file/c:/myProject/package.json:5:10"></a>
|
||||||
|
```
|
||||||
|
|
||||||
|
- 1949b1e: Ignore plain and html encoded mailto links
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- source -->
|
||||||
|
<a href="mailto:address@example.com">contact</a>
|
||||||
|
|
||||||
|
<!-- html encoded -->
|
||||||
|
<a
|
||||||
|
href="mailto:address@example.com"
|
||||||
|
>contact</a
|
||||||
|
>
|
||||||
|
```
|
||||||
|
|
||||||
## 0.2.2
|
## 0.2.2
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ A fast checker for broken links/references in HTML.
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```
|
```shell
|
||||||
npm i -D check-html-links
|
npm i -D check-html-links
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```
|
```bash
|
||||||
npx check-html-links _site
|
npx check-html-links _site
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "check-html-links",
|
"name": "check-html-links",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -37,7 +37,8 @@
|
|||||||
"command-line-args": "^5.1.1",
|
"command-line-args": "^5.1.1",
|
||||||
"glob": "^7.0.0",
|
"glob": "^7.0.0",
|
||||||
"minimatch": "^3.0.4",
|
"minimatch": "^3.0.4",
|
||||||
"sax-wasm": "^2.0.0"
|
"sax-wasm": "^2.0.0",
|
||||||
|
"slash": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/glob": "^7.0.0"
|
"@types/glob": "^7.0.0"
|
||||||
|
|||||||
@@ -182,6 +182,18 @@ function getValueAndAnchor(inValue) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} url
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function isNonHttpSchema(url) {
|
||||||
|
const found = url.match(/([a-z]+):/);
|
||||||
|
if (found) {
|
||||||
|
return found.length > 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {Link[]} links
|
* @param {Link[]} links
|
||||||
@@ -207,8 +219,13 @@ async function resolveLinks(links, { htmlFilePath, rootDir, ignoreUsage }) {
|
|||||||
|
|
||||||
if (ignoreUsage(value)) {
|
if (ignoreUsage(value)) {
|
||||||
// ignore
|
// ignore
|
||||||
} else if (value.includes('mailto:')) {
|
} else if (
|
||||||
|
value.startsWith('mailto:') ||
|
||||||
|
value.startsWith('mailto:') // = "mailto:" but html encoded
|
||||||
|
) {
|
||||||
// ignore for now - could add a check to validate if the email address is valid
|
// ignore for now - could add a check to validate if the email address is valid
|
||||||
|
} else if (value.startsWith('tel:')) {
|
||||||
|
// ignore for now - could add a check to validate if the phone number is valid
|
||||||
} else if (valueFile === '' && anchor !== '') {
|
} else if (valueFile === '' && anchor !== '') {
|
||||||
addLocalFile(htmlFilePath, anchor, usageObj);
|
addLocalFile(htmlFilePath, anchor, usageObj);
|
||||||
} else if (value.startsWith('//') || value.startsWith('http')) {
|
} else if (value.startsWith('//') || value.startsWith('http')) {
|
||||||
@@ -219,6 +236,8 @@ async function resolveLinks(links, { htmlFilePath, rootDir, ignoreUsage }) {
|
|||||||
addLocalFile(filePath, anchor, usageObj);
|
addLocalFile(filePath, anchor, usageObj);
|
||||||
} else if (value === '' && anchor === '') {
|
} else if (value === '' && anchor === '') {
|
||||||
// no need to check it
|
// no need to check it
|
||||||
|
} else if (isNonHttpSchema(value)) {
|
||||||
|
// not a schema we handle
|
||||||
} else {
|
} else {
|
||||||
const filePath = path.join(path.dirname(htmlFilePath), valueFile);
|
const filePath = path.join(path.dirname(htmlFilePath), valueFile);
|
||||||
addLocalFile(filePath, anchor, usageObj);
|
addLocalFile(filePath, anchor, usageObj);
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
<a href="mailto:foo@bar.com"></a>
|
<a href="mailto:foo@bar.com"></a>
|
||||||
|
<!-- encoded mailto links -->
|
||||||
|
<a href="mailto:address@example.com"></a>
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<a href="sketch://add-library?url=https%3A%2F%2Fmyexample.com%2Fdesign%2Fui-kit.xml"></a>
|
||||||
|
<a href="vscode://file/c:/myProject/package.json:5:10"></a>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<a href="tel:99999"></a>
|
||||||
@@ -183,6 +183,16 @@ describe('validateFolder', () => {
|
|||||||
expect(cleanup(errors)).to.deep.equal([]);
|
expect(cleanup(errors)).to.deep.equal([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('ignores tel links', async () => {
|
||||||
|
const { errors, cleanup } = await execute('fixtures/tel');
|
||||||
|
expect(cleanup(errors)).to.deep.equal([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ignore not http schema urls', async () => {
|
||||||
|
const { errors, cleanup } = await execute('fixtures/not-http-schema');
|
||||||
|
expect(cleanup(errors)).to.deep.equal([]);
|
||||||
|
});
|
||||||
|
|
||||||
it('ignoring a folder', async () => {
|
it('ignoring a folder', async () => {
|
||||||
const { errors, cleanup } = await execute('fixtures/internal-link-ignore', {
|
const { errors, cleanup } = await execute('fixtures/internal-link-ignore', {
|
||||||
ignoreLinkPatterns: ['./relative/*', './relative/**/*'],
|
ignoreLinkPatterns: ['./relative/*', './relative/**/*'],
|
||||||
|
|||||||
@@ -1,5 +1,228 @@
|
|||||||
# @rocket/cli
|
# @rocket/cli
|
||||||
|
|
||||||
|
## 0.10.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 60310ab: Improve performance by initializing sax-wasm only once even when it is running in parallel
|
||||||
|
- Updated dependencies [60310ab]
|
||||||
|
- @rocket/eleventy-rocket-nav@0.3.1
|
||||||
|
|
||||||
|
## 0.10.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 15a82c0: Enable including script files into the simulator via `<script src=".." mdjs-use>`
|
||||||
|
- 15a82c0: Allow only a limited set of characters for simulator includes `[a-zA-Z0-9\/\-_]`.
|
||||||
|
Notably, there is no:
|
||||||
|
|
||||||
|
- `:` to prevent `http://...` includes
|
||||||
|
- `.` so filenames as `this.is.my.js` are not supported. Also includes will be without file endings which will be added automatically
|
||||||
|
|
||||||
|
## 0.10.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 70bb7a1: BREAKING CHANGE: Update to latest plugins manager to get type safe options
|
||||||
|
|
||||||
|
There is no longer a name string as a key for a plugin. It is identified by it's function/class. You will need to adjust your code if you are adding or adjusting plugins.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- addPlugin({ name: 'my-plugin', plugin: myPlugin, options: { myFlag: true }, location: 'top' });
|
||||||
|
+ addPlugin(myPlugin, { myFlag: true }, { location: 'top' });
|
||||||
|
- adjustPluginOptions('my-plugin', { myFlag: true });
|
||||||
|
+ adjustPluginOptions(myPlugin, { myFlag: true });
|
||||||
|
```
|
||||||
|
|
||||||
|
For more details please see the [Changelog](https://github.com/modernweb-dev/rocket/blob/main/packages/plugins-manager/CHANGELOG.md#030) of the plugins-manager package.
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- plugins-manager@0.3.0
|
||||||
|
- @rocket/eleventy-plugin-mdjs-unified@0.6.0
|
||||||
|
- @rocket/building-rollup@0.4.0
|
||||||
|
|
||||||
|
## 0.9.11
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 7301a0f: Pass on rocketConfig to the eleventy function to enable conditional configurations/filters
|
||||||
|
- 42418f2: Disable the service worker for local development
|
||||||
|
- 5ac6aa6: Set the encoding of the simulator to utf8 via a html meta tag
|
||||||
|
|
||||||
|
## 0.9.10
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 738941a: In `rocket.config.js` you can now supply a rollup config function.
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
rollup: config => {
|
||||||
|
// config will be the fully generated config object after all presets have been applied
|
||||||
|
if (config.plugins.includes('...')) {
|
||||||
|
// change some config options
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## 0.9.9
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- adf0f1d: use img openEnd to insert responsive image
|
||||||
|
|
||||||
|
## 0.9.8
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- a5661b8: Updates dependencies
|
||||||
|
|
||||||
|
## 0.9.7
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- d91e46b: Add `bootstrap` command
|
||||||
|
- 9978ea7: Improves typings for `addPlugin`
|
||||||
|
- Updated dependencies [9978ea7]
|
||||||
|
- @rocket/eleventy-plugin-mdjs-unified@0.5.1
|
||||||
|
- plugins-manager@0.2.3
|
||||||
|
|
||||||
|
## 0.9.6
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- bf99541: Adjust copy logic to
|
||||||
|
|
||||||
|
1. for `_assets/_static` copy over everything
|
||||||
|
2. for all other paths copy over everything except `*.html` and `*.md`
|
||||||
|
|
||||||
|
- 579e8e7: Unordered joiningBlocks are now considered with the order number `10 000` and will generally be at the bottom.
|
||||||
|
You can use numbers `> 10 000` to place files even after unordered joiningBlocks.
|
||||||
|
|
||||||
|
## 0.9.5
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 1b9559f: Adds `before11ty` hook to config and presets
|
||||||
|
|
||||||
|
## 0.9.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 2b5c61d: Allow configuring the imagePreset ignore rules via the option `ignore`
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
imagePresets: {
|
||||||
|
responsive: {
|
||||||
|
// ...
|
||||||
|
ignore: ({ src }) =>
|
||||||
|
src.endsWith('.jpeg') || src.endsWith('svg') || src.includes('rocket-unresponsive.'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
- 2b5c61d: Do not generate responsive images for files ending in `.svg` or that include `rocket-ignore.`
|
||||||
|
- ce0b00e: don't transform external images
|
||||||
|
- 3b1a0cf: Allow to configure check-html-links
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
checkLinks: {
|
||||||
|
/* ... */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## 0.9.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 795a361: The server worker url should respect a set pathPrefix.
|
||||||
|
|
||||||
|
## 0.9.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 5330740: When replacing images with responsive picture tags do this from the bottom up so the initial dom parsing locations still hold true.
|
||||||
|
|
||||||
|
## 0.9.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 43a7ca1: Responsive images need to respect a set pathPrefix
|
||||||
|
|
||||||
|
## 0.9.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- eae2007: Update to mdjs version that uses lit 2 and renders stories to light dom
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [eae2007]
|
||||||
|
- @rocket/eleventy-plugin-mdjs-unified@0.5.0
|
||||||
|
|
||||||
|
## 0.8.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 60e85a1: Support `picture` tags by handling `source` tags with `srcset` attributes in the rollup asset gathering build phase.
|
||||||
|
- Updated dependencies [60e85a1]
|
||||||
|
- @rocket/building-rollup@0.3.1
|
||||||
|
|
||||||
|
## 0.8.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- c338696: Updated dependency of eleventy-img for M1 compatibility
|
||||||
|
|
||||||
|
## 0.8.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 8bba4a8: Every content image in markdown will outputted in multiple widths and formats to ensure small image file sizes while retaining quality.
|
||||||
|
You can adjust the defaults by setting `imagePresets.responsive`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
imagePresets: {
|
||||||
|
responsive: {
|
||||||
|
widths: [600, 900, 1640],
|
||||||
|
formats: ['avif', 'jpeg'],
|
||||||
|
sizes: '(min-width: 1024px) 820px, calc(100vw - 40px)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## 0.7.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 2724f07: The service worker no longer precaches all urls and assets. It now
|
||||||
|
|
||||||
|
- caches already visited pages
|
||||||
|
- caches assets of visited pages (up to 100 files then it replaces older entries)
|
||||||
|
- on service worker activation it will reload the page if a newer version is available
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [2724f07]
|
||||||
|
- @rocket/building-rollup@0.3.0
|
||||||
|
|
||||||
## 0.6.3
|
## 0.6.3
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,10 +1,26 @@
|
|||||||
const { setComputedConfig, getComputedConfig } = require('./src/public/computedConfig.cjs');
|
const { setComputedConfig, getComputedConfig } = require('./src/public/computedConfig.cjs');
|
||||||
const { generateEleventyComputed } = require('./src/public/generateEleventyComputed.cjs');
|
const {
|
||||||
|
generateEleventyComputed,
|
||||||
|
LayoutPlugin,
|
||||||
|
TitleMetaPlugin,
|
||||||
|
TitlePlugin,
|
||||||
|
EleventyNavigationPlugin,
|
||||||
|
SectionPlugin,
|
||||||
|
SocialMediaImagePlugin,
|
||||||
|
JoiningBlocksPlugin,
|
||||||
|
} = require('./src/public/generateEleventyComputed.cjs');
|
||||||
const { createSocialImage } = require('./src/public/createSocialImage.cjs');
|
const { createSocialImage } = require('./src/public/createSocialImage.cjs');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setComputedConfig,
|
setComputedConfig,
|
||||||
getComputedConfig,
|
getComputedConfig,
|
||||||
generateEleventyComputed,
|
generateEleventyComputed,
|
||||||
|
LayoutPlugin,
|
||||||
|
TitleMetaPlugin,
|
||||||
|
TitlePlugin,
|
||||||
|
EleventyNavigationPlugin,
|
||||||
|
SectionPlugin,
|
||||||
|
SocialMediaImagePlugin,
|
||||||
|
JoiningBlocksPlugin,
|
||||||
createSocialImage,
|
createSocialImage,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,16 @@
|
|||||||
/** @typedef {import('@rocket/cli/types/main').RocketCliOptions} RocketCliOptions */
|
/** @typedef {import('@rocket/cli/types/main').RocketCliOptions} RocketCliOptions */
|
||||||
|
|
||||||
|
export { setComputedConfig, getComputedConfig } from './src/public/computedConfig.cjs';
|
||||||
|
export {
|
||||||
|
generateEleventyComputed,
|
||||||
|
LayoutPlugin,
|
||||||
|
TitleMetaPlugin,
|
||||||
|
TitlePlugin,
|
||||||
|
EleventyNavigationPlugin,
|
||||||
|
SectionPlugin,
|
||||||
|
SocialMediaImagePlugin,
|
||||||
|
JoiningBlocksPlugin,
|
||||||
|
} from './src/public/generateEleventyComputed.cjs';
|
||||||
|
export { createSocialImage } from './src/public/createSocialImage.cjs';
|
||||||
|
|
||||||
export { RocketCli } from './src/RocketCli.js';
|
export { RocketCli } from './src/RocketCli.js';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/cli",
|
"name": "@rocket/cli",
|
||||||
"version": "0.6.3",
|
"version": "0.10.2",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -56,25 +56,26 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@11ty/eleventy": "^0.11.1",
|
"@11ty/eleventy": "^0.11.1",
|
||||||
"@11ty/eleventy-img": "^0.7.4",
|
"@11ty/eleventy-img": "^0.9.0",
|
||||||
"@rocket/building-rollup": "^0.2.0",
|
"@rocket/building-rollup": "^0.4.0",
|
||||||
"@rocket/core": "^0.1.2",
|
"@rocket/core": "^0.1.2",
|
||||||
"@rocket/eleventy-plugin-mdjs-unified": "^0.4.1",
|
"@rocket/eleventy-plugin-mdjs-unified": "^0.6.0",
|
||||||
"@rocket/eleventy-rocket-nav": "^0.3.0",
|
"@rocket/eleventy-rocket-nav": "^0.3.1",
|
||||||
"@rollup/plugin-babel": "^5.2.2",
|
"@rollup/plugin-babel": "^5.2.2",
|
||||||
"@rollup/plugin-node-resolve": "^11.0.1",
|
"@rollup/plugin-node-resolve": "^11.0.1",
|
||||||
"@web/config-loader": "^0.1.3",
|
"@web/config-loader": "^0.1.3",
|
||||||
"@web/dev-server": "^0.1.4",
|
"@web/dev-server": "^0.1.4",
|
||||||
"@web/dev-server-rollup": "^0.3.2",
|
"@web/dev-server-rollup": "^0.3.2",
|
||||||
"@web/rollup-plugin-copy": "^0.2.0",
|
"@web/rollup-plugin-copy": "^0.2.0",
|
||||||
"check-html-links": "^0.2.2",
|
"check-html-links": "^0.2.3",
|
||||||
"command-line-args": "^5.1.1",
|
"command-line-args": "^5.1.1",
|
||||||
"command-line-usage": "^6.1.1",
|
"command-line-usage": "^6.1.1",
|
||||||
"fs-extra": "^9.0.1",
|
"fs-extra": "^9.0.1",
|
||||||
"micromatch": "^4.0.2",
|
"micromatch": "^4.0.2",
|
||||||
"plugins-manager": "^0.2.1",
|
"plugins-manager": "^0.3.0",
|
||||||
"slash": "^3.0.0",
|
"slash": "^3.0.0",
|
||||||
"utf8": "^3.0.0"
|
"utf8": "^3.0.0",
|
||||||
|
"workbox-window": "^6.1.5"
|
||||||
},
|
},
|
||||||
"types": "dist-types/index.d.ts"
|
"types": "dist-types/index.d.ts"
|
||||||
}
|
}
|
||||||
|
|||||||
22
packages/cli/preset/_assets/scripts/registerServiceWorker.js
Normal file
22
packages/cli/preset/_assets/scripts/registerServiceWorker.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
(async () => {
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
const { Workbox } = await import('workbox-window');
|
||||||
|
|
||||||
|
const url = window.__rocketServiceWorkerUrl || '/service-worker.js';
|
||||||
|
const wb = new Workbox(url);
|
||||||
|
wb.addEventListener('message', event => {
|
||||||
|
if (event.data.type === 'CACHE_UPDATED') {
|
||||||
|
const { updatedURL } = event.data.payload;
|
||||||
|
console.log(`Reloading as a newer version of ${updatedURL} became available!`);
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
wb.register()
|
||||||
|
.then(function () {
|
||||||
|
console.log('ServiceWorker registered.');
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
console.log('ServiceWorker registration failed: ', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
29
packages/cli/preset/_assets/service-worker.js
Normal file
29
packages/cli/preset/_assets/service-worker.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { registerRoute } from 'workbox-routing';
|
||||||
|
import { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies';
|
||||||
|
import { BroadcastUpdatePlugin } from 'workbox-broadcast-update';
|
||||||
|
import { ExpirationPlugin } from 'workbox-expiration';
|
||||||
|
|
||||||
|
addEventListener('install', () => {
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
skipWaiting();
|
||||||
|
});
|
||||||
|
|
||||||
|
// addEventListener('activate', () => {
|
||||||
|
// console.log('activate');
|
||||||
|
// });
|
||||||
|
|
||||||
|
const cacheFirst = new CacheFirst({
|
||||||
|
cacheName: 'assets',
|
||||||
|
plugins: [
|
||||||
|
new ExpirationPlugin({
|
||||||
|
maxEntries: 100,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
const staleWhileRevalidate = new StaleWhileRevalidate({
|
||||||
|
cacheName: 'pages',
|
||||||
|
plugins: [new BroadcastUpdatePlugin()],
|
||||||
|
});
|
||||||
|
|
||||||
|
registerRoute(/(\/|\.html)$/, staleWhileRevalidate);
|
||||||
|
registerRoute(/\.(css|m?js|svg|woff2|png|jpg|gif|json|xml)$/, cacheFirst);
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{% set rocketServiceWorkerUrl = '/' + rocketConfig.serviceWorkerName %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.__rocketServiceWorkerUrl = '{{ rocketServiceWorkerUrl | url }}';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% if rocketConfig.command == 'build' %}
|
||||||
|
<script type="module" inject-service-worker="" src="{{ '/_assets/scripts/registerServiceWorker.js' | asset | url }}"></script>
|
||||||
|
{% endif %}
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<script>
|
|
||||||
{{ '_assets/_inline-scripts/serviceWorkerUpdate.js' | asset | toAbsPath | inlineFilePath | safe }}
|
|
||||||
</script>
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<html theme="light" platform="web" lang="en">
|
<html theme="light" platform="web" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta charset="utf-8">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -11,21 +12,39 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import { render } from 'lit-html';
|
import { render } from '@mdjs/mdjs-story';
|
||||||
|
|
||||||
|
function sanitize(input, type) {
|
||||||
|
return `${document.location.origin}/${input.match(/[a-zA-Z0-9\/\-_]*/)[0]}.${type}`;
|
||||||
|
}
|
||||||
|
|
||||||
async function onHashChange() {
|
async function onHashChange() {
|
||||||
const urlParts = new URLSearchParams(document.location.hash.substr(1));
|
const urlParts = new URLSearchParams(document.location.hash.substr(1));
|
||||||
|
|
||||||
if (urlParts.get('stylesheets')) {
|
if (urlParts.get('stylesheets')) {
|
||||||
for (const stylesheet of urlParts.getAll('stylesheets')) {
|
for (const stylesheet of urlParts.getAll('stylesheets')) {
|
||||||
if (!document.querySelector(`link[rel="stylesheet"][href="${stylesheet}"]`)) {
|
const safeStylesheetUrl = sanitize(stylesheet, 'css');
|
||||||
|
if (!document.querySelector(`link[rel="stylesheet"][href="${safeStylesheetUrl}"]`)) {
|
||||||
const link = document.createElement('link');
|
const link = document.createElement('link');
|
||||||
link.rel = 'stylesheet';
|
link.rel = 'stylesheet';
|
||||||
link.href = stylesheet;
|
link.href = safeStylesheetUrl;
|
||||||
document.head.appendChild(link);
|
document.head.appendChild(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (urlParts.get('moduleUrls')) {
|
||||||
|
for (const moduleUrl of urlParts.getAll('moduleUrls')) {
|
||||||
|
const safeModuleUrl = sanitize(moduleUrl, 'js');
|
||||||
|
if (!document.querySelector(`script[type=module][src="${safeModuleUrl}"]`)) {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.type = 'module';
|
||||||
|
script.src = safeModuleUrl;
|
||||||
|
document.head.appendChild(script);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (urlParts.get('theme')) {
|
if (urlParts.get('theme')) {
|
||||||
document.documentElement.setAttribute('theme', urlParts.get('theme'));
|
document.documentElement.setAttribute('theme', urlParts.get('theme'));
|
||||||
}
|
}
|
||||||
@@ -45,7 +64,8 @@
|
|||||||
document.documentElement.removeAttribute('edge-distance');
|
document.documentElement.removeAttribute('edge-distance');
|
||||||
}
|
}
|
||||||
|
|
||||||
const mod = await import(urlParts.get('story-file'));
|
const safeStoryUrl = sanitize(urlParts.get('story-file'), 'js');
|
||||||
|
const mod = await import(safeStoryUrl);
|
||||||
render(mod[urlParts.get('story-key')]({ shadowRoot: document }), document.body);
|
render(mod[urlParts.get('story-key')]({ shadowRoot: document }), document.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ import { rollup } from 'rollup';
|
|||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { copy } from '@web/rollup-plugin-copy';
|
import { copy } from '@web/rollup-plugin-copy';
|
||||||
|
import { rollupPluginHTML } from '@web/rollup-plugin-html';
|
||||||
|
|
||||||
import { createMpaConfig } from '@rocket/building-rollup';
|
import { createMpaConfig, createServiceWorkerConfig } from '@rocket/building-rollup';
|
||||||
import { addPlugin, adjustPluginOptions } from 'plugins-manager';
|
import { addPlugin, adjustPluginOptions } from 'plugins-manager';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,18 +26,14 @@ async function buildAndWrite(config) {
|
|||||||
|
|
||||||
async function productionBuild(config) {
|
async function productionBuild(config) {
|
||||||
const defaultSetupPlugins = [
|
const defaultSetupPlugins = [
|
||||||
addPlugin({
|
addPlugin(copy, {
|
||||||
name: 'copy',
|
patterns: ['!(*.md|*.html)*', '_merged_assets/_static/**/*'],
|
||||||
plugin: copy,
|
rootDir: config.outputDevDir,
|
||||||
options: {
|
|
||||||
patterns: ['!(*.md|*.html)*', '_merged_assets/_static/**/*.{png,gif,jpg,json,css,svg,ico}'],
|
|
||||||
rootDir: config.outputDevDir,
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
if (config.pathPrefix) {
|
if (config.pathPrefix) {
|
||||||
defaultSetupPlugins.push(
|
defaultSetupPlugins.push(
|
||||||
adjustPluginOptions('html', { absolutePathPrefix: config.pathPrefix }),
|
adjustPluginOptions(rollupPluginHTML, { absolutePathPrefix: config.pathPrefix }),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,8 +51,20 @@ async function productionBuild(config) {
|
|||||||
...config.setupBuildPlugins,
|
...config.setupBuildPlugins,
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
const finalConfig = typeof config.rollup === 'function' ? config.rollup(mpaConfig) : mpaConfig;
|
||||||
|
await buildAndWrite(finalConfig);
|
||||||
|
|
||||||
await buildAndWrite(mpaConfig);
|
const serviceWorkerSourcePath = path.resolve('docs/_merged_assets/service-worker.js');
|
||||||
|
if (fs.existsSync(serviceWorkerSourcePath)) {
|
||||||
|
const serviceWorkerConfig = createServiceWorkerConfig({
|
||||||
|
input: serviceWorkerSourcePath,
|
||||||
|
output: {
|
||||||
|
file: path.join(path.resolve(config.outputDir), config.serviceWorkerName),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await buildAndWrite(serviceWorkerConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RocketBuild {
|
export class RocketBuild {
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ const { setComputedConfig } = computedConfigPkg;
|
|||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
export class RocketEleventy extends Eleventy {
|
export class RocketEleventy extends Eleventy {
|
||||||
|
/** @type{Required<import('../types/main').RocketCliOptions>} */
|
||||||
|
// @ts-expect-error: awkward to type this in jsdoc
|
||||||
|
config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {string} output
|
* @param {string} output
|
||||||
@@ -26,11 +30,14 @@ export class RocketEleventy extends Eleventy {
|
|||||||
*/
|
*/
|
||||||
constructor(input, output, cli) {
|
constructor(input, output, cli) {
|
||||||
super(input, output);
|
super(input, output);
|
||||||
|
/** @type {*} */
|
||||||
|
this.eleventyFiles;
|
||||||
this.__rocketCli = cli;
|
this.__rocketCli = cli;
|
||||||
}
|
}
|
||||||
|
|
||||||
async write() {
|
async write() {
|
||||||
await this.__rocketCli.mergePresets();
|
await this.__rocketCli.mergePresets();
|
||||||
|
for (const fn of this.__rocketCli.config.__before11tyFunctions) await fn();
|
||||||
await super.write();
|
await super.write();
|
||||||
await this.__rocketCli.update();
|
await this.__rocketCli.update();
|
||||||
}
|
}
|
||||||
@@ -45,7 +52,10 @@ export class RocketEleventy extends Eleventy {
|
|||||||
path.join(this.__rocketCli.config._inputDirCwdRelative, '_includes', '**'),
|
path.join(this.__rocketCli.config._inputDirCwdRelative, '_includes', '**'),
|
||||||
];
|
];
|
||||||
|
|
||||||
ignores = ignores.filter(ignore => !keepWatching.includes(ignore));
|
ignores = ignores.filter(
|
||||||
|
/** @param {string} ignore */
|
||||||
|
ignore => !keepWatching.includes(ignore),
|
||||||
|
);
|
||||||
// debug("Ignoring watcher changes to: %o", ignores);
|
// debug("Ignoring watcher changes to: %o", ignores);
|
||||||
|
|
||||||
let configOptions = this.config.chokidarConfig;
|
let configOptions = this.config.chokidarConfig;
|
||||||
@@ -69,6 +79,10 @@ export class RocketCli {
|
|||||||
/** @type {string[]} */
|
/** @type {string[]} */
|
||||||
errors = [];
|
errors = [];
|
||||||
|
|
||||||
|
/** @type{Required<import('../types/main').RocketCliOptions>} */
|
||||||
|
// @ts-expect-error: awkward to type this in jsdoc
|
||||||
|
config;
|
||||||
|
|
||||||
constructor({ argv } = { argv: undefined }) {
|
constructor({ argv } = { argv: undefined }) {
|
||||||
const mainDefinitions = [
|
const mainDefinitions = [
|
||||||
{ name: 'command', defaultOption: true, defaultValue: 'help' },
|
{ name: 'command', defaultOption: true, defaultValue: 'help' },
|
||||||
@@ -106,7 +120,8 @@ export class RocketCli {
|
|||||||
|
|
||||||
const config = new TemplateConfig(null, relCwdPathToConfig);
|
const config = new TemplateConfig(null, relCwdPathToConfig);
|
||||||
elev.config = config.getConfig();
|
elev.config = config.getConfig();
|
||||||
elev.resetConfig();
|
/** @type {*} */
|
||||||
|
(elev).resetConfig();
|
||||||
elev.setConfigPathOverride(relCwdPathToConfig);
|
elev.setConfigPathOverride(relCwdPathToConfig);
|
||||||
|
|
||||||
elev.isVerbose = false;
|
elev.isVerbose = false;
|
||||||
@@ -120,7 +135,7 @@ export class RocketCli {
|
|||||||
for (const folder of ['_assets', '_data', '_includes']) {
|
for (const folder of ['_assets', '_data', '_includes']) {
|
||||||
const to = path.join(this.config._inputDirCwdRelative, `_merged${folder}`);
|
const to = path.join(this.config._inputDirCwdRelative, `_merged${folder}`);
|
||||||
await fs.emptyDir(to);
|
await fs.emptyDir(to);
|
||||||
for (const sourceDir of this.config._presetPathes) {
|
for (const sourceDir of this.config._presetPaths) {
|
||||||
const from = path.join(sourceDir, folder);
|
const from = path.join(sourceDir, folder);
|
||||||
if (fs.existsSync(from)) {
|
if (fs.existsSync(from)) {
|
||||||
if (folder === '_includes') {
|
if (folder === '_includes') {
|
||||||
@@ -138,7 +153,9 @@ export class RocketCli {
|
|||||||
*/
|
*/
|
||||||
async setup() {
|
async setup() {
|
||||||
if (this.__isSetup === false) {
|
if (this.__isSetup === false) {
|
||||||
this.config = await normalizeConfig(this.argvConfig);
|
this.config =
|
||||||
|
/** @type{Required<import('../types/main').RocketCliOptions>} */
|
||||||
|
(await normalizeConfig(this.argvConfig));
|
||||||
setComputedConfig(this.config);
|
setComputedConfig(this.config);
|
||||||
this.__isSetup = true;
|
this.__isSetup = true;
|
||||||
}
|
}
|
||||||
@@ -147,6 +164,10 @@ export class RocketCli {
|
|||||||
async run() {
|
async run() {
|
||||||
await this.setup();
|
await this.setup();
|
||||||
|
|
||||||
|
if (this.config.command === 'bootstrap') {
|
||||||
|
return this.bootstrap();
|
||||||
|
}
|
||||||
|
|
||||||
for (const plugin of this.config.plugins) {
|
for (const plugin of this.config.plugins) {
|
||||||
if (this.considerPlugin(plugin) && typeof plugin.setupCommand === 'function') {
|
if (this.considerPlugin(plugin) && typeof plugin.setupCommand === 'function') {
|
||||||
this.config = plugin.setupCommand(this.config);
|
this.config = plugin.setupCommand(this.config);
|
||||||
@@ -187,6 +208,45 @@ export class RocketCli {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async bootstrap() {
|
||||||
|
const outputDir = path.join(this.config.outputDir, '..');
|
||||||
|
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
const bootstrapFilesDir = path.join(moduleDir, 'public', 'bootstrap');
|
||||||
|
const packageJsonPath = path.join(outputDir, 'package.json');
|
||||||
|
const gitignorePath = path.join(outputDir, '.gitignore');
|
||||||
|
|
||||||
|
if (!(await fs.pathExists(packageJsonPath))) {
|
||||||
|
await fs.writeJson(packageJsonPath, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
await fs.copy(bootstrapFilesDir, outputDir, {
|
||||||
|
errorOnExist: true,
|
||||||
|
filter: file => !file.endsWith('_gitignore'),
|
||||||
|
});
|
||||||
|
|
||||||
|
const packageJson = await fs.readJson(packageJsonPath);
|
||||||
|
|
||||||
|
await fs.writeJson(
|
||||||
|
packageJsonPath,
|
||||||
|
{
|
||||||
|
...packageJson,
|
||||||
|
type: 'module',
|
||||||
|
scripts: {
|
||||||
|
...packageJson.scripts,
|
||||||
|
start: 'rocket start',
|
||||||
|
docs: 'rocket build',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ spaces: 2 },
|
||||||
|
);
|
||||||
|
|
||||||
|
await fs.ensureFile(gitignorePath);
|
||||||
|
await fs.appendFile(
|
||||||
|
gitignorePath,
|
||||||
|
await fs.readFile(path.join(bootstrapFilesDir, '_gitignore'), 'utf8'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {RocketPlugin} plugin
|
* @param {RocketPlugin} plugin
|
||||||
*/
|
*/
|
||||||
@@ -238,7 +298,7 @@ export class RocketCli {
|
|||||||
async cleanup() {
|
async cleanup() {
|
||||||
setComputedConfig({});
|
setComputedConfig({});
|
||||||
if (this.eleventy) {
|
if (this.eleventy) {
|
||||||
this.eleventy.finish();
|
// this.eleventy.finish();
|
||||||
// await this.eleventy.stopWatch();
|
// await this.eleventy.stopWatch();
|
||||||
}
|
}
|
||||||
this.stop();
|
this.stop();
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ export class RocketLint {
|
|||||||
|
|
||||||
const checkLinks = new CheckHtmlLinksCli();
|
const checkLinks = new CheckHtmlLinksCli();
|
||||||
checkLinks.setOptions({
|
checkLinks.setOptions({
|
||||||
|
...this.config.checkLinks,
|
||||||
rootDir: this.config.lintInputDir,
|
rootDir: this.config.lintInputDir,
|
||||||
printOnError: false,
|
printOnError: false,
|
||||||
continueOnError: true,
|
continueOnError: true,
|
||||||
|
|||||||
@@ -1,11 +1,61 @@
|
|||||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
import { startDevServer } from '@web/dev-server';
|
import { startDevServer } from '@web/dev-server';
|
||||||
import { fromRollup } from '@web/dev-server-rollup';
|
import { fromRollup } from '@web/dev-server-rollup';
|
||||||
import { metaConfigToWebDevServerConfig } from 'plugins-manager';
|
import { executeSetupFunctions } from 'plugins-manager';
|
||||||
|
|
||||||
/** @typedef {import('../types/main').RocketCliOptions} RocketCliOptions */
|
/** @typedef {import('../types/main').RocketCliOptions} RocketCliOptions */
|
||||||
/** @typedef {import('@web/dev-server').DevServerConfig} DevServerConfig */
|
/** @typedef {import('@web/dev-server').DevServerConfig} DevServerConfig */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} config
|
||||||
|
* @param {MetaPluginWrapable[]} metaPlugins
|
||||||
|
* @param {object} [options]
|
||||||
|
* @param {function | null} [options.rollupWrapperFunction]
|
||||||
|
*/
|
||||||
|
export function metaConfigToWebDevServerConfig(
|
||||||
|
config,
|
||||||
|
metaPlugins,
|
||||||
|
{ rollupWrapperFunction = null } = {},
|
||||||
|
) {
|
||||||
|
if (config.plugins) {
|
||||||
|
delete config.setupPlugins;
|
||||||
|
delete config.setupRollupPlugins;
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
const metaPluginsNoWrap = metaPlugins.map(pluginObj => {
|
||||||
|
pluginObj.__noWrap = true;
|
||||||
|
return pluginObj;
|
||||||
|
});
|
||||||
|
|
||||||
|
const rollupPlugins = /** @type {MetaPluginWrapable[]} */ (executeSetupFunctions(
|
||||||
|
config.setupRollupPlugins,
|
||||||
|
[...metaPluginsNoWrap],
|
||||||
|
));
|
||||||
|
|
||||||
|
const wrappedRollupPlugins = rollupPlugins.map(pluginObj => {
|
||||||
|
if (typeof rollupWrapperFunction === 'function' && pluginObj.__noWrap !== true) {
|
||||||
|
pluginObj.plugin = rollupWrapperFunction(pluginObj.plugin);
|
||||||
|
}
|
||||||
|
return pluginObj;
|
||||||
|
});
|
||||||
|
|
||||||
|
const _metaPlugins = executeSetupFunctions(config.setupPlugins, [...wrappedRollupPlugins]);
|
||||||
|
|
||||||
|
const plugins = _metaPlugins.map(pluginObj => {
|
||||||
|
if (pluginObj.options) {
|
||||||
|
return pluginObj.plugin(pluginObj.options);
|
||||||
|
} else {
|
||||||
|
return pluginObj.plugin();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
config.plugins = plugins;
|
||||||
|
|
||||||
|
delete config.setupPlugins;
|
||||||
|
delete config.setupRollupPlugins;
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
export class RocketStart {
|
export class RocketStart {
|
||||||
static pluginName = 'RocketStart';
|
static pluginName = 'RocketStart';
|
||||||
commands = ['start'];
|
commands = ['start'];
|
||||||
|
|||||||
266
packages/cli/src/eleventy-plugins/insertResponsiveImages.cjs
Normal file
266
packages/cli/src/eleventy-plugins/insertResponsiveImages.cjs
Normal file
@@ -0,0 +1,266 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const EleventyImage = require('@11ty/eleventy-img');
|
||||||
|
const urlFilter = require('@11ty/eleventy/src/Filters/Url.js');
|
||||||
|
const { SaxEventType, SAXParser } = require('sax-wasm');
|
||||||
|
const { getComputedConfig } = require('../public/computedConfig.cjs');
|
||||||
|
|
||||||
|
const saxPath = require.resolve('sax-wasm/lib/sax-wasm.wasm');
|
||||||
|
const saxWasmBuffer = fs.readFileSync(saxPath);
|
||||||
|
|
||||||
|
/** @typedef {import('../types').Heading} Heading */
|
||||||
|
|
||||||
|
/** @typedef {import('sax-wasm').Text} Text */
|
||||||
|
/** @typedef {import('sax-wasm').Tag} Tag */
|
||||||
|
/** @typedef {import('sax-wasm').Position} Position */
|
||||||
|
|
||||||
|
// Instantiate
|
||||||
|
const parser = new SAXParser(
|
||||||
|
SaxEventType.CloseTag,
|
||||||
|
{ highWaterMark: 256 * 1024 }, // 256k chunks
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {object} options
|
||||||
|
* @param {string} options.html
|
||||||
|
* @param {Position} options.start
|
||||||
|
* @param {Position} options.end
|
||||||
|
* @param {string} options.insert
|
||||||
|
*/
|
||||||
|
function replaceBetween({ html, start, end, insert = '' }) {
|
||||||
|
const lines = html.split('\n');
|
||||||
|
const i = start.line;
|
||||||
|
const line = lines[i];
|
||||||
|
const upToChange = line.slice(0, start.character);
|
||||||
|
const afterChange = line.slice(end.character);
|
||||||
|
|
||||||
|
lines[i] = `${upToChange}${insert}${afterChange}`;
|
||||||
|
return lines.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Tag} data
|
||||||
|
* @param {string} name
|
||||||
|
*/
|
||||||
|
function getAttribute(data, name) {
|
||||||
|
if (data.attributes) {
|
||||||
|
const { attributes } = data;
|
||||||
|
const foundIndex = attributes.findIndex(entry => entry.name.value === name);
|
||||||
|
if (foundIndex !== -1) {
|
||||||
|
return attributes[foundIndex].value.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Tag} data
|
||||||
|
*/
|
||||||
|
function getAttributes(data) {
|
||||||
|
if (data.attributes) {
|
||||||
|
const { attributes } = data;
|
||||||
|
return attributes.map(entry => ({ name: entry.name.value, value: entry.value.value }));
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @param {Tag} data
|
||||||
|
// */
|
||||||
|
// function getText(data) {
|
||||||
|
// if (data.textNodes) {
|
||||||
|
// return data.textNodes.map(textNode => textNode.value).join('');
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @param {Tag} data
|
||||||
|
// */
|
||||||
|
// function getClassList(data) {
|
||||||
|
// const classString = getAttribute(data, 'class');
|
||||||
|
// return classString ? classString.split(' ') : [];
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param src {string} image src attribute value.
|
||||||
|
* @returns {boolean} true if src starts with https://, http:// or //
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isExternalSrc(src) {
|
||||||
|
return /^(?:https?:)?\/\//.test(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} html
|
||||||
|
*/
|
||||||
|
function getImages(html, { imagePresets }) {
|
||||||
|
/** @type {Heading[]} */
|
||||||
|
const images = [];
|
||||||
|
parser.eventHandler = (ev, _data) => {
|
||||||
|
if (ev === SaxEventType.CloseTag) {
|
||||||
|
const data = /** @type {Tag} */ (/** @type {any} */ (_data));
|
||||||
|
if (data.name === 'img') {
|
||||||
|
// Img tag only has open tag.
|
||||||
|
const { openStart, openEnd } = data;
|
||||||
|
|
||||||
|
const attributes = getAttributes(data);
|
||||||
|
const presetName = getAttribute(data, 'rocket-image');
|
||||||
|
const src = getAttribute(data, 'src');
|
||||||
|
const title = getAttribute(data, 'title');
|
||||||
|
const alt = getAttribute(data, 'alt');
|
||||||
|
|
||||||
|
if (presetName) {
|
||||||
|
const presetSettings = imagePresets[presetName];
|
||||||
|
if (!presetSettings) {
|
||||||
|
throw new Error(`Could not find imagePresets: { ${presetName}: {} }`);
|
||||||
|
}
|
||||||
|
const { ignore } = presetSettings;
|
||||||
|
const ignoreFn = typeof ignore === 'function' ? ignore : () => false;
|
||||||
|
|
||||||
|
if (!isExternalSrc(src) && !ignoreFn({ src, title, alt, attributes })) {
|
||||||
|
images.push({
|
||||||
|
presetName,
|
||||||
|
attributes,
|
||||||
|
src,
|
||||||
|
title,
|
||||||
|
alt,
|
||||||
|
openStart,
|
||||||
|
openEnd,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
parser.write(Buffer.from(html, 'utf8'));
|
||||||
|
parser.end();
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
return images;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSrcsetAttribute(imageFormat) {
|
||||||
|
return `srcset="${imageFormat.map(entry => entry.srcset).join(', ')}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function responsiveImages(images, { inputPath, outputDir, imagePresets = {} }) {
|
||||||
|
for (let i = 0; i < images.length; i += 1) {
|
||||||
|
const { alt, filePath, title, src, presetName, attributes } = images[i];
|
||||||
|
|
||||||
|
if (alt === undefined) {
|
||||||
|
throw new Error(`Missing \`alt\` on responsive image from: ${src} in ${inputPath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const presetSettings = imagePresets[presetName];
|
||||||
|
if (!presetSettings) {
|
||||||
|
throw new Error(`Could not find imagePresets: { ${presetName}: {} }`);
|
||||||
|
}
|
||||||
|
const sizes = presetSettings.sizes || '100vw';
|
||||||
|
|
||||||
|
const metadata = await EleventyImage(filePath, {
|
||||||
|
outputDir: path.join(outputDir, 'images'),
|
||||||
|
urlPath: urlFilter('/images/'),
|
||||||
|
...presetSettings,
|
||||||
|
});
|
||||||
|
const lowsrc = metadata.jpeg[0];
|
||||||
|
|
||||||
|
let pictureStartWithSources = '';
|
||||||
|
let srcsetAttribute = '';
|
||||||
|
let sizesAttribute = '';
|
||||||
|
let pictureEnd = '';
|
||||||
|
|
||||||
|
if (Object.keys(metadata).length > 1) {
|
||||||
|
const sources = Object.values(metadata)
|
||||||
|
.map(imageFormat => {
|
||||||
|
return `<source type="${imageFormat[0].sourceType}" ${getSrcsetAttribute(
|
||||||
|
imageFormat,
|
||||||
|
)} sizes="${sizes}">`;
|
||||||
|
})
|
||||||
|
.join('\n');
|
||||||
|
pictureStartWithSources = `<picture>\n${sources}`;
|
||||||
|
pictureEnd = '</picture>';
|
||||||
|
} else {
|
||||||
|
srcsetAttribute = getSrcsetAttribute(Object.values(metadata)[0]);
|
||||||
|
sizesAttribute = `sizes="${sizes}"`;
|
||||||
|
}
|
||||||
|
const attributesString = attributes
|
||||||
|
.filter(attribute => !['src', 'title'].includes(attribute.name))
|
||||||
|
.map(attribute => `${attribute.name}="${attribute.value}"`)
|
||||||
|
.join(' ');
|
||||||
|
|
||||||
|
const figureStart = title ? '<figure>' : '';
|
||||||
|
const figureEndWithCaption = title ? `<figcaption>${title}</figcaption>\n</figure>` : '';
|
||||||
|
|
||||||
|
images[i].newHtml = `
|
||||||
|
${figureStart}
|
||||||
|
${pictureStartWithSources}
|
||||||
|
<img
|
||||||
|
${attributesString}
|
||||||
|
src="${lowsrc.url}"
|
||||||
|
${srcsetAttribute}
|
||||||
|
${sizesAttribute}
|
||||||
|
width="${lowsrc.width}"
|
||||||
|
height="${lowsrc.height}"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
${pictureEnd}
|
||||||
|
${figureEndWithCaption}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
return images;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateHtml(html, changes) {
|
||||||
|
let newHtml = html;
|
||||||
|
for (const change of changes.reverse()) {
|
||||||
|
newHtml = replaceBetween({
|
||||||
|
html: newHtml,
|
||||||
|
start: change.openStart,
|
||||||
|
end: change.openEnd,
|
||||||
|
insert: change.newHtml,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return newHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveFilePath(images, { inputPath }) {
|
||||||
|
for (let i = 0; i < images.length; i += 1) {
|
||||||
|
images[i].filePath = path.join(path.dirname(inputPath), images[i].src);
|
||||||
|
}
|
||||||
|
return images;
|
||||||
|
}
|
||||||
|
|
||||||
|
let isSetup = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} html
|
||||||
|
*/
|
||||||
|
async function insertResponsiveImages(html) {
|
||||||
|
const config = getComputedConfig();
|
||||||
|
|
||||||
|
if (!isSetup) {
|
||||||
|
isSetup = parser.prepareWasm(saxWasmBuffer);
|
||||||
|
}
|
||||||
|
await isSetup;
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
inputPath: this.inputPath,
|
||||||
|
outputDir: this.outputDir,
|
||||||
|
imagePresets: config.imagePresets,
|
||||||
|
};
|
||||||
|
|
||||||
|
let images = getImages(html, options);
|
||||||
|
images = resolveFilePath(images, options);
|
||||||
|
images = await responsiveImages(images, options);
|
||||||
|
const newHtml = updateHtml(html, images);
|
||||||
|
|
||||||
|
return newHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
insertResponsiveImages,
|
||||||
|
};
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
const rocketCopy = {
|
const rocketCopy = {
|
||||||
configFunction: (eleventyConfig, { _inputDirCwdRelative, filesExtensionsToCopy }) => {
|
configFunction: (eleventyConfig, { _inputDirCwdRelative }) => {
|
||||||
eleventyConfig.addPassthroughCopy(`${_inputDirCwdRelative}/**/*.{${filesExtensionsToCopy}}`);
|
eleventyConfig.addPassthroughCopy(`${_inputDirCwdRelative}/!(*.md|*.html)*`);
|
||||||
|
eleventyConfig.addPassthroughCopy(
|
||||||
|
`${_inputDirCwdRelative}/!(_includes|_data|_assets|_merged_data|_merged_includes)*/**/!(*.md|*.html)*`,
|
||||||
|
);
|
||||||
|
eleventyConfig.addPassthroughCopy(`${_inputDirCwdRelative}/_merged_assets/_static/**/*`);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { processLocalReferences } = require('./processLocalReferences.cjs');
|
const { processLocalReferences } = require('./processLocalReferences.cjs');
|
||||||
|
const { insertResponsiveImages } = require('./insertResponsiveImages.cjs');
|
||||||
|
|
||||||
function inlineFilePath(filePath) {
|
function inlineFilePath(filePath) {
|
||||||
let data = fs.readFileSync(filePath, function (err, contents) {
|
let data = fs.readFileSync(filePath, function (err, contents) {
|
||||||
@@ -24,6 +25,7 @@ const rocketFilters = {
|
|||||||
|
|
||||||
eleventyConfig.addFilter('inlineFilePath', inlineFilePath);
|
eleventyConfig.addFilter('inlineFilePath', inlineFilePath);
|
||||||
|
|
||||||
|
eleventyConfig.addTransform('insertResponsiveImages', insertResponsiveImages);
|
||||||
eleventyConfig.addTransform('processLocalReferences', processLocalReferences);
|
eleventyConfig.addTransform('processLocalReferences', processLocalReferences);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
/** @typedef {import('@web/dev-server').DevServerConfig} DevServerConfig */
|
/** @typedef {import('@web/dev-server').DevServerConfig} DevServerConfig */
|
||||||
|
|
||||||
/** @typedef {import('../types/main').RocketCliOptions} RocketCliOptions */
|
/** @typedef {import('../types/main').RocketCliOptions} RocketCliOptions */
|
||||||
|
/** @typedef {import('../types/main').ImagePreset} ImagePreset */
|
||||||
/** @typedef {import('../types/main').RocketPlugin} RocketPlugin */
|
/** @typedef {import('../types/main').RocketPlugin} RocketPlugin */
|
||||||
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
@@ -19,9 +20,25 @@ import { fileURLToPath } from 'url';
|
|||||||
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default responsive ignore function will ignore files
|
||||||
|
* - ending in `.svg`
|
||||||
|
* - containing `rocket-unresponsive.`
|
||||||
|
*
|
||||||
|
* @param {object} opts
|
||||||
|
* @param {string} opts.src
|
||||||
|
* @param {string} opts.title
|
||||||
|
* @param {string} opts.alt
|
||||||
|
* @param {{name: string, value: string}[]} opts.attributes
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function ignore({ src }) {
|
||||||
|
return src.endsWith('svg') || src.includes('rocket-unresponsive.');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Partial<RocketCliOptions>} inConfig
|
* @param {Partial<RocketCliOptions>} inConfig
|
||||||
* @returns {Promise<RocketCliOptions>}
|
* @returns {Promise<RocketCliOptions & { __before11tyFunctions: RocketCliOptions['before11ty'][] }>}
|
||||||
*/
|
*/
|
||||||
export async function normalizeConfig(inConfig) {
|
export async function normalizeConfig(inConfig) {
|
||||||
let config = {
|
let config = {
|
||||||
@@ -40,15 +57,35 @@ export async function normalizeConfig(inConfig) {
|
|||||||
inputDir: 'docs',
|
inputDir: 'docs',
|
||||||
outputDir: '_site',
|
outputDir: '_site',
|
||||||
outputDevDir: '_site-dev',
|
outputDevDir: '_site-dev',
|
||||||
|
serviceWorkerName: 'service-worker.js',
|
||||||
build: {},
|
build: {},
|
||||||
devServer: {},
|
devServer: {},
|
||||||
|
|
||||||
...inConfig,
|
...inConfig,
|
||||||
|
|
||||||
|
/** @type{RocketCliOptions['before11ty'][]} */
|
||||||
|
__before11tyFunctions: [],
|
||||||
|
|
||||||
|
/** @type{{[key: string]: ImagePreset}} */
|
||||||
|
imagePresets: {
|
||||||
|
responsive: {
|
||||||
|
widths: [600, 900, 1640],
|
||||||
|
formats: ['avif', 'jpeg'],
|
||||||
|
sizes: '100vw',
|
||||||
|
ignore,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (inConfig && inConfig.devServer) {
|
if (inConfig && inConfig.devServer) {
|
||||||
config.devServer = { ...config.devServer, ...inConfig.devServer };
|
config.devServer = { ...config.devServer, ...inConfig.devServer };
|
||||||
}
|
}
|
||||||
|
if (inConfig.imagePresets && inConfig.imagePresets.responsive) {
|
||||||
|
config.imagePresets.responsive = {
|
||||||
|
...config.imagePresets.responsive,
|
||||||
|
...inConfig.imagePresets.responsive,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let userConfigFile;
|
let userConfigFile;
|
||||||
let __configDir = process.cwd();
|
let __configDir = process.cwd();
|
||||||
@@ -72,7 +109,14 @@ export async function normalizeConfig(inConfig) {
|
|||||||
...config.devServer,
|
...config.devServer,
|
||||||
...fileConfig.devServer,
|
...fileConfig.devServer,
|
||||||
},
|
},
|
||||||
|
imagePresets: config.imagePresets,
|
||||||
};
|
};
|
||||||
|
if (fileConfig.imagePresets && fileConfig.imagePresets.responsive) {
|
||||||
|
config.imagePresets.responsive = {
|
||||||
|
...config.imagePresets.responsive,
|
||||||
|
...fileConfig.imagePresets.responsive,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Could not read rocket config file', error);
|
console.error('Could not read rocket config file', error);
|
||||||
@@ -83,9 +127,13 @@ export async function normalizeConfig(inConfig) {
|
|||||||
const _inputDirCwdRelative = path.join(_configDirCwdRelative, config.inputDir);
|
const _inputDirCwdRelative = path.join(_configDirCwdRelative, config.inputDir);
|
||||||
|
|
||||||
// cli core preset is always first
|
// cli core preset is always first
|
||||||
config._presetPathes = [path.join(__dirname, '..', 'preset')];
|
config._presetPaths = [path.join(__dirname, '..', 'preset')];
|
||||||
for (const preset of config.presets) {
|
for (const preset of config.presets) {
|
||||||
config._presetPathes.push(preset.path);
|
config._presetPaths.push(preset.path);
|
||||||
|
|
||||||
|
if (preset.adjustImagePresets) {
|
||||||
|
config.imagePresets = preset.adjustImagePresets(config.imagePresets);
|
||||||
|
}
|
||||||
|
|
||||||
if (preset.setupUnifiedPlugins) {
|
if (preset.setupUnifiedPlugins) {
|
||||||
config.setupUnifiedPlugins = [...config.setupUnifiedPlugins, ...preset.setupUnifiedPlugins];
|
config.setupUnifiedPlugins = [...config.setupUnifiedPlugins, ...preset.setupUnifiedPlugins];
|
||||||
@@ -117,16 +165,16 @@ export async function normalizeConfig(inConfig) {
|
|||||||
if (preset.setupCliPlugins) {
|
if (preset.setupCliPlugins) {
|
||||||
config.setupCliPlugins = [...config.setupCliPlugins, ...preset.setupCliPlugins];
|
config.setupCliPlugins = [...config.setupCliPlugins, ...preset.setupCliPlugins];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof preset.before11ty === 'function') {
|
||||||
|
config.__before11tyFunctions.push(preset.before11ty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// add "local" preset
|
// add "local" preset
|
||||||
config._presetPathes.push(path.resolve(_inputDirCwdRelative));
|
config._presetPaths.push(path.resolve(_inputDirCwdRelative));
|
||||||
|
|
||||||
/** @type {MetaPlugin[]} */
|
/** @type {MetaPlugin[]} */
|
||||||
let pluginsMeta = [
|
let pluginsMeta = [{ plugin: RocketStart }, { plugin: RocketBuild }, { plugin: RocketLint }];
|
||||||
{ name: 'RocketStart', plugin: RocketStart },
|
|
||||||
{ name: 'RocketBuild', plugin: RocketBuild },
|
|
||||||
{ name: 'RocketLint', plugin: RocketLint },
|
|
||||||
];
|
|
||||||
|
|
||||||
if (Array.isArray(config.setupCliPlugins)) {
|
if (Array.isArray(config.setupCliPlugins)) {
|
||||||
for (const setupFn of config.setupCliPlugins) {
|
for (const setupFn of config.setupCliPlugins) {
|
||||||
@@ -144,6 +192,10 @@ export async function normalizeConfig(inConfig) {
|
|||||||
plugins.push(pluginInst);
|
plugins.push(pluginInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof config.before11ty === 'function') {
|
||||||
|
config.__before11tyFunctions.push(config.before11ty);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: check pathPrefix to NOT have a '/' at the end as it will mean it may get ignored by 11ty 🤷♂️
|
// TODO: check pathPrefix to NOT have a '/' at the end as it will mean it may get ignored by 11ty 🤷♂️
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
6
packages/cli/src/public/bootstrap/_gitignore
Normal file
6
packages/cli/src/public/bootstrap/_gitignore
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
node_modules
|
||||||
|
|
||||||
|
## Rocket ignore files (need to be the full relative path to the folders)
|
||||||
|
docs/_merged_data/
|
||||||
|
docs/_merged_assets/
|
||||||
|
docs/_merged_includes/
|
||||||
3
packages/cli/src/public/bootstrap/docs/.eleventyignore
Normal file
3
packages/cli/src/public/bootstrap/docs/.eleventyignore
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
_assets
|
||||||
|
_includes
|
||||||
|
_data
|
||||||
3
packages/cli/src/public/bootstrap/docs/index.md
Normal file
3
packages/cli/src/public/bootstrap/docs/index.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Welcome to Your Rocket Site
|
||||||
|
|
||||||
|
Add your markdown content here.
|
||||||
5
packages/cli/src/public/bootstrap/rocket.config.js
Normal file
5
packages/cli/src/public/bootstrap/rocket.config.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { rocketLaunch } from '@rocket/launch';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
presets: [rocketLaunch()],
|
||||||
|
};
|
||||||
@@ -5,8 +5,10 @@ const { createSocialImage: defaultCreateSocialImage } = require('./createSocialI
|
|||||||
const { getComputedConfig } = require('./computedConfig.cjs');
|
const { getComputedConfig } = require('./computedConfig.cjs');
|
||||||
const { executeSetupFunctions } = require('plugins-manager');
|
const { executeSetupFunctions } = require('plugins-manager');
|
||||||
|
|
||||||
function titleMetaPlugin() {
|
class TitleMetaPlugin {
|
||||||
return async data => {
|
static dataName = 'titleMeta';
|
||||||
|
|
||||||
|
async execute(data) {
|
||||||
if (data.titleMeta) {
|
if (data.titleMeta) {
|
||||||
return data.titleMeta;
|
return data.titleMeta;
|
||||||
}
|
}
|
||||||
@@ -17,29 +19,35 @@ function titleMetaPlugin() {
|
|||||||
return titleMetaFromContent;
|
return titleMetaFromContent;
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function titlePlugin() {
|
class TitlePlugin {
|
||||||
return async data => {
|
static dataName = 'title';
|
||||||
|
|
||||||
|
async execute(data) {
|
||||||
if (data.title) {
|
if (data.title) {
|
||||||
return data.title;
|
return data.title;
|
||||||
}
|
}
|
||||||
return data.titleMeta?.title;
|
return data.titleMeta?.title;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function eleventyNavigationPlugin() {
|
class EleventyNavigationPlugin {
|
||||||
return async data => {
|
static dataName = 'eleventyNavigation';
|
||||||
|
|
||||||
|
async execute(data) {
|
||||||
if (data.eleventyNavigation) {
|
if (data.eleventyNavigation) {
|
||||||
return data.eleventyNavigation;
|
return data.eleventyNavigation;
|
||||||
}
|
}
|
||||||
return data.titleMeta?.eleventyNavigation;
|
return data.titleMeta?.eleventyNavigation;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sectionPlugin() {
|
class SectionPlugin {
|
||||||
return async data => {
|
static dataName = 'section';
|
||||||
|
|
||||||
|
async execute(data) {
|
||||||
if (data.section) {
|
if (data.section) {
|
||||||
return data.section;
|
return data.section;
|
||||||
}
|
}
|
||||||
@@ -52,11 +60,17 @@ function sectionPlugin() {
|
|||||||
return parts[1];
|
return parts[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function layoutPlugin({ defaultLayout = 'layout-default' } = {}) {
|
class LayoutPlugin {
|
||||||
return async data => {
|
static dataName = 'layout';
|
||||||
|
|
||||||
|
constructor({ defaultLayout = 'layout-default' } = {}) {
|
||||||
|
this.defaultLayout = defaultLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(data) {
|
||||||
if (data.layout) {
|
if (data.layout) {
|
||||||
return data.layout;
|
return data.layout;
|
||||||
}
|
}
|
||||||
@@ -66,22 +80,29 @@ function layoutPlugin({ defaultLayout = 'layout-default' } = {}) {
|
|||||||
return 'layout-index';
|
return 'layout-index';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return defaultLayout;
|
return this.defaultLayout;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function socialMediaImagePlugin(args = {}) {
|
class SocialMediaImagePlugin {
|
||||||
const { createSocialImage = defaultCreateSocialImage, rocketConfig = {} } = args;
|
static dataName = 'socialMediaImage';
|
||||||
|
|
||||||
const cleanedUpArgs = { ...args };
|
constructor(args = {}) {
|
||||||
delete cleanedUpArgs.createSocialImage;
|
const { createSocialImage = defaultCreateSocialImage, rocketConfig = {} } = args;
|
||||||
|
|
||||||
return async data => {
|
this.cleanedUpArgs = { ...args };
|
||||||
|
delete this.cleanedUpArgs.createSocialImage;
|
||||||
|
|
||||||
|
this.rocketConfig = rocketConfig;
|
||||||
|
this.createSocialImage = createSocialImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(data) {
|
||||||
if (data.socialMediaImage) {
|
if (data.socialMediaImage) {
|
||||||
return data.socialMediaImage;
|
return data.socialMediaImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rocketConfig.createSocialMediaImages === false) {
|
if (this.rocketConfig.createSocialMediaImages === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,18 +116,18 @@ function socialMediaImagePlugin(args = {}) {
|
|||||||
const section = data.section ? ' ' + data.section[0].toUpperCase() + data.section.slice(1) : '';
|
const section = data.section ? ' ' + data.section[0].toUpperCase() + data.section.slice(1) : '';
|
||||||
const footer = `${data.site.name}${section}`;
|
const footer = `${data.site.name}${section}`;
|
||||||
|
|
||||||
const imgUrl = await createSocialImage({
|
const imgUrl = await this.createSocialImage({
|
||||||
title,
|
title,
|
||||||
subTitle,
|
subTitle,
|
||||||
footer,
|
footer,
|
||||||
section,
|
section,
|
||||||
...cleanedUpArgs,
|
...this.cleanedUpArgs,
|
||||||
});
|
});
|
||||||
return imgUrl;
|
return imgUrl;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sortyByOrder(a, b) {
|
function sortByOrder(a, b) {
|
||||||
if (a.order > b.order) {
|
if (a.order > b.order) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -127,45 +148,50 @@ async function dirToTree(sourcePath, extra = '') {
|
|||||||
if (entry.isDirectory()) {
|
if (entry.isDirectory()) {
|
||||||
const value = await dirToTree(sourcePath, relativePath);
|
const value = await dirToTree(sourcePath, relativePath);
|
||||||
unsortedEntries.push({
|
unsortedEntries.push({
|
||||||
order: matches && matches.length > 0 ? parseInt(matches[1]) : 0,
|
order: matches && matches.length > 0 ? parseInt(matches[1]) : 10000,
|
||||||
name: entry.name,
|
name: entry.name,
|
||||||
value,
|
value,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
unsortedEntries.push({
|
unsortedEntries.push({
|
||||||
order: matches && matches.length > 0 ? parseInt(matches[1]) : 0,
|
order: matches && matches.length > 0 ? parseInt(matches[1]) : 10000,
|
||||||
name: entry.name,
|
name: entry.name,
|
||||||
value: relativePath,
|
value: relativePath,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const sortedTree = {};
|
const sortedTree = {};
|
||||||
for (const unsortedEntry of unsortedEntries.sort(sortyByOrder)) {
|
for (const unsortedEntry of unsortedEntries.sort(sortByOrder)) {
|
||||||
sortedTree[unsortedEntry.name] = unsortedEntry.value;
|
sortedTree[unsortedEntry.name] = unsortedEntry.value;
|
||||||
}
|
}
|
||||||
return sortedTree;
|
return sortedTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
function joiningBlocksPlugin(rocketConfig) {
|
class JoiningBlocksPlugin {
|
||||||
const { _inputDirCwdRelative } = rocketConfig;
|
static dataName = '_joiningBlocks';
|
||||||
const partialsSource = path.resolve(_inputDirCwdRelative, '_merged_includes');
|
|
||||||
return async () => {
|
constructor(rocketConfig) {
|
||||||
const joiningBlocks = await dirToTree(partialsSource, '_joiningBlocks');
|
const { _inputDirCwdRelative } = rocketConfig;
|
||||||
|
this.partialsSource = path.resolve(_inputDirCwdRelative, '_merged_includes');
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute() {
|
||||||
|
const joiningBlocks = await dirToTree(this.partialsSource, '_joiningBlocks');
|
||||||
return joiningBlocks;
|
return joiningBlocks;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateEleventyComputed() {
|
function generateEleventyComputed() {
|
||||||
const rocketConfig = getComputedConfig();
|
const rocketConfig = getComputedConfig();
|
||||||
|
|
||||||
let metaPlugins = [
|
let metaPlugins = [
|
||||||
{ name: 'titleMeta', plugin: titleMetaPlugin },
|
{ plugin: TitleMetaPlugin, options: {} },
|
||||||
{ name: 'title', plugin: titlePlugin },
|
{ plugin: TitlePlugin, options: {} },
|
||||||
{ name: 'eleventyNavigation', plugin: eleventyNavigationPlugin },
|
{ plugin: EleventyNavigationPlugin, options: {} },
|
||||||
{ name: 'section', plugin: sectionPlugin },
|
{ plugin: SectionPlugin, options: {} },
|
||||||
{ name: 'socialMediaImage', plugin: socialMediaImagePlugin, options: { rocketConfig } },
|
{ plugin: SocialMediaImagePlugin, options: { rocketConfig } },
|
||||||
{ name: '_joiningBlocks', plugin: joiningBlocksPlugin, options: rocketConfig },
|
{ plugin: JoiningBlocksPlugin, options: rocketConfig },
|
||||||
{ name: 'layout', plugin: layoutPlugin },
|
{ plugin: LayoutPlugin, options: {} },
|
||||||
];
|
];
|
||||||
|
|
||||||
const finalMetaPlugins = executeSetupFunctions(
|
const finalMetaPlugins = executeSetupFunctions(
|
||||||
@@ -176,13 +202,24 @@ function generateEleventyComputed() {
|
|||||||
const eleventyComputed = {};
|
const eleventyComputed = {};
|
||||||
for (const pluginObj of finalMetaPlugins) {
|
for (const pluginObj of finalMetaPlugins) {
|
||||||
if (pluginObj.options) {
|
if (pluginObj.options) {
|
||||||
eleventyComputed[pluginObj.name] = pluginObj.plugin(pluginObj.options);
|
const inst = new pluginObj.plugin(pluginObj.options);
|
||||||
|
eleventyComputed[inst.constructor.dataName] = inst.execute.bind(inst);
|
||||||
} else {
|
} else {
|
||||||
eleventyComputed[pluginObj.name] = pluginObj.plugin();
|
const inst = new pluginObj.plugin();
|
||||||
|
eleventyComputed[inst.constructor.dataName] = inst.execute.bind(inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return eleventyComputed;
|
return eleventyComputed;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { generateEleventyComputed };
|
module.exports = {
|
||||||
|
generateEleventyComputed,
|
||||||
|
LayoutPlugin,
|
||||||
|
TitleMetaPlugin,
|
||||||
|
TitlePlugin,
|
||||||
|
EleventyNavigationPlugin,
|
||||||
|
SectionPlugin,
|
||||||
|
SocialMediaImagePlugin,
|
||||||
|
JoiningBlocksPlugin,
|
||||||
|
};
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user