* adding a video

* updating docs

* wip: getting tailwind working better with postcss-loader

* finally got tailwind working

* WIP: site fix up

* Cleaning up tailwind!

* updating docs

* moved things around drastically

* revamped docs

* data from commander cli options

* examples for cache

* adding shiki twoslash and the config.md updated to use it

* some more config updates

* fixing broken links
This commit is contained in:
Kenneth Chau 2022-09-18 17:01:05 -07:00 коммит произвёл GitHub
Родитель 6b88431304
Коммит 8df964b017
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
74 изменённых файлов: 1045 добавлений и 851 удалений

Просмотреть файл

@ -1,4 +1,4 @@
{
"label": "Contributing",
"position": 3
"position": 5
}

Просмотреть файл

@ -1,7 +1,7 @@
---
sidebar_position: 1
sidebar_position: 2
title: Contributing to Lage
title: Contributor License Agreement
---
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

Просмотреть файл

@ -0,0 +1,21 @@
---
sidebar_position: 1
title: Lage Packages
---
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
`lage` itself is a [monorepo](https://github.com/microsoft/lage/tree/master/packages). We dogfood our own task runner, of course! The packages and their responsibilities are listed below:
<ThemedImage
alt="Package graph with task graph equals target graph"
sources={{
light: useBaseUrl("/img/contributor-guide-light.png"),
dark: useBaseUrl("/img/contributor-guide-dark.png"),
}}
style={{
width: "100%",
}}
/>

Просмотреть файл

@ -8,7 +8,7 @@ title: Migration Guide
## v0.x.y -> v1.0.0
Lage is graduating to 1.0.0! We have a breaking change. Namely, the remote cache mechanism is changing. See this [PR #172](https://github.com/microsoft/lage/pull/172) for details. The behavior is [described here](./remote-cache). The behavior is changed for remote cache:
Lage is graduating to 1.0.0! We have a breaking change. Namely, the remote cache mechanism is changing. See this [PR #172](https://github.com/microsoft/lage/pull/172) for details. The behavior is [described here](Tutorial/remote-cache.md). The behavior is changed for remote cache:
1. `lage` only write to a remote cache if the environment variable `LAGE_WRITE_REMOTE_CACHE` is set to true
2. remote cache now works as a fallback; always reading & writing to the local cache first

Просмотреть файл

@ -1,4 +0,0 @@
{
"label": "Guide",
"position": 2
}

Просмотреть файл

@ -1,214 +0,0 @@
---
sidebar_position: 10
title: CLI usage
---
# CLI usage
`lage` is meant to be run as a CLI. After installing `lage` inside the repository or globally, you can run the npm scripts from your repository like this:
```
$ lage build
```
## Caching
`lage` by default will skip tasks that it has already done recently. As long as the source file and the command called to `lage` has not changed, those packages will be skipped. Sometimes, this incremental behavior is not desired. You can override the caching behavior by using the `no-cache` argument.
```
$ lage build --no-cache
```
## Verbose
`lage` by default will hide the output from successful tasks. If you want to see the output as they are being generated, call `lage` with the `verbose` argument.
```
$ lage build --verbose
```
## Options
### CliOptions
#### cache
_type: boolean_
default: true, --no-cache will skip fetching cache or saving cache
`lage` by default will skip tasks that it has already done recently. As long as the source file and the command called to `lage` has not changed, those packages will be skipped. Sometimes, this incremental behavior is not desired. You can override the caching behavior by using the `no-cache` argument.
```
$ lage build --no-cache
```
#### command
_type: string[]_
positional arguments that specify which tasks to run
Commands are collected as an array like this:
```
lage build test bundle
```
This will tell `lage` to execute all three commands against all the packages
#### concurrency
_type: number_
number of parallel tasks that can be run at a time
By default, this is the number of CPU cores detected by `os.cpus().length`,
change to any number to achieve desired concurrency.
#### deps
_type: boolean_
default: true, --no-deps will skip dependent packages and tasks
This has the semantic of running tasks up to what is specified in the command line
such as with `--scope` or `--since`
#### grouped
_type: boolean_
Specify whether to make the console logger to group the logs per package task
Example: `lage --grouped`
#### ignore
_type: string[]_
Ignores certain files when calculating the scope with `--since`
Certain files might need to be changed during the preparation of a build
job. In that situation, `lage` can ignore those files when calculating what
has changed with the `--since` flag.
#### include-dependencies
_type: boolean_
Include all transitive dependencies when running a command(s).
This is useful for situations where you want to "set up" a package that relies on other packages being set up.
```
lage setup --scope my-package --include-dependencies
# my-package and all of its dependencies will be setup
```
#### node
_type: string[]_
node arguments to be passed into the npm lifecycle scripts
For example:
To increase the amount of memory to use for the npm tasks
```
lage --node="--max_old_space_size=8192"
```
#### only
_type: boolean_
only run the commands, do not consider dependent tasks
For example, if `test` depends on `build`, `lage` will always run `build` before `test`.
You can type this `lage test --only` to skip running `build` task altogether. This is much
like what is the default of `lerna` or `rush`.
#### profile
_type: boolean_
Creates a flamegraph-profile JSON for Chromium-based devtool
Pay attention to the output summary to find the location of the JSON file.
#### reporter
_type: string_
Specify whether to use the JSON Reporter to create a parsable log output
Example: `lage --reporter json`
#### resetCache
_type: boolean_
--reset-cache will skip fetching cache, but will overwrite cache
```
lage --reset-cache
```
Will always run the tasks, while reseting the saved cache
#### scope
_type: string[]_
Which specific packages to consider as in scope for the run
This act as the "entry point" of the package-task graph traversal. To prevent
running tasks for dependent package, use the `--no-deps` flag in combination.
You can specify multiple scoped packages like this:
```
lage build --scope foo --scope bar --scope baz
```
#### since
_type: string_
calculate which packages are in scope based on changed packages since a mergebase
This uses the `git diff ${target_branch}...` mechanism to identify which packages
have changed. There is an assumption of all the input files for a package exist
inside their respective package folders.
#### to
_type: string[]_
Scopes a list of packages, and not built their dependents (consuming packages).
This implies `--scope` and `--no-deps`.
Just like the `--scope` argument, you can specify multiple packages like this:
```
lage build --to foo --to bar
```
#### verbose
_type: boolean_
Verbose mode, turns on all logging
`lage` by default will hide the output from successful tasks. If you want to see the
output as they are being generated, call `lage` with the `verbose` argument.
```
$ lage build --verbose
```
#### safe-exit
_type: boolean_
Runs currently executing tasks to completion before exiting.
This prevents the risk of having orphaned child processes running after
`lage` has exited.

Просмотреть файл

@ -1,94 +0,0 @@
---
sidebar_position: 9
title: Configuration
---
Configuration is provided by [Cosmiconfig](https://www.npmjs.com/package/cosmiconfig), so `lage` configuration is very flexible! We recommend the use of a `lage.config.js` because it is both concise and flexible.
Create a `lage.config.js` file and place all your configurations there:
```js
module.exports = {
pipeline: {
build: ["^build"],
test: ["build"],
},
};
```
## Options
### CacheOptions
_type: BackfillCacheOptions & { environmentGlob: string[] }_
### ConfigOptions
#### cache
_type: boolean_
Should cache be enabled
#### cacheOptions
_type: [CacheOptions](#CacheOptions)_
Backfill cache options
#### ignore
_type: string[]_
Which files to ignore when calculating scopes with --since
#### npmClient
_type: "npm" | "yarn" | "pnpm"_
Which NPM Client to use when running npm lifecycle scripts
#### pipeline
_type: [Pipeline](#Pipeline)_
Defines the task pipeline, prefix with "^" character to denote a topological dependency
Example:
```
{
build: ["^build"],
test: ["build"],
lint: []
}
```
#### priorities
_type: [Priority](#Priority)[]_
Optional priority to set on tasks in a package to make the scheduler give priority to tasks on the critical path for high priority tasks
#### repoWideChanges
_type: string[]_
disables --since flag when any of this list of files changed
### Pipeline
### Pipelines
_type: Map<string, [Pipeline](#Pipeline)>_
### Priority
#### package
_type: string_
package name, as in package.json
#### priority
_type: number_
priority, the higher the more priority; undefined priority means lowest priority
#### task
_type: string_
task name, as listed in the `scripts` section of package.json

Просмотреть файл

@ -1,104 +0,0 @@
---
sidebar_position: 1
title: Getting Started
---
# Getting started
Getting started with `lage` is quite easy! There are 2 ways to do this: automated or manual.
## Automated
### 1. Invoke the `lage init` command in the monorepo root to get started:
```
npx lage init
```
This will let `lage` install the latest version of lage into your repo as a one of the `devDependencies` at the root level.
Since `lage` is compatible with all the popular workspace managers, this can be applied to a `yarn`, `pnpm`, or `rush` workspace. `lage` is an excellent
replacement for `lerna` in handling running tasks in your repo topologically.
### 2. Customize `lage.config.js`
The `init` command will also generate a default `lage.config.js`. This will likely need to be modified. In particular, pay attention to the `pipeline`
configuration:
```js
module.exports = {
pipeline: {
build: ["^build"],
test: ["build"],
lint: [],
},
};
```
You may or may not have these scripts in your packages' `package.json` files. Remember the `^` character is to indicate that the task is run in
topological order.
To build with the freshly installed `lage` runner, type the following:
```
npm run lage build
```
or
```
yarn lage build
```
## Manual - Yarn and PNPM Workspaces
You can manually install `lage` as well.
### 1. Place `lage` in the `devDependencies` at the root level:
```json
{
"devDependencies": {
...,
"lage": "0.16.0",
...
}
}
```
### 2. Add a `lage.config.js` file to configure the pipeline:
```js
module.exports = {
pipeline: {
build: ["^build"],
test: ["build"],
lint: [],
},
};
```
### 3. Inside your monorepo, run `yarn` or `pnpm install`
```
yarn
```
or
```
pnpm install
```
### 4. Run `lage` commands
```
yarn lage build
```
or
```
pnpm run lage build
```

Просмотреть файл

@ -1,28 +0,0 @@
---
sidebar_position: 8
title: Priorities
---
# Priorities
As your repo gets more and more complex, you'll need to do some some [profiling](./profile) to understand bottlenecks. Sometimes, the package tasks are not queued in the order that will produce the most optimized run times.
To manually pick a package task to be higher priority, simply place a [`priorities` configuration](./Config) in the `lage.config.js`:
```js
module.exports = {
pipeline: { ... },
priorities: [
{
package: 'foo',
task: 'test',
priority: 100
}
]
}
```
The higher the priority number, the higher the priority. These numbers are relative with each other. Anything that is not listed in the priorities array means they are not prioritized.
> Note: an active research here is how to provide `lage` historical data to automatically prioritize in subsequent runs. PR's are welcome!

Просмотреть файл

@ -1,29 +0,0 @@
---
sidebar_position: 3
title: Scoped builds
---
# Scoped Builds
Scoping a task runner can speed up the process especially if there are distinct clusters of packages that are not related to each other within the repository. `lage` has a `scope` option that allows the task running to proceed up to the packages found that matches the `scope` argument. This is a string matcher based on the name of the packages (not the package path).
> It is important to note that dependents and dependencies refer to the package & task.
## Scoped builds with all its dependents
By default, it is helpful to be able to run tasks on all affected packages within a scope. Packages that changed will affect downstream consumers. In this case, pass along the `scope` to build all the dependencies as well.
> Note: you can use wild card character: `*`. This is particularly helpful when packages are named by group or by scope.
```
$ lage build --scope *build-tools*
```
## Scoped builds with no dependent & their dependencies
Sometimes we want to run the tasks needed to satisfy the `build` script of all the packages that has the `build-tools` string in their names. Think of this as running tasks up and including the package matched in the scope. Simply add a `--no-deps` flag to run up to a package task.
```
$ lage build --scope *build-tools* --no-deps
```

Просмотреть файл

@ -1,63 +0,0 @@
## Overview
Your JS repo has gotten large enough that you have turned to using a tool to help you manage multiple packages inside a repository. That's great! However, you realized quickly that the tasks defined inside the workspace have to be run in package dependency order.
Lerna, Rush, wsrun and even pnpm will provide a simple way for you to run npm scripts in a topological order. However, these tools will force you to run your tasks by script name one at a time. For example, all the `build` scripts will have to run first. Then all the `test` scripts run in the topological order.
This usually means that there are wasted CPU cycles in between `build` and `test`. We can achieve better pipelining the npm scripts if we had a way to say that `test` can run as soon as `build` are done for the package.
`lage` (Norwegian for "make", pronounced law-geh) solves this by providing a terse pipelining syntax. It has many features geared towards speeding up the task runner that we'll explore later.
## Quick Start
`lage` gives you this capability with very little configuration. First, let's install the `lage` utility. You can place this in your workspace's root `package.json` by running `yarn add`:
```
yarn add -D lage
```
Confirm with `yarn` that you are sure to add a package at the root level, you then place a root level script inside the `package.json` to run `lage`:
```
{
"scripts": {
"build": "lage build",
"test": "lage test"
}
}
```
Add a configuration file in the root to get started. Create this file at the root `lage.config.js`:
```js
module.exports = {
pipeline: {
build: ["^build"],
test: ["build"],
},
};
```
Do not worry about the syntax for now. We will go over the configuration file in a coming section. You can now run this command:
```
$ lage test
```
`lage` will detect that you need to run `build` steps before `test`s are run.
# Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

Просмотреть файл

@ -1,4 +0,0 @@
{
"label": "Introducing Lage",
"position": 1
}

Просмотреть файл

@ -1,29 +1,60 @@
---
sidebar_position: 2
title: How does `lage` work?
sidebar_position: 1
sidebar_label: Introduction
sidebar_class_name: green
slug: Introduction
---
# How does `lage` work?
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
When your JavaScript repository has grown large enough that you have turned to using a [monorepo](https://monorepo.tools) to help you organize your code as multiple packages inside a repository. That's great! However, you realized quickly that the build scripts defined inside the workspace have to be run in package dependency order.
There exists tools in the market that will provide a way for you to run these npm scripts in a topological order. These tools will allow you execute your tasks in the correct order. So why choose `lage` for your repository?
1. `lage` is battle tested - it is in use by many JavaScript repositories number in the millions lines of code each
2. `lage` can be easily adopted - all it takes is just one npm package install with a single configuration file for the entire repository
3. `lage` supports remote cache as a fallback - never build the same code twice
4. `lage` is optimized for modern multi-core development machines - don't waste your CPU resource waiting on a single core when you have so many to spare!
## How does `lage` schedule tasks?
`lage` has a secret weapon: it has a "pipeline" configuration syntax to define the implicit relationship between tasks. Combined with a package graph, `lage` knows how to schedule which task to run first and which one can be run in parallel. Let's look at an example:
<ThemedImage
alt="Package graph with task graph equals target graph"
sources={{
light: useBaseUrl("/img/graph-diagram-light.png"),
dark: useBaseUrl("/img/graph-diagram-dark.png"),
}}
style={{
width: "100%",
}}
/>
## How does `lage` make builds faster?
So how does `lage` make builds faster? To fully appreciate how `lage` gives you the best build performance compared to other monorepo task runners, take a look at this example. Here we have a repo with this dependency graph:
import Mermaid from '@theme/Mermaid';
import Mermaid from "@theme/Mermaid";
<Mermaid chart={`
<Mermaid
chart={`
graph TD
FooCore --> BuildTool
BarCore --> BuildTool
FooApp1 --> FooCore
FooApp2 --> FooCore
BarPage --> BarCore
`} />
`}
/>
## Level 1: Typical Lerna or Workspace Runners
### Level 1: Legacy Workspace Runners
First, let's take a look at the typical workspace runners. `Lerna`, `pnpm recursive`, `rush` and `wsrun` all will run one task at a time. This creates a sort of "build phase" effect where `test` scripts are not allowed to run until `build`.
First, let's take a look at the typical workspace runners. `Lerna` (before ), `pnpm recursive`, `rush` and `wsrun` all will run one task at a time. This creates a sort of "build phase" effect where `test` scripts are not allowed to run until `build`.
<Mermaid chart={`gantt
<Mermaid
chart={`gantt
title Level 1: Typical Lerna or Workspace Runners
dateFormat s
axisFormat %S
@ -55,13 +86,15 @@ First, let's take a look at the typical workspace runners. `Lerna`, `pnpm recurs
prepare: bp_prepare, after bc_prepare, 10s
build: bp_build, after bc_build, 25s
test: bp_test, after total_build, 12s
`} />
`}
/>
## Level 2: Scoping
### Level 2: Scoping
One of the first way to speeding up build jobs is to use "scoping". Usually a change only affect a subset of the graph. We can get rid of the builds of `FooCore`, `FooApp1` and `FooApp2` if the only changes are inside `BarCore`. However, we'll note that `BarPage` is still affected, resulting in this.
<Mermaid chart={`gantt
<Mermaid
chart={`gantt
title Level 2: Scoping
dateFormat s
axisFormat %S
@ -88,13 +121,15 @@ One of the first way to speeding up build jobs is to use "scoping". Usually a ch
prepare: bp_prepare, after bc_prepare, 10s
build: bp_build, after bc_build, 25s
test: bp_test, after total_build, 12s
`} />
`}
/>
## Level 3. Caching
### Level 3. Caching
To further improve build times, we can take advantage of build caches. If we had previously built certain packages, we should be able to speed up the build with a cache. Here, the `BarCore` packages have already been built and tested, and so
<Mermaid chart={`gantt
<Mermaid
chart={`gantt
title Level 3: Caching
dateFormat s
axisFormat %S
@ -122,13 +157,15 @@ To further improve build times, we can take advantage of build caches. If we had
prepare: bp_prepare, after bc_prepare, 10s
build: bp_build, after bc_build, 25s
test: bp_test, after total_build, 12s
`} />
`}
/>
## Level 4. Pipelining
### Level 4. Pipelining
Finally, the last thing we can to speed things up is to break down the wall between build phases from the task runner. In `lage`, we define the relationship between scripts in the `pipeline` configuration.
<Mermaid chart={`gantt
<Mermaid
chart={`gantt
title Level 4: Pipelining
dateFormat s
axisFormat %S
@ -157,4 +194,5 @@ Finally, the last thing we can to speed things up is to break down the wall betw
prepare: bp_prepare, after bc_prepare, 10s
build: bp_build, after bp_prepare, 25s
test: bp_test, after bp_build, 12s
`} />
`}
/>

Просмотреть файл

@ -0,0 +1,72 @@
---
sidebar_position: 2
sidebar_label: Quick Start
title: Quick Start
---
## Automated Installation
```
npx lage init
```
This will let `lage` install the latest version of lage into your repo as a one of the `devDependencies` at the root level.
`lage` is compatible with all the popular workspace managers, this can be applied to a `yarn`, `pnpm`, or `rush` workspace.
## Customize `lage.config.js`
The `init` command will also generate a default `lage.config.js`. This will likely need to be modified. In particular, pay attention to the `pipeline`
configuration:
```js
module.exports = {
pipeline: {
build: ["^build"],
test: ["build"],
lint: [],
},
};
```
## Customize workspace (root level) `package.json`
Modify the `package.json` to use `lage` to run your tasks:
```json
{
"name": "workspace-root",
"scripts": {
"build": "lage build",
"test": "lage test",
"lint": "lage lint"
},
"devDependencies": {
"lage": "latest"
}
}
```
## Ready to Build, Test, and Lint!
You are now ready to start running all the commands in your repository with `lage`. You'll notice that tasks are now cached!
```
npm run build
```
or
```
yarn build
```
or
```
pnpm build
```
## Next Steps
Now that you've configured `lage`, dig deeper in the [Tutorial](Tutorial/pipeline.md) section for features like remote caching, task skipping, customized pipelines, and setting priorities.

Просмотреть файл

@ -0,0 +1,4 @@
{
"label": "Reference",
"position": 4
}

Просмотреть файл

@ -0,0 +1,164 @@
---
sidebar_position: 1
title: Command Line Options
---
`lage` is meant to be run as a CLI. After installing `lage` inside the repository or globally, you can run the npm scripts from your repository like this:
```
$ lage [options] <command>
```
---
## Run Command
Runs a set of commands in a target graph. The targets are defined by packages and their scripts as defined the package.json files.
Usage: `lage [run] <command1> [command2...commandN] [options] run commands`
### Options
```
--reporter <reporter...> reporter (default: "npmLog")
--log-level <level> log level (choices: "info", "warn", "error", "verbose", "silly")
--verbose verbose output
-c, --concurrency <n> concurrency (default: 9)
--scope <scope...> scopes the run to a subset of packages (by default, includes the dependencies and dependents as well)
--no-dependents|--no-deps disables running any dependents of the scoped packages
--dependencies|--include-dependencies adds the scoped packages dependencies as the "entry points" for the target graph run
--since <since> only runs packages that have changed since the given commit, tag, or branch
--to <scope...> runs up to a package (shorthand for --scope=<scope...> --no-dependents)
--grouped groups the logs (default: false)
--no-cache disables the cache
--reset-cache resets the cache, filling it after a run
--skip-local-cache skips caching locally
--profile [profile] writes a run profile into a file that can be processed by Chromium devtool
--nodearg <nodeArg> arguments to be passed to node (e.g. --nodearg="--max_old_space_size=1234 --heap-prof" - set via "NODE_OPTIONS" environment variable
--continue continues the run even on error
-h, --help display help for command
```
### Examples
#### Basic case, running "build", "test", and "lint" against all packages
$ lage build test lint
#### Concurrency
$ lage build test lint --concurrency=4
#### Filtering by certain packages
Scoped to "package-a" and "package-b" and their dependencies and dependents:
$ lage build test lint --scope package-a package-b
Scoped to "package-a" and "package-b" only:
$ lage build test lint --scope package-a package-b --no-deps
Scoped to packages that have changed in the current branch against a target merge branch:
$ lage build test lint --since origin/master
#### Continue running even after encountering an error for one of the targets
$ lage build test lint --continue
#### Controlling logged outputs
Show verbose output for each target:
$ lage build test lint --verbose
Show only errors for each target:
$ lage build test lint --log-level=error
Show logs as grouped by each target:
$ lage build test lint --grouped --verbose
Choosing a different reporter while logging (e.g. nice outputs for Azure DevOps):
$ lage build test lint --reporter=azureDevOps
---
## Cache Command
`lage` by default will skip tasks that it has already done recently. As long as the source file and the command called to `lage` has not changed, those packages will be skipped. Sometimes, this incremental behavior is not desired. You can override the caching behavior by using the `no-cache` argument.
```
$ lage build --no-cache
```
### Options
```
--reporter <reporter...> reporter (default: "npmLog")
--log-level <level> log level (choices: "info", "warn", "error", "verbose", "silly")
--verbose verbose output
--prune <days> Prunes cache older than certain number of <days>
--clear Clears the cache locally
-h, --help display help for command
```
### Examples
#### Prune local cache older than 30 days
```
$ lage cache --prune 30
```
#### Completely clear all local cache
```
$ lage cache --clear
```
---
## Global Options
These are options that apply to all commands.
### Verbosity, Log Levels, and Grouping
`lage` by default will hide the output from successful tasks. If you want to see the output as they are being generated, call `lage` with the `verbose` argument.
```
$ lage build --verbose
```
#### Log Levels
You can control the log level instead of using "--verbose" argument. You can display `warn` messages and above (`error`) in the following example:
```
$ lage build --log-level warn
```
Valid values here are `silly`, `verbose`, `info`, `warn`, `error`. If `erorr` is passed to `--log-level`, you'll receive the least amount of information. The defualt is `info`.
#### Grouped logs
`lage` will interweave all the `stdout` and `stderr` from all active targets as they are running. This may become a mess, so `lage` can group output messages together. These messages will only be displayed when the target is completed:
```
$ lage build --verbose --grouped
```
### Reporter
`lage` comes with various kinds of reporters. Reporters take the logged messages of the target runs, format them, and display them. The default one can group messages, and there are ones that would work well with various Continuous Integration systems like Azure DevOps.
You can pick the reporter by passing the `--reporter` flag:
```
$ lage build --reporter json
```
Available reporters are: `azureDevops`, `json`. By default the log messages are formatted with the "default" reporter.

Просмотреть файл

@ -0,0 +1,95 @@
---
sidebar_position: 9
title: Configuration
---
Configuration is provided by [Cosmiconfig](https://www.npmjs.com/package/cosmiconfig), so `lage` configuration is very flexible! We recommend the use of a `lage.config.js` because it is both concise and flexible.
Create a `lage.config.js` file and place all your configurations there:
```js
module.exports = {
pipeline: {
build: ["^build"],
test: ["build"],
},
};
```
### A Complete Tour of the Config
:::tip
Roll over the various properties to tour the different configs
:::
```js twoslash
/// <reference types="node" />
/** @type {import("@lage-run/cli").ConfigOptions} */
// ---cut---
module.exports = {
pipeline: {
build: ["^build"],
test: {
outputs: [],
dependsOn: ["build"],
},
lint: {
type: "worker",
options: {
maxWorkers: 4,
worker: "path/to/scripts/worker/lint.js",
},
},
start: [], // Calls "start" in all the packages
"specific-package-a#test": ["specific-package-b#build"],
},
npmClient: "yarn", // optional, by default "npm run" is used; "yarn" can exhibit slightly different behavior,
cacheOptions: {
/** @see https://github.com/microsoft/backfill#configuration */
cacheStorageConfig: {
provider: "azure-blob", // use this to specify a remote cache provider such as "azure-blob",
options: {
// There are specific options here for different cache provider
},
},
/**
* Any of these files changed would invalidate the cache
*
* NOTE: lockfiles are NOT necessary here. lage already takes external dependency versions into account.
*/
environmentGlob: [".github/**", ".azure-devops/**"],
/**
* Useful for when caches need to be versioned
*/
cacheKey: "v1",
/**
* Manually set this to true so that remote caches are pushed - useful in CI systems that do *not* use standard
* environment variables to indicate that it is run from a CI system.
*/
writeRemoteCache: boolean,
/**
* Skips writes to local cache - also useful in CI (defaults to true when CI systems are detected)
*/
skipLocalCache: boolean,
},
/**
* affects the --since flag: ignore changes in these paths, so they do not count as changes between refs
*/
ignore: ["*.md"],
/**
* affects the --since flag: any changes in these paths mean that --since flag is disabled; caching is not affected by this flag
*/
repoWideChanges: ["yarn.lock"],
};
```

Просмотреть файл

Просмотреть файл

@ -0,0 +1,4 @@
{
"label": "Tutorial",
"position": 3
}

Просмотреть файл

@ -1,14 +1,12 @@
---
sidebar_position: 4
title: Caching
title: 4. Local Caching
---
# Caching
`lage` by default will cache tasks that it has already done recently locally on disk. As long as the source file and the command arguments have not changed, those cached results will be restored.
See (Remote Cache)[./remote-cache] for details about speeding up local dev environment even further with a remote cache from Continuous Integration jobs.
See [Remote Cache](Tutorial/remote-cache.md) for details about speeding up local dev environment even further with a remote cache from Continuous Integration jobs.
## Turn off cache
@ -23,7 +21,7 @@ $ lage build --no-cache
Once in a while, the cache might need to be recreated from scratch. In those situations, you can reset the cache by passing in the `--reset-cache` argument to the command line.
```
lage --reset-cache
lage build --reset-cache
```
## Cache Options

Просмотреть файл

@ -0,0 +1,63 @@
---
sidebar_position: 1
title: 1. Installation
---
import { StackBlitz } from "@site/src/components/StackBlitz";
Getting started with `lage` is easy. We have already covered the automated installation in the [Quick Start](/Quick Start) guide. If you prefer having more control, read about how to install `lage` manually in this page.
## Manually install `lage` in a Yarn and PNPM workspace
You can manually install `lage` as well.
### 1. Place `lage` in the `devDependencies` at the root level.
Feel free to replace `latest` tag with something specific. Take a look at the [npm link for lage](https://www.npmjs.com/package/lage) to see what the latest version may be at the time.
```json
{
"devDependencies": {
...,
"lage": "latest",
...
}
}
```
### 2. Add a `lage.config.js` file to configure the pipeline:
```js
module.exports = {
pipeline: {
build: ["^build"],
test: ["build"],
lint: [],
},
};
```
### 3. Inside your monorepo, run `yarn` or `pnpm install`
```
yarn
```
or
```
pnpm install
```
### 4. Run `lage` commands
```
yarn lage build
```
or
```
pnpm run lage build
```

Просмотреть файл

@ -1,12 +1,14 @@
---
sidebar_position: 6
sidebar_position: 2
title: Pipeline
title: 2. Pipeline
---
# Pipelining package tasks
In this step, you'll learn about how to influence how `lage` schedules which "target" runs at which time. For full details on how to configure pipelines, make sure to consult with the [reference for configuration](/docs/Reference/config).
In the traditional monorepo task runners, like `lerna`, each npm lifecycle script like `build` or `test` is run topologically or in parallel individually. Depending on the graph of the packages, CPU cores are left idle wasting developer time.
## What is a `lage` pipeline?
In the traditional monorepo task runners, each npm lifecycle script like `build` or `test` is run topologically or in parallel individually. Depending on the graph of the packages, CPU cores are left idle wasting developer time.
Futhermore, the developer is expected to keep track of an **implicit** graph of the tasks. For example, the developer is expected to understand that perhaps the `test` task is only available after `build` has completed.
@ -34,33 +36,45 @@ What you are declaring here in the `pipeline` object of the configuration is a d
The `^` symbol explicitly declares that the task has a package-topological dependency on another task. For example, if `foo` package depends on `bar`, `lage build` will guarantee that the `build` task of `bar` will happen before `foo`'s `build` task.
```json
{
"pipeline": {
"build": ["^build"]
}
}
```
### Empty dependency list
The `lint` task above has NO dependencies. This means that it can start whenever it can!
```json
{
"pipeline": {
"lint": []
}
}
```
### Tasks that are in the `pipeline` but not in SOME `package.json`
Sometimes tasks declared in the `pipeline` are not present in all packages' `package.json` files. `lage` will automatically ignore those. No problem!
### Pipeline tasks are the only ones that `lage` knows about
`lage` will only account for tasks declared in the `pipeline` configuration. If it's not listed there, `lage` will not know how to run them.
### Specific package tasks
Sometimes it becomes necessary to manually place a package-task dependency on another package-task. This can occur especially in repos that are just coming off of a lerna or rush repository where the tasks are traditionally run in separate phases. Sometimes assumptions were made those repositories that are not expressable in the simple task pipeline configuration as seen above. For thoes cases, simply place those alongside with the rest of the pipeline configuration like this:
```js
module.exports = {
pipeline: {
build: ["^build"],
test: ["build"],
lint: [],
"foo#build": ["bar#test"],
},
};
```
Sometimes it becomes necessary to manually place a package task dependency on another package task. This can occur especially in repos that are just coming off of a lerna or rush repository where the tasks are traditionally run in separate phases. Sometimes assumptions were made in those repositories that are not expressable in the simple task pipeline configuration as seen above. For thoes cases, simply place those alongside with the rest of the pipeline configuration.
In this example, we illustrate a `build` script of `foo` package depends on the `test` script of `bar`. The syntax is `[package]#[task]`.
```json
// package-a build depends on the output of package-b build.
{
"pipeline": {
"test": ["build"],
"foo#build": ["bar#test"]
}
}
```
This seems like it goes against the `test: ["build"]`, but it does not. Since `test` scripts does not have a topological dependency, it theoretically can get triggered anytime its own package's `build` script has finished! The general guidance is to get rid of these specific package-task to package-task dependency in the pipeline as quickly as possible so the builds can be optimized better.

Просмотреть файл

@ -0,0 +1,44 @@
---
sidebar_position: 7
title: 7. Priorities
---
In a large monorepo, you'll need to do some [profiling](Tutorial/profile.md) to understand bottlenecks. Sometimes, the package tasks are not scheduled in the order that will produce the most optimized run times.
## v2 styled configuration for priority
This syntax was introduced in v2.x of `lage`, you can now configure the priority inside the target pipeline configuration:
```js
module.exports = {
pipeline: {
build: ["^build"],
test: ["build"],
"foo#test": {
priority: 100,
dependsOn: ["build"]
}
},
}
```
## Legacy (v1 + v2) way of configuring priority
To manually pick a package task to be higher priority, simply place a [`priorities` configuration](Reference/config.md) in the `lage.config.js`:
```js
module.exports = {
pipeline: { ... },
priorities: [
{
package: 'foo',
task: 'test',
priority: 100
}
]
}
```
The higher the priority number, the higher the priority. These numbers are relative with each other. Anything that is not listed in the priorities array means they are not prioritized.

Просмотреть файл

@ -1,7 +1,7 @@
---
sidebar_position: 7
sidebar_position: 6
title: Profiling `lage`
title: 6. Profiling `lage`
---
# Profiling `lage`

Просмотреть файл

@ -1,11 +1,9 @@
---
sidebar_position: 5
title: Remote Cache
title: 5. Remote Cache
---
# Remote Cache
As your repo grows in size and complexity, the build takes longer and longer even locally. `lage` elegantly provides an incremental build capability given a locally available cache. When we pair the caching capability of `lage` with a cloud storage provider, we can speed up local builds with remote cache made available by Continuous Integration, or CI, jobs.
The theory is that when the CI job runs, it'll produce a "last known good" cache to be uploaded in a cloud storage, like Azure Blob Storage. The remote cache has been made available both for build-over-build speed ups in future CI jobs, as well as the local first build scenario.
@ -18,7 +16,7 @@ Follow these steps to set up a remote cache
## 1. Make sure to upgrade to latest `lage` (v1.0.0+)
See [migration guide](./migration)
See [migration guide](Cookbook/migration.md)
```
$ yarn upgrade lage
@ -81,7 +79,7 @@ Create a secret named "BACKFILL_CACHE_PROVIDER_OPTIONS":
{"connectionString":"the **read-write** connection string","container":"CONTAINER NAME"}
```
## Notes
::Note
### Uploading cache to a remote is *not* the default
Without the `LAGE_WRITE_REMOTE_CACHE` environment variable, `lage` no longer uploads build caches to the remote server.
@ -89,4 +87,6 @@ Without the `LAGE_WRITE_REMOTE_CACHE` environment variable, `lage` no longer upl
### Accessing environment variables
Lage picks up your `.env` file contents using [`dotenv`](https://www.npmjs.com/package/dotenv) utility under the hood (see [backfill-utils-dotenv implementation](https://github.com/microsoft/backfill/blob/03b0e808d978faebf7be922a3f87d764ad0efce2/packages/utils-dotenv/README.md)).
Need to access environment variables from the `.env` file in your application? You would need to setup a mechanism to inject them. Try using utilities like `dotenv` (for Node.js) or [`env-cmd`](https://www.npmjs.com/package/env-cmd) (for executing commands).
Need to access environment variables from the `.env` file in your application? You would need to setup a mechanism to inject them. Try using utilities like `dotenv` (for Node.js) or [`env-cmd`](https://www.npmjs.com/package/env-cmd) (for executing commands).
::

Просмотреть файл

@ -0,0 +1,60 @@
---
sidebar_position: 3
title: 3. Scoping by packages
---
By examining the [target graph](Introduction.mdx#how-does-lage-schedule-tasks), `lage` can understand which some targets that are not affected by a particular change being proposed in a pull request. In that case `lage` has a few CLI arguments that controls which target to run.
:::info
A target is an unit of execution in the `lage` graph. Think of it as a tuple of `[package, task]`.
:::
## Scoped builds with all its dependents
By default, `lage` runs tasks on all affected packages within a scope. Packages that changed will affect downstream consumers of the "scope". In this example, the `scope` is set as `a-common-library` - all of its transitive dependents (consumers of the `a-common-library` package) will also have their "build" script be called.
```
$ lage build --scope a-common-library
```
You can use wild card character: `*`. This is particularly helpful when packages are named by group or by scope. For example, `components-*` would match `components-foo` and `components-bar` packages.
```
$ lage build --scope components-*
```
:::note
npm has a concept of [@-scoped packages](https://docs.npmjs.com/cli/v8/using-npm/scope) in the package names. This describes a kind of grouping by an organization as defined by the npm spec. It is a *different* concept than the `lage` scope.
:::
Speaking of @-scopes. We found that typing the @-scopes when specifying the `lage` scoped runs is a kind of [toil](https://sre.google/sre-book/eliminating-toil/) as a command line argument. So, `lage` will accept bare package names like this:
```
# Given that there is a package named: @myorg/wonderful-library, we can match it this way:
$ lage build --scope wonderful-library
```
## Scoped builds with no dependent & their dependencies
If you simply want to run all targets up to a certain scope, this is how you can achieve it:
```
## v2
$ lage build --scope build-tools --no-dependents
## v1
$ lage build --scope build-tools --no-deps
```
In fact, this is so useful that `lage` has a special syntactic sugar for it:
```
## syntactic sugar for --scope build-tools --no-dependents
$ lage build --to build-tools
```

Просмотреть файл

@ -1,38 +1,44 @@
// @ts-check
// Note: type annotations allow type checking and IDEs autocompletion
const lightCodeTheme = require('prism-react-renderer/themes/github');
const darkCodeTheme = require('prism-react-renderer/themes/dracula');
const lightCodeTheme = require("prism-react-renderer/themes/github");
const darkCodeTheme = require("prism-react-renderer/themes/dracula");
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'Lage',
tagline: 'A Beautiful JS Monorepo Task Runner',
url: process.env.DEPLOY_URL ? process.env.DEPLOY_URL : 'https://microsoft.github.io',
baseUrl: '/lage/',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
favicon: 'img/lage-logo.svg',
organizationName: 'microsoft', // Usually your GitHub org/user name.
projectName: 'lage', // Usually your repo name.
customFields:{
image: 'img/lage.png'
title: "Lage",
tagline: "A Beautiful JS Monorepo Task Runner",
url: process.env.DEPLOY_URL ? process.env.DEPLOY_URL : "https://microsoft.github.io",
baseUrl: "/lage/",
onBrokenLinks: "throw",
onBrokenMarkdownLinks: "warn",
favicon: "img/lage-logo.svg",
organizationName: "microsoft", // Usually your GitHub org/user name.
projectName: "lage", // Usually your repo name.
customFields: {
image: "img/lage.png",
},
presets: [
[
'classic',
"classic",
/** @type {import('@docusaurus/preset-classic').Options} */
({
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
sidebarPath: require.resolve("./sidebars.js"),
// Please change this to your repo.
editUrl: 'https://github.com/microsoft/lage/',
editUrl: "https://github.com/microsoft/lage/",
},
theme: {
customCss: require.resolve('./src/css/custom.css'),
customCss: [require.resolve("./src/css/custom.css")],
},
}),
},
],
[
"docusaurus-preset-shiki-twoslash",
{
themes: ["min-light", "nord"],
},
],
],
@ -41,25 +47,20 @@ const config = {
({
navbar: {
logo: {
alt: 'Lage Logo',
src: 'img/lage.png',
alt: "Lage Logo",
src: "img/lage.png",
},
items: [
{
type: 'doc',
docId: 'Introducing Lage/Overview',
position: 'left',
label: 'Guide',
type: "doc",
docId: "Introduction",
position: "left",
label: "Guide",
},
{
href: 'grapher',
position: 'left',
label: 'Grapher',
},
{
href: 'https://github.com/microsoft/lage',
label: 'GitHub',
position: 'right',
href: "https://github.com/microsoft/lage",
label: "GitHub",
position: "right",
},
],
},
@ -67,11 +68,24 @@ const config = {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
},
colorMode : {
defaultMode: 'dark',
disableSwitch: true
colorMode: {
disableSwitch: false,
},
}),
plugins: [
async function tailwindPlugin(context, options) {
return {
name: "docusaurus-tailwindcss",
configurePostCss(postcssOptions) {
// Appends TailwindCSS and AutoPrefixer.
postcssOptions.plugins.push(require("tailwindcss"));
return postcssOptions;
},
};
},
],
};
module.exports = config;

Просмотреть файл

@ -11,20 +11,21 @@
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
"build-css": "tailwindcss -i src/css/custom.css -o src/css/tailwind-styles.css"
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
"@docusaurus/core": "2.1.0",
"@docusaurus/preset-classic": "2.1.0",
"docusaurus-preset-shiki-twoslash": "^1.1.38",
"@mdx-js/react": "^1.6.21",
"@stackblitz/sdk": "^1.8.0",
"clsx": "^1.1.1",
"mermaid": "^9.0.0",
"prism-react-renderer": "^1.2.1",
"react-dom": "^17.0.1",
"react-flow-renderer": "^10.3.7",
"react": "^17.0.1",
"tailwindcss": "^3.0.24"
"tailwindcss": "^3.1.8"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "2.1.0",

Просмотреть файл

@ -1,6 +0,0 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
}

Просмотреть файл

@ -1,26 +0,0 @@
import React from 'react';
import { styles } from "./shared-styles"
import { FeatureList } from '../data/FeatureList';
function Feature({Svg, title}) {
return (
<div className="text--center padding-horiz--md">
<div className="items-center">
<Svg className="fill-blue-300 h-16 w-16 flex justify-center mx-auto pt-3" alt={title} />
</div>
<div className="text--center padding-horiz--md">
<p className={styles.featureText}>{title}</p>
</div>
</div>
);
}
export default function Features() {
return (
<div className="grid grid-cols-3 my-4">
{FeatureList.map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
);
}

Просмотреть файл

@ -1,13 +0,0 @@
import React from "react";
export const Highlight = (props) => {
return (
<div>
<div className="flex items-center h-20 bg-white mt-4 mx-4 md:mx-8 rounded-r-full rounded-l-full">
<p className="font-bahnschrift font-bold text-lg text-bodySecondary px-4 mx-auto text-center">
{props.children}
</p>
</div>
</div>
);
};

Просмотреть файл

@ -1,12 +0,0 @@
import React from "react";
export const Illustration = (props) => {
const imageStyle = `mx-auto ${
props.isWave ? "w-full h-full max-h-40" : "w-3/4 h-3/4 md:w-full md:h-full"
}`;
return (
<div>
<img className={imageStyle} src={props.src} />
</div>
);
};

Просмотреть файл

@ -0,0 +1,20 @@
import * as React from "react";
import stackblitzSdk, { EmbedOptions } from "@stackblitz/sdk";
interface StackBlitzProps extends EmbedOptions {
githubRepo: string;
}
export const StackBlitz = (props: StackBlitzProps) => {
const { githubRepo, ...embedOptions } = props;
const editorRef = React.createRef<HTMLDivElement>();
React.useEffect(() => {
if (editorRef.current) {
stackblitzSdk.embedGithubProject(editorRef.current, githubRepo, embedOptions);
}
}, [editorRef.current]);
return <div ref={editorRef}></div>;
};

Просмотреть файл

@ -6,40 +6,35 @@ import { Point } from "./Point";
import { Illustration } from "./Illustration";
import { Description } from "./Description";
import { Button } from "./Button";
import { Section } from "./Section";
export default function Footer() {
export function Footer() {
return (
<div className="theme-color bg-bodyPrimary py-8">
<div className="2xl:w-big-screen 2xl:mx-auto">
<div className="mt-16 md:mt-28" />
<div className="container md:mx-auto">
<div className="mt-8" />
<TwoColumns imageOnTop={true} imageFirst={true}>
<Illustration src="img/frog-sing0.png" />
<div>
<Point>Seeing is believing give Lage a spin</Point>
<Description>
Theres no better time than now to save yourself time. Get started
within a minute with a single command!
Theres no better time than now to save yourself time. Get started within a minute with a single command!
</Description>
<SideBySide>
<Button isEmphasized={true} to="/docs/Introducing Lage/Overview">
<Button isEmphasized={true} to="/docs/Introduction">
Get Started
</Button>
<Button isEmphasized={false} to="/docs/Introducing Lage/Overview">
Try the Demo
</Button>
</SideBySide>
</div>
</TwoColumns>
<div className="mt-16 md:mt-28" />
<Point> Better together</Point>
<Description>
Lage works great on its own, but even better alongside its related
tools.
</Description>
<Tools />
<div className="mt-16" />
<Section>
<Point>Better together</Point>
<Description>Lage works great on its own, but even better alongside its related tools.</Description>
<Tools />
</Section>
</div>
</div>
);

Просмотреть файл

@ -6,7 +6,7 @@ import { ProductDescription } from "./ProductDescription";
import { Button } from "./Button";
import { Illustration } from "./Illustration";
export default function Header() {
export function Header() {
return (
<header className="theme-color bg-bodySecondary flex justify-center items-center pt-8 pb-24">
<div className="2xl:w-big-screen">
@ -17,15 +17,12 @@ export default function Header() {
Give your monorepo the smarts to <i>actually</i> save you time
</ProductDescription>
<SideBySide>
<Button isEmphasized={true} to="/docs/Introducing Lage/Overview">
<Button isEmphasized={true} to="/docs/Introduction">
Get Started
</Button>
<Button isEmphasized={false} to="/docs/Introducing Lage/Overview">
Try the Demo
</Button>
</SideBySide>
</div>
<Illustration src="img/frog-monitor0.png" />
<Illustration src="img/frog.webm" />
</TwoColumns>
</div>
</header>

Просмотреть файл

@ -0,0 +1,11 @@
import React from "react";
export const Highlight = (props) => {
return (
<div className="flex justify-center items-center h-20 bg-white my-4 mx-4 md:mx-8 rounded-r-full rounded-l-full font-bahnschrift">
<p className="font-bold text-lg text-bodySecondary px-4 my-0 py-0">
{props.children}
</p>
</div>
);
};

Просмотреть файл

@ -0,0 +1,15 @@
import React from "react";
export const Illustration = (props) => {
const imageStyle = "w-3/4 h-3/4 md:w-full md:h-full";
return (
<div>
{props.src.endsWith(".mp4") || props.src.endsWith(".webm") ? (
<video className={imageStyle} src={props.src} autoPlay muted />
) : (
<img className={imageStyle} src={props.src} />
)}
</div>
);
};

Просмотреть файл

@ -0,0 +1,5 @@
import * as React from 'react';
export const Section = ({children}) => {
return <section className="container md:mx-auto">{children}</section>
}

Просмотреть файл

@ -1,5 +1,5 @@
import React from "react";
import { ToolList } from "../data/ToolList";
import { ToolList } from "../../data/ToolList";
function Tool({ Svg, title, description }) {
return (

Просмотреть файл

@ -2,7 +2,7 @@ import React from "react";
export const TwoColumns = (props) => {
return (
<div className="mx-auto">
<div>
<div className="flex items-center md:hidden">
{props.imageOnTop && props.imageFirst && (
<div>

Просмотреть файл

@ -0,0 +1,8 @@
import * as React from "react";
export const WaveDivider = () => {
return (
<div className="h-20 w-full">
<img alt="divider" src="img/Wave Shape 1.svg" className="w-full h-full" />
</div>
);
};

Просмотреть файл

@ -5,7 +5,7 @@ import { Cross } from "./Cross";
import { Hamburger } from "./Hamburger";
import { HamburgerButton } from "./HamburgerButton";
export default function NavBar() {
export function NavBar() {
const [isNavOpen, setIsNavOpen] = useState(false);
return (
<div className="pl-4 pr-4 md:pr-20 bg-bodySecondary md:bg-navbar">
@ -28,20 +28,13 @@ export default function NavBar() {
}
>
{/*Creating the cross to exit the hamburger menu*/}
<div
className="absolute top-0 right-0 px-8 py-8"
onClick={() => setIsNavOpen(false)}
>
<div className="absolute top-0 right-0 px-8 py-8" onClick={() => setIsNavOpen(false)}>
<Cross />
</div>
{/*Contents of the hamburger menu*/}
<div className="flex flex-col space-y-2 px-4 py-24">
<HamburgerButton to="/docs/Introducing Lage/Overview">
Guide
</HamburgerButton>
<HamburgerButton to="https://github.com/microsoft/lage">
GitHub
</HamburgerButton>
<HamburgerButton to="/docs/Introduction">Guide</HamburgerButton>
<HamburgerButton to="https://github.com/microsoft/lage">GitHub</HamburgerButton>
</div>
</div>
</section>
@ -53,8 +46,7 @@ export default function NavBar() {
<a href=".">
<img className="w-20 h-7" src="img/lage.png" alt="Logo" />
</a>
<NavButton to="/docs/Introducing Lage/Overview">Guide</NavButton>
<NavButton to="/lage/grapher">Grapher</NavButton>
<NavButton to="/docs/Introduction">Guide</NavButton>
</div>
{/*Aligned to right*/}
<div className="flex items-center">

Просмотреть файл

@ -1,26 +1,19 @@
@tailwind base;
@tailwind components;
@font-face {
font-family: "Londrina Solid";
src: url(../../static/fonts/LondrinaSolid.ttf) format('truetype');
};
@font-face {
font-family: "Bahnschrift";
src: url(../../static/fonts/Bahnschrift.ttf) format('truetype');
};
@tailwind utilities;
.theme-color {
--color-button: 134 0 156;
--color-point: 255 214 107;
--color-bodySecondary: 33 153 190;
--color-bodyPrimary: 6 119 126;
--color-primary: 255 255 255;
--color-secondary: 33 153 190;
--color-tertiary: 255 0 0;
--color-navbar: 28 88 106;
--color-tool: 14 70 74;
}
:root {
--ifm-color-primary: rgb(28 88 106);
--ifm-code-font-size: 95%;
--ifm-background-surface-color: rgb(28 88 106);
--ifm-navbar-link-color: white;
--ifm-navbar-link-hover-color: white;
}
html[data-theme='dark'] {
--ifm-color-primary: rgb(70, 189, 226);
}
[data-theme="light"] .shiki.nord {
display: none;
}
[data-theme="dark"] .shiki.min-light {
display: none;
}

Просмотреть файл

@ -0,0 +1,25 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
.theme-color {
--color-button: 134 0 156;
--color-point: 255 214 107;
--color-bodySecondary: 33 153 190;
--color-bodyPrimary: 6 119 126;
--color-primary: 255 255 255;
--color-secondary: 33 153 190;
--color-tertiary: 255 0 0;
--color-navbar: 28 88 106;
--color-tool: 14 70 74;
}
@font-face {
font-family: "Londrina Solid";
src: url(../../static/fonts/LondrinaSolid.ttf) format('truetype');
}
@font-face {
font-family: "Bahnschrift";
src: url(../../static/fonts/Bahnschrift.ttf) format('truetype');
}

Просмотреть файл

@ -1,10 +1,9 @@
import React from "react";
import "../css/tailwind-styles.css";
import { Description } from "../components/Description";
import NavBar from "../components/NavBar";
import { Description } from "../components/home/Description";
import { NavBar } from "../components/navbar/NavBar";
import { useState } from "react";
import { FlowGraph } from "../components/flow-graph/FlowGraph";
import { Point } from "../components/Point";
import { Point } from "../components/home/Point";
export default function Grapher() {
const [input, setInput] = useState("");
@ -46,9 +45,8 @@ export default function Grapher() {
<Point>Dependency Graph Visualizer</Point>
<Description>
After running the <span className="text-button font-bold">graph </span>
command in your root directory, copy and paste the content of the{" "}
<span className="text-button font-bold">output.js</span> file here.{" "}
<br />
command in your root directory, copy and paste the content of the <span className="text-button font-bold">output.js</span> file
here. <br />
The content should be a JSON object.
</Description>
<form>
@ -79,10 +77,7 @@ export default function Grapher() {
</div>
<Description>
Don't know what to look for?{" "}
<a
className="text-black hover:text-bodyPrimary italic"
onClick={downloadTxtFile}
>
<a className="text-black hover:text-bodyPrimary italic" onClick={downloadTxtFile}>
{" "}
Here is a content example.
</a>

Просмотреть файл

@ -1,113 +1,104 @@
import "../css/tailwind.css";
import { Description } from "../components/home/Description";
import { Highlight } from "../components/home/Highlight";
import { Illustration } from "../components/home/Illustration";
import { Point } from "../components/home/Point";
import { Quote } from "../components/home/Quote";
import { Section } from "../components/home/Section";
import { TwoColumns } from "../components/home/TwoColumns";
import { WaveDivider } from "../components/home/WaveDivider";
import { Footer } from "../components/home/Footer";
import { Header } from "../components/home/Header";
import { NavBar } from "../components/navbar/NavBar";
import React from "react";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import "../css/tailwind-styles.css";
import Header from "../components/Header";
import Footer from "../components/Footer";
import { TwoColumns } from "../components/TwoColumns";
import { Highlight } from "../components/Highlight";
import { Illustration } from "../components/Illustration";
import { Point } from "../components/Point";
import { Description } from "../components/Description";
import { Quote } from "../components/Quote";
import NavBar from "../components/NavBar";
export default function Home() {
const { siteConfig } = useDocusaurusContext();
return (
<div className="theme-color">
<div className="theme-color bg-bodySecondary" id="tailwind">
<NavBar />
<Header />
<Illustration src="img/Wave Shape 1.svg" isWave={true} />
<main className="theme-color bg-gradient-to-b from-bodyPrimary to-bodySecondary pb-20">
<div className="2xl:w-big-screen 2xl:mx-auto">
<Section>
<Header />
</Section>
<WaveDivider />
<main className="theme-color bg-gradient-to-b from-bodyPrimary to-bodySecondary pb-20 md:mx-auto">
<Section>
<Quote author="Jason Gore" organization="Microsoft Loop">
Finally a task runner that
<span className="text-point"> truly understands</span> the structure
of my workspaces!
<span className="text-point"> truly understands</span> the structure of my workspaces!
</Quote>
</Section>
<Section>
<TwoColumns imageOnTop={false} imageFirst={true}>
<Illustration src="img/frog-skip0.png" isWave={false} />
<Illustration src="img/frog-skip0.png" />
<div>
<Point>Seriously, never build more than once</Point>
<Description>
Building once is painful enough! Lage will remember what is done
before and skip any work that is not needed. Lage even skips the
work based on your changes really!
Building once is painful enough! Lage will remember what is done before and skip any work that is not needed. Lage even
skips the work based on your changes really!
</Description>
<div className="hidden md:block">
<Highlight>
It's not just you. Lage will skip work if others already did
it too!
</Highlight>
<Highlight>It's not just you. Lage will skip work if others already did it too!</Highlight>
</div>
</div>
</TwoColumns>
</Section>
<div className="md:hidden">
<Highlight>
Visualize your build graphs with Lage's suite of tools.
</Highlight>
</div>
<Quote
author="Brandon Thomas"
organization="Microsoft 365 Admin Design System"
>
With Lage, we've been able to parallelize our builds and use cache
to reduce CI time from about 40 minutes to
<Section>
<Quote author="Brandon Thomas" organization="Microsoft 365 Admin Design System">
With Lage, we've been able to parallelize our builds and use cache to reduce CI time from about 40 minutes to
<span className="text-point"> five minutes.</span>
</Quote>
</Section>
<Section>
<TwoColumns imageOnTop={false} imageFirst={false}>
<div>
<Point>Speeding up your repo takes no time</Point>
<Description>
Lage is simple to setup and works everywhere. It just takes a
minute, seriously!
</Description>
<Description>Lage is simple to setup and works everywhere. It just takes a minute, seriously!</Description>
<div className="hidden md:block">
<Highlight>Use one of our clouds, or bring your own!</Highlight>
</div>
</div>
<Illustration src="img/frog-cloud0.png" isWave={false} />
<Illustration src="img/frog-cloud0.png" />
</TwoColumns>
</Section>
<Section>
<div className="md:hidden">
<Highlight>Use one of our clouds, or bring your own!</Highlight>
</div>
</Section>
<Section>
<Quote author="Jason Gore" organization="Microsoft Loop">
Lage upends the notion that monorepo builds have to be linear and
sequential, [it] leverages{" "}
<span className="text-point">modern processing power</span> and is
incredibly powerful and configurable.
Lage upends the notion that monorepo builds have to be linear and sequential, [it] leverages{" "}
<span className="text-point">modern processing power</span> and is incredibly powerful and configurable.
</Quote>
</Section>
<Section>
<TwoColumns imageOnTop={false} imageFirst={true}>
<Illustration src="img/frog-hero0.png" isWave={false} />
<Illustration src="img/frog-hero0.png" />
<div>
<Point>Discover what is slowing you down</Point>
<Description>
With the built-in profiler, Lage will let you see exactly where
the bottlenecks are. Yes, you can be the hero of your team.
With the built-in profiler, Lage will let you see exactly where the bottlenecks are. Yes, you can be the hero of your team.
</Description>
<div className="hidden md:block">
<Highlight>
Visualize your build graphs with Lage's suite of tools.
</Highlight>
<Highlight>Visualize your build graphs with Lage's suite of tools.</Highlight>
</div>
</div>
</TwoColumns>
</Section>
<Section>
<div className="md:hidden">
<Highlight>
Visualize your build graphs with Lage's suite of tools.
</Highlight>
<Highlight>Visualize your build graphs with Lage's suite of tools.</Highlight>
</div>
</div>
</Section>
</main>
<Illustration src="img/Wave Shape 2.svg" isWave={true} />
<WaveDivider />
<Footer />
</div>
);

Просмотреть файл

@ -0,0 +1,12 @@
import React from "react";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import "../css/tailwind.css";
export default function Test() {
const { siteConfig } = useDocusaurusContext();
return (
<div className="theme-color" id="tailwind">
<div className="md:bg-navbar">test</div>
</div>
);
}

Двоичные данные
docs-beta/static/img/contributor-guide-dark.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 500 KiB

Двоичные данные
docs-beta/static/img/contributor-guide-light.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 415 KiB

Двоичные данные
docs-beta/static/img/frog.webm Executable file

Двоичный файл не отображается.

Двоичные данные
docs-beta/static/img/graph-diagram-dark.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.0 MiB

Двоичные данные
docs-beta/static/img/graph-diagram-light.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.0 MiB

Двоичные данные
docs-beta/static/img/package-graph-dark.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 236 KiB

Двоичные данные
docs-beta/static/img/package-graph.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 232 KiB

Двоичные данные
docs-beta/static/img/target-graph-dark.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 406 KiB

Двоичные данные
docs-beta/static/img/target-graph.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 393 KiB

Двоичные данные
docs-beta/static/img/task-graph-dark.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 102 KiB

Двоичные данные
docs-beta/static/img/task-graph.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 101 KiB

Просмотреть файл

@ -7,14 +7,16 @@ function withOpacityValue(variable) {
};
}
module.exports = {
corePlugins: {
preflight: false,
},
content: [
"./src/pages/*.js",
"./src/components/*.js",
"./src/pages/**/*.tsx",
"./src/pages/**/*.ts",
"./src/pages/**/*.js",
"./src/components/*.tsx",
"./src/components/*.ts",
"./src/components/**/*.js",
"./src/components/**/*.tsx",
"./src/components/**/*.ts",
],
theme: {
container: {
@ -26,7 +28,7 @@ module.exports = {
bahnschrift: ["Bahnschrift"],
},
spacing: {
'big-screen': '1920px',
"big-screen": "1920px",
},
colors: {
button: withOpacityValue("--color-button"),

176
yarn.lock
Просмотреть файл

@ -2282,6 +2282,11 @@
p-map "^4.0.0"
webpack-sources "^3.2.2"
"@stackblitz/sdk@^1.8.0":
version "1.8.0"
resolved "https://registry.yarnpkg.com/@stackblitz/sdk/-/sdk-1.8.0.tgz#9bd5f028ccfc1a921d66f914d1e7ea2761139c1e"
integrity sha512-hbS4CpQVF3bxJ+ZD8qu8lAjTZVLTPToLbMtgxbxUmp1AIgqm7i0gMFM1POBA8BqY84CT1A3z74gdCd1bsro7qA==
"@svgr/babel-plugin-add-jsx-attribute@^6.0.0":
version "6.0.0"
resolved "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.0.0.tgz"
@ -2907,6 +2912,29 @@
"@typescript-eslint/types" "5.30.7"
eslint-visitor-keys "^3.3.0"
"@typescript/twoslash@3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@typescript/twoslash/-/twoslash-3.1.0.tgz#20b4d4bb58729681ff7f4b187af98757ea8723d4"
integrity sha512-kTwMUQ8xtAZaC4wb2XuLkPqFVBj2dNBueMQ89NWEuw87k2nLBbuafeG5cob/QEr6YduxIdTVUjix0MtC7mPlmg==
dependencies:
"@typescript/vfs" "1.3.5"
debug "^4.1.1"
lz-string "^1.4.4"
"@typescript/vfs@1.3.4":
version "1.3.4"
resolved "https://registry.yarnpkg.com/@typescript/vfs/-/vfs-1.3.4.tgz#07f89d2114f6e29255d589395ed7f3b4af8a00c2"
integrity sha512-RbyJiaAGQPIcAGWFa3jAXSuAexU4BFiDRF1g3hy7LmRqfNpYlTQWGXjcrOaVZjJ8YkkpuwG0FcsYvtWQpd9igQ==
dependencies:
debug "^4.1.1"
"@typescript/vfs@1.3.5":
version "1.3.5"
resolved "https://registry.yarnpkg.com/@typescript/vfs/-/vfs-1.3.5.tgz#801e3c97b5beca4ff5b8763299ca5fd605b862b8"
integrity sha512-pI8Saqjupf9MfLw7w2+og+fmb0fZS0J6vsKXXrp4/PDXEFvntgzXmChCXC/KefZZS0YGS6AT8e0hGAJcTsdJlg==
dependencies:
debug "^4.1.1"
"@webassemblyjs/ast@1.11.1":
version "1.11.1"
resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz"
@ -3278,11 +3306,16 @@ arg@^4.1.0:
resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz"
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
arg@^5.0.0, arg@^5.0.1:
arg@^5.0.0:
version "5.0.1"
resolved "https://registry.npmjs.org/arg/-/arg-5.0.1.tgz"
integrity sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==
arg@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz"
@ -5134,9 +5167,9 @@ detect-port@^1.3.0:
address "^1.0.1"
debug "^2.6.0"
detective@^5.2.0:
detective@^5.2.1:
version "5.2.1"
resolved "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz"
resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.1.tgz#6af01eeda11015acb0e73f933242b70f24f91034"
integrity sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==
dependencies:
acorn-node "^1.8.2"
@ -5194,6 +5227,15 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
docusaurus-preset-shiki-twoslash@^1.1.38:
version "1.1.38"
resolved "https://registry.yarnpkg.com/docusaurus-preset-shiki-twoslash/-/docusaurus-preset-shiki-twoslash-1.1.38.tgz#297ddff7b5b84bc6bc9ebf32a3ee1ff17ae0e035"
integrity sha512-v8bp6Q6gUNLuWmf4x19Tk2VvjEc8Luuy6o7fpTg7fTFUwo7ZBVWPTrxJe/aN4OmjkVBmuDfBc/muUGEAJTVm2g==
dependencies:
copy-text-to-clipboard "^3.0.1"
remark-shiki-twoslash "3.1.0"
typescript ">3"
dom-converter@^0.2.0:
version "0.2.0"
resolved "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz"
@ -5302,9 +5344,9 @@ ee-first@1.1.1:
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
electron-to-chromium@^1.4.251:
version "1.4.253"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.253.tgz#3402fd2159530fc6d94237f1b9535fa7bebaf399"
integrity sha512-1pezJ2E1UyBTGbA7fUlHdPSXQw1k+82VhTFLG5G0AUqLGvsZqFzleOblceqegZzxYX4kC7hGEEdzIQI9RZ1Cuw==
version "1.4.251"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.251.tgz#8b62448f3c591f0d32488df09454dda72dec96d5"
integrity sha512-k4o4cFrWPv4SoJGGAydd07GmlRVzmeDIJ6MaEChTUjk4Dmomn189tCicSzil2oyvbPoGgg2suwPDNWq4gWRhoQ==
email-addresses@^3.0.1:
version "3.1.0"
@ -5777,6 +5819,11 @@ feed@^4.2.2:
dependencies:
xml-js "^1.6.11"
fenceparser@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/fenceparser/-/fenceparser-1.1.1.tgz#e10a5f12a54884d4f14edb0f7a52a0edc58fa667"
integrity sha512-VdkTsK7GWLT0VWMK5S5WTAPn61wJ98WPFwJiRHumhg4ESNUO/tnkU8bzzzc62o6Uk1SVhuZFLnakmDA4SGV7wA==
file-entry-cache@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
@ -7487,6 +7534,11 @@ json5@^2.1.2, json5@^2.2.1:
resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz"
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
jsonc-parser@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76"
integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz"
@ -7621,6 +7673,11 @@ lilconfig@^2.0.3, lilconfig@^2.0.5:
resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz"
integrity sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==
lilconfig@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4"
integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==
lines-and-columns@^1.1.6:
version "1.1.6"
resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz"
@ -7770,6 +7827,11 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
lz-string@^1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"
integrity sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==
magic-string@^0.25.7:
version "0.25.9"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c"
@ -8604,7 +8666,7 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatc
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
pify@^2.0.0:
pify@^2.0.0, pify@^2.3.0:
version "2.3.0"
resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz"
integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
@ -8698,6 +8760,15 @@ postcss-discard-unused@^5.1.0:
dependencies:
postcss-selector-parser "^6.0.5"
postcss-import@^14.1.0:
version "14.1.0"
resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-14.1.0.tgz#a7333ffe32f0b8795303ee9e40215dac922781f0"
integrity sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==
dependencies:
postcss-value-parser "^4.0.0"
read-cache "^1.0.0"
resolve "^1.1.7"
postcss-js@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz"
@ -8982,7 +9053,7 @@ postcss-value-parser@^3.0.0:
resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz"
integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
version "4.2.0"
resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
@ -9000,7 +9071,7 @@ postcss@^7.0.0, postcss@^7.0.32:
picocolors "^0.2.1"
source-map "^0.6.1"
postcss@^8.3.11, postcss@^8.4.12, postcss@^8.4.13, postcss@^8.4.14, postcss@^8.4.7:
postcss@^8.3.11, postcss@^8.4.13, postcss@^8.4.14, postcss@^8.4.7:
version "8.4.14"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz"
integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==
@ -9406,6 +9477,13 @@ react@^17.0.1:
loose-envify "^1.1.0"
object-assign "^4.1.1"
read-cache@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774"
integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==
dependencies:
pify "^2.3.0"
read-yaml-file@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-2.0.0.tgz"
@ -9508,6 +9586,11 @@ regenerator-runtime@^0.13.4:
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz"
integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==
regenerator-runtime@^0.13.7:
version "0.13.9"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
regenerator-transform@^0.15.0:
version "0.15.0"
resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz"
@ -9613,6 +9696,21 @@ remark-parse@8.0.3:
vfile-location "^3.0.0"
xtend "^4.0.1"
remark-shiki-twoslash@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/remark-shiki-twoslash/-/remark-shiki-twoslash-3.1.0.tgz#b5e58eec9f97458ade1df73cb96566d031cc75bd"
integrity sha512-6LqSqVtHQR4S0DKfdQ2/ePn9loTKUtpyopYvwk8johjDTeUW5MkaLQuZHlWNkkST/4aMbz6aTkstIcwfwcHpXg==
dependencies:
"@typescript/twoslash" "3.1.0"
"@typescript/vfs" "1.3.4"
fenceparser "^1.1.0"
regenerator-runtime "^0.13.7"
shiki "0.10.1"
shiki-twoslash "3.1.0"
tslib "2.1.0"
typescript ">3"
unist-util-visit "^2.0.0"
remark-squeeze-paragraphs@4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz"
@ -9683,7 +9781,7 @@ resolve.exports@^1.1.0:
resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz"
integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==
resolve@^1.1.6, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.3.2:
resolve@^1.1.6, resolve@^1.1.7, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.3.2:
version "1.22.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
@ -10005,6 +10103,25 @@ shelljs@^0.8.5:
interpret "^1.0.0"
rechoir "^0.6.2"
shiki-twoslash@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/shiki-twoslash/-/shiki-twoslash-3.1.0.tgz#818aaa15e83e0f34325dd56a991f7023f7e8e6db"
integrity sha512-uDqrTutOIZzyHbo103GsK7Vvc10saK1XCCivnOQ1NHJzgp3FBilEpftGeVzVSMOJs+JyhI7whkvhXV7kXQ5zCg==
dependencies:
"@typescript/twoslash" "3.1.0"
"@typescript/vfs" "1.3.4"
shiki "0.10.1"
typescript ">3"
shiki@0.10.1:
version "0.10.1"
resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.10.1.tgz#6f9a16205a823b56c072d0f1a0bcd0f2646bef14"
integrity sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==
dependencies:
jsonc-parser "^3.0.0"
vscode-oniguruma "^1.6.1"
vscode-textmate "5.2.0"
side-channel@^1.0.4:
version "1.0.4"
resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz"
@ -10371,32 +10488,33 @@ svgo@^2.5.0, svgo@^2.7.0:
picocolors "^1.0.0"
stable "^0.1.8"
tailwindcss@^3.0.24:
version "3.0.24"
resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.0.24.tgz"
integrity sha512-H3uMmZNWzG6aqmg9q07ZIRNIawoiEcNFKDfL+YzOPuPsXuDXxJxB9icqzLgdzKNwjG3SAro2h9SYav8ewXNgig==
tailwindcss@^3.1.8:
version "3.1.8"
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.1.8.tgz#4f8520550d67a835d32f2f4021580f9fddb7b741"
integrity sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==
dependencies:
arg "^5.0.1"
arg "^5.0.2"
chokidar "^3.5.3"
color-name "^1.1.4"
detective "^5.2.0"
detective "^5.2.1"
didyoumean "^1.2.2"
dlv "^1.1.3"
fast-glob "^3.2.11"
glob-parent "^6.0.2"
is-glob "^4.0.3"
lilconfig "^2.0.5"
lilconfig "^2.0.6"
normalize-path "^3.0.0"
object-hash "^3.0.0"
picocolors "^1.0.0"
postcss "^8.4.12"
postcss "^8.4.14"
postcss-import "^14.1.0"
postcss-js "^4.0.0"
postcss-load-config "^3.1.4"
postcss-nested "5.0.6"
postcss-selector-parser "^6.0.10"
postcss-value-parser "^4.2.0"
quick-lru "^5.1.1"
resolve "^1.22.0"
resolve "^1.22.1"
tapable@^1.0.0:
version "1.1.3"
@ -10615,6 +10733,11 @@ ts-node@8.10.2:
source-map-support "^0.5.17"
yn "3.1.1"
tslib@2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
tslib@^1.10.0, tslib@^1.14.1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
version "1.14.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
@ -10699,6 +10822,11 @@ typescript@4.6.4, typescript@^4.4.4:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9"
integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==
typescript@>3:
version "4.8.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.3.tgz#d59344522c4bc464a65a730ac695007fdb66dd88"
integrity sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==
ua-parser-js@^0.7.30:
version "0.7.31"
resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz"
@ -11017,6 +11145,16 @@ vfile@^4.0.0:
unist-util-stringify-position "^2.0.0"
vfile-message "^2.0.0"
vscode-oniguruma@^1.6.1:
version "1.6.2"
resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz#aeb9771a2f1dbfc9083c8a7fdd9cccaa3f386607"
integrity sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==
vscode-textmate@5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e"
integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==
wait-on@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/wait-on/-/wait-on-6.0.1.tgz"