Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions docs/devGuide/design/projectStructure.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This page gives you an overview of the MarkBind's internal project structure.

## Packages

The MarkBind project is developed in a monorepo ([MarkBind/markbind](https://github.com/MarkBind/markbind)) of 4 packages:
The MarkBind project is developed in a <tooltip content="We follow a monorepo approach, similar to Babel and other open source projects. To see a discussion on the pros and cons of this approach, read [here](https://github.com/babel/babel/blob/main/doc/design/monorepo.md).">monorepo</tooltip> ([MarkBind/markbind](https://github.com/MarkBind/markbind)) of 4 packages:

* The core library, which parses and processes MarkBind's various syntaxes, resides in the `packages/core/` directory.

Expand All @@ -32,29 +32,42 @@ The MarkBind project is developed in a monorepo ([MarkBind/markbind](https://git

**The core library mainly houses:**

1. Functions and libraries used to parse and process MarkBind into usable output are stored in `src` The architecture described in [Architecture](../design/architecture) is contained here. A brief rundown of what it includes:
* Functions and libraries used to parse and process MarkBind into usable output are stored in `src`. The architecture described in [Architecture](../design/architecture) is contained here. A brief rundown of what it includes:

* Various key functionalities in processing MarkBind syntax into valid html output, stored in `html`. The other part of the content processing flow is found in `variables`, which manages site variables and facillitates the Nunjucks calls.

* `Page` files generate a single page of the site, and are managed by the `Site` instance. `Site` uses the Page model's interface to generate pages, and performs various other utility-like functions related to site generation such as copying of external assets into the output folder.

* `Layout` holds the files relating to the layout of the site and are managed by `LayoutManager`. Similarly, `External` files, which are separate output files to be loaded dynamically and on-demand, are managed by a `ExternalManager` instance.

* Various libraries (contained in `lib`) and plugins (in `plugins`) are also stored here. Some external libraries have also been amended to suit Markbind's purpose – see `patches`.

1. MarkBind's [templates](https://markbind.org/userGuide/templates.html), used in the `markbind init` command.
* MarkBind's [templates](https://markbind.org/userGuide/templates.html), used in the `markbind init` command.

1. Unit Tests (though there are more unit tests and functional tests in the cli library)
* Unit Tests (though there are more unit tests and functional tests in the cli library)

**The key external libraries used are:**

* [markdown-it](https://github.com/markdown-it/markdown-it), which does the Markdown parsing and rendering. There are also several customized markdown-it plugins used in MarkBind, which are located inside the `src/lib/markdown-it/` directory.

* Serveral markdown-it plugins are installed to enhance the existing Markdown syntax. They can be found in `src/package.json`. Some of them are patched in the `src/lib/markdown-it/patches/` directory to fit MarkBind's needs.

* Additionally, there are some markdown-it plugins in the `src/lib/markdown-it/plugins/` directory (either forked, modified or written to enhance existing functionalities).

* [htmlparser2](https://github.com/fb55/htmlparser2), a speedy and forgiving html parser which exposes a dom-like object structure to work on. To comply with the markdown spec, and our custom requirements, `src/patches/htmlparser2.js` patches various behaviours of this library.

Comment thread
tlylt marked this conversation as resolved.
* [cheerio](https://cheerio.js.org/), which is a node.js equivalent of [jQuery](https://jquery.com/). Cheerio uses [htmlparser2](https://github.com/fb55/htmlparser2) to parse the html as well, hence our patches propagate here.

* [Nunjucks](https://mozilla.github.io/nunjucks/), which is a JavaScript templating engine. Nunjucks is used to support our variable system to help with reusing small bits of code in multiple places. The package is patched and stored in `src/patches/nunjucks` to make it compatible with other MarkBind syntax processing steps.

### MarkBind CLI

The CLI application uses and further builds on the interface exposed by the core library's `Site` model to provide functionalities for the author, such as `markbind serve` which initiates a live reload workflow.

The CLI program is built using [commander.js](https://github.com/tj/commander.js/).
**The key external libraries used are:**
* [commander.js](https://github.com/tj/commander.js/), which is a node.js CLI framework.

* [live-server](https://github.com/tapio/live-server), which is a simple web server for local development and preview of a MarkBind site. The package is patched and stored in `src/lib/live-server` with our custom fine tuning.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good thing you updated the libraries here to mention live-server! (as I was the patcher, I haven't yet included that info here)


### MarkBind core-web library

Expand Down
21 changes: 21 additions & 0 deletions docs/devGuide/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,3 +242,24 @@ First, follow the instruction to [delete the dependency](#to-delete-a-dependency
<box type="warning">
Dependency updates are not trivial, and can be the source of subtle bugs. You should always check the respective dependency changelogs before doing so!
</box>

### Points for consideration
There are a few ways to incorporate external packages into MarkBind, each with its pros and cons. The following table shows some of the common trade-offs:

Approach | Pros | Cons |
:-----------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------|
Installing | <ul><li>Ease of upgrade</li><li>Traceable in `package.json`</li></ul> | <ul><li>May not satisfy custom behavior</li><li>Become vulnerable if the source repo is no longer actively maintained</li></ul>
Forking | <ul><li>Relatively easy to upgrade</li><li>Leverage upstream testing procedures</li><li>Benefit others who share the same use cases</li></ul> | <ul><li>May become out-of-sync with the latest version</li><li>Difficult to maintain it externally in the long run</li></ul>
Patching | <ul><li>Quick - no need to maintain / publish more npm packages or setup release procedures etc</li><li>Ensure the changes propagate to other dependencies</li><li>Enjoy the benefits of monorepo</li></ul> | <ul><li>Difficult to upgrade</li></ul>

As the choice is highly dependent on context and details of the implementation, below are some additional questions to ask before proceeding:

- Is the package actively maintained?
- How big is the package?
- How invasive are the proposed changes?
- Are there existing APIs/plugin system from the package (to modify default behaviors)?

<box type="tip" seamless>

Find out more about the key external libraries used in MarkBind from the [project structure](design/projectStructure.md) section. Also, the rationales behind most existing patches are documented in their respective files, read them (and their respective PRs/issues) for more context!
</box>