Add template support (#7716)
* Add template support * Update templates version check * Update TypeScript template README
@@ -1,78 +1,79 @@
|
||||
#
|
||||
# Azure Pipelines configuration for building and testing create-react-app on Linux, Windows, and macOS.
|
||||
#
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
variables:
|
||||
CI: true
|
||||
# Overrides the Yarn and NPM cache directories so they are on the same drive as the source. This helps improve build performance on Windows hosted agents.
|
||||
YARN_CACHE_FOLDER: $(Build.SourcesDirectory)/../yarn-cache
|
||||
NPM_CONFIG_CACHE: $(Build.SourcesDirectory)/../npm-cache
|
||||
# Sets TEMP to be on the same drive as the cloned source on Windows. This avoids test scripts that "cd" into a directory under TEMP from failing because this directory is on a different drive from the current directory.
|
||||
VSTS_OVERWRITE_TEMP: True
|
||||
# Override Verdaccio package to use. This is temporary and is needed to avoid socket timeouts on hosted Windows agent (on Azure). This also changes Verdaccio to return a 503 (service unavailable) instead of a 404 (not found) when the connection to the uplink timesout.
|
||||
VERDACCIO_PACKAGE: https://github.com/willsmythe/verdaccio/releases/download/create-react-app/verdaccio-4.0.0-alpha.8.tgz
|
||||
|
||||
# ******************************************************************************
|
||||
# Simple test suite
|
||||
# ******************************************************************************
|
||||
jobs:
|
||||
- template: azure-pipelines-test-job.yml
|
||||
parameters:
|
||||
name: Simple
|
||||
testScript: tasks/e2e-simple.sh
|
||||
|
||||
# ******************************************************************************
|
||||
# Installs test suite
|
||||
# ******************************************************************************
|
||||
- template: azure-pipelines-test-job.yml
|
||||
parameters:
|
||||
name: Installs
|
||||
testScript: tasks/e2e-installs.sh
|
||||
|
||||
# ******************************************************************************
|
||||
# Kitchensink test suite
|
||||
# ******************************************************************************
|
||||
- template: azure-pipelines-test-job.yml
|
||||
parameters:
|
||||
name: Kitchensink
|
||||
testScript: tasks/e2e-kitchensink.sh
|
||||
|
||||
# ******************************************************************************
|
||||
# Kitchensink Eject test suite
|
||||
# ******************************************************************************
|
||||
- template: azure-pipelines-test-job.yml
|
||||
parameters:
|
||||
name: KitchensinkEject
|
||||
testScript: tasks/e2e-kitchensink-eject.sh
|
||||
|
||||
# ******************************************************************************
|
||||
# Behavior test suite
|
||||
# ******************************************************************************
|
||||
- template: azure-pipelines-test-job.yml
|
||||
parameters:
|
||||
name: Behavior
|
||||
testScript: tasks/e2e-behavior.sh
|
||||
configurations:
|
||||
LinuxNode8: { vmImage: 'ubuntu-16.04', nodeVersion: 8.x }
|
||||
LinuxNode10: { vmImage: 'ubuntu-16.04', nodeVersion: 10.x }
|
||||
# WindowsNode8: { vmImage: 'vs2017-win2016', nodeVersion: 8.x }
|
||||
# WindowsNode10: { vmImage: 'vs2017-win2016', nodeVersion: 10.x }
|
||||
MacNode8: { vmImage: 'macOS-10.13', nodeVersion: 8.x }
|
||||
MacNode10: { vmImage: 'macOS-10.13', nodeVersion: 10.x }
|
||||
|
||||
# ******************************************************************************
|
||||
# Old Node test suite
|
||||
# ******************************************************************************
|
||||
- job: OldNode
|
||||
pool:
|
||||
vmImage: ubuntu-16.04
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: 6.x
|
||||
displayName: 'Install Node.js 6.x'
|
||||
- bash: tasks/e2e-old-node.sh
|
||||
displayName: 'Run tests'
|
||||
#
|
||||
# Azure Pipelines configuration for building and testing create-react-app on Linux, Windows, and macOS.
|
||||
#
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
variables:
|
||||
CI: true
|
||||
# Overrides the Yarn and NPM cache directories so they are on the same drive as the source. This helps improve build performance on Windows hosted agents.
|
||||
YARN_CACHE_FOLDER: $(Build.SourcesDirectory)/../yarn-cache
|
||||
NPM_CONFIG_CACHE: $(Build.SourcesDirectory)/../npm-cache
|
||||
# Sets TEMP to be on the same drive as the cloned source on Windows. This avoids test scripts that "cd" into a directory under TEMP from failing because this directory is on a different drive from the current directory.
|
||||
VSTS_OVERWRITE_TEMP: True
|
||||
# Override Verdaccio package to use. This is temporary and is needed to avoid socket timeouts on hosted Windows agent (on Azure). This also changes Verdaccio to return a 503 (service unavailable) instead of a 404 (not found) when the connection to the uplink timesout.
|
||||
VERDACCIO_PACKAGE: https://github.com/willsmythe/verdaccio/releases/download/create-react-app/verdaccio-4.0.0-alpha.8.tgz
|
||||
CRA_INTERNAL_TEST: true
|
||||
|
||||
# ******************************************************************************
|
||||
# Simple test suite
|
||||
# ******************************************************************************
|
||||
jobs:
|
||||
- template: azure-pipelines-test-job.yml
|
||||
parameters:
|
||||
name: Simple
|
||||
testScript: tasks/e2e-simple.sh
|
||||
|
||||
# ******************************************************************************
|
||||
# Installs test suite
|
||||
# ******************************************************************************
|
||||
- template: azure-pipelines-test-job.yml
|
||||
parameters:
|
||||
name: Installs
|
||||
testScript: tasks/e2e-installs.sh
|
||||
|
||||
# ******************************************************************************
|
||||
# Kitchensink test suite
|
||||
# ******************************************************************************
|
||||
- template: azure-pipelines-test-job.yml
|
||||
parameters:
|
||||
name: Kitchensink
|
||||
testScript: tasks/e2e-kitchensink.sh
|
||||
|
||||
# ******************************************************************************
|
||||
# Kitchensink Eject test suite
|
||||
# ******************************************************************************
|
||||
- template: azure-pipelines-test-job.yml
|
||||
parameters:
|
||||
name: KitchensinkEject
|
||||
testScript: tasks/e2e-kitchensink-eject.sh
|
||||
|
||||
# ******************************************************************************
|
||||
# Behavior test suite
|
||||
# ******************************************************************************
|
||||
- template: azure-pipelines-test-job.yml
|
||||
parameters:
|
||||
name: Behavior
|
||||
testScript: tasks/e2e-behavior.sh
|
||||
configurations:
|
||||
LinuxNode8: { vmImage: 'ubuntu-16.04', nodeVersion: 8.x }
|
||||
LinuxNode10: { vmImage: 'ubuntu-16.04', nodeVersion: 10.x }
|
||||
# WindowsNode8: { vmImage: 'vs2017-win2016', nodeVersion: 8.x }
|
||||
# WindowsNode10: { vmImage: 'vs2017-win2016', nodeVersion: 10.x }
|
||||
MacNode8: { vmImage: 'macOS-10.13', nodeVersion: 8.x }
|
||||
MacNode10: { vmImage: 'macOS-10.13', nodeVersion: 10.x }
|
||||
|
||||
# ******************************************************************************
|
||||
# Old Node test suite
|
||||
# ******************************************************************************
|
||||
- job: OldNode
|
||||
pool:
|
||||
vmImage: ubuntu-16.04
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: 6.x
|
||||
displayName: 'Install Node.js 6.x'
|
||||
- bash: tasks/e2e-old-node.sh
|
||||
displayName: 'Run tests'
|
||||
|
||||
@@ -12,14 +12,16 @@ title: Adding TypeScript
|
||||
To start a new Create React App project with [TypeScript](https://www.typescriptlang.org/), you can run:
|
||||
|
||||
```sh
|
||||
npx create-react-app my-app --typescript
|
||||
npx create-react-app my-app --template typescript
|
||||
|
||||
# or
|
||||
|
||||
yarn create react-app my-app --typescript
|
||||
yarn create react-app my-app --template typescript
|
||||
```
|
||||
|
||||
> If you've previously installed `create-react-app` globally via `npm install -g create-react-app`, we recommend you uninstall the package using `npm uninstall -g create-react-app` to ensure that `npx` always uses the latest version.
|
||||
>
|
||||
> Global installs of `create-react-app` are no longer supported.
|
||||
|
||||
To add [TypeScript](https://www.typescriptlang.org/) to a Create React App project, first install it:
|
||||
|
||||
@@ -49,5 +51,4 @@ If your project is not created with TypeScript enabled, npx may be using a cache
|
||||
|
||||
If you are currently using [create-react-app-typescript](https://github.com/wmonk/create-react-app-typescript/), see [this blog post](https://vincenttunru.com/migrate-create-react-app-typescript-to-create-react-app/) for instructions on how to migrate to Create React App.
|
||||
|
||||
|
||||
Constant enums and namespaces are not supported, you can learn about the constraints of [using Babel with TypeScript here](https://babeljs.io/docs/en/babel-plugin-transform-typescript#caveats).
|
||||
|
||||
@@ -11,7 +11,7 @@ You can adjust various development and production settings by setting environmen
|
||||
| :---------------------- | :---------: | :--------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BROWSER | ✅ Used | 🚫 Ignored | By default, Create React App will open the default system browser, favoring Chrome on macOS. Specify a [browser](https://github.com/sindresorhus/open#app) to override this behavior, or set it to `none` to disable it completely. If you need to customize the way the browser is launched, you can specify a node script instead. Any arguments passed to `npm start` will also be passed to this script, and the url where your app is served will be the last argument. Your script's file name must have the `.js` extension. |
|
||||
| BROWSER_ARGS | ✅ Used | 🚫 Ignored | When the `BROWSER` environment variable is specified, any arguments that you set to this environment variable will be passed to the browser instance. Multiple arguments are supported as a space separated list. By default, no arguments are passed through to browsers. |
|
||||
| HOST | ✅ Used | 🚫 Ignored | By default, the development web server binds to all hostnames on the device (`localhost`, LAN network address, etc.). You may use this variable to specify a different host. |
|
||||
| HOST | ✅ Used | 🚫 Ignored | By default, the development web server binds to all hostnames on the device (`localhost`, LAN network address, etc.). You may use this variable to specify a different host. |
|
||||
| PORT | ✅ Used | 🚫 Ignored | By default, the development web server will attempt to listen on port 3000 or prompt you to attempt the next available port. You may use this variable to specify a different port. |
|
||||
| HTTPS | ✅ Used | 🚫 Ignored | When set to `true`, Create React App will run the development server in `https` mode. |
|
||||
| PUBLIC_URL | 🚫 Ignored | ✅ Used | Create React App assumes your application is hosted at the serving web server's root or a subpath as specified in [`package.json` (`homepage`)](deployment#building-for-relative-paths). Normally, Create React App ignores the hostname. You may use this variable to force assets to be referenced verbatim to the url you provide (hostname included). This may be particularly useful when using a CDN to host your application. |
|
||||
|
||||
@@ -62,13 +62,33 @@ yarn create react-app my-app
|
||||
|
||||
_`yarn create` is available in Yarn 0.25+_
|
||||
|
||||
### Creating a TypeScript app
|
||||
### Selecting a template
|
||||
|
||||
Follow our [Adding TypeScript](adding-typescript.md) documentation to create a TypeScript app.
|
||||
You can now optionally start a new app from a template by appending `--template [template-name]` to the creation command.
|
||||
|
||||
If you don't select a template, we'll create your project with our base template.
|
||||
|
||||
Templates are always named in the format `cra-template-[template-name]`, however you only need to provide the `[template-name]` to the creation command.
|
||||
|
||||
```sh
|
||||
npx create-react-app my-app --template [template-name]
|
||||
```
|
||||
|
||||
> You can find a a list of available templates by searching for ["cra-template-\*"](https://www.npmjs.com/search?q=cra-template-*) on npm.
|
||||
|
||||
#### Creating a TypeScript app
|
||||
|
||||
You can start a new TypeScript app using templates. To use our provided TypeScript template, append `--template typescript` to the creation command.
|
||||
|
||||
```sh
|
||||
npx create-react-app my-app --template typescript
|
||||
```
|
||||
|
||||
If you already have a project and would like to add TypeScript, see our [Adding TypeScript](adding-typescript.md) documentation.
|
||||
|
||||
### Selecting a package manager
|
||||
|
||||
When you create a new app, the CLI will use [Yarn](https://yarnpkg.com/) to install dependencies (when available). If you have Yarn installed, but would prefer to use npm, you can append --use-npm to the creation command. For example:
|
||||
When you create a new app, the CLI will use [Yarn](https://yarnpkg.com/) to install dependencies (when available). If you have Yarn installed, but would prefer to use npm, you can append `--use-npm` to the creation command. For example:
|
||||
|
||||
```sh
|
||||
npx create-react-app my-app --use-npm
|
||||
|
||||
20
packages/cra-template-typescript/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# cra-template-typescript
|
||||
|
||||
This is the official TypeScript template for [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
To use this template, add `--template typescript` when creating a new app.
|
||||
|
||||
For example:
|
||||
|
||||
```sh
|
||||
npx create-react-app my-app --template typescript
|
||||
|
||||
# or
|
||||
|
||||
yarn create react-app my-app --template typescript
|
||||
```
|
||||
|
||||
For more information, please refer to:
|
||||
|
||||
- [Getting Started](https://create-react-app.dev/docs/getting-started) – How to create a new app.
|
||||
- [User Guide](https://create-react-app.dev) – How to develop apps bootstrapped with Create React App.
|
||||
28
packages/cra-template-typescript/package.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "cra-template-typescript",
|
||||
"version": "1.0.0",
|
||||
"keywords": [
|
||||
"react",
|
||||
"create-react-app",
|
||||
"template",
|
||||
"typescript"
|
||||
],
|
||||
"description": "The base TypeScript template for Create React App.",
|
||||
"main": "template.json",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facebook/create-react-app.git",
|
||||
"directory": "packages/cra-template-typescript"
|
||||
},
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.10"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/facebook/create-react-app/issues"
|
||||
},
|
||||
"files": [
|
||||
"template",
|
||||
"template.json"
|
||||
]
|
||||
}
|
||||
9
packages/cra-template-typescript/template.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@types/node": "^12.0.0",
|
||||
"@types/react": "^16.9.0",
|
||||
"@types/react-dom": "^16.9.0",
|
||||
"@types/jest": "^24.0.0",
|
||||
"typescript": "^3.6.0"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
10
packages/cra-template/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# cra-template
|
||||
|
||||
This is the official base template for [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
If you don't specify a template (for example, `--template typescript`), this template will be used by default.
|
||||
|
||||
For more information, please refer to:
|
||||
|
||||
- [Getting Started](https://create-react-app.dev/docs/getting-started) – How to create a new app.
|
||||
- [User Guide](https://create-react-app.dev) – How to develop apps bootstrapped with Create React App.
|
||||
27
packages/cra-template/package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "cra-template",
|
||||
"version": "1.0.0",
|
||||
"keywords": [
|
||||
"react",
|
||||
"create-react-app",
|
||||
"template"
|
||||
],
|
||||
"description": "The base template for Create React App.",
|
||||
"main": "template.json",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facebook/create-react-app.git",
|
||||
"directory": "packages/cra-template"
|
||||
},
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/facebook/create-react-app/issues"
|
||||
},
|
||||
"files": [
|
||||
"template",
|
||||
"template.json"
|
||||
]
|
||||
}
|
||||
3
packages/cra-template/template.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"dependencies": {}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
13
packages/cra-template/template/src/index.css
Normal file
@@ -0,0 +1,13 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
@@ -76,9 +76,17 @@ const program = new commander.Command(packageJson.name)
|
||||
'--scripts-version <alternative-package>',
|
||||
'use a non-standard version of react-scripts'
|
||||
)
|
||||
.option(
|
||||
'--template <path-to-template>',
|
||||
'specify a template for the created project'
|
||||
)
|
||||
.option('--use-npm')
|
||||
.option('--use-pnp')
|
||||
.option('--typescript')
|
||||
// TODO: Remove this in next major release.
|
||||
.option(
|
||||
'--typescript',
|
||||
'(this option will be removed in favour of templates in the next major release of create-react-app)'
|
||||
)
|
||||
.allowUnknownOption()
|
||||
.on('--help', () => {
|
||||
console.log(` Only ${chalk.green('<project-directory>')} is required.`);
|
||||
@@ -112,6 +120,28 @@ const program = new commander.Command(packageJson.name)
|
||||
` It is not needed unless you specifically want to use a fork.`
|
||||
);
|
||||
console.log();
|
||||
console.log(` A custom ${chalk.cyan('--template')} can be one of:`);
|
||||
console.log(
|
||||
` - a custom fork published on npm: ${chalk.green(
|
||||
'cra-template-typescript'
|
||||
)}`
|
||||
);
|
||||
console.log(
|
||||
` - a local path relative to the current working directory: ${chalk.green(
|
||||
'file:../my-custom-template'
|
||||
)}`
|
||||
);
|
||||
console.log(
|
||||
` - a .tgz archive: ${chalk.green(
|
||||
'https://mysite.com/my-custom-template-0.8.2.tgz'
|
||||
)}`
|
||||
);
|
||||
console.log(
|
||||
` - a .tar.gz archive: ${chalk.green(
|
||||
'https://mysite.com/my-custom-template-0.8.2.tar.gz'
|
||||
)}`
|
||||
);
|
||||
console.log();
|
||||
console.log(
|
||||
` If you have any problems, do not hesitate to file an issue:`
|
||||
);
|
||||
@@ -166,35 +196,27 @@ function printValidationResults(results) {
|
||||
}
|
||||
}
|
||||
|
||||
const hiddenProgram = new commander.Command()
|
||||
.option(
|
||||
'--internal-testing-template <path-to-template>',
|
||||
'(internal usage only, DO NOT RELY ON THIS) ' +
|
||||
'use a non-standard application template'
|
||||
)
|
||||
.parse(process.argv);
|
||||
|
||||
createApp(
|
||||
projectName,
|
||||
program.verbose,
|
||||
program.scriptsVersion,
|
||||
program.template,
|
||||
program.useNpm,
|
||||
program.usePnp,
|
||||
program.typescript,
|
||||
hiddenProgram.internalTestingTemplate
|
||||
program.typescript
|
||||
);
|
||||
|
||||
function createApp(
|
||||
name,
|
||||
verbose,
|
||||
version,
|
||||
template,
|
||||
useNpm,
|
||||
usePnp,
|
||||
useTypescript,
|
||||
template
|
||||
useTypeScript
|
||||
) {
|
||||
const unsupportedNodeVersion = !semver.satisfies(process.version, '>=8.10.0');
|
||||
if (unsupportedNodeVersion && useTypescript) {
|
||||
if (unsupportedNodeVersion && useTypeScript) {
|
||||
console.log(
|
||||
chalk.red(
|
||||
`You are using Node ${process.version} with the TypeScript template. Node 8.10 or higher is required to use TypeScript.\n`
|
||||
@@ -248,9 +270,7 @@ function createApp(
|
||||
if (npmInfo.npmVersion) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
`You are using npm ${
|
||||
npmInfo.npmVersion
|
||||
} so the project will be bootstrapped with an old unsupported version of tools.\n\n` +
|
||||
`You are using npm ${npmInfo.npmVersion} so the project will be bootstrapped with an old unsupported version of tools.\n\n` +
|
||||
`Please update to npm 5 or higher for a better, fully supported experience.\n`
|
||||
)
|
||||
);
|
||||
@@ -264,9 +284,7 @@ function createApp(
|
||||
if (yarnInfo.yarnVersion) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
`You are using Yarn ${
|
||||
yarnInfo.yarnVersion
|
||||
} together with the --use-pnp flag, but Plug'n'Play is only supported starting from the 1.12 release.\n\n` +
|
||||
`You are using Yarn ${yarnInfo.yarnVersion} together with the --use-pnp flag, but Plug'n'Play is only supported starting from the 1.12 release.\n\n` +
|
||||
`Please update to Yarn 1.12 or higher for a better, fully supported experience.\n`
|
||||
)
|
||||
);
|
||||
@@ -276,6 +294,23 @@ function createApp(
|
||||
}
|
||||
}
|
||||
|
||||
if (useTypeScript) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'The --typescript option has been deprecated and will be removed in a future release.'
|
||||
)
|
||||
);
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
`In future, please use ${chalk.cyan('--template typescript')}.`
|
||||
)
|
||||
);
|
||||
console.log();
|
||||
if (!template) {
|
||||
template = 'typescript';
|
||||
}
|
||||
}
|
||||
|
||||
if (useYarn) {
|
||||
let yarnUsesDefaultRegistry = true;
|
||||
try {
|
||||
@@ -302,8 +337,7 @@ function createApp(
|
||||
originalDirectory,
|
||||
template,
|
||||
useYarn,
|
||||
usePnp,
|
||||
useTypescript
|
||||
usePnp
|
||||
);
|
||||
}
|
||||
|
||||
@@ -386,38 +420,72 @@ function run(
|
||||
originalDirectory,
|
||||
template,
|
||||
useYarn,
|
||||
usePnp,
|
||||
useTypescript
|
||||
usePnp
|
||||
) {
|
||||
getInstallPackage(version, originalDirectory).then(packageToInstall => {
|
||||
Promise.all([
|
||||
getInstallPackage(version, originalDirectory),
|
||||
getTemplateInstallPackage(template, originalDirectory),
|
||||
]).then(([packageToInstall, templateToInstall]) => {
|
||||
const allDependencies = ['react', 'react-dom', packageToInstall];
|
||||
if (useTypescript) {
|
||||
allDependencies.push(
|
||||
// TODO: get user's node version instead of installing latest
|
||||
'@types/node',
|
||||
'@types/react',
|
||||
'@types/react-dom',
|
||||
// TODO: get version of Jest being used instead of installing latest
|
||||
'@types/jest',
|
||||
'typescript'
|
||||
);
|
||||
}
|
||||
|
||||
console.log('Installing packages. This might take a couple of minutes.');
|
||||
getPackageName(packageToInstall)
|
||||
.then(packageName =>
|
||||
|
||||
Promise.all([
|
||||
getPackageInfo(packageToInstall),
|
||||
getPackageInfo(templateToInstall),
|
||||
])
|
||||
.then(([packageInfo, templateInfo]) =>
|
||||
checkIfOnline(useYarn).then(isOnline => ({
|
||||
isOnline: isOnline,
|
||||
packageName: packageName,
|
||||
isOnline,
|
||||
packageInfo,
|
||||
templateInfo,
|
||||
}))
|
||||
)
|
||||
.then(info => {
|
||||
const isOnline = info.isOnline;
|
||||
const packageName = info.packageName;
|
||||
.then(({ isOnline, packageInfo, templateInfo }) => {
|
||||
let packageVersion = semver.coerce(packageInfo.version);
|
||||
const templatesVersionMinimum = process.env.CRA_INTERNAL_TEST
|
||||
? '3.2.0'
|
||||
: '3.3.0';
|
||||
|
||||
// Assume compatibility if we can't test the version.
|
||||
if (!semver.valid(packageVersion)) {
|
||||
packageVersion = templatesVersionMinimum;
|
||||
}
|
||||
|
||||
// Only support templates when used alongside new react-scripts versions.
|
||||
const supportsTemplates = semver.gte(
|
||||
semver.coerce(packageVersion),
|
||||
templatesVersionMinimum
|
||||
);
|
||||
if (supportsTemplates) {
|
||||
allDependencies.push(templateToInstall);
|
||||
} else if (template) {
|
||||
console.log('');
|
||||
console.log(
|
||||
`The ${chalk.cyan(packageInfo.name)} version you're using ${
|
||||
packageInfo.name === 'react-scripts' ? 'is not' : 'may not be'
|
||||
} compatible with the ${chalk.cyan('--template')} option.`
|
||||
);
|
||||
console.log('');
|
||||
}
|
||||
|
||||
// TODO: Remove with next major release.
|
||||
if (!supportsTemplates && (template || '').includes('typescript')) {
|
||||
allDependencies.push(
|
||||
'@types/node',
|
||||
'@types/react',
|
||||
'@types/react-dom',
|
||||
'@types/jest',
|
||||
'typescript'
|
||||
);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Installing ${chalk.cyan('react')}, ${chalk.cyan(
|
||||
'react-dom'
|
||||
)}, and ${chalk.cyan(packageName)}...`
|
||||
)}, and ${chalk.cyan(packageInfo.name)}${
|
||||
supportsTemplates ? ` with ${chalk.cyan(templateInfo.name)}` : ''
|
||||
}...`
|
||||
);
|
||||
console.log();
|
||||
|
||||
@@ -428,9 +496,15 @@ function run(
|
||||
allDependencies,
|
||||
verbose,
|
||||
isOnline
|
||||
).then(() => packageName);
|
||||
).then(() => ({
|
||||
packageInfo,
|
||||
supportsTemplates,
|
||||
templateInfo,
|
||||
}));
|
||||
})
|
||||
.then(async packageName => {
|
||||
.then(async ({ packageInfo, supportsTemplates, templateInfo }) => {
|
||||
const packageName = packageInfo.name;
|
||||
const templateName = supportsTemplates ? templateInfo.name : undefined;
|
||||
checkNodeVersion(packageName);
|
||||
setCaretRangeForRuntimeDeps(packageName);
|
||||
|
||||
@@ -443,7 +517,7 @@ function run(
|
||||
cwd: process.cwd(),
|
||||
args: nodeArgs,
|
||||
},
|
||||
[root, appName, verbose, originalDirectory, template],
|
||||
[root, appName, verbose, originalDirectory, templateName],
|
||||
`
|
||||
var init = require('${packageName}/scripts/init.js');
|
||||
init.apply(null, JSON.parse(process.argv[1]));
|
||||
@@ -528,7 +602,9 @@ function getInstallPackage(version, originalDirectory) {
|
||||
{
|
||||
name: 'react-scripts-ts',
|
||||
message: chalk.yellow(
|
||||
'The react-scripts-ts package is deprecated. TypeScript is now supported natively in Create React App. You can use the --typescript option instead when generating your app to include TypeScript support. Would you like to continue using react-scripts-ts?'
|
||||
`The react-scripts-ts package is deprecated. TypeScript is now supported natively in Create React App. You can use the ${chalk.green(
|
||||
'--template typescript'
|
||||
)} option instead when generating your app to include TypeScript support. Would you like to continue using react-scripts-ts?`
|
||||
),
|
||||
},
|
||||
];
|
||||
@@ -555,6 +631,29 @@ function getInstallPackage(version, originalDirectory) {
|
||||
return Promise.resolve(packageToInstall);
|
||||
}
|
||||
|
||||
function getTemplateInstallPackage(template, originalDirectory) {
|
||||
let templateToInstall = 'cra-template';
|
||||
if (template) {
|
||||
if (template.match(/^file:/)) {
|
||||
templateToInstall = `file:${path.resolve(
|
||||
originalDirectory,
|
||||
template.match(/^file:(.*)?$/)[1]
|
||||
)}`;
|
||||
} else if (
|
||||
template.includes('://') ||
|
||||
template.match(/^.+\.(tgz|tar\.gz)$/)
|
||||
) {
|
||||
// for tar.gz or alternative paths
|
||||
templateToInstall = template;
|
||||
} else if (!template.startsWith(templateToInstall)) {
|
||||
// Add prefix `cra-template` to non-prefixed templates.
|
||||
templateToInstall += `-${template}`;
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve(templateToInstall);
|
||||
}
|
||||
|
||||
function getTemporaryDirectory() {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Unsafe cleanup lets us recursively delete the directory if it contains
|
||||
@@ -594,7 +693,7 @@ function extractStream(stream, dest) {
|
||||
}
|
||||
|
||||
// Extract package name from tarball url or path.
|
||||
function getPackageName(installPackage) {
|
||||
function getPackageInfo(installPackage) {
|
||||
if (installPackage.match(/^.+\.(tgz|tar\.gz)$/)) {
|
||||
return getTemporaryDirectory()
|
||||
.then(obj => {
|
||||
@@ -607,9 +706,12 @@ function getPackageName(installPackage) {
|
||||
return extractStream(stream, obj.tmpdir).then(() => obj);
|
||||
})
|
||||
.then(obj => {
|
||||
const packageName = require(path.join(obj.tmpdir, 'package.json')).name;
|
||||
const { name, version } = require(path.join(
|
||||
obj.tmpdir,
|
||||
'package.json'
|
||||
));
|
||||
obj.cleanup();
|
||||
return packageName;
|
||||
return { name, version };
|
||||
})
|
||||
.catch(err => {
|
||||
// The package name could be with or without semver version, e.g. react-scripts-0.2.0-alpha.1.tgz
|
||||
@@ -625,27 +727,30 @@ function getPackageName(installPackage) {
|
||||
assumedProjectName
|
||||
)}"`
|
||||
);
|
||||
return Promise.resolve(assumedProjectName);
|
||||
return Promise.resolve({ name: assumedProjectName });
|
||||
});
|
||||
} else if (installPackage.indexOf('git+') === 0) {
|
||||
// Pull package name out of git urls e.g:
|
||||
// git+https://github.com/mycompany/react-scripts.git
|
||||
// git+ssh://github.com/mycompany/react-scripts.git#v1.2.3
|
||||
return Promise.resolve(installPackage.match(/([^/]+)\.git(#.*)?$/)[1]);
|
||||
return Promise.resolve({
|
||||
name: installPackage.match(/([^/]+)\.git(#.*)?$/)[1],
|
||||
});
|
||||
} else if (installPackage.match(/.+@/)) {
|
||||
// Do not match @scope/ when stripping off @version or @tag
|
||||
return Promise.resolve(
|
||||
installPackage.charAt(0) + installPackage.substr(1).split('@')[0]
|
||||
);
|
||||
return Promise.resolve({
|
||||
name: installPackage.charAt(0) + installPackage.substr(1).split('@')[0],
|
||||
version: installPackage.split('@')[1],
|
||||
});
|
||||
} else if (installPackage.match(/^file:/)) {
|
||||
const installPackagePath = installPackage.match(/^file:(.*)?$/)[1];
|
||||
const installPackageJson = require(path.join(
|
||||
const { name, version } = require(path.join(
|
||||
installPackagePath,
|
||||
'package.json'
|
||||
));
|
||||
return Promise.resolve(installPackageJson.name);
|
||||
return Promise.resolve({ name, version });
|
||||
}
|
||||
return Promise.resolve(installPackage);
|
||||
return Promise.resolve({ name: installPackage });
|
||||
}
|
||||
|
||||
function checkNpmVersion() {
|
||||
|
||||
23
packages/react-scripts/config/paths.js
vendored
@@ -132,27 +132,28 @@ if (
|
||||
!reactScriptsLinked &&
|
||||
__dirname.indexOf(path.join('packages', 'react-scripts', 'config')) !== -1
|
||||
) {
|
||||
const templatePath = '../cra-template/template';
|
||||
module.exports = {
|
||||
dotenv: resolveOwn('template/.env'),
|
||||
dotenv: resolveOwn(`${templatePath}/.env`),
|
||||
appPath: resolveApp('.'),
|
||||
appBuild: resolveOwn('../../build'),
|
||||
appPublic: resolveOwn('template/public'),
|
||||
appHtml: resolveOwn('template/public/index.html'),
|
||||
appIndexJs: resolveModule(resolveOwn, 'template/src/index'),
|
||||
appPublic: resolveOwn(`${templatePath}/public`),
|
||||
appHtml: resolveOwn(`${templatePath}/public/index.html`),
|
||||
appIndexJs: resolveModule(resolveOwn, `${templatePath}/src/index`),
|
||||
appPackageJson: resolveOwn('package.json'),
|
||||
appSrc: resolveOwn('template/src'),
|
||||
appTsConfig: resolveOwn('template/tsconfig.json'),
|
||||
appJsConfig: resolveOwn('template/jsconfig.json'),
|
||||
yarnLockFile: resolveOwn('template/yarn.lock'),
|
||||
testsSetup: resolveModule(resolveOwn, 'template/src/setupTests'),
|
||||
proxySetup: resolveOwn('template/src/setupProxy.js'),
|
||||
appSrc: resolveOwn(`${templatePath}/src`),
|
||||
appTsConfig: resolveOwn(`${templatePath}/tsconfig.json`),
|
||||
appJsConfig: resolveOwn(`${templatePath}/jsconfig.json`),
|
||||
yarnLockFile: resolveOwn(`${templatePath}/yarn.lock`),
|
||||
testsSetup: resolveModule(resolveOwn, `${templatePath}/src/setupTests`),
|
||||
proxySetup: resolveOwn(`${templatePath}/src/setupProxy.js`),
|
||||
appNodeModules: resolveOwn('node_modules'),
|
||||
publicUrl: getPublicUrl(resolveOwn('package.json')),
|
||||
servedPath: getServedPath(resolveOwn('package.json')),
|
||||
// These properties only exist before ejecting:
|
||||
ownPath: resolveOwn('.'),
|
||||
ownNodeModules: resolveOwn('node_modules'),
|
||||
appTypeDeclarations: resolveOwn('template/src/react-app-env.d.ts'),
|
||||
appTypeDeclarations: resolveOwn(`${templatePath}/src/react-app-env.d.ts`),
|
||||
ownTypeDeclarations: resolveOwn('lib/react-app.d.ts'),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
REACT_APP_X = x-from-original-env
|
||||
REACT_APP_ORIGINAL_1 = from-original-env-1
|
||||
REACT_APP_ORIGINAL_2 = from-original-env-2
|
||||
REACT_APP_BASIC = basic
|
||||
REACT_APP_BASIC_EXPAND = ${REACT_APP_BASIC}
|
||||
REACT_APP_BASIC_EXPAND_SIMPLE = $REACT_APP_BASIC
|
||||
REACT_APP_EXPAND_EXISTING = $REACT_APP_SHELL_ENV_MESSAGE
|
||||
5
packages/react-scripts/fixtures/kitchensink/package.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "kitchensink",
|
||||
"main": "template.json",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
#feature-svg-in-css {
|
||||
background-image: url("./logo.svg");
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
REACT_APP_X = x-from-original-env
|
||||
REACT_APP_ORIGINAL_1 = from-original-env-1
|
||||
REACT_APP_ORIGINAL_2 = from-original-env-2
|
||||
REACT_APP_BASIC = basic
|
||||
REACT_APP_BASIC_EXPAND = ${REACT_APP_BASIC}
|
||||
REACT_APP_BASIC_EXPAND_SIMPLE = $REACT_APP_BASIC
|
||||
REACT_APP_EXPAND_EXISTING = $REACT_APP_SHELL_ENV_MESSAGE
|
||||
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |