Skip to content

Commit af03be0

Browse files
lambdalisueclaude
andcommitted
docs: Update to recommend workspace + deno.jsonc for dependency management
This commit restructures the documentation to present dependency management more appropriately: Key changes: - Keep Getting Started simple with direct URL imports - Add note in Getting Started pointing to tutorials for import maps - Create new tutorial section "Managing Dependencies" explaining import maps - Move all detailed import map explanations to the tutorial - Revert Hello World tutorial to use direct URL imports - Keep Maze tutorial using import maps as an advanced example Structure improvements: - Getting Started: Simple direct imports for beginners - Tutorial: Dedicated section explaining the recommended approach - Clear progression from simple to advanced patterns The documentation now properly guides users: 1. Start simple with direct URL imports 2. Learn about import maps in the dedicated tutorial section 3. Apply import maps in real projects (Maze tutorial) Technical notes: - Import map features require Denops v8.0.0+ - Use @denops/std@^8.0.0 in import map examples - Use @denops/std@^7.0.0 in direct import examples 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 13390fa commit af03be0

12 files changed

+226
-34
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- [Creating a minimal Denops plugin](./tutorial/helloworld/creating-a-minimal-denops-plugin.md)
1111
- [Adding Denops APIs](./tutorial/helloworld/adding-an-api.md)
1212
- [Calling Vim features](./tutorial/helloworld/calling-vim-features.md)
13+
- [Managing dependencies](./tutorial/helloworld/managing-dependencies.md)
1314
- [Tutorial (Maze)](./tutorial/maze/README.md)
1415
- [Utilizing third-party library](./tutorial/maze/utilizing-third-party-library.md)
1516
- [Outputting content to buffer](./tutorial/maze/outputting-content-to-buffer.md)

