Skip to content

Commit 1d9d911

Browse files
authored
feat(nx-dev): tutorialkit project (#29992)
Adds a tutorial project under nx-dev The tutorials are run in browser and can be accessed here: [/tutorials](https://nx-dev-git-nx-dev-tutorialkit-nrwl.vercel.app/tutorials) The tutorials include: - TypeScript Packages - React Monorepo - Angular Monorepo In the future, we will link directly from the sidebar to the in-browser tutorials.
1 parent 7b85d91 commit 1d9d911

File tree

706 files changed

+214413
-314
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

706 files changed

+214413
-314
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ jest.debug.config.js
2222
/graph/client/src/assets/generated-task-inputs
2323
/graph/client/src/assets/generated-source-maps
2424
/nx-dev/nx-dev/public/documentation
25+
/nx-dev/nx-dev/public/tutorials
2526
/nx-dev/nx-dev/public/images/open-graph
2627
**/tests/temp-db
2728

@@ -38,6 +39,9 @@ out
3839
# Angular Cache
3940
.angular
4041

42+
# Astro Cache
43+
.astro
44+
4145
# Local dev files
4246
.env.local
4347
.bashrc

.nxignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
nx-dev/**/jest.config.js
2-
.next
2+
.next
3+
_files
4+
_solution
5+
nx-dev/tutorial/**/templates

.prettierignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,6 @@ CODEOWNERS
4747
.pnpm-store
4848

4949
/.nx/workspace-data
50-
/.nx/workflows/dynamic-changesets.yaml
50+
/.nx/workflows/dynamic-changesets.yaml
51+
_files
52+
_solution

docs/shared/tutorials/react-monorepo.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,7 @@ Nx comes with a generic mechanism that allows you to assign "tags" to projects.
927927
}
928928
```
929929

930-
Then go to the `project.json` of your `products` library and assign the tags `type:feature` and `scope:products` to it.
930+
Then go to the `package.json` of your `products` library and assign the tags `type:feature` and `scope:products` to it.
931931

932932
```json {% fileName="libs/products/package.json" %}
933933
{
@@ -938,7 +938,7 @@ Then go to the `project.json` of your `products` library and assign the tags `ty
938938
}
939939
```
940940

941-
Finally, go to the `project.json` of the `shared-ui` library and assign the tags `type:ui` and `scope:shared` to it.
941+
Finally, go to the `package.json` of the `shared-ui` library and assign the tags `type:ui` and `scope:shared` to it.
942942

943943
```json {% fileName="libs/shared/ui/package.json" %}
944944
{

graph/ui-project-details/src/lib/target-configuration-details-header/target-configuration-details-header.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
/* eslint-disable @nx/enforce-module-boundaries */
22
// nx-ignore-next-line
33
import type { TargetConfiguration } from '@nx/devkit';
4+
import { CopyToClipboardButton } from '@nx/graph/legacy/components';
45
import {
56
ChevronDownIcon,
67
ChevronUpIcon,
78
EyeIcon,
89
PlayIcon,
910
} from '@heroicons/react/24/outline';
10-
import { CopyToClipboardButton } from '@nx/graph/legacy/components';
11+
1112
import { Tooltip } from '@nx/graph/legacy/tooltips';
1213
import { twMerge } from 'tailwind-merge';
1314
import { Pill } from '../pill';

graph/ui-project-details/src/lib/target-configuration-details/target-configuration-details.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { FadingCollapsible } from './fading-collapsible';
1919
import { TargetConfigurationProperty } from './target-configuration-property';
2020
import { TooltipTriggerText } from './tooltip-trigger-text';
2121
import { PropertyInfoTooltip } from '../tooltips/property-info-tooltip';
22+
2223
interface TargetConfigurationDetailsProps {
2324
projectName: string;
2425
targetName: string;

graph/ui-project-details/src/lib/target-executor/target-executor-title.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { CopyToClipboardButton } from '@nx/graph/legacy/components';
21
import { Tooltip } from '@nx/graph/legacy/tooltips';
2+
import { CopyToClipboardButton } from '@nx/graph/legacy/components';
33
import { TooltipTriggerText } from '../target-configuration-details/tooltip-trigger-text';
44
import { PropertyInfoTooltip } from '../tooltips/property-info-tooltip';
55

nx-dev/feature-search/src/lib/algolia-search.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DocSearchModal, useDocSearchKeyboardEvents } from '@docsearch/react';
1+
import * as docsearchReact from '@docsearch/react';
22
import {
33
InternalDocSearchHit,
44
StoredDocSearchHit,
@@ -10,6 +10,8 @@ import { useRouter } from 'next/navigation';
1010
import { ReactNode, useCallback, useEffect, useRef, useState } from 'react';
1111
import { createPortal } from 'react-dom';
1212

13+
const { DocSearchModal, useDocSearchKeyboardEvents } = docsearchReact;
14+
1315
const ACTION_KEY_DEFAULT = ['Ctrl ', 'Control'];
1416
const ACTION_KEY_APPLE = ['⌘', 'Command'];
1517

nx-dev/nx-dev/copy-tutorial.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const { copySync, rmSync } = require('fs-extra');
2+
const path = require('path');
3+
4+
/**
5+
* Copies the tutorial kit build artifacts
6+
*/
7+
rmSync(path.resolve(path.join(__dirname, 'public/tutorials')), {
8+
recursive: true,
9+
force: true,
10+
});
11+
copySync(
12+
path.resolve(path.join(__dirname, '../tutorial/dist')),
13+
path.resolve(path.join(__dirname, 'public/tutorials')),
14+
{ overwrite: true }
15+
);

nx-dev/nx-dev/next.config.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ module.exports = withNx({
1313
},
1414
async headers() {
1515
return [
16+
{
17+
source: '/tutorials/:path*',
18+
headers: [
19+
{ key: 'Cross-Origin-Embedder-Policy', value: 'require-corp' },
20+
{ key: 'Cross-Origin-Opener-Policy', value: 'same-origin' },
21+
],
22+
},
1623
{
1724
source: '/:path*',
1825
headers: [
@@ -24,11 +31,23 @@ module.exports = withNx({
2431
{ key: 'X-XSS-Protection', value: '1; mode=block' },
2532
{ key: 'X-Content-Type-Options', value: 'nosniff' },
2633
{ key: 'X-Frame-Options', value: 'DENY' },
27-
{ key: 'Referrer-Policy', value: 'no-referrer' },
34+
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
2835
],
2936
},
3037
];
3138
},
39+
async rewrites() {
40+
return [
41+
{
42+
source: '/tutorials/:path*',
43+
destination: '/tutorials/:path*/index.html',
44+
},
45+
{
46+
source: '/tutorials',
47+
destination: '/tutorials/index.html',
48+
},
49+
];
50+
},
3251
async redirects() {
3352
const rules = [];
3453

nx-dev/nx-dev/project.json

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,20 @@
6464
"cwd": "nx-dev/nx-dev"
6565
}
6666
},
67+
"copy-tutorial": {
68+
"inputs": ["{workspaceRoot}/nx-dev/tutorial/**/*"],
69+
"outputs": ["{projectRoot}/public/tutorials"],
70+
"command": "node ./copy-tutorial.js",
71+
"dependsOn": ["tutorial:build"],
72+
"options": {
73+
"cwd": "nx-dev/nx-dev"
74+
}
75+
},
6776
"serve-docs": {
6877
"executor": "nx:run-commands",
6978
"options": {
7079
"commands": [
71-
"nx watch --projects=docs -- nx run nx-dev:copy-docs",
80+
"nx watch --projects=docs,tutorial -- nx run-many -t=copy-docs,copy-tutorial -p nx-dev",
7281
"nx run nx-dev:serve"
7382
],
7483
"parallel": true
@@ -80,7 +89,7 @@
8089
},
8190
"serve": {
8291
"executor": "@nx/next:server",
83-
"dependsOn": ["copy-docs"],
92+
"dependsOn": ["copy-docs", "copy-tutorial"],
8493
"options": {
8594
"buildTarget": "nx-dev:build-base",
8695
"dev": true
@@ -111,6 +120,10 @@
111120
"command": "nx copy-docs nx-dev",
112121
"description": "Copy generated docs to build output"
113122
},
123+
{
124+
"command": "nx copy-tutorial nx-dev",
125+
"description": "Copy tutorial to build output"
126+
},
114127
{
115128
"command": "npx ts-node -P scripts/tsconfig.scripts.json scripts/documentation/plugin-quality-indicators.ts",
116129
"description": "Fetch plugin data"

nx-dev/tutorial/README.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# TutorialKit Starter
2+
3+
👋 Welcome to TutorialKit!
4+
5+
This README includes everything you need to start writing your tutorial content quickly.
6+
7+
## Project Structure
8+
9+
```bash
10+
.
11+
├── astro.config.mjs # TutorialKit uses Astro 🚀 (https://astro.build)
12+
├── src
13+
│ ├── ...
14+
│ ├── content
15+
│ │ └── tutorial # Your tutorial content lives here
16+
│ └── templates # Your templates (see below for more information)
17+
├── public
18+
│ ├── favicon.svg
19+
│ └── logo.svg # Default logo used in top left for your tutorial
20+
├── ...
21+
├── theme.ts # Customize the theme of the tutorial
22+
└── uno.config.ts # UnoCSS config (https://unocss.dev/)
23+
```
24+
25+
## Getting Started
26+
27+
Make sure you have all dependencies installed and started the dev server:
28+
29+
```bash
30+
npm install
31+
npm run dev
32+
```
33+
34+
## UI Structure
35+
36+
```markdown
37+
┌─────────────────────────────────────────────────────┐
38+
│ ● ● ● │
39+
├───────────────────────────┬─────────────────────────┤
40+
│ │ │
41+
│ │ │
42+
│ │ │
43+
│ │ │
44+
│ │ Code Editor │
45+
│ │ │
46+
│ │ │
47+
│ │ │
48+
│ │ │
49+
│ Content ├─────────────────────────┤
50+
│ │ │
51+
│ │ │
52+
│ │ Preview & Boot Screen │
53+
│ │ │
54+
│ │ │
55+
│ ├─────────────────────────┤
56+
│ │ │
57+
│ │ Terminal │
58+
│ │ │
59+
└───────────────────────────┴─────────────────────────┘
60+
```
61+
62+
## Authoring Content
63+
64+
A tutorial consists of parts, chapters, and lessons. For example:
65+
66+
- Part 1: Basics of Vite
67+
- Chapter 1: Introduction
68+
- Lesson 1: Welcome!
69+
- Lesson 2: Why Vite?
70+
-
71+
- Chapter 2: Your first Vite project
72+
- Part 2: CLI
73+
-
74+
75+
Your content is organized into lessons, with chapters and parts providing a structure and defining common metadata for these lessons.
76+
77+
Here’s an example of how it would look like in `src/content/tutorial`:
78+
79+
```bash
80+
tutorial
81+
├── 1-basics-of-vite
82+
│ ├── 1-introduction
83+
│ │ ├── 1-welcome
84+
│ │ │ ├── content.md # The content of your lesson
85+
│ │ │ ├── _files # Initial set of files
86+
│ │ │ │ └── ...
87+
│ │ │ └── _solution # Solution of the lesson
88+
│ │ │ └── ...
89+
│ │ ├── 2-why-vite
90+
│ │ │ ├── content.md
91+
│ │ │ └── _files
92+
│ │ │ └── ...
93+
│ │ └── meta.md # Metadata for the chapter
94+
│ └── meta.md # Metadata for the part
95+
├── 2-advanced
96+
│ ├── ...
97+
│ └── meta.md
98+
└── meta.md # Metadata for the tutorial
99+
```
100+
101+
### Supported Content Formats
102+
103+
Content can be either written as Markdown (`.md`) files or using [MDX](https://mdxjs.com/) (`.mdx`). Files have a Front Matter at the top that contains the metadata and everything that comes after is the content of your lesson.
104+
105+
**Example**
106+
107+
```markdown
108+
---
109+
type: lesson
110+
title: Welcome!
111+
---
112+
113+
# Welcome to TutorialKit!
114+
115+
In this tutorial we'll walk you through how to setup your environment to
116+
write your first tutorial 🤩
117+
```
118+
119+
The metadata file (`meta.md`) of parts, chapters, and lessons do not contain any content. It only contains the Front Matter for configuration.
120+
121+
### Metadata
122+
123+
Here is an overview of the properties that can be used as part of the Front Matter:
124+
125+
| Property | Required | Type | Inherited | Description |
126+
| --------------- | -------- | --------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
127+
| type || `part \| chapter \| lesson` || The type of the metadata. |
128+
| title || `string` || The title of the part, chapter, or lesson. |
129+
| slug | | `string` || Let’s you customize the URL pathname which is `/:partSlug/:chapterSlug/:lessonSlug`. |
130+
| previews | | `Preview[]` || Configure which ports should be used for the previews. If not specified, the lowest port will be used. |
131+
| autoReload | | `boolean` || Navigating to a lesson that specifies `autoReload` will always reload the preview. This is typically only needed if your server does not support HMR. |
132+
| prepareCommands | | `Command[]` || List of commands to execute sequentially. They are typically used to install dependencies or to run scripts. |
133+
| mainCommand | | `Command` || The main command to be executed. This command will run after the `prepareCommands`. |
134+
135+
A `Command` has the following shape:
136+
137+
```ts
138+
string | [command: string, title: string] | { command: string, title: string }
139+
```
140+
141+
The `title` is used as part of the boot screen (see [UI Structure](#ui-structure)).
142+
143+
A `Preview` has the following shape:
144+
145+
```ts
146+
string | [port: number, title: string] | { port: number, title: string }
147+
```
148+
149+
In most cases, metadata is inherited. For example, if you specify a `mainCommand` on a chapter without specifying it on any of its lessons, each lesson will use the `mainCommand` from its respective chapter. This extends to chapter and parts as well.

nx-dev/tutorial/astro.config.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import tutorialkit from '@tutorialkit/astro';
2+
import { defineConfig, envField } from 'astro/config';
3+
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
4+
5+
export const config = defineConfig({
6+
base: '/tutorials',
7+
devToolbar: {
8+
enabled: false,
9+
},
10+
experimental: {
11+
env: {
12+
schema: {
13+
NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA: envField.string({
14+
context: 'client',
15+
access: 'public',
16+
optional: true,
17+
}),
18+
NEXT_PUBLIC_FARO_URL: envField.string({
19+
context: 'client',
20+
access: 'public',
21+
optional: true,
22+
}),
23+
NEXT_PUBLIC_VERCEL_ENV: envField.string({
24+
context: 'client',
25+
access: 'public',
26+
optional: true,
27+
}),
28+
},
29+
},
30+
},
31+
vite: {
32+
plugins: [nxViteTsPaths() as any],
33+
ssr: {
34+
noExternal: [
35+
'@tutorialkit/astro',
36+
'@astrojs/mdx',
37+
'@astrojs/react',
38+
'astro-expressive-code',
39+
],
40+
},
41+
},
42+
integrations: [
43+
tutorialkit({
44+
components: {
45+
HeadTags: './src/components/HeadTags.astro',
46+
TopBar: './src/components/TopBar.astro',
47+
},
48+
}),
49+
],
50+
});
51+
52+
export default config;

0 commit comments

Comments
 (0)