Skip to content

Commit

Permalink
Merge branch 'canary' into title-in-document-head-eslint-rule
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] authored May 7, 2021
2 parents 7ebeabd + 9c77cda commit 82c70a1
Show file tree
Hide file tree
Showing 19 changed files with 530 additions and 38 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ packages/next-codemod/transforms/__tests__/**/*
packages/next-codemod/**/*.js
packages/next-codemod/**/*.d.ts
packages/next-env/**/*.d.ts
packages/create-next-app/templates/**
test/integration/async-modules/**
test/integration/eslint/**
test-timings.json
8 changes: 8 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ npx create-next-app
yarn create next-app
```

If you want to start with a TypeScript project you can use the `--typescript` flag:

```bash
npx create-next-app --typescript
# or
yarn create next-app --typescript
```

After the installation is complete, follow the instructions to start the development server. Try editing `pages/index.js` and see the result on your browser.

For more information on how to use `create-next-app`, you can review the [`create-next-app` documentation](/docs/api-reference/create-next-app.md)
Expand Down
1 change: 1 addition & 0 deletions packages/create-next-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ npx create-next-app blog-app

`create-next-app` comes with the following options:

- **--ts, --typescript** - Initialize as a TypeScript project.
- **-e, --example [name]|[github-url]** - An example to bootstrap the app with. You can use an example name from the [Next.js repo](https://github.com/vercel/next.js/tree/master/examples) or a GitHub URL. The URL can use any branch and/or subdirectory.
- **--example-path <path-to-example>** - In a rare case, your GitHub URL might contain a branch name with a slash (e.g. bug/fix-1) and the path to the example (e.g. foo/bar). In this case, you must specify the path to the example separately: `--example-path foo/bar`
- **--use-npm** - Explicitly tell the CLI to bootstrap the app using npm. Yarn will be used by default if it's installed
Expand Down
81 changes: 70 additions & 11 deletions packages/create-next-app/create-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@ export async function createApp({
useNpm,
example,
examplePath,
typescript,
}: {
appPath: string
useNpm: boolean
example?: string
examplePath?: string
typescript?: boolean
}): Promise<void> {
let repoInfo: RepoInfo | undefined
const template = typescript ? 'typescript' : 'default'

if (example) {
let repoUrl: URL | undefined
Expand Down Expand Up @@ -124,6 +127,9 @@ export async function createApp({
process.chdir(root)

if (example) {
/**
* If an example repository is provided, clone it.
*/
try {
if (repoInfo) {
const repoInfo2 = repoInfo
Expand Down Expand Up @@ -154,7 +160,7 @@ export async function createApp({
const ignorePath = path.join(root, '.gitignore')
if (!fs.existsSync(ignorePath)) {
fs.copyFileSync(
path.join(__dirname, 'templates', 'default', 'gitignore'),
path.join(__dirname, 'templates', template, 'gitignore'),
ignorePath
)
}
Expand All @@ -165,30 +171,83 @@ export async function createApp({
await install(root, null, { useYarn, isOnline })
console.log()
} else {
/**
* Otherwise, if an example repository is not provided for cloning, proceed
* by installing from a template.
*/
console.log(chalk.bold(`Using ${displayedCommand}.`))
/**
* Create a package.json for the new project.
*/
const packageJson = {
name: appName,
version: '0.1.0',
private: true,
scripts: { dev: 'next dev', build: 'next build', start: 'next start' },
scripts: {
dev: 'next dev',
build: 'next build',
start: 'next start',
},
}
/**
* Write it to disk.
*/
fs.writeFileSync(
path.join(root, 'package.json'),
JSON.stringify(packageJson, null, 2) + os.EOL
)
/**
* These flags will be passed to `install()`.
*/
const installFlags = { useYarn, isOnline }
/**
* Default dependencies.
*/
const dependencies = ['react', 'react-dom', 'next']
/**
* Default devDependencies.
*/
const devDependencies = []
/**
* TypeScript projects will have type definitions and other devDependencies.
*/
if (typescript) {
devDependencies.push('typescript', '@types/react', '@types/next')
}
/**
* Install package.json dependencies if they exist.
*/
if (dependencies.length) {
console.log()
console.log('Installing dependencies:')
for (const dependency of dependencies) {
console.log(`- ${chalk.cyan(dependency)}`)
}
console.log()

console.log(
`Installing ${chalk.cyan('react')}, ${chalk.cyan(
'react-dom'
)}, and ${chalk.cyan('next')} using ${displayedCommand}...`
)
console.log()
await install(root, dependencies, installFlags)
}
/**
* Install package.json devDependencies if they exist.
*/
if (devDependencies.length) {
console.log()
console.log('Installing devDependencies:')
for (const devDependency of devDependencies) {
console.log(`- ${chalk.cyan(devDependency)}`)
}
console.log()

await install(root, ['react', 'react-dom', 'next'], { useYarn, isOnline })
const devInstallFlags = { devDependencies: true, ...installFlags }
await install(root, devDependencies, devInstallFlags)
}
console.log()

/**
* Copy the template files to the target directory.
*/
await cpy('**', root, {
parents: true,
cwd: path.join(__dirname, 'templates', 'default'),
cwd: path.join(__dirname, 'templates', template),
rename: (name) => {
switch (name) {
case 'gitignore': {
Expand Down
105 changes: 81 additions & 24 deletions packages/create-next-app/helpers/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,98 @@
import chalk from 'chalk'
import spawn from 'cross-spawn'

interface InstallArgs {
/**
* Indicate whether to install packages using Yarn.
*/
useYarn: boolean
/**
* Indicate whether there is an active Internet connection.
*/
isOnline: boolean
/**
* Indicate whether the given dependencies are devDependencies.
*/
devDependencies?: boolean
}

/**
* Spawn a package manager installation with either Yarn or NPM.
*
* @returns A Promise that resolves once the installation is finished.
*/
export function install(
root: string,
dependencies: string[] | null,
{ useYarn, isOnline }: { useYarn: boolean; isOnline: boolean }
{ useYarn, isOnline, devDependencies }: InstallArgs
): Promise<void> {
/**
* NPM-specific command-line flags.
*/
const npmFlags: string[] = ['--logLevel', 'error']
/**
* Yarn-specific command-line flags.
*/
const yarnFlags: string[] = []
/**
* Return a Promise that resolves once the installation is finished.
*/
return new Promise((resolve, reject) => {
let command: string
let args: string[]
if (useYarn) {
command = 'yarnpkg'
args = dependencies ? ['add', '--exact'] : ['install']
if (!isOnline) {
args.push('--offline')
}
if (dependencies) {
let command: string = useYarn ? 'yarnpkg' : 'npm'

if (dependencies && dependencies.length) {
/**
* If there are dependencies, run a variation of `{displayCommand} add`.
*/
if (useYarn) {
/**
* Call `yarn add --exact (--offline)? (-D)? ...`.
*/
args = ['add', '--exact']
if (!isOnline) args.push('--offline')
args.push('--cwd', root)
if (devDependencies) args.push('--dev')
args.push(...dependencies)
} else {
/**
* Call `npm install [--save|--save-dev] ...`.
*/
args = ['install', '--save-exact']
args.push(devDependencies ? '--save-dev' : '--save')
args.push(...dependencies)
}
args.push('--cwd', root)

if (!isOnline) {
console.log(chalk.yellow('You appear to be offline.'))
console.log(chalk.yellow('Falling back to the local Yarn cache.'))
console.log()
} else {
/**
* If there are no dependencies, run a variation of `{displayCommand}
* install`.
*/
args = ['install']
if (useYarn) {
if (!isOnline) {
console.log(chalk.yellow('You appear to be offline.'))
console.log(chalk.yellow('Falling back to the local Yarn cache.'))
console.log()
args.push('--offline')
}
} else {
if (!isOnline) {
console.log(chalk.yellow('You appear to be offline.'))
console.log()
}
}
}
/**
* Add any package manager-specific flags.
*/
if (useYarn) {
args.push(...yarnFlags)
} else {
command = 'npm'
args = ([
'install',
dependencies && '--save',
dependencies && '--save-exact',
'--loglevel',
'error',
].filter(Boolean) as string[]).concat(dependencies || [])
args.push(...npmFlags)
}

/**
* Spawn the installation process.
*/
const child = spawn(command, args, {
stdio: 'inherit',
env: { ...process.env, ADBLOCK: '1', DISABLE_OPENCOLLECTIVE: '1' },
Expand Down
22 changes: 20 additions & 2 deletions packages/create-next-app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,20 @@ const program = new Commander.Command(packageJson.name)
.action((name) => {
projectPath = name
})
.option('--use-npm', 'Explicitly tell the CLI to bootstrap the app using npm')
.option(
'--ts, --typescript',
`
Initialize as a TypeScript project.
`
)
.option(
'--use-npm',
`
Explicitly tell the CLI to bootstrap the app using npm
`
)
.option(
'-e, --example [name]|[github-url]',
`
Expand Down Expand Up @@ -113,6 +126,7 @@ async function run(): Promise<void> {
useNpm: !!program.useNpm,
example: example && example !== 'default' ? example : undefined,
examplePath: program.examplePath,
typescript: program.typescript,
})
} catch (reason) {
if (!(reason instanceof DownloadError)) {
Expand All @@ -131,7 +145,11 @@ async function run(): Promise<void> {
throw reason
}

await createApp({ appPath: resolvedProjectPath, useNpm: !!program.useNpm })
await createApp({
appPath: resolvedProjectPath,
useNpm: !!program.useNpm,
typescript: program.typescript,
})
}
}

Expand Down
34 changes: 34 additions & 0 deletions packages/create-next-app/templates/typescript/README-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.

[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.

The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
34 changes: 34 additions & 0 deletions packages/create-next-app/templates/typescript/gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local

# vercel
.vercel
2 changes: 2 additions & 0 deletions packages/create-next-app/templates/typescript/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// <reference types="next" />
/// <reference types="next/types/global" />
Loading

0 comments on commit 82c70a1

Please sign in to comment.