src/getting-started/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ export const main: Entrypoint = (denops) => {
3333
};
3434
```
3535

36+
> [!NOTE]
37+
>
38+
> This example uses direct URL imports for simplicity. The recommended approach
39+
> for managing dependencies is to use `deno.jsonc` with import maps, which
40+
> you'll learn about in the [tutorials](../tutorial.md).
41+
3642
## Activate the Plugin
3743

3844
Add the following line to your Vim or Neovim configuration file (e.g.,

src/introduction.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ features:
1818
- **Unified codebase for Vim and Neovim**:<br>Denops provides a unified API for
1919
both Vim and Neovim. You can write a plugin that functions on both Vim and
2020
Neovim with a single codebase.
21-
- **No worries about dependency management**:<br>Deno includes a built-in
22-
dependency management system, allowing developers to write plugins with
23-
third-party libraries without concerns about dependency management.
21+
- **Modern dependency management**:<br>Deno's built-in dependency system with
22+
import maps provides clean, maintainable dependency management. The workspace
23+
configuration ensures each plugin's dependencies are isolated, preventing
24+
conflicts when multiple Denops plugins are installed together.
2425
- **Simple and efficient code**:<br>Deno utilizes the V8 engine, significantly
2526
faster than Vim script. You can write a plugin with straightforward code,
2627
without the need for complex optimizations solely for performance.

src/tutorial/helloworld/calling-vim-features.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,11 @@ as a result.
5757

5858
## Next Steps
5959

60-
In the next step, follow the tutorial to learn how to develop a real Denops
61-
plugin.
60+
Learn about managing dependencies with import maps for cleaner code:
61+
62+
- [Managing dependencies](./managing-dependencies.md)
63+
64+
Or jump to the maze tutorial to learn more advanced concepts:
6265

6366
- [Tutorial (Maze)](../../tutorial/maze/index.html)
6467
- [API reference](https://jsr.io/@denops/std)
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Managing Dependencies with Import Maps
2+
3+
In the previous examples, we used direct URL imports like
4+
`jsr:@denops/std@^7.0.0`. While this works, the recommended approach for Denops
5+
plugins (v8.0.0+) is to use import maps with `deno.jsonc` for cleaner and more
6+
maintainable dependency management.
7+
8+
## Why Use Import Maps?
9+
10+
When Vim/Neovim loads plugins, all plugin directories are merged into a single
11+
runtime path. This creates a challenge:
12+
13+
```
14+
# Multiple plugins installed:
15+
~/.vim/pack/plugins/start/plugin-a/
16+
~/.vim/pack/plugins/start/plugin-b/
17+
18+
# Merged runtime view:
19+
plugin/ # Files from both plugins
20+
denops/ # Unique subdirectories preserved
21+
├── plugin-a/
22+
└── plugin-b/
23+
```
24+
25+
If we put configuration files in the root directory, they would conflict. That's
26+
why we place `deno.jsonc` inside each plugin's unique `denops/` subdirectory.
27+
28+
## Setting Up Your Plugin Structure
29+
30+
Update your `denops-helloworld` structure to include configuration files:
31+
32+
```
33+
denops-helloworld/
34+
├── deno.jsonc # Development configuration
35+
├── denops/
36+
│ └── denops-helloworld/
37+
│ ├── deno.jsonc # Runtime dependencies
38+
│ └── main.ts
39+
└── plugin/
40+
└── denops-helloworld.vim
41+
```
42+
43+
### Root deno.jsonc (Development)
44+
45+
Create a `deno.jsonc` in your repository root for development tools:
46+
47+
```json
48+
{
49+
"workspace": [
50+
"./denops/denops-helloworld"
51+
],
52+
// Optional: Development tool configuration
53+
"fmt": {
54+
"indentWidth": 2,
55+
"lineWidth": 80
56+
},
57+
"lint": {
58+
"rules": {
59+
"tags": ["recommended"]
60+
}
61+
}
62+
}
63+
```
64+
65+
This enables commands like `deno fmt`, `deno lint`, and `deno test` to work from
66+
your project root.
67+
68+
### Plugin deno.jsonc (Runtime)
69+
70+
Create `denops/denops-helloworld/deno.jsonc` for runtime dependencies:
71+
72+
```json
73+
{
74+
"imports": {
75+
"@denops/std": "jsr:@denops/std@^8.0.0",
76+
"@core/unknownutil": "jsr:@core/unknownutil@^4.3.0"
77+
}
78+
}
79+
```
80+
81+
## Updating Your Code
82+
83+
With import maps configured, update your imports from:
84+
85+
```typescript
86+
import type { Entrypoint } from "jsr:@denops/std@^8.0.0";
87+
import { assert, is } from "jsr:@core/unknownutil@^4.3.0";
88+
```
89+
90+
To cleaner versions:
91+
92+
```typescript
93+
import type { Entrypoint } from "@denops/std";
94+
import { assert, is } from "@core/unknownutil";
95+
```
96+
97+
## Alternative: import_map.json
98+
99+
Denops also supports `import_map.json(c)` files, but they require more verbose
100+
configuration:
101+
102+
```json
103+
// denops/denops-helloworld/import_map.json
104+
{
105+
"imports": {
106+
"@denops/std": "jsr:@denops/std@^8.0.0",
107+
"@denops/std/": "jsr:@denops/std@^8.0.0/" // Required for submodules
108+
}
109+
}
110+
```
111+
112+
We recommend using `deno.jsonc` as it's less verbose and integrates better with
113+
Deno tooling.
114+
115+
> [!IMPORTANT]
116+
>
117+
> Import map features require Denops v8.0.0 or later. For older versions,
118+
> continue using direct URL imports.
119+
120+
## Benefits
121+
122+
1. **Cleaner imports**: No more long URLs in your code
123+
2. **Version management**: Update dependencies in one place
124+
3. **Better IDE support**: Auto-completion and type checking work seamlessly
125+
4. **No conflicts**: Each plugin manages its own dependencies
126+
5. **Development tools**: Format and lint your code from the project root

src/tutorial/maze/adjusting-maze-size-to-fit-the-window.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ Let's modify the plugin to ensure the generated maze fits the current window
88
size.
99

1010
```typescript,title=denops/denops-helloworld/main.ts
11-
import type { Entrypoint } from "jsr:@denops/std@^7.0.0";
12-
import * as fn from "jsr:@denops/std@^7.0.0/function";
13-
import { Maze } from "npm:@thewizardbear/maze_generator@^0.4.0";
11+
import type { Entrypoint } from "@denops/std";
12+
import * as fn from "@denops/std/function";
13+
import { Maze } from "maze_generator";
1414

