mirror of
https://github.com/withastro/astro.git
synced 2025-01-22 10:31:53 -05:00
create-astro updates (#12083)
Co-authored-by: Reuben Tier <64310361+TheOtterlord@users.noreply.github.com> Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com> Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev> Co-authored-by: Reuben Tier <otterlord.dev@gmail.com>
This commit is contained in:
parent
731b69712b
commit
9263e96593
60 changed files with 367 additions and 614 deletions
10
.changeset/old-actors-learn.md
Normal file
10
.changeset/old-actors-learn.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
'create-astro': minor
|
||||
---
|
||||
|
||||
Reworks the experience of creating a new Astro project using the `create astro` CLI command.
|
||||
|
||||
- Updates the list of templates to include Starlight and combines the "minimal" and "basics" templates into a new, refreshed "Basics" template to serve as the single, minimal Astro project starter.
|
||||
- Removes the TypeScript question. Astro is TypeScript-only, so this question was often misleading. The "Strict" preset is now the default, but it can still be changed manually in `tsconfig.json`.
|
||||
- `astro check` is no longer automatically added to the build script.
|
||||
- Added a new `--add` flag to install additional integrations after creating a project. For example, `pnpm create astro --add react` will create a new Astro project and install the React integration.
|
|
@ -21,8 +21,6 @@ Inside of your Astro project, you'll see the following folders and files:
|
|||
├── public/
|
||||
│ └── favicon.svg
|
||||
├── src/
|
||||
│ ├── components/
|
||||
│ │ └── Card.astro
|
||||
│ ├── layouts/
|
||||
│ │ └── Layout.astro
|
||||
│ └── pages/
|
||||
|
@ -30,11 +28,7 @@ Inside of your Astro project, you'll see the following folders and files:
|
|||
└── package.json
|
||||
```
|
||||
|
||||
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
||||
|
||||
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
||||
|
||||
Any static assets, like images, can be placed in the `public/` directory.
|
||||
To learn more about the folder structure of an Astro project, refer to [our guide on project structure](https://docs.astro.build/en/basics/project-structure/).
|
||||
|
||||
## 🧞 Commands
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
// https://astro.build/config
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
---
|
||||
interface Props {
|
||||
title: string;
|
||||
body: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
const { href, title, body } = Astro.props;
|
||||
---
|
||||
|
||||
<li class="link-card">
|
||||
<a href={href}>
|
||||
<h2>
|
||||
{title}
|
||||
<span>→</span>
|
||||
</h2>
|
||||
<p>
|
||||
{body}
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<style>
|
||||
.link-card {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
padding: 1px;
|
||||
background-color: #23262d;
|
||||
background-image: none;
|
||||
background-size: 400%;
|
||||
border-radius: 7px;
|
||||
background-position: 100%;
|
||||
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.link-card > a {
|
||||
width: 100%;
|
||||
text-decoration: none;
|
||||
line-height: 1.4;
|
||||
padding: calc(1.5rem - 1px);
|
||||
border-radius: 8px;
|
||||
color: white;
|
||||
background-color: #23262d;
|
||||
opacity: 0.8;
|
||||
}
|
||||
h2 {
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
p {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.link-card:is(:hover, :focus-within) {
|
||||
background-position: 0;
|
||||
background-image: var(--accent-gradient);
|
||||
}
|
||||
.link-card:is(:hover, :focus-within) h2 {
|
||||
color: rgb(var(--accent-light));
|
||||
}
|
||||
</style>
|
|
@ -1,50 +1,13 @@
|
|||
---
|
||||
interface Props {
|
||||
title: string;
|
||||
}
|
||||
|
||||
const { title } = Astro.props;
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="Astro description" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{title}</title>
|
||||
<title>Astro Basics</title>
|
||||
</head>
|
||||
<body>
|
||||
<slot />
|
||||
</body>
|
||||
</html>
|
||||
<style is:global>
|
||||
:root {
|
||||
--accent: 136, 58, 234;
|
||||
--accent-light: 224, 204, 250;
|
||||
--accent-dark: 49, 10, 101;
|
||||
--accent-gradient: linear-gradient(
|
||||
45deg,
|
||||
rgb(var(--accent)),
|
||||
rgb(var(--accent-light)) 30%,
|
||||
white 60%
|
||||
);
|
||||
}
|
||||
html {
|
||||
font-family: system-ui, sans-serif;
|
||||
background: #13151a;
|
||||
}
|
||||
code {
|
||||
font-family:
|
||||
Menlo,
|
||||
Monaco,
|
||||
Lucida Console,
|
||||
Liberation Mono,
|
||||
DejaVu Sans Mono,
|
||||
Bitstream Vera Sans Mono,
|
||||
Courier New,
|
||||
monospace;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,123 +1,8 @@
|
|||
---
|
||||
import { Welcome } from 'astro:components';
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
import Card from '../components/Card.astro';
|
||||
---
|
||||
|
||||
<Layout title="Welcome to Astro.">
|
||||
<main>
|
||||
<svg
|
||||
class="astro-a"
|
||||
width="495"
|
||||
height="623"
|
||||
viewBox="0 0 495 623"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M167.19 364.254C83.4786 364.254 0 404.819 0 404.819C0 404.819 141.781 19.4876 142.087 18.7291C146.434 7.33701 153.027 0 162.289 0H332.441C341.703 0 348.574 7.33701 352.643 18.7291C352.92 19.5022 494.716 404.819 494.716 404.819C494.716 404.819 426.67 364.254 327.525 364.254L264.41 169.408C262.047 159.985 255.147 153.581 247.358 153.581C239.569 153.581 232.669 159.985 230.306 169.408L167.19 364.254ZM160.869 530.172C160.877 530.18 160.885 530.187 160.894 530.195L160.867 530.181C160.868 530.178 160.868 530.175 160.869 530.172ZM136.218 411.348C124.476 450.467 132.698 504.458 160.869 530.172C160.997 529.696 161.125 529.242 161.248 528.804C161.502 527.907 161.737 527.073 161.917 526.233C165.446 509.895 178.754 499.52 195.577 500.01C211.969 500.487 220.67 508.765 223.202 527.254C224.141 534.12 224.23 541.131 224.319 548.105C224.328 548.834 224.337 549.563 224.347 550.291C224.563 566.098 228.657 580.707 237.264 593.914C245.413 606.426 256.108 615.943 270.749 622.478C270.593 621.952 270.463 621.508 270.35 621.126C270.045 620.086 269.872 619.499 269.685 618.911C258.909 585.935 266.668 563.266 295.344 543.933C298.254 541.971 301.187 540.041 304.12 538.112C310.591 533.854 317.059 529.599 323.279 525.007C345.88 508.329 360.09 486.327 363.431 457.844C364.805 446.148 363.781 434.657 359.848 423.275C358.176 424.287 356.587 425.295 355.042 426.275C351.744 428.366 348.647 430.33 345.382 431.934C303.466 452.507 259.152 455.053 214.03 448.245C184.802 443.834 156.584 436.019 136.218 411.348Z"
|
||||
fill="url(#paint0_linear_1805_24383)"></path>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_1805_24383"
|
||||
x1="247.358"
|
||||
y1="0"
|
||||
x2="247.358"
|
||||
y2="622.479"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-opacity="0.9"></stop>
|
||||
<stop offset="1" stop-opacity="0.2"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<h1>Welcome to <span class="text-gradient">Astro</span></h1>
|
||||
<p class="instructions">
|
||||
To get started, open the directory <code>src/pages</code> in your project.<br />
|
||||
<strong>Code Challenge:</strong> Tweak the "Welcome to Astro" message above.
|
||||
</p>
|
||||
<ul role="list" class="link-card-grid">
|
||||
<Card
|
||||
href="https://docs.astro.build/"
|
||||
title="Documentation"
|
||||
body="Learn how Astro works and explore the official API docs."
|
||||
/>
|
||||
<Card
|
||||
href="https://astro.build/integrations/"
|
||||
title="Integrations"
|
||||
body="Supercharge your project with new frameworks and libraries."
|
||||
/>
|
||||
<Card
|
||||
href="https://astro.build/themes/"
|
||||
title="Themes"
|
||||
body="Explore a galaxy of community-built starter themes."
|
||||
/>
|
||||
<Card
|
||||
href="https://astro.build/chat/"
|
||||
title="Community"
|
||||
body="Come say hi to our amazing Discord community. ❤️"
|
||||
/>
|
||||
</ul>
|
||||
</main>
|
||||
<Layout>
|
||||
<Welcome title="Welcome to Astro" />
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
main {
|
||||
margin: auto;
|
||||
padding: 1rem;
|
||||
width: 800px;
|
||||
max-width: calc(100% - 2rem);
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.astro-a {
|
||||
position: absolute;
|
||||
top: -32px;
|
||||
left: 50%;
|
||||
transform: translatex(-50%);
|
||||
width: 220px;
|
||||
height: auto;
|
||||
z-index: -1;
|
||||
}
|
||||
h1 {
|
||||
font-size: 4rem;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.text-gradient {
|
||||
background-image: var(--accent-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-size: 400%;
|
||||
background-position: 0%;
|
||||
}
|
||||
.instructions {
|
||||
margin-bottom: 2rem;
|
||||
border: 1px solid rgba(var(--accent-light), 25%);
|
||||
background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%));
|
||||
padding: 1.5rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.instructions code {
|
||||
font-size: 0.8em;
|
||||
font-weight: bold;
|
||||
background: rgba(var(--accent-light), 12%);
|
||||
color: rgb(var(--accent-light));
|
||||
border-radius: 4px;
|
||||
padding: 0.3em 0.4em;
|
||||
}
|
||||
.instructions strong {
|
||||
color: rgb(var(--accent-light));
|
||||
}
|
||||
.link-card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
|
||||
gap: 2rem;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import mdx from '@astrojs/mdx';
|
||||
|
||||
import sitemap from '@astrojs/sitemap';
|
||||
|
||||
// https://astro.build/config
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"],
|
||||
"compilerOptions": {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"],
|
||||
"compilerOptions": {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import alpine from '@astrojs/alpinejs';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import preact from '@astrojs/preact';
|
||||
import react from '@astrojs/react';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"],
|
||||
"compilerOptions": {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import preact from '@astrojs/preact';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"],
|
||||
"compilerOptions": {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import react from '@astrojs/react';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"],
|
||||
"compilerOptions": {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import solid from '@astrojs/solid-js';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"],
|
||||
"compilerOptions": {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import svelte from '@astrojs/svelte';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import vue from '@astrojs/vue';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"],
|
||||
"compilerOptions": {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import node from '@astrojs/node';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base"
|
||||
"extends": "astro/tsconfigs/strict"
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
// https://astro.build/config
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
// https://astro.build/config
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
|
|
5
examples/server-islands/tsconfig.json
Normal file
5
examples/server-islands/tsconfig.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import svelte from '@astrojs/svelte';
|
||||
import node from '@astrojs/node';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
// https://astro.build/config
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import markdoc from '@astrojs/markdoc';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"],
|
||||
"compilerOptions": {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import mdx from '@astrojs/mdx';
|
||||
import preact from '@astrojs/preact';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import preact from '@astrojs/preact';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"],
|
||||
"compilerOptions": {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import tailwind from '@astrojs/tailwind';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
// https://astro.build/config
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
|
|
172
packages/astro/components/Welcome.astro
Normal file
172
packages/astro/components/Welcome.astro
Normal file
|
@ -0,0 +1,172 @@
|
|||
---
|
||||
interface Props {
|
||||
title?: string;
|
||||
}
|
||||
|
||||
const cards = [
|
||||
{
|
||||
href: 'https://docs.astro.build/',
|
||||
title: 'Documentation',
|
||||
body: 'Learn how Astro works and explore the official API docs.',
|
||||
},
|
||||
{
|
||||
href: 'https://astro.build/integrations/',
|
||||
title: 'Integrations',
|
||||
body: 'Supercharge your project with new frameworks and libraries.',
|
||||
},
|
||||
{
|
||||
href: 'https://astro.build/themes/',
|
||||
title: 'Themes',
|
||||
body: 'Explore a galaxy of community-built starter themes.',
|
||||
},
|
||||
{
|
||||
href: 'https://astro.build/chat/',
|
||||
title: 'Community',
|
||||
body: 'Come say hi to our amazing Discord community. ❤️',
|
||||
},
|
||||
];
|
||||
|
||||
const { title = 'Welcome to Astro' } = Astro.props;
|
||||
---
|
||||
|
||||
<main>
|
||||
<svg
|
||||
class="astro-a"
|
||||
width="495"
|
||||
height="623"
|
||||
viewBox="0 0 495 623"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M167.19 364.254C83.4786 364.254 0 404.819 0 404.819C0 404.819 141.781 19.4876 142.087 18.7291C146.434 7.33701 153.027 0 162.289 0H332.441C341.703 0 348.574 7.33701 352.643 18.7291C352.92 19.5022 494.716 404.819 494.716 404.819C494.716 404.819 426.67 364.254 327.525 364.254L264.41 169.408C262.047 159.985 255.147 153.581 247.358 153.581C239.569 153.581 232.669 159.985 230.306 169.408L167.19 364.254ZM160.869 530.172C160.877 530.18 160.885 530.187 160.894 530.195L160.867 530.181C160.868 530.178 160.868 530.175 160.869 530.172ZM136.218 411.348C124.476 450.467 132.698 504.458 160.869 530.172C160.997 529.696 161.125 529.242 161.248 528.804C161.502 527.907 161.737 527.073 161.917 526.233C165.446 509.895 178.754 499.52 195.577 500.01C211.969 500.487 220.67 508.765 223.202 527.254C224.141 534.12 224.23 541.131 224.319 548.105C224.328 548.834 224.337 549.563 224.347 550.291C224.563 566.098 228.657 580.707 237.264 593.914C245.413 606.426 256.108 615.943 270.749 622.478C270.593 621.952 270.463 621.508 270.35 621.126C270.045 620.086 269.872 619.499 269.685 618.911C258.909 585.935 266.668 563.266 295.344 543.933C298.254 541.971 301.187 540.041 304.12 538.112C310.591 533.854 317.059 529.599 323.279 525.007C345.88 508.329 360.09 486.327 363.431 457.844C364.805 446.148 363.781 434.657 359.848 423.275C358.176 424.287 356.587 425.295 355.042 426.275C351.744 428.366 348.647 430.33 345.382 431.934C303.466 452.507 259.152 455.053 214.03 448.245C184.802 443.834 156.584 436.019 136.218 411.348Z"
|
||||
fill="url(#paint0_linear_1805_24383)"></path>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_1805_24383"
|
||||
x1="247.358"
|
||||
y1="0"
|
||||
x2="247.358"
|
||||
y2="622.479"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-opacity="0.9"></stop>
|
||||
<stop offset="1" stop-opacity="0.2"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<h1>{title}</h1>
|
||||
<p class="instructions">
|
||||
To get started, open the directory <code>src/pages</code> in your project.<br />
|
||||
<strong>Code Challenge:</strong> Tweak the "Welcome to Astro" message above.
|
||||
</p>
|
||||
<ul role="list" class="link-card-grid">
|
||||
{
|
||||
cards.map((card) => (
|
||||
<li class="link-card">
|
||||
<a href={card.href}>
|
||||
<h2>
|
||||
{card.title}
|
||||
<span>→</span>
|
||||
</h2>
|
||||
<p>{card.body}</p>
|
||||
</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
main {
|
||||
margin: auto;
|
||||
padding: 1rem;
|
||||
width: 800px;
|
||||
max-width: calc(100% - 2rem);
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.astro-a {
|
||||
position: absolute;
|
||||
top: -32px;
|
||||
left: 50%;
|
||||
transform: translatex(-50%);
|
||||
width: 220px;
|
||||
height: auto;
|
||||
z-index: -1;
|
||||
}
|
||||
h1 {
|
||||
font-size: 4rem;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.instructions {
|
||||
margin-bottom: 2rem;
|
||||
border: 1px solid rgba(var(--accent-light), 25%);
|
||||
background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%));
|
||||
padding: 1.5rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.instructions code {
|
||||
font-size: 0.8em;
|
||||
font-weight: bold;
|
||||
background: rgba(var(--accent-light), 12%);
|
||||
color: rgb(var(--accent-light));
|
||||
border-radius: 4px;
|
||||
padding: 0.3em 0.4em;
|
||||
}
|
||||
.instructions strong {
|
||||
color: rgb(var(--accent-light));
|
||||
}
|
||||
.link-card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
|
||||
gap: 2rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.link-card {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
padding: 1px;
|
||||
background-color: #23262d;
|
||||
background-image: none;
|
||||
background-size: 400%;
|
||||
border-radius: 7px;
|
||||
background-position: 100%;
|
||||
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.link-card > a {
|
||||
width: 100%;
|
||||
text-decoration: none;
|
||||
line-height: 1.4;
|
||||
padding: calc(1.5rem - 1px);
|
||||
border-radius: 8px;
|
||||
color: white;
|
||||
background-color: #23262d;
|
||||
opacity: 0.8;
|
||||
}
|
||||
h2 {
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
p {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.link-card:is(:hover, :focus-within) {
|
||||
background-position: 0;
|
||||
background-image: var(--accent-gradient);
|
||||
}
|
||||
.link-card:is(:hover, :focus-within) h2 {
|
||||
color: rgb(var(--accent-light));
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,8 @@
|
|||
// The `ts-ignore` comments here are necessary because we're importing this file inside the `astro:components`
|
||||
// virtual module's types, which means that `tsc` will try to resolve these imports. Don't mind the editor errors.
|
||||
// virtual module's types, which means that `tsc` will try to resolve these imports.
|
||||
// @ts-ignore
|
||||
export { default as Code } from './Code.astro';
|
||||
export { default as Code } from "./Code.astro";
|
||||
// @ts-ignore
|
||||
export { default as Debug } from './Debug.astro';
|
||||
export { default as Debug } from "./Debug.astro";
|
||||
// @ts-ignore
|
||||
export { default as Welcome } from "./Welcome.astro";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
// https://astro.build/config
|
||||
|
|
|
@ -45,19 +45,19 @@ npm create astro@latest my-astro-project -- --template cassidoo/shopify-react-as
|
|||
|
||||
May be provided in place of prompts
|
||||
|
||||
| Name | Description |
|
||||
| :--------------------------- | :----------------------------------------------------- |
|
||||
| `--help` (`-h`) | Display available flags. |
|
||||
| `--template <name>` | Specify your template. |
|
||||
| `--install` / `--no-install` | Install dependencies (or not). |
|
||||
| `--git` / `--no-git` | Initialize git repo (or not). |
|
||||
| `--yes` (`-y`) | Skip all prompts by accepting defaults. |
|
||||
| `--no` (`-n`) | Skip all prompts by declining defaults. |
|
||||
| `--dry-run` | Walk through steps without executing. |
|
||||
| `--skip-houston` | Skip Houston animation. |
|
||||
| `--ref` | Specify an Astro branch (default: latest). |
|
||||
| `--fancy` | Enable full Unicode support for Windows. |
|
||||
| `--typescript <option>` | TypeScript option: `strict` / `strictest` / `relaxed`. |
|
||||
| Name | Description |
|
||||
| :--------------------------- | :----------------------------------------- |
|
||||
| `--help` (`-h`) | Display available flags. |
|
||||
| `--template <name>` | Specify your template. |
|
||||
| `--install` / `--no-install` | Install dependencies (or not). |
|
||||
| `--add <integrations>` | Add integrations. |
|
||||
| `--git` / `--no-git` | Initialize git repo (or not). |
|
||||
| `--yes` (`-y`) | Skip all prompts by accepting defaults. |
|
||||
| `--no` (`-n`) | Skip all prompts by declining defaults. |
|
||||
| `--dry-run` | Walk through steps without executing. |
|
||||
| `--skip-houston` | Skip Houston animation. |
|
||||
| `--ref` | Specify an Astro branch (default: latest). |
|
||||
| `--fancy` | Enable full Unicode support for Windows. |
|
||||
|
||||
[examples]: https://github.com/withastro/astro/tree/main/examples
|
||||
[typescript]: https://github.com/withastro/astro/tree/main/packages/astro/tsconfigs
|
||||
|
|
|
@ -15,6 +15,7 @@ export interface Context {
|
|||
version: Promise<string>;
|
||||
skipHouston: boolean;
|
||||
fancy?: boolean;
|
||||
add?: string[];
|
||||
dryRun?: boolean;
|
||||
yes?: boolean;
|
||||
projectName?: string;
|
||||
|
@ -43,11 +44,11 @@ export async function getContext(argv: string[]): Promise<Context> {
|
|||
'--no-install': Boolean,
|
||||
'--git': Boolean,
|
||||
'--no-git': Boolean,
|
||||
'--typescript': String,
|
||||
'--skip-houston': Boolean,
|
||||
'--dry-run': Boolean,
|
||||
'--help': Boolean,
|
||||
'--fancy': Boolean,
|
||||
'--add': [String],
|
||||
|
||||
'-y': '--yes',
|
||||
'-n': '--no',
|
||||
|
@ -67,11 +68,11 @@ export async function getContext(argv: string[]): Promise<Context> {
|
|||
'--no-install': noInstall,
|
||||
'--git': git,
|
||||
'--no-git': noGit,
|
||||
'--typescript': typescript,
|
||||
'--fancy': fancy,
|
||||
'--skip-houston': skipHouston,
|
||||
'--dry-run': dryRun,
|
||||
'--ref': ref,
|
||||
'--add': add,
|
||||
} = flags;
|
||||
let projectName = cwd;
|
||||
|
||||
|
@ -79,12 +80,11 @@ export async function getContext(argv: string[]): Promise<Context> {
|
|||
yes = false;
|
||||
if (install == undefined) install = false;
|
||||
if (git == undefined) git = false;
|
||||
if (typescript == undefined) typescript = 'strict';
|
||||
}
|
||||
|
||||
skipHouston =
|
||||
((os.platform() === 'win32' && !fancy) || skipHouston) ??
|
||||
[yes, no, install, git, typescript].some((v) => v !== undefined);
|
||||
[yes, no, install, git].some((v) => v !== undefined);
|
||||
|
||||
const { messages, hats, ties } = getSeasonalData({ fancy });
|
||||
|
||||
|
@ -96,6 +96,7 @@ export async function getContext(argv: string[]): Promise<Context> {
|
|||
version: getVersion(packageManager, 'astro', process.env.ASTRO_VERSION),
|
||||
skipHouston,
|
||||
fancy,
|
||||
add,
|
||||
dryRun,
|
||||
projectName,
|
||||
template,
|
||||
|
@ -106,7 +107,6 @@ export async function getContext(argv: string[]): Promise<Context> {
|
|||
yes,
|
||||
install: install ?? (noInstall ? false : undefined),
|
||||
git: git ?? (noGit ? false : undefined),
|
||||
typescript,
|
||||
cwd,
|
||||
exit(code) {
|
||||
process.exit(code);
|
||||
|
|
|
@ -6,7 +6,10 @@ import { shell } from '../shell.js';
|
|||
import type { Context } from './context.js';
|
||||
|
||||
export async function dependencies(
|
||||
ctx: Pick<Context, 'install' | 'yes' | 'prompt' | 'packageManager' | 'cwd' | 'dryRun' | 'tasks'>,
|
||||
ctx: Pick<
|
||||
Context,
|
||||
'install' | 'yes' | 'prompt' | 'packageManager' | 'cwd' | 'dryRun' | 'tasks' | 'add'
|
||||
>,
|
||||
) {
|
||||
let deps = ctx.install ?? ctx.yes;
|
||||
if (deps === undefined) {
|
||||
|
@ -21,8 +24,10 @@ export async function dependencies(
|
|||
ctx.install = deps;
|
||||
}
|
||||
|
||||
ctx.add = ctx.add?.reduce<string[]>((acc, item) => acc.concat(item.split(',')), []);
|
||||
|
||||
if (ctx.dryRun) {
|
||||
await info('--dry-run', `Skipping dependency installation`);
|
||||
await info('--dry-run', `Skipping dependency installation${ ctx.add ? ` and adding ${ctx.add.join(', ')}` : '' }`);
|
||||
} else if (deps) {
|
||||
ctx.tasks.push({
|
||||
pending: 'Dependencies',
|
||||
|
@ -39,6 +44,27 @@ export async function dependencies(
|
|||
},
|
||||
while: () => install({ packageManager: ctx.packageManager, cwd: ctx.cwd }),
|
||||
});
|
||||
|
||||
let add = ctx.add;
|
||||
|
||||
if (add) {
|
||||
ctx.tasks.push({
|
||||
pending: 'Integrations',
|
||||
start: `Adding integrations with astro add`,
|
||||
end: 'Integrations added',
|
||||
onError: (e) => {
|
||||
error('error', e);
|
||||
error(
|
||||
'error',
|
||||
`Failed to add integrations, please run ${color.bold(
|
||||
`astro add ${add.join(' ')}`,
|
||||
)} to install them manually after setup.`,
|
||||
);
|
||||
},
|
||||
while: () =>
|
||||
astroAdd({ integrations: add, packageManager: ctx.packageManager, cwd: ctx.cwd }),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
await info(
|
||||
ctx.yes === false ? 'deps [skip]' : 'No problem!',
|
||||
|
@ -47,6 +73,19 @@ export async function dependencies(
|
|||
}
|
||||
}
|
||||
|
||||
async function astroAdd({
|
||||
integrations,
|
||||
packageManager,
|
||||
cwd,
|
||||
}: { integrations: string[]; packageManager: string; cwd: string }) {
|
||||
if (packageManager === 'yarn') await ensureYarnLock({ cwd });
|
||||
return shell(
|
||||
packageManager === 'npm' ? 'npx' : `${packageManager} dlx`,
|
||||
['astro add', integrations.join(' '), '-y'],
|
||||
{ cwd, timeout: 90_000, stdio: 'ignore' },
|
||||
);
|
||||
}
|
||||
|
||||
async function install({ packageManager, cwd }: { packageManager: string; cwd: string }) {
|
||||
if (packageManager === 'yarn') await ensureYarnLock({ cwd });
|
||||
return shell(packageManager, ['install'], { cwd, timeout: 90_000, stdio: 'ignore' });
|
||||
|
|
|
@ -10,6 +10,7 @@ export function help() {
|
|||
['--help (-h)', 'See all available flags.'],
|
||||
['--template <name>', 'Specify your template.'],
|
||||
['--install / --no-install', 'Install dependencies (or not).'],
|
||||
['--add <integrations>', 'Add integrations.'],
|
||||
['--git / --no-git', 'Initialize git repo (or not).'],
|
||||
['--yes (-y)', 'Skip all prompts by accepting defaults.'],
|
||||
['--no (-n)', 'Skip all prompts by declining defaults.'],
|
||||
|
@ -17,7 +18,6 @@ export function help() {
|
|||
['--skip-houston', 'Skip Houston animation.'],
|
||||
['--ref', 'Choose astro branch (default: latest).'],
|
||||
['--fancy', 'Enable full Unicode support for Windows.'],
|
||||
['--typescript <option>', 'TypeScript option: strict | strictest | relaxed.'],
|
||||
],
|
||||
},
|
||||
});
|
||||
|
|
|
@ -21,9 +21,9 @@ export async function template(
|
|||
message: 'How would you like to start your new project?',
|
||||
initial: 'basics',
|
||||
choices: [
|
||||
{ value: 'basics', label: 'Include sample files', hint: '(recommended)' },
|
||||
{ value: 'basics', label: 'A basic, minimal starter', hint: '(recommended)' },
|
||||
{ value: 'blog', label: 'Use blog template' },
|
||||
{ value: 'minimal', label: 'Empty' },
|
||||
{ value: 'starlight', label: 'Use docs (Starlight) template' },
|
||||
],
|
||||
});
|
||||
ctx.template = tmpl;
|
||||
|
|
|
@ -1,166 +0,0 @@
|
|||
import { readFile, rm, writeFile } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { color } from '@astrojs/cli-kit';
|
||||
import stripJsonComments from 'strip-json-comments';
|
||||
import { error, getVersion, info, title, typescriptByDefault } from '../messages.js';
|
||||
import type { Context } from './context.js';
|
||||
|
||||
type PickedTypeScriptContext = Pick<
|
||||
Context,
|
||||
| 'typescript'
|
||||
| 'yes'
|
||||
| 'prompt'
|
||||
| 'dryRun'
|
||||
| 'cwd'
|
||||
| 'exit'
|
||||
| 'packageManager'
|
||||
| 'install'
|
||||
| 'tasks'
|
||||
>;
|
||||
|
||||
export async function typescript(ctx: PickedTypeScriptContext) {
|
||||
let ts = ctx.typescript ?? (typeof ctx.yes !== 'undefined' ? 'strict' : undefined);
|
||||
if (ts === undefined) {
|
||||
const { useTs } = await ctx.prompt({
|
||||
name: 'useTs',
|
||||
type: 'confirm',
|
||||
label: title('ts'),
|
||||
message: `Do you plan to write TypeScript?`,
|
||||
initial: true,
|
||||
});
|
||||
if (!useTs) {
|
||||
await typescriptByDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
({ ts } = await ctx.prompt({
|
||||
name: 'ts',
|
||||
type: 'select',
|
||||
label: title('use'),
|
||||
message: `How strict should TypeScript be?`,
|
||||
initial: 'strict',
|
||||
choices: [
|
||||
{ value: 'strict', label: 'Strict', hint: `(recommended)` },
|
||||
{ value: 'strictest', label: 'Strictest' },
|
||||
{ value: 'base', label: 'Relaxed' },
|
||||
],
|
||||
}));
|
||||
} else {
|
||||
if (!['strict', 'strictest', 'relaxed', 'default', 'base'].includes(ts)) {
|
||||
if (!ctx.dryRun) {
|
||||
await rm(ctx.cwd, { recursive: true, force: true });
|
||||
}
|
||||
error(
|
||||
'Error',
|
||||
`Unknown TypeScript option ${color.reset(ts)}${color.dim(
|
||||
'! Expected strict | strictest | relaxed',
|
||||
)}`,
|
||||
);
|
||||
ctx.exit(1);
|
||||
}
|
||||
await info('ts', `Using ${color.reset(ts)}${color.dim(' TypeScript configuration')}`);
|
||||
}
|
||||
|
||||
if (ctx.dryRun) {
|
||||
await info('--dry-run', `Skipping TypeScript setup`);
|
||||
} else if (ts && ts !== 'unsure') {
|
||||
if (ts === 'relaxed' || ts === 'default') {
|
||||
ts = 'base';
|
||||
}
|
||||
ctx.tasks.push({
|
||||
pending: 'TypeScript',
|
||||
start: 'TypeScript customizing...',
|
||||
end: 'TypeScript customized',
|
||||
while: () =>
|
||||
setupTypeScript(ts!, ctx).catch((e) => {
|
||||
error('error', e);
|
||||
process.exit(1);
|
||||
}),
|
||||
});
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
const FILES_TO_UPDATE = {
|
||||
'package.json': async (
|
||||
file: string,
|
||||
options: { value: string; ctx: PickedTypeScriptContext },
|
||||
) => {
|
||||
try {
|
||||
// inject additional command to build script
|
||||
const data = await readFile(file, { encoding: 'utf-8' });
|
||||
const indent = /(^\s+)/m.exec(data)?.[1] ?? '\t';
|
||||
const parsedPackageJson = JSON.parse(data);
|
||||
|
||||
const buildScript = parsedPackageJson.scripts?.build;
|
||||
|
||||
// in case of any other template already have astro checks defined, we don't want to override it
|
||||
if (typeof buildScript === 'string' && !buildScript.includes('astro check')) {
|
||||
// Mutate the existing object to avoid changing user-defined script order
|
||||
parsedPackageJson.scripts.build = `astro check && ${buildScript}`;
|
||||
}
|
||||
|
||||
const [astroCheckVersion, typescriptVersion] = await Promise.all([
|
||||
getVersion(options.ctx.packageManager, '@astrojs/check', process.env.ASTRO_CHECK_VERSION),
|
||||
getVersion(options.ctx.packageManager, 'typescript', process.env.TYPESCRIPT_VERSION),
|
||||
]);
|
||||
parsedPackageJson.dependencies ??= {};
|
||||
parsedPackageJson.dependencies['@astrojs/check'] = `^${astroCheckVersion}`;
|
||||
parsedPackageJson.dependencies.typescript = `^${typescriptVersion}`;
|
||||
|
||||
await writeFile(file, JSON.stringify(parsedPackageJson, null, indent) + '\n', 'utf-8');
|
||||
} catch (err) {
|
||||
// if there's no package.json (which is very unlikely), then do nothing
|
||||
if (err && (err as any).code === 'ENOENT') return;
|
||||
if (err instanceof Error) throw new Error(err.message);
|
||||
}
|
||||
},
|
||||
'tsconfig.json': async (file: string, options: { value: string }) => {
|
||||
try {
|
||||
const data = await readFile(file, { encoding: 'utf-8' });
|
||||
const templateTSConfig = JSON.parse(stripJsonComments(data));
|
||||
if (templateTSConfig && typeof templateTSConfig === 'object') {
|
||||
const result = Object.assign(templateTSConfig, {
|
||||
extends: `astro/tsconfigs/${options.value}`,
|
||||
});
|
||||
|
||||
await writeFile(file, JSON.stringify(result, null, 2) + '\n');
|
||||
} else {
|
||||
throw new Error(
|
||||
"There was an error applying the requested TypeScript settings. This could be because the template's tsconfig.json is malformed",
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
if (err && (err as any).code === 'ENOENT') {
|
||||
// If the template doesn't have a tsconfig.json, let's add one instead
|
||||
await writeFile(
|
||||
file,
|
||||
JSON.stringify({ extends: `astro/tsconfigs/${options.value}` }, null, 2) + '\n',
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
'astro.config.mjs': async (file: string, options: { value: string }) => {
|
||||
if (!(options.value === 'strict' || options.value === 'strictest')) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let data = await readFile(file, { encoding: 'utf-8' });
|
||||
data = `// @ts-check\n${data}`;
|
||||
await writeFile(file, data, { encoding: 'utf-8' });
|
||||
} catch (err) {
|
||||
// if there's no astro.config.mjs (which is very unlikely), then do nothing
|
||||
if (err && (err as any).code === 'ENOENT') return;
|
||||
if (err instanceof Error) throw new Error(err.message);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export async function setupTypeScript(value: string, ctx: PickedTypeScriptContext) {
|
||||
await Promise.all(
|
||||
Object.entries(FILES_TO_UPDATE).map(async ([file, update]) =>
|
||||
update(path.resolve(path.join(ctx.cwd, file)), { value, ctx }),
|
||||
),
|
||||
);
|
||||
}
|
|
@ -8,7 +8,6 @@ import { intro } from './actions/intro.js';
|
|||
import { next } from './actions/next-steps.js';
|
||||
import { projectName } from './actions/project-name.js';
|
||||
import { template } from './actions/template.js';
|
||||
import { setupTypeScript, typescript } from './actions/typescript.js';
|
||||
import { verify } from './actions/verify.js';
|
||||
import { setStdout } from './messages.js';
|
||||
|
||||
|
@ -36,7 +35,6 @@ export async function main() {
|
|||
intro,
|
||||
projectName,
|
||||
template,
|
||||
typescript,
|
||||
dependencies,
|
||||
|
||||
// Steps which write to files need to go above git
|
||||
|
@ -61,16 +59,4 @@ export async function main() {
|
|||
process.exit(0);
|
||||
}
|
||||
|
||||
export {
|
||||
dependencies,
|
||||
getContext,
|
||||
git,
|
||||
intro,
|
||||
next,
|
||||
projectName,
|
||||
setStdout,
|
||||
setupTypeScript,
|
||||
template,
|
||||
typescript,
|
||||
verify,
|
||||
};
|
||||
export { dependencies, getContext, git, intro, next, projectName, setStdout, template, verify };
|
||||
|
|
|
@ -51,6 +51,11 @@ describe('context', () => {
|
|||
assert.deepEqual(ctx.install, true);
|
||||
});
|
||||
|
||||
it('add', async () => {
|
||||
const ctx = await getContext(['--add', 'node']);
|
||||
assert.deepEqual(ctx.add, ['node']);
|
||||
});
|
||||
|
||||
it('no install', async () => {
|
||||
const ctx = await getContext(['--no-install']);
|
||||
assert.deepEqual(ctx.install, false);
|
||||
|
@ -65,9 +70,4 @@ describe('context', () => {
|
|||
const ctx = await getContext(['--no-git']);
|
||||
assert.deepEqual(ctx.git, false);
|
||||
});
|
||||
|
||||
it('typescript', async () => {
|
||||
const ctx = await getContext(['--typescript', 'strict']);
|
||||
assert.deepEqual(ctx.typescript, 'strict');
|
||||
});
|
||||
});
|
||||
|
|
60
packages/create-astro/test/integrations.test.js
Normal file
60
packages/create-astro/test/integrations.test.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
import assert from 'node:assert/strict';
|
||||
import { describe, it } from 'node:test';
|
||||
import { dependencies } from '../dist/index.js';
|
||||
import { setup } from './utils.js';
|
||||
describe('integrations', () => {
|
||||
const fixture = setup();
|
||||
|
||||
it('--add node', async () => {
|
||||
const context = {
|
||||
cwd: '',
|
||||
yes: true,
|
||||
packageManager: 'npm',
|
||||
dryRun: true,
|
||||
add: ['node'],
|
||||
};
|
||||
|
||||
await dependencies(context);
|
||||
|
||||
assert.ok(fixture.hasMessage('--dry-run Skipping dependency installation and adding node'));
|
||||
});
|
||||
|
||||
it('--add node --add react', async () => {
|
||||
const context = {
|
||||
cwd: '',
|
||||
yes: true,
|
||||
packageManager: 'npm',
|
||||
dryRun: true,
|
||||
add: ['node', 'react'],
|
||||
};
|
||||
|
||||
await dependencies(context);
|
||||
|
||||
assert.ok(fixture.hasMessage('--dry-run Skipping dependency installation and adding node, react'));
|
||||
});
|
||||
|
||||
it('--add node,react', async () => {
|
||||
const context = {
|
||||
cwd: '',
|
||||
yes: true,
|
||||
packageManager: 'npm',
|
||||
dryRun: true,
|
||||
add: ['node,react']
|
||||
};
|
||||
|
||||
await dependencies(context);
|
||||
|
||||
assert.ok(fixture.hasMessage('--dry-run Skipping dependency installation and adding node, react'));
|
||||
});
|
||||
|
||||
it('-y', async () => {
|
||||
const context = {
|
||||
cwd: '',
|
||||
yes: true,
|
||||
packageManager: 'npm',
|
||||
dryRun: true,
|
||||
};
|
||||
await dependencies(context);
|
||||
assert.ok(fixture.hasMessage('--dry-run Skipping dependency installation'));
|
||||
});
|
||||
});
|
|
@ -1,155 +0,0 @@
|
|||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import { after, beforeEach, describe, it } from 'node:test';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { setupTypeScript, typescript } from '../dist/index.js';
|
||||
import { resetFixtures, setup } from './utils.js';
|
||||
|
||||
describe('typescript', async () => {
|
||||
const fixture = setup();
|
||||
|
||||
it('none', async () => {
|
||||
const context = { cwd: '', dryRun: true, prompt: () => ({ ts: 'strict', useTs: true }) };
|
||||
await typescript(context);
|
||||
|
||||
assert.ok(fixture.hasMessage('Skipping TypeScript setup'));
|
||||
});
|
||||
|
||||
it('use false', async () => {
|
||||
const context = { cwd: '', dryRun: true, prompt: () => ({ ts: 'strict', useTs: false }) };
|
||||
await typescript(context);
|
||||
|
||||
assert.ok(fixture.hasMessage('No worries'));
|
||||
});
|
||||
|
||||
it('strict', async () => {
|
||||
const context = {
|
||||
typescript: 'strict',
|
||||
cwd: '',
|
||||
dryRun: true,
|
||||
prompt: () => ({ ts: 'strict' }),
|
||||
};
|
||||
await typescript(context);
|
||||
assert.ok(fixture.hasMessage('Using strict TypeScript configuration'));
|
||||
assert.ok(fixture.hasMessage('Skipping TypeScript setup'));
|
||||
});
|
||||
|
||||
it('default', async () => {
|
||||
const context = {
|
||||
typescript: 'default',
|
||||
cwd: '',
|
||||
dryRun: true,
|
||||
prompt: () => ({ ts: 'strict' }),
|
||||
};
|
||||
await typescript(context);
|
||||
assert.ok(fixture.hasMessage('Using default TypeScript configuration'));
|
||||
assert.ok(fixture.hasMessage('Skipping TypeScript setup'));
|
||||
});
|
||||
|
||||
it('relaxed', async () => {
|
||||
const context = {
|
||||
typescript: 'relaxed',
|
||||
cwd: '',
|
||||
dryRun: true,
|
||||
prompt: () => ({ ts: 'strict' }),
|
||||
};
|
||||
await typescript(context);
|
||||
assert.ok(fixture.hasMessage('Using relaxed TypeScript configuration'));
|
||||
assert.ok(fixture.hasMessage('Skipping TypeScript setup'));
|
||||
});
|
||||
|
||||
it('other', async () => {
|
||||
const context = {
|
||||
typescript: 'other',
|
||||
cwd: '',
|
||||
dryRun: true,
|
||||
prompt: () => ({ ts: 'strict' }),
|
||||
exit(code) {
|
||||
throw code;
|
||||
},
|
||||
};
|
||||
let err = null;
|
||||
try {
|
||||
await typescript(context);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
assert.equal(err, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('typescript: setup tsconfig', async () => {
|
||||
beforeEach(() => resetFixtures());
|
||||
after(() => resetFixtures());
|
||||
|
||||
it('none', async () => {
|
||||
const root = new URL('./fixtures/empty/', import.meta.url);
|
||||
const tsconfig = new URL('./tsconfig.json', root);
|
||||
|
||||
await setupTypeScript('strict', { cwd: fileURLToPath(root) });
|
||||
assert.deepEqual(JSON.parse(fs.readFileSync(tsconfig, { encoding: 'utf-8' })), {
|
||||
extends: 'astro/tsconfigs/strict',
|
||||
});
|
||||
assert(
|
||||
fs.readFileSync(tsconfig, { encoding: 'utf-8' }).endsWith('\n'),
|
||||
'The file does not end with a newline',
|
||||
);
|
||||
});
|
||||
|
||||
it('exists', async () => {
|
||||
const root = new URL('./fixtures/not-empty/', import.meta.url);
|
||||
const tsconfig = new URL('./tsconfig.json', root);
|
||||
await setupTypeScript('strict', { cwd: fileURLToPath(root) });
|
||||
assert.deepEqual(JSON.parse(fs.readFileSync(tsconfig, { encoding: 'utf-8' })), {
|
||||
extends: 'astro/tsconfigs/strict',
|
||||
});
|
||||
assert(
|
||||
fs.readFileSync(tsconfig, { encoding: 'utf-8' }).endsWith('\n'),
|
||||
'The file does not end with a newline',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('typescript: setup package', async () => {
|
||||
beforeEach(() => resetFixtures());
|
||||
after(() => resetFixtures());
|
||||
|
||||
it('none', async () => {
|
||||
const root = new URL('./fixtures/empty/', import.meta.url);
|
||||
const packageJson = new URL('./package.json', root);
|
||||
|
||||
await setupTypeScript('strictest', { cwd: fileURLToPath(root), install: false });
|
||||
assert.ok(!fs.existsSync(packageJson));
|
||||
});
|
||||
|
||||
it('none', async () => {
|
||||
const root = new URL('./fixtures/not-empty/', import.meta.url);
|
||||
const packageJson = new URL('./package.json', root);
|
||||
assert.equal(
|
||||
JSON.parse(fs.readFileSync(packageJson, { encoding: 'utf-8' })).scripts.build,
|
||||
'astro build',
|
||||
);
|
||||
|
||||
await setupTypeScript('strictest', { cwd: fileURLToPath(root), install: false });
|
||||
assert(
|
||||
fs.readFileSync(packageJson, { encoding: 'utf-8' }).endsWith('\n'),
|
||||
'The file does not end with a newline',
|
||||
);
|
||||
const { scripts, dependencies } = JSON.parse(
|
||||
fs.readFileSync(packageJson, { encoding: 'utf-8' }),
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
Object.keys(scripts),
|
||||
['dev', 'build', 'preview'],
|
||||
'does not override existing scripts',
|
||||
);
|
||||
|
||||
for (const value of Object.values(dependencies)) {
|
||||
assert.doesNotMatch(value, /undefined$/, 'does not include undefined values');
|
||||
}
|
||||
|
||||
assert.equal(scripts.build, 'astro check && astro build', 'prepends astro check command');
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue