mirror of
https://github.com/withastro/astro.git
synced 2024-12-30 22:03:56 -05:00
parent
71e5de76f1
commit
1acd5ee310
10 changed files with 86 additions and 52 deletions
28
README.md
28
README.md
|
@ -28,6 +28,28 @@ Then run:
|
||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### ⚙️ Configuration
|
||||||
|
|
||||||
|
To configure Astro, add a `astro.config.mjs` file in the root of your project. All of the options can be omitted. Here are the defaults:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
/** Where to resolve all URLs relative to. Useful if you have a monorepo project. */
|
||||||
|
projectRoot: '.',
|
||||||
|
/** Path to Astro components, pages, and data */
|
||||||
|
astroRoot: './astro',
|
||||||
|
/** When running `astro build`, path to final static output */
|
||||||
|
dist: './_site',
|
||||||
|
/** A folder of static files Astro will copy to the root. Useful for favicons, images, and other files that don‘t need processing. */
|
||||||
|
public: './public',
|
||||||
|
/** Extension-specific handlings */
|
||||||
|
extensions: {
|
||||||
|
/** Set this to "preact" or "react" to determine what *.jsx files should load */
|
||||||
|
'.jsx': 'react',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### 💧 Partial Hydration
|
### 💧 Partial Hydration
|
||||||
|
|
||||||
By default, Astro outputs zero client-side JS. If you'd like to include an interactive component in the client output, you may use any of the following techniques.
|
By default, Astro outputs zero client-side JS. If you'd like to include an interactive component in the client output, you may use any of the following techniques.
|
||||||
|
@ -50,7 +72,7 @@ If you‘ve used [Svelte][svelte]’s styles before, Astro works almost the same
|
||||||
<div class="scoped">I’m a scoped style</div>
|
<div class="scoped">I’m a scoped style</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Sass
|
#### 👓 Sass
|
||||||
|
|
||||||
Astro also supports [Sass][sass] out-of-the-box; no configuration needed:
|
Astro also supports [Sass][sass] out-of-the-box; no configuration needed:
|
||||||
|
|
||||||
|
@ -71,11 +93,11 @@ Supports:
|
||||||
- `lang="scss"`: load as the `.scss` extension
|
- `lang="scss"`: load as the `.scss` extension
|
||||||
- `lang="sass"`: load as the `.sass` extension (no brackets; indent-style)
|
- `lang="sass"`: load as the `.sass` extension (no brackets; indent-style)
|
||||||
|
|
||||||
#### Autoprefixer
|
#### 🦊 Autoprefixer
|
||||||
|
|
||||||
We also automatically add browser prefixes using [Autoprefixer][autoprefixer]. By default, Astro loads the default values, but you may also specify your own by placing a [Browserslist][browserslist] file in your project root.
|
We also automatically add browser prefixes using [Autoprefixer][autoprefixer]. By default, Astro loads the default values, but you may also specify your own by placing a [Browserslist][browserslist] file in your project root.
|
||||||
|
|
||||||
#### Tailwind
|
#### 🍃 Tailwind
|
||||||
|
|
||||||
Astro can be configured to use [Tailwind][tailwind] easily! Install the dependencies:
|
Astro can be configured to use [Tailwind][tailwind] easily! Install the dependencies:
|
||||||
|
|
||||||
|
|
11
src/cli.ts
11
src/cli.ts
|
@ -58,14 +58,13 @@ async function printVersion() {
|
||||||
|
|
||||||
/** Handle `astro run` command */
|
/** Handle `astro run` command */
|
||||||
async function runCommand(rawRoot: string, cmd: (a: AstroConfig) => Promise<void>) {
|
async function runCommand(rawRoot: string, cmd: (a: AstroConfig) => Promise<void>) {
|
||||||
const astroConfig = await loadConfig(rawRoot);
|
try {
|
||||||
if (typeof astroConfig === 'undefined') {
|
const astroConfig = await loadConfig(rawRoot);
|
||||||
console.error(colors.red(' An astro.config.mjs file is required.\n'));
|
return cmd(astroConfig);
|
||||||
printHelp();
|
} catch (err) {
|
||||||
|
console.error(colors.red(err.toString() || err));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd(astroConfig);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const cmdMap = new Map([
|
const cmdMap = new Map([
|
||||||
|
|
|
@ -2,25 +2,70 @@ import type { AstroConfig } from './@types/astro';
|
||||||
import { join as pathJoin, resolve as pathResolve } from 'path';
|
import { join as pathJoin, resolve as pathResolve } from 'path';
|
||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
|
|
||||||
|
/** Type util */
|
||||||
|
const type = (thing: any): string => (Array.isArray(thing) ? 'Array' : typeof thing);
|
||||||
|
|
||||||
|
/** Throws error if a user provided an invalid config. Manually-implemented to avoid a heavy validation library. */
|
||||||
|
function validateConfig(config: any): void {
|
||||||
|
// basic
|
||||||
|
if (config === undefined || config === null) throw new Error(`[astro config] Config empty!`);
|
||||||
|
if (typeof config !== 'object') throw new Error(`[astro config] Expected object, received ${typeof config}`);
|
||||||
|
|
||||||
|
// strings
|
||||||
|
for (const key of ['projectRoot', 'astroRoot', 'dist', 'public']) {
|
||||||
|
if (config[key] && typeof config[key] !== 'string') {
|
||||||
|
throw new Error(`[astro config] ${key}: ${JSON.stringify(config[key])}\n Expected string, received ${type(config[key])}.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set default config values */
|
||||||
|
function configDefaults(userConfig?: any): any {
|
||||||
|
const config: any = { ...(userConfig || {}) };
|
||||||
|
|
||||||
|
if (!config.projectRoot) config.projectRoot = '.';
|
||||||
|
if (!config.astroRoot) config.astroRoot = './astro';
|
||||||
|
if (!config.dist) config.dist = './_site';
|
||||||
|
if (!config.public) config.public = './public';
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Turn raw config values into normalized values */
|
||||||
|
function normalizeConfig(userConfig: any, root: string): AstroConfig {
|
||||||
|
const config: any = { ...(userConfig || {}) };
|
||||||
|
|
||||||
|
config.projectRoot = new URL(config.projectRoot + '/', root);
|
||||||
|
config.astroRoot = new URL(config.astroRoot + '/', root);
|
||||||
|
config.public = new URL(config.public + '/', root);
|
||||||
|
|
||||||
|
return config as AstroConfig;
|
||||||
|
}
|
||||||
|
|
||||||
/** Attempt to load an `astro.config.mjs` file */
|
/** Attempt to load an `astro.config.mjs` file */
|
||||||
export async function loadConfig(rawRoot: string | undefined): Promise<AstroConfig | undefined> {
|
export async function loadConfig(rawRoot: string | undefined): Promise<AstroConfig> {
|
||||||
if (typeof rawRoot === 'undefined') {
|
if (typeof rawRoot === 'undefined') {
|
||||||
rawRoot = process.cwd();
|
rawRoot = process.cwd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let config: any;
|
||||||
|
|
||||||
const root = pathResolve(rawRoot);
|
const root = pathResolve(rawRoot);
|
||||||
const fileProtocolRoot = `file://${root}/`;
|
const fileProtocolRoot = `file://${root}/`;
|
||||||
const astroConfigPath = pathJoin(root, 'astro.config.mjs');
|
const astroConfigPath = pathJoin(root, 'astro.config.mjs');
|
||||||
|
|
||||||
if (!existsSync(astroConfigPath)) {
|
// load
|
||||||
return undefined;
|
if (existsSync(astroConfigPath)) {
|
||||||
|
config = configDefaults((await import(astroConfigPath)).default);
|
||||||
|
} else {
|
||||||
|
config = configDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
const astroConfig: AstroConfig = (await import(astroConfigPath)).default;
|
// validate
|
||||||
astroConfig.projectRoot = new URL(astroConfig.projectRoot + '/', fileProtocolRoot);
|
validateConfig(config);
|
||||||
astroConfig.astroRoot = new URL(astroConfig.astroRoot + '/', fileProtocolRoot);
|
|
||||||
|
|
||||||
const publicFolder = astroConfig.public ? astroConfig.public + '/' : './public/';
|
// normalize
|
||||||
astroConfig.public = new URL(publicFolder, fileProtocolRoot);
|
config = normalizeConfig(config, fileProtocolRoot);
|
||||||
return astroConfig;
|
|
||||||
|
return config as AstroConfig;
|
||||||
}
|
}
|
||||||
|
|
5
test/fixtures/astro-basic/astro.config.mjs
vendored
5
test/fixtures/astro-basic/astro.config.mjs
vendored
|
@ -1,5 +0,0 @@
|
||||||
export default {
|
|
||||||
projectRoot: '.',
|
|
||||||
astroRoot: './astro',
|
|
||||||
dist: './_site',
|
|
||||||
};
|
|
5
test/fixtures/astro-doctype/astro.config.mjs
vendored
5
test/fixtures/astro-doctype/astro.config.mjs
vendored
|
@ -1,5 +0,0 @@
|
||||||
export default {
|
|
||||||
projectRoot: '.',
|
|
||||||
astroRoot: './astro',
|
|
||||||
dist: './_site',
|
|
||||||
};
|
|
|
@ -1,8 +1,5 @@
|
||||||
export default {
|
export default {
|
||||||
projectRoot: '.',
|
|
||||||
astroRoot: './astro',
|
|
||||||
dist: './_site',
|
|
||||||
extensions: {
|
extensions: {
|
||||||
'.jsx': 'preact'
|
'.jsx': 'preact',
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
export default {
|
export default {
|
||||||
projectRoot: '.',
|
|
||||||
astroRoot: './astro',
|
|
||||||
dist: './_site',
|
|
||||||
extensions: {
|
extensions: {
|
||||||
'.jsx': 'preact',
|
'.jsx': 'preact',
|
||||||
},
|
},
|
||||||
|
|
5
test/fixtures/astro-request/astro.config.mjs
vendored
5
test/fixtures/astro-request/astro.config.mjs
vendored
|
@ -1,5 +0,0 @@
|
||||||
export default {
|
|
||||||
projectRoot: '.',
|
|
||||||
astroRoot: './astro',
|
|
||||||
dist: './_site'
|
|
||||||
};
|
|
|
@ -1,5 +0,0 @@
|
||||||
export default {
|
|
||||||
projectRoot: '.',
|
|
||||||
astroRoot: './astro',
|
|
||||||
dist: './_site',
|
|
||||||
};
|
|
|
@ -1,6 +0,0 @@
|
||||||
export default {
|
|
||||||
projectRoot: '.',
|
|
||||||
astroRoot: './astro',
|
|
||||||
dist: './_site',
|
|
||||||
// No extensions needed, React is the default.
|
|
||||||
};
|
|
Loading…
Reference in a new issue