mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-16 10:37:20 +02:00
feat(create): better detection of package manager preference (#6679)
Co-authored-by: sebastienlorber <lorber.sebastien@gmail.com>
This commit is contained in:
parent
c3370be64d
commit
26d223dbeb
2 changed files with 101 additions and 18 deletions
|
@ -17,12 +17,56 @@ import {fileURLToPath} from 'url';
|
||||||
const RecommendedTemplate = 'classic';
|
const RecommendedTemplate = 'classic';
|
||||||
const TypeScriptTemplateSuffix = '-typescript';
|
const TypeScriptTemplateSuffix = '-typescript';
|
||||||
|
|
||||||
function hasYarn() {
|
const DefaultPackageManager = 'npm';
|
||||||
try {
|
|
||||||
return shell.exec('yarnpkg --version', {silent: true}).code === 0;
|
const SupportedPackageManagers = {
|
||||||
} catch (e) {
|
npm: 'package-lock.json',
|
||||||
return false;
|
yarn: 'yarn.lock',
|
||||||
|
pnpm: 'pnpm-lock.yaml',
|
||||||
|
};
|
||||||
|
|
||||||
|
type SupportedPackageManager = keyof typeof SupportedPackageManagers;
|
||||||
|
|
||||||
|
const PackageManagersList = Object.keys(
|
||||||
|
SupportedPackageManagers,
|
||||||
|
) as SupportedPackageManager[];
|
||||||
|
|
||||||
|
async function findPackageManagerFromLockFile(): Promise<
|
||||||
|
SupportedPackageManager | undefined
|
||||||
|
> {
|
||||||
|
for (const packageManager of PackageManagersList) {
|
||||||
|
const lockFilePath = path.resolve(
|
||||||
|
process.cwd(),
|
||||||
|
SupportedPackageManagers[packageManager],
|
||||||
|
);
|
||||||
|
if (await fs.pathExists(lockFilePath)) {
|
||||||
|
return packageManager;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findPackageManagerFromUserAgent():
|
||||||
|
| SupportedPackageManager
|
||||||
|
| undefined {
|
||||||
|
return PackageManagersList.find((packageManager) =>
|
||||||
|
process.env.npm_config_user_agent?.startsWith(packageManager),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getPackageManager(
|
||||||
|
forceUseNpm?: boolean,
|
||||||
|
): Promise<SupportedPackageManager> {
|
||||||
|
// TODO replace --use-npm by --package-manager option
|
||||||
|
if (forceUseNpm) {
|
||||||
|
return 'npm';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
(await findPackageManagerFromLockFile()) ??
|
||||||
|
findPackageManagerFromUserAgent() ??
|
||||||
|
DefaultPackageManager
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidGitRepoUrl(gitRepoUrl: string) {
|
function isValidGitRepoUrl(gitRepoUrl: string) {
|
||||||
|
@ -131,14 +175,13 @@ export default async function init(
|
||||||
gitStrategy: typeof gitStrategies[number];
|
gitStrategy: typeof gitStrategies[number];
|
||||||
}> = {},
|
}> = {},
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const useYarn = cliOptions.useNpm ? false : hasYarn();
|
const pkgManager = await getPackageManager(cliOptions.useNpm);
|
||||||
const templatesDir = fileURLToPath(new URL('../templates', import.meta.url));
|
const templatesDir = fileURLToPath(new URL('../templates', import.meta.url));
|
||||||
const templates = await readTemplates(templatesDir);
|
const templates = await readTemplates(templatesDir);
|
||||||
const hasTS = (templateName: string) =>
|
const hasTS = (templateName: string) =>
|
||||||
fs.pathExists(
|
fs.pathExists(
|
||||||
path.resolve(templatesDir, `${templateName}${TypeScriptTemplateSuffix}`),
|
path.resolve(templatesDir, `${templateName}${TypeScriptTemplateSuffix}`),
|
||||||
);
|
);
|
||||||
|
|
||||||
let name = siteName;
|
let name = siteName;
|
||||||
|
|
||||||
// Prompt if siteName is not passed from CLI.
|
// Prompt if siteName is not passed from CLI.
|
||||||
|
@ -313,21 +356,23 @@ export default async function init(
|
||||||
await fs.remove(path.join(dest, 'gitignore'));
|
await fs.remove(path.join(dest, 'gitignore'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const pkgManager = useYarn ? 'yarn' : 'npm';
|
|
||||||
// Display the most elegant way to cd.
|
// Display the most elegant way to cd.
|
||||||
const cdpath = path.relative('.', dest);
|
const cdpath = path.relative('.', dest);
|
||||||
if (!cliOptions.skipInstall) {
|
if (!cliOptions.skipInstall) {
|
||||||
shell.cd(dest);
|
shell.cd(dest);
|
||||||
logger.info`Installing dependencies with name=${pkgManager}...`;
|
logger.info`Installing dependencies with name=${pkgManager}...`;
|
||||||
if (
|
if (
|
||||||
shell.exec(useYarn ? 'yarn' : 'npm install --color always', {
|
shell.exec(
|
||||||
env: {
|
pkgManager === 'yarn' ? 'yarn' : `${pkgManager} install --color always`,
|
||||||
...process.env,
|
{
|
||||||
// Force coloring the output, since the command is invoked by shelljs,
|
env: {
|
||||||
// which is not the interactive shell
|
...process.env,
|
||||||
...(supportsColor.stdout ? {FORCE_COLOR: '1'} : {}),
|
// Force coloring the output, since the command is invoked,
|
||||||
|
// by shelljs which is not the interactive shell
|
||||||
|
...(supportsColor.stdout ? {FORCE_COLOR: '1'} : {}),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}).code !== 0
|
).code !== 0
|
||||||
) {
|
) {
|
||||||
logger.error('Dependency installation failed.');
|
logger.error('Dependency installation failed.');
|
||||||
logger.info`The site directory has already been created, and you can retry by typing:
|
logger.info`The site directory has already been created, and you can retry by typing:
|
||||||
|
@ -338,16 +383,17 @@ export default async function init(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const useNpm = pkgManager === 'npm';
|
||||||
logger.success`Created path=${cdpath}.`;
|
logger.success`Created path=${cdpath}.`;
|
||||||
logger.info`Inside that directory, you can run several commands:
|
logger.info`Inside that directory, you can run several commands:
|
||||||
|
|
||||||
code=${`${pkgManager} start`}
|
code=${`${pkgManager} start`}
|
||||||
Starts the development server.
|
Starts the development server.
|
||||||
|
|
||||||
code=${`${pkgManager} ${useYarn ? '' : 'run '}build`}
|
code=${`${pkgManager} ${useNpm ? 'run ' : ''}build`}
|
||||||
Bundles your website into static files for production.
|
Bundles your website into static files for production.
|
||||||
|
|
||||||
code=${`${pkgManager} ${useYarn ? '' : 'run '}serve`}
|
code=${`${pkgManager} ${useNpm ? 'run ' : ''}serve`}
|
||||||
Serves the built website locally.
|
Serves the built website locally.
|
||||||
|
|
||||||
code=${`${pkgManager} deploy`}
|
code=${`${pkgManager} deploy`}
|
||||||
|
|
|
@ -3,6 +3,11 @@ id: installation
|
||||||
title: Installation
|
title: Installation
|
||||||
---
|
---
|
||||||
|
|
||||||
|
```mdx-code-block
|
||||||
|
import Tabs from '@theme/Tabs';
|
||||||
|
import TabItem from '@theme/TabItem';
|
||||||
|
```
|
||||||
|
|
||||||
Docusaurus is essentially a set of npm [packages](https://github.com/facebook/docusaurus/tree/main/packages).
|
Docusaurus is essentially a set of npm [packages](https://github.com/facebook/docusaurus/tree/main/packages).
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
|
@ -17,7 +22,6 @@ Use **[docusaurus.new](https://docusaurus.new)** to test Docusaurus immediately
|
||||||
|
|
||||||
- [Node.js](https://nodejs.org/en/download/) version >= 14 or above (which can be checked by running `node -v`). You can use [nvm](https://github.com/nvm-sh/nvm) for managing multiple Node versions on a single machine installed.
|
- [Node.js](https://nodejs.org/en/download/) version >= 14 or above (which can be checked by running `node -v`). You can use [nvm](https://github.com/nvm-sh/nvm) for managing multiple Node versions on a single machine installed.
|
||||||
- When installing Node.js, you are recommended to check all checkboxes related to dependencies.
|
- When installing Node.js, you are recommended to check all checkboxes related to dependencies.
|
||||||
- [Yarn](https://yarnpkg.com/en/) version >= 1.5 (which can be checked by running `yarn --version`). Yarn is a performant package manager for JavaScript and replaces the `npm` client. It is not strictly necessary but highly encouraged.
|
|
||||||
|
|
||||||
## Scaffold project website {#scaffold-project-website}
|
## Scaffold project website {#scaffold-project-website}
|
||||||
|
|
||||||
|
@ -59,6 +63,39 @@ You can also use the template's TypeScript variant by passing the `--typescript`
|
||||||
npx create-docusaurus@latest my-website classic --typescript
|
npx create-docusaurus@latest my-website classic --typescript
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Alternative installation methods</summary>
|
||||||
|
|
||||||
|
You can also initialize a new project using your preferred project manager:
|
||||||
|
|
||||||
|
````mdx-code-block
|
||||||
|
<Tabs>
|
||||||
|
<TabItem value="npm v6+">
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm init docusaurus website classic
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="yarn">
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn create docusaurus website classic
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="pnpm">
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm create docusaurus website classic
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
````
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
## Project structure {#project-structure}
|
## Project structure {#project-structure}
|
||||||
|
|
||||||
Assuming you chose the classic template and named your site `my-website`, you will see the following files generated under a new directory `my-website/`:
|
Assuming you chose the classic template and named your site `my-website`, you will see the following files generated under a new directory `my-website/`:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue