diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..8b9e431 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,42 @@ +name: Pages + +on: + push: + branches: + - master + paths: + - 'site/**' + - '.github/workflows/pages.yml' + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +# One deployment at a time; a queued run waits instead of cancelling +# the one in progress. +concurrency: + group: pages + cancel-in-progress: false + +jobs: + deploy: + name: Deploy site + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + steps: + - uses: actions/checkout@v7 + + - uses: actions/configure-pages@v6 + + # The files in site/ are served as is, there is no build step. + - uses: actions/upload-pages-artifact@v5 + with: + path: site + + - id: deployment + uses: actions/deploy-pages@v5 diff --git a/site/index.html b/site/index.html new file mode 100644 index 0000000..f212faa --- /dev/null +++ b/site/index.html @@ -0,0 +1,183 @@ + + + + + + + + nodeenv - Node.js virtual environment + + + + +
+
+ nodeenv + +
+
+ +
+
+

Node.js virtual environment

+

+ A tool to create isolated node.js environments. Each environment has + its own installation directories and doesn't share libraries with + other environments. It can also be added to a Python virtualenv. +

+
+ $ pip install nodeenv +
+

+ PyPI version + CI status + Supported Python versions +

+
+ +
+

Quick start

+
+ $ nodeenv env + $ . env/bin/activate + (env) $ node -v + (env) $ deactivate_node +
+

+ On Windows, activate with the script for your shell in + env\Scripts: activate.bat for cmd, + Activate.ps1 for PowerShell, or activate + for git-bash. +

+
+ +
+

Features

+
+
+

Any node version

+

+ Choose an exact version, an npm semver range, or lts + for the latest LTS release. Ranges also work in a + .node-version file. --list shows the + available versions. +

+
+ $ nodeenv --list + $ nodeenv --node=22 env + $ nodeenv --node=lts env + $ nodeenv --node=">=20 <22" env +
+
+
+

Reproducible

+

+ freeze saves the installed packages to a file. + -r, short for --requirements, installs + them into a new environment. Add --update to install + them into an existing one. .node-version pins node.js + itself. +

+
+ (env) $ freeze reqs.txt + (env) $ node -v > .node-version + $ nodeenv -r reqs.txt copy +
+
+
+

Inside virtualenv

+

+ Add node.js to an existing Python virtualenv. Packages installed + with npm install -g then go into the virtualenv. +

+
+ $ . venv/bin/activate + (venv) $ nodeenv -p +
+
+
+
+ +
+

Prebuilt, mirror or system node.js

+
+
+
--prebuilt
+
+ Install node.js from a prebuilt package. This is the default. +
+
+
+
--mirror=URL
+
+ Download from a mirror of nodejs.org. A file:// URL + points at a local directory. +
+
+
+
--node=system
+
+ Use the system-wide node.js. --prefer-system uses it + only when it is found in PATH. Not supported on + Windows. +
+
+
+
+ +
+

Defaults in ~/.nodeenvrc

+

+ Set default values for options in an INI file. The keys are the long + option names, written with underscores. With this file nodeenv uses + the system-wide node.js when it is found in PATH, and + installs the latest LTS release otherwise. +

+
+ [nodeenv] + node = lts + prefer_system = True +
+
+ +
+

Read more

+ +
+
+ + + + diff --git a/site/style.css b/site/style.css new file mode 100644 index 0000000..6bab387 --- /dev/null +++ b/site/style.css @@ -0,0 +1,322 @@ +/* nodeenv landing page. No build step: this file is served as is. */ + +:root { + color-scheme: light dark; + --paper: #f6f7f9; + --surface: #eceff3; + --ink: #18202b; + --muted: #555f6d; + --rule: #d9dee5; + --accent: #2b7a31; + /* Lines typed inside an environment are tinted with the accent. */ + --band: color-mix(in srgb, var(--accent) 11%, transparent); + --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", + Arial, sans-serif; + --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, + "Liberation Mono", monospace; +} + +@media (prefers-color-scheme: dark) { + :root { + --paper: #111519; + --surface: #1a2027; + --ink: #e3e8ee; + --muted: #9aa5b1; + --rule: #2a323c; + --accent: #7cc47f; + } +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + -webkit-text-size-adjust: 100%; + text-size-adjust: 100%; +} + +body { + margin: 0; + background: var(--paper); + color: var(--ink); + font: 1rem/1.6 var(--sans); +} + +a { + color: var(--accent); + text-underline-offset: 0.2em; +} + +a:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + border-radius: 2px; +} + +code { + font-family: var(--mono); + font-size: 0.875em; +} + +code:not(.line) { + padding: 0.1em 0.3em; + border-radius: 4px; + background: var(--surface); + /* Keep flags such as --requirements from breaking at a hyphen. */ + white-space: nowrap; +} + +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip: rect(0 0 0 0); + white-space: nowrap; +} + +.wrap { + max-width: 64rem; + margin: 0 auto; + padding: 0 1.25rem; +} + +/* Top bar */ + +.topbar { + border-bottom: 1px solid var(--rule); +} + +.topbar-inner { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + gap: 0.5rem 1.5rem; + min-height: 3.5rem; +} + +.wordmark { + color: var(--ink); + font: 700 1.125rem/1 var(--mono); + text-decoration: none; +} + +.wordmark span { + color: var(--accent); +} + +.topbar nav { + display: flex; + gap: 1.25rem; +} + +.topbar nav a { + color: var(--muted); + font-size: 0.9375rem; + text-decoration: none; +} + +.topbar nav a:hover { + color: var(--accent); +} + +/* Sections */ + +main > section { + padding: 2.75rem 0; + border-top: 1px solid var(--rule); +} + +main > section.hero { + padding: clamp(3rem, 9vw, 6rem) 0 3rem; + border-top: 0; +} + +h1 { + max-width: 14ch; + margin: 0 0 1.25rem; + font-size: clamp(2.25rem, 1.5rem + 3.5vw, 3.75rem); + font-weight: 750; + line-height: 1.05; + letter-spacing: -0.03em; +} + +h2 { + margin: 0 0 1rem; + font-size: 1.375rem; + line-height: 1.25; + letter-spacing: -0.01em; +} + +h2 code:not(.line) { + padding: 0; + background: none; +} + +h3 { + margin: 0 0 0.5rem; + font-size: 1.0625rem; + line-height: 1.3; +} + +p { + max-width: 40rem; + margin: 0 0 1rem; +} + +.lead { + margin-bottom: 2rem; + color: var(--muted); + font-size: 1.1875rem; +} + +.note { + margin: 1rem 0 0; + color: var(--muted); + font-size: 0.9375rem; +} + +.badges { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin: 1.5rem 0 0; +} + +.badges img { + display: block; +} + +/* Terminal blocks */ + +.term { + /* A grid lets every line stretch to the widest one, so the tint of + lines inside an environment stays even when the block scrolls. */ + display: grid; + overflow-x: auto; + padding: 0.875rem 0; + border: 1px solid var(--rule); + border-radius: 8px; + background: var(--surface); + font: 0.875rem/1.75 var(--mono); +} + +.line { + display: block; + padding: 0 1rem; + font-size: inherit; + white-space: pre; +} + +.line.in { + background: var(--band); + box-shadow: inset 3px 0 0 var(--accent); +} + +/* Prompts are not selectable, so copying a block copies only commands. */ +.ps { + color: var(--muted); + -webkit-user-select: none; + user-select: none; +} + +.env { + color: var(--accent); + font-weight: 600; +} + +.install { + max-width: 24rem; + font-size: 1.0625rem; +} + +.file { + max-width: 24rem; +} + +/* Feature cards */ + +.cards { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: 1.25rem; +} + +.card { + display: flex; + flex-direction: column; + overflow: hidden; + padding: 1.25rem 1.25rem 0; + border: 1px solid var(--rule); + border-radius: 10px; +} + +.card p { + margin-bottom: 1.25rem; + color: var(--muted); + font-size: 0.9375rem; +} + +.card .term { + margin: auto -1.25rem 0; + border-width: 1px 0 0; + border-radius: 0; +} + +@media (min-width: 60rem) { + .cards { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } +} + +/* Node sources */ + +.sources { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: 1.25rem 2rem; + margin: 0; +} + +.sources dt { + margin-bottom: 0.25rem; + font-weight: 600; +} + +.sources dd { + margin: 0; + color: var(--muted); + font-size: 0.9375rem; +} + +@media (min-width: 48rem) { + .sources { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } +} + +/* Links and footer */ + +.more { + display: flex; + flex-wrap: wrap; + gap: 0.5rem 1.75rem; + margin: 0; + padding: 0; + list-style: none; +} + +.footer { + border-top: 1px solid var(--rule); + color: var(--muted); + font-size: 0.875rem; +} + +.footer p { + margin: 0; + padding: 1.5rem 0 2.5rem; +}