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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ lib-cov
logs
node_modules
temp
packages/docs/.vitepress/cache
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
# vue-note
<p align="center">
<img src="https://raw.githubusercontent.com/liangmiQwQ/vue-note/main/packages/docs/src/public/favicon.svg" style="width:100px;" />
</p>

# Vue Note

State: **🚧 Work in progress**

vue-note is another style to write Vue. It's light, easy and fast!

## Getting Started

Use the follwing command to install Vue Note exist project

```
npm install -D vue-note
```

Learn more at [vue-note.liangmi.dev](https://vue-note.liangmi.dev/)!

## Contribute Guide

We're so excited that you are willing to help improve Vue Note, before starting your contribution, please take a moment to read the [Contribute Guide](https://vue-note.liangmi.dev/extra/contribute)

## License

[MIT](./LICENSE) License, 2025 - Present [Liang Mi](https://github.com/liangmiqwq)
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"dev": "tsdown --watch",
"play": "pnpm -C playground dev",
"lint": "eslint",
"docs": "pnpm -r --filter vue-note-docs docs:dev",
"docs:build": "pnpm -r --filter vue-note-docs docs:build",
"prepublishOnly": "nr build",
"release": "bumpp -r",
"test": "vitest",
Expand Down
56 changes: 56 additions & 0 deletions packages/docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import UnoCSS from 'unocss/vite'
import { defineConfig } from 'vitepress'

const SidebarNav = [
{ text: 'Guide', items: [
{ text: 'Introduction', link: '/guide/introduction' },
{ text: 'Quick Start', link: '/guide/quick-start' },
{ text: 'Flexibility', link: '/guide/flexibility' },
] },
{ text: 'Advenced', items: [
{ text: 'Linter & Formatter', link: '/advenced/linter-formatter' },
{ text: 'TypeScript', link: '/advenced/typescript' },
{ text: 'API Reference', link: '/advenced/api-reference' },

] },
{ text: 'Extra Topic', items: [
{ text: 'Design Philosophy', link: '/extra/design-philosophy' },
{ text: 'Contribute Guide', link: '/extra/contribute' },
{ text: 'Credits', link: '/extra/credits' },
] },
]

export default defineConfig({
title: 'Vue Note',
description: 'Write Vue template in code comment?',
srcDir: './src',
head: [
['link', { rel: 'icon', href: '/favicon.svg', type: 'image/svg+xml' }],
],
themeConfig: {
logo: '/favicon.svg',
nav: SidebarNav,
search: {
provider: 'local',
},
sidebar: {
'/': SidebarNav,
},
socialLinks: [
{ icon: 'github', link: 'https://github.com/liangmiQwQ/vue-note' },
],
editLink: {
pattern: 'https://github.com/liangmiQwQ/vue-note/edit/main/packages/docs/src/:path',
text: 'Suggest changes to this page',
},
footer: {
message: 'Released under the MIT License.',
copyright: 'Copyright 2025 - Present Liang Mi',
},
},
vite: {
plugins: [
UnoCSS(),
],
},
})
18 changes: 18 additions & 0 deletions packages/docs/.vitepress/theme/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
:root {
--vp-home-hero-name-color: transparent;
--vp-c-brand-1: hsla(120, 60%, 40%);
--vp-c-brand-2: hsl(120, 50%, 50%);
--vp-c-brand-3: hsl(120, 60%, 42%);
--vp-home-hero-image-background-image: url('/favicon.svg');
--vp-home-hero-image-filter: blur(15px);
--vp-home-hero-name-background: linear-gradient(
170deg,
var(--vp-c-brand-2) 40%,
var(--vp-c-brand-3) 60%
);
}

.dark {
--vp-home-hero-image-background-image: url('/favicon.svg');
--vp-home-hero-image-filter: blur(0px);
}
5 changes: 5 additions & 0 deletions packages/docs/.vitepress/theme/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import DefaultTheme from 'vitepress/theme'
import './custom.css'
import 'uno.css'

export default DefaultTheme
18 changes: 18 additions & 0 deletions packages/docs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "vue-note-docs",
"type": "module",
"private": true,
"description": "Document for Vue Note",
"author": "Liang Mi",
"license": "MIT",
"scripts": {
"docs:dev": "vitepress dev",
"docs:build": "vitepress build",
"docs:preview": "vitepress preview"
},
"devDependencies": {
"@iconify-json/carbon": "catalog:docs",
"unocss": "catalog:docs",
"vitepress": "catalog:docs"
}
}
92 changes: 92 additions & 0 deletions packages/docs/src/advenced/api-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Api Reference

## Macros

::: warning
Please only call the macro in `.ts` file but not `.vue` or `.tsx` file, otherwise something unexpected may get happended.
:::

### `defineCommentComponent`

```typescript
import { defineCommentComponent } from 'vue-note'

declare function defineCommentComponent(component: () => void): Component
```

Can be used to define a component with Vue Note.

```typescript
import { defineCommentComponent, defineTemplate } from 'vue-note'

export default defineCommentComponent(() => {
// Function body will turn into <script setup> part
const msg = ref('Hello World')

defineTemplate(/* @template
<h1>{{ msg }}</h1>
*/)
})
```

The above code has the same behavior as the following SFC

```vue
<script setup lang='ts'>
const msg = ref('Hello World')
</script>

<template>
<h1>{{ msg }}</h1>
</template>
```

### `defineTemplate`

```typescript
import { defineTemplate } from 'vue-note'

declare function defineTemplate(): void
```

Can be used to define template in a comment component. **Can be ONLY called in [`defineCommentComponent`](#definecommentcomponent) function body and for only ONE time**.

And although there is no params requires, you need to write the component with a JavaScript block comment(multi-line comment) in the following struct

```typescript
defineTemplate(/* @template<!--any template you want--> */)
```

or with any format

```typescript
defineTemplate(/* @template
<!--any template you want-->
*/)
```

## Vite

### `VueNote`

Get the VueNote Vite plugin

```typescript
declare function VueNote(): PluginOption
```

and use it in [Vite Config](https://vite.dev/config/)

```typescript{3,7}
import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'
import { VueNote } from 'vue-note/vite'

export default defineConfig({
plugins: [
VueNote(),
Vue(),
],
})

```
1 change: 1 addition & 0 deletions packages/docs/src/advenced/linter-formatter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
State: **🚧 Work in progress**
1 change: 1 addition & 0 deletions packages/docs/src/advenced/typescript.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
State: **🚧 Work in progress**
61 changes: 61 additions & 0 deletions packages/docs/src/extra/contribute.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Contributing Guide

Thank you for your interest in contributing to vue-note! This guide will help you get started with development.

## Project Structure

This is a monorepo using pnpm workspaces:

- **Main package**: `packages/vue-note/` - Core compiler and Vite plugin
- **Playground**: `playground/` - Development playground for testing

## Development Setup

### Preparation

- Node.js latest LTS
- pnpm ([ni](https://github.com/antfu-collective/ni) recommended)

### Development Commands

```bash
# Build the project
pnpm build

# Build in watch mode
pnpm dev

# Run playground development server
pnpm play

# Run tests
pnpm test

# Run type checking
pnpm typecheck

# Run linting
pnpm lint
```

## Before Submitting PR

Ensure your changes pass:

- `pnpm build` - Build succeeds
- `pnpm test` - All tests pass
- `pnpm typecheck` - No TypeScript errors
- `pnpm lint` - Code style compliance

Your PR should pass the GitHub CI checks, which run these same commands.

## Contribution Guidelines

- It's best to submit an [issue](https://github.com/liangmiQwQ/vue-note/issues/new) for discussion if you want to make a new feature.
- If you encounter any issues during development or contributing, please check the [Design Philosophy](https://vue-note.liangmi.dev/extra/design-philosophy) documentation first. You can also reach me directly at [hi@liangmi.dev](mailto:hi@liangmi.dev).

## Thank You!

Your contributions are greatly appreciated! Whether you're fixing bugs, adding features, or improving documentation, every contribution helps make vue-note better for everyone.

If you have any questions or need help getting started, don't hesitate to reach out!
8 changes: 8 additions & 0 deletions packages/docs/src/extra/credits.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Credits (in alphabetical order)

- [Antfu's Starter-TS](https://github.com/antfu/starter-ts) for its excellent tools and workespace config
- [oxc](https://oxc.rs/) for its wonderful and fast parser and walker
- [Recast](https://github.com/benjamn/recast) for its powerful TypeScript code generation capabilities
- [tsdown](https://github.com/rolldown/tsdown) for its fast and easy-config TypeScript bundling
- [Vite](https://vite.dev) for its fast and wonderful developing experience
- [Vue Vine](https://vue-vine.dev/) for pioneering a new template syntax that serves as a great inspiration
57 changes: 57 additions & 0 deletions packages/docs/src/extra/design-philosophy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Design Philosophy

To make Vue Note easier to use, there are a few tips you'd better know when designing or making a new feature.

## Keep the original Vue experience

### What we want to achieve

We want developers to have a great experience when using Vue Note. The target is to **make it feel just like using regular Vue Single File Components (SFCs)**, or even **better**.

This means:
- **Full Vue.js compatibility**: All Vue.js features should work exactly the same way, even compile-time syntax, like `defineProps`, `defineEmits`
- **Third-party library support**: Any Vue library should work without any changes

### Why it is important

Vue.js has been tested by millions of developers. When we're not actually sure we have a better solution, **it's safer to use what the community already knows and trusts.** It is easier to change ourselves than to change the community.

Also, we hope developers should **be able to switch between Vue Note and regular Vue without learning too many new things**. This makes adoption easier and reduces worries about compatibility.

When we don't break existing syntax, developers don't need to find workarounds or learn special tricks. Everything just works the way they expect. **It also bring better DX.**

### How we make it work

Instead of rewriting everything, **we need to try to reuse the code what Vue or the community has already done**, for example, we use `@vue/compiler-sfc` instead of using `@vue/compiler-dom` to make sure all the macro and the scripts work the same as native Vue. It also bring us **less code for us to maintain and fewer bugs.**

However, if sometimes our code does change how Vue work. We also need to fix it to ensure the developer experience stays the same. Here is a example.

::: info An example of Component importing

In Vue Note, when you write a component like this:

```typescript
import { Button } from 'some-ui-library' // ⬅️ Outside

defineCommentComponent(() => {
defineTemplate(/* @template
<Button>Click me</Button> // ⬅️ Inside
*/)
})
```

The `Button` import is outside the component function, so Vue's compiler can't find it and may cause unexpected bug. This may break the developer experience. To fix this, we inject a fake import statement:

```typescript
import { Button } from 'vue-note'
```

and remove it later (after `vue/compiler-sfc` compiled)

This makes Vue's compiler think `Button` comes from `vue-note`, preserving the expected behavior without requiring developers to change their import patterns.

:::

Another important thing is that we need **good design**. For example, we don't wrap templates in template string because that would break how template strings work inside templates. We use the block JavaScript comment since Vue templates don't support regular JavaScript comments anyway.

In a word, the final goal is that we want Vue Note to feel like a **natural extension** of Vue.js, not a completely different framework. This makes it easier for developers to adopt and use in their projects.
Loading