1515
export const main: Entrypoint = (denops) => {
1616
denops.dispatcher = {

src/tutorial/maze/creating-applicative-plugin.md

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,31 @@ augroup denops_maze
2828
augroup END
2929
```
3030

31-
Then, modify the `main.ts` file to accept the optional argument for a custom
31+
Then, update your `denops/denops-maze/deno.jsonc` to include the unknownutil
32+
dependency:
33+
34+
```json,title=denops/denops-maze/deno.jsonc
35+
{
36+
"imports": {
37+
"@denops/std": "jsr:@denops/std@^8.0.0",
38+
"@denops/std/": "jsr:@denops/std@^8.0.0/",
39+
"@core/unknownutil": "jsr:@core/unknownutil@^4.3.0",
40+
"maze_generator": "npm:@thewizardbear/maze_generator@^0.4.0"
41+
}
42+
}
43+
```
44+
45+
Now modify the `main.ts` file to accept the optional argument for a custom
3246
opener, generate a maze that fits the current window size, configure the buffer
3347
options to make it non-file readonly buffer, etc.
3448

3549
```typescript,title=denops/denops-maze/main.ts
36-
import type { Entrypoint } from "jsr:@denops/std@^7.0.0";
37-
import { batch, collect } from "jsr:@denops/std@^7.0.0/batch";
38-
import * as fn from "jsr:@denops/std@^7.0.0/function";
39-
import * as op from "jsr:@denops/std@^7.0.0/option";
40-
import { Maze } from "npm:@thewizardbear/maze_generator@^0.4.0";
41-
import { assert, is } from "jsr:@core/unknownutil@^4.3.0";
50+
import type { Entrypoint } from "@denops/std";
51+
import { batch, collect } from "@denops/std/batch";
52+
import * as fn from "@denops/std/function";
53+
import * as op from "@denops/std/option";
54+
import { Maze } from "maze_generator";
55+
import { assert, is } from "@core/unknownutil";
4256

4357
export const main: Entrypoint = (denops) => {
4458
denops.dispatcher = {

src/tutorial/maze/outputting-content-to-buffer.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ the maze to a buffer so that users can yank the maze with daily Vim operations!
77
Let's modify the code to make the generated maze output to a buffer.
88

99
```typescript,title=denops/denops-maze/main.ts
10-
import type { Entrypoint } from "jsr:@denops/std@^7.0.0";
11-
import { Maze } from "npm:@thewizardbear/maze_generator@^0.4.0";
10+
import type { Entrypoint } from "@denops/std";
11+
import { Maze } from "maze_generator";
1212

1313
export const main: Entrypoint = (denops) => {
1414
denops.dispatcher = {

src/tutorial/maze/properly-configured-the-buffer.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ buffer after closure. Open the `main.ts` file and modify the `maze` method as
77
follows:
88

99
```typescript,title=denops/denops-maze/main.ts
10-
import type { Entrypoint } from "jsr:@denops/std@^7.0.0";
11-
import * as buffer from "jsr:@denops/std@^7.0.0/buffer";
12-
import * as fn from "jsr:@denops/std@^7.0.0/function";
13-
import * as op from "jsr:@denops/std@^7.0.0/option";
14-
import { Maze } from "npm:@thewizardbear/maze_generator@^0.4.0";
10+
import type { Entrypoint } from "@denops/std";
11+
import * as buffer from "@denops/std/buffer";
12+
import * as fn from "@denops/std/function";
13+
import * as op from "@denops/std/option";
14+
import { Maze } from "maze_generator";
1515

1616
export const main: Entrypoint = (denops) => {
1717
denops.dispatcher = {

src/tutorial/maze/properly-create-a-virtual-buffer.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ proper virtual buffer that concretizes the buffer content. Let's modify the
1010
`main.ts` file as follows:
1111

1212
```typescript,title=denops/denops-maze/main.ts
13-
import type { Entrypoint } from "jsr:@denops/std@^7.0.0";
14-
import * as buffer from "jsr:@denops/std@^7.0.0/buffer";
15-
import * as fn from "jsr:@denops/std@^7.0.0/function";
16-
import { Maze } from "npm:@thewizardbear/maze_generator@^0.4.0";
13+
import type { Entrypoint } from "@denops/std";
14+
import * as buffer from "@denops/std/buffer";
15+
import * as fn from "@denops/std/function";
16+
import { Maze } from "maze_generator";
1717

1818
export const main: Entrypoint = (denops) => {
1919
denops.dispatcher = {

0 commit comments

Comments
 (0)