WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit a1c9cd7

Browse files
committed
feat: initial eleventy config
1 parent b220040 commit a1c9cd7

File tree

7 files changed

+3726
-20
lines changed

7 files changed

+3726
-20
lines changed

.eleventy.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module.exports = function (eleventyConfig) {
2+
let markdownIt = require('markdown-it');
3+
let options = {
4+
html: true,
5+
};
6+
7+
eleventyConfig.setLibrary('md', markdownIt(options));
8+
9+
return {
10+
dir: { input: 'content', output: 'live' },
11+
passthroughFileCopy: true,
12+
templateFormats: ['njk', 'md', 'css', 'yml'],
13+
htmlTemplateEngine: 'njk',
14+
};
15+
};

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
3+
live/

content/_includes/layout.njk

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!DOCTYPE html>
2+
<html lang="en" class="no-js">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
7+
<title>{{ title }}</title>
8+
<meta name="description" content="{{ description }}" />
9+
<meta name="keywords" content="{{ tags }}" />
10+
</head>
11+
<body>
12+
<h1>{{ title }}</h1>
13+
{{ content | safe }}
14+
</body>
15+
</html>

content/index.md

Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
---
2+
layout: layout.njk
3+
title: Introducing mdjs - live demos everywhere
4+
published: false
5+
description: Combine markdown and javascript to create the ultimate documentation to allow live demos everywhere.
6+
tags: markdown, javascript, webcomponents, demos
7+
cover_image: https://github.com/open-wc/blog-posts/blob/2019-11-storybook-for-web-components/2019-11-storybook-for-web-components-on-steroids/images/nong-vang-9pw4TKvT3po-unsplash.jpg?raw=true
8+
---
9+
10+
Every shared code needs had written documentation to show what it can be used for and what the idea behind is.
11+
Users should at least on the high level understand what the are using for what and why.
12+
13+
On the web, we have many many different ways of writing documentation.
14+
However, one thing almost all of them have in common is that they rely on [Markdown](https://en.wikipedia.org/wiki/Markdown) or of variations of it.
15+
16+
It is supported literally everywhere (vscode, atom, github, gitlab, dev.to, npmjs, ...)
17+
18+
## For tools that do not run in the browser
19+
20+
In that case, you will mostly share code snippets that people will need to run in their own projects so traditional static site generators like [Docusaurus](https://docusaurus.io/), [VuePress](https://vuepress.vuejs.org/), [Gatsby](https://www.gatsbyjs.org/), ... work great. All of them have full support for Markdown and therefore can create beautiful documentation pages with code snippets/highlighting, ...
21+
22+
Honestly, if that is your use case almost everything should be possible as long as you feel comfortable with the tools ecosystem/framework.
23+
24+
## For (visual) components that do run in the browser
25+
26+
Here people do expect a live demo to see different options in action. So pure Markdown is usually not enough as we now want to actually execute code and "insert" our working component. This requires specialized handling for each framework.
27+
28+
### Vue
29+
30+
For Vue you can use for example VuePress which auto registers all vue components in a certain folder and then you can use as normal html tags as Markdown allows html
31+
32+
```
33+
.
34+
└─ .vuepress
35+
└─ components
36+
├─ demo-1.vue
37+
```
38+
39+
```html
40+
<demo-1 />
41+
```
42+
43+
- supports vue components and has "magical" import for them
44+
- no support for generic javascript or passing properties to components
45+
46+
### React
47+
48+
For React you can use [mdx](https://mdxjs.com/) which extends Markdown with JSX support. Mdx is available via multiple tools like [Gatsby](https://www.gatsbyjs.org/), [docz](https://www.docz.site/), [storybook](https://storybook.js.org/), ...
49+
50+
```md
51+
import { Chart } from '../components/chart'
52+
53+
# Here’s a chart
54+
55+
The chart is rendered inside our MDX document.
56+
<Chart />
57+
```
58+
59+
- supports import/export JavaScript
60+
- passes everything through JSX
61+
- looks "bad" on github, requires special tools in editors to get highlighting
62+
63+
## Limitations
64+
65+
What all these specialized tools have in common is that they require a specific build tooling setup to work.
66+
For web components, none of that is actually needed. Markdown already allows for HTML. The only missing piece is how to load a web component?
67+
68+
## Introducing Markdown with JavaScript (mdjs)
69+
70+
The primary goals are
71+
72+
- minimal complexity
73+
- follows progressive enhancement
74+
- markdown needs to still make sense
75+
- code highlighting in editors without additional tools
76+
- looks good on github/gitlab/any source code management tool
77+
78+
The fundamental idea is laughable simple. We "enhance" a code fence block with additional meta data `js script`.
79+
80+
```js script
81+
import './my-component.js';
82+
```
83+
# This is my component
84+
<my-component></my-component>
85+
86+
And that's it 😅
87+
88+
Enough talk you can see it here live:
89+
90+
[==> Link to editable demo <==](https://webcomponents.dev/edit/aPQdZ4FtAiqJ7YXnRe2s?pm=1&sv=1)
91+
92+
**How does it work**
93+
94+
Mdjs hooks into [remark](https://remark.js.org/) and extracts all those tagged js blocks.
95+
In the end, html and js is separately available.
96+
97+
```js
98+
{
99+
html: '<h1>This is my component</h1><my-component></my-component>',
100+
jsCode: "import './my-component.js';"
101+
}
102+
```
103+
104+
It can then be combined/processed by any tool to create an actual documentation page.
105+
106+
The process looks like this:
107+
108+
1. Extract `js script` and separate it from md
109+
2. Render md
110+
3. Provide html & js
111+
112+
==> INSERT ANIMATION <==
113+
114+
This already is powerful enough to directly include JavaScript and render web components with attributes.
115+
116+
## Enhancing mdjs with demo format
117+
118+
Now that we can execute JavaScript within our Markdown this opens the door for more advanced features.
119+
120+
Our first step is to create another enhanced js code block `js preview-story`.
121+
In there you should export a function that can be executed on demand.
122+
This will add a border around and a button to show/hide the actual source code.
123+
124+
```js script
125+
import './my-component.js';
126+
```
127+
# This is my component
128+
```js preview-story
129+
export const demo = () => `<my-component header="from attribute"></my-component>`
130+
```
131+
132+
> if you do not want to border and button you can use `js story`
133+
134+
What you get looks something like this
135+
136+
```js
137+
{
138+
html: '<h1>This is my component</h1><my-component></my-component>',
139+
jsCode: "import './my-component.js';",
140+
stories: [
141+
key: 'demo',
142+
name: 'demo',
143+
code: 'export const demo = () => `<my-component header="from attribute"></my-component>`',
144+
]
145+
}
146+
```
147+
148+
This adds an extra step to the processing:
149+
150+
1. Extract `js script` and separate from md
151+
2. Extract `js story` and `js preview-story` and separate from md
152+
3. Put a placeholder `<mdjs-story mdjs-story-name="demo"></mdjs-story>` or `mdjs-preview` at it's place
153+
4. Render md
154+
5. Provide html & js & stories
155+
156+
With that information you can now create full javascript and demo capable pages purely from markdown.
157+
158+
By default Mdjs takes it a small step further by supporting an actual template system - namely [lit-html](https://lit-html.polymer-project.org/).
159+
160+
```js script
161+
import './my-component.js';
162+
import { html } from 'lit-html';
163+
164+
const name = 'from variable';
165+
```
166+
# This is my component
167+
```js story
168+
export const demo = () => html`
169+
<my-component .header=${name}></my-component>
170+
`;
171+
```
172+
173+
==> INSERT ANIMATION <==
174+
175+
Here another playground mimicking a full documentation page.
176+
177+
[==> Link to editable demo <==](https://webcomponents.dev/edit/PqrQkg3abvFJ7vxyZuqa?pm=1&sv=1)
178+
179+
## mdjs default docs page
180+
181+
Once all this meta-information is available you can render a specific docs page.
182+
183+
It basically comes down to generating this code which assigns the demo function to the actual web component.
184+
185+
```js
186+
const stories = [{ key: 'demo', story: demo, code: demo }];
187+
for (const story of stories) {
188+
const storyEl = rootNode.querySelector(`[mdjs-story-name="${story.key}"]`);
189+
storyEl.story = story.story;
190+
storyEl.code = story.code;
191+
}
192+
```
193+
194+
All of this happens under the hood for you 🤗
195+
196+
## Where can you use mdjs?
197+
198+
### You can use it locally via es-dev-server
199+
200+
This will create a github like markdown view for all your local markdown files including live demos.
201+
202+
![es-dev-server screenshot](https://raw.githubusercontent.com/open-wc/blog-posts/feat/mdjs/2020-04-introducing-mdjs-live-demos-everywhere/images/es-dev-server-screenshot.png)
203+
204+
- Add to your `package.json`:
205+
206+
```json
207+
"scripts": {
208+
"start": "es-dev-server",
209+
}
210+
```
211+
212+
- Create a `es-dev-server.config.js` in the root of your repo.
213+
214+
```js
215+
const { mdjsTransformer } = require('@mdjs/core');
216+
217+
module.exports = {
218+
nodeResolve: true,
219+
open: 'README.md',
220+
watch: true,
221+
responseTransformers: [mdjsTransformer],
222+
};
223+
```
224+
225+
After executing `npm run start` you can happily browse you live documentation via [http://localhost:8000/README.md](http://localhost:8000/README.md).
226+
227+
You can see an example setup in the [demo-wc-card repo](https://github.com/daKmoR/demo-wc-card).
228+
229+
### You can use it via storybook
230+
231+
If you want to work on individual components or get a list of all demos you can use storybook.
232+
233+
![storybook screenshot](https://raw.githubusercontent.com/open-wc/blog-posts/feat/mdjs/2020-04-introducing-mdjs-live-demos-everywhere/images/storybook-screenshot.png)
234+
235+
- Install dependencies `npm i -D @open-wc/demoing-storybook`
236+
237+
- Add to your `package.json`:
238+
239+
```json
240+
"scripts": {
241+
"storybook": "start-storybook --experimental-md-docs",
242+
}
243+
```
244+
245+
- Adjust your `.storybook/main.js` to load markdown files
246+
247+
```js
248+
module.exports = {
249+
stories: ['../README.md', '../docs/**/*.md'],
250+
esDevServer: {
251+
nodeResolve: true,
252+
watch: true,
253+
open: true,
254+
},
255+
};
256+
```
257+
258+
- Add to every markdown file that should be in storybook a name via
259+
260+
```js
261+
export default {
262+
title: 'My Group/My Awesome Component',
263+
};
264+
```
265+
266+
With that, you are good to go.
267+
No additional changes to any files are needed a plugin will take care of it by converting your markdown files to the support mdx format of storybook.
268+
269+
For more detailed information please see [https://open-wc.org/demoing-storybook/](https://open-wc.org/demoing-storybook/).
270+
271+
### Show it on github
272+
273+
Github supports markdown out of the box and with this format we can go one step further.
274+
275+
As it's not (yet - let's ask 😬) supported by github directly you will need a chrome extension called [mdjs-viewer](https://chrome.google.com/webstore/detail/mdjs-viewer/ifkkmomkjknligelmlcnakclabgohafe).
276+
277+
You wanna see a demo without opening a different page? mdjs-viewer
278+
You wanna show a live example of the issue you are having? mdjs-viewer
279+
280+
==> INSERT SCREENSHOT/GIF/VIDEO <==
281+
282+
It sure looks like black magic.
283+
Install a chrome extension and suddenly github gets superpowers.
284+
285+
All that is needed is to have Markdown files with the correct code fence blocks.
286+
And yeah your code needs to be able to run from within [unpkg.com](https://unpkg.com).
287+
288+
**How does it actually work?**
289+
290+
The extension detects on which github page you are.
291+
If it actually finds a markdown file or an issue with mdjs code then it adds a "show demo" button to can active it.
292+
Only if you click the button it will start gathering all the needed info.
293+
294+
- find the nearest `package.json`
295+
- read the actual markdown file/issue content
296+
- replace all bare import with `unpkg.com` imports
297+
- replace all relative imports with `unpkg.com` and the name of the package.json + relative path for it
298+
- create a secured iframe
299+
- position the iframe absolute as an overlays
300+
- put the jsCode and html code inside the iframe
301+
- the button becomes a toggle to show/hide the iframe
302+
303+
Some of the tasks are more complicated and require some extra work to make it secure but in the sense that's it.
304+
305+
With that, you can put documentation with live examples on github.
306+
Even issues with demos showing the actual error in the code are possible.
307+
308+
That sure sounds like a hell of a tool to improve your documentation an issue reproduction.
309+
Especially as the readme & issue content still remain useful even without the extension.
310+
311+
### Supported on webcomponents.dev
312+
313+
Fully supported by this awesome online editor.
314+
315+
![webcomponent.dev screenshot](https://raw.githubusercontent.com/open-wc/blog-posts/feat/mdjs/2020-04-introducing-mdjs-live-demos-everywhere/images/webcomponents-dev-screenshot.png)
316+
317+
As in the screenshot above you can start directly with documentation.
318+
319+
Or even better you can use it in every Markdown file or README.md 💪
320+
321+
Give it a go and document your components in all it's glory.
322+
323+
All the demo links are actually from [webcomponents.dev](https://webcomponents.dev/edit/collection/lsZ2eaviDNwy6pIBEDeL/tS7JYfymt6yeshma8Gn1?pm=1&sv=1).
324+
325+
Be sure to [check it out](https://webcomponents.dev/).
326+
327+
## How you can add support for mdjs
328+
329+
Please check the official documentation page at [https://open-wc.org/mdjs/](https://open-wc.org/mdjs/).
330+
331+
## Resume
332+
333+
There you have it - mdjs is a format that can be shown in many different ways.
334+
It is your single source of truth for good looking documentation everywhere.
335+
Be it your locally, a published storybook, on github or npmjs it always looks good even if there is no direct support for it. If possible it will become interactive demos through progressive enhancement.
336+
337+
Now go out there and write good documentation for your components.
338+
339+
## Future
340+
341+
- Have a separate github repo (potentially group as well).
342+
- Have a dedicated homepage
343+
- The default story preview frame should look a little nicer
344+
- Highlighting of code snippets
345+
- More helpers to be used within stories
346+
- ... (feel free to open issues within the corresponding projects)
347+
348+
## Acknowledgements
349+
350+
Follow us on [Twitter](https://twitter.com/openwc), or follow me on my personal [Twitter](https://twitter.com/dakmor).
351+
Make sure to check out our other tools and recommendations at [open-wc.org](https://open-wc.org).
352+
353+
Thanks to [Benny](https://dev.to/bennypowers) and [Lars](https://github.com/LarsDenBakker) for feedback and helping turn my scribbles to a followable story.
354+
355+
Cover Photo by [Nong Vang](https://unsplash.com/@californong) on [Unsplash](https://unsplash.com/)

0 commit comments

Comments
 (0)