Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use env var to detect yarn or npm as the package manager #11322

Merged
merged 5 commits into from
Sep 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ jobs:
# ******************************************************************************
# Installs test suite
# ******************************************************************************
# - template: azure-pipelines-test-job.yml
# parameters:
# name: Installs
# testScript: tasks/e2e-installs.sh
- template: azure-pipelines-test-job.yml
parameters:
name: Installs
testScript: tasks/e2e-installs.sh

# ******************************************************************************
# Kitchensink test suite
Expand Down
7 changes: 5 additions & 2 deletions docusaurus/docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,13 @@ If you already have a project and would like to add TypeScript, see our [Adding

### 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 [npm](https://docs.npmjs.com) or [Yarn](https://yarnpkg.com/) to install dependencies, depending on which tool you use to run `create-react-app`. For example:

```sh
npx create-react-app my-app --use-npm
# Run this to use npm
npx create-react-app my-app
# Or run this to use yarn
yarn create react-app my-app
```

## Output
Expand Down
20 changes: 7 additions & 13 deletions packages/create-react-app/createReactApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ const validateProjectName = require('validate-npm-package-name');

const packageJson = require('./package.json');

function isUsingYarn() {
return (process.env.npm_config_user_agent || '').indexOf('yarn') === 0;
}

let projectName;

function init() {
Expand All @@ -69,7 +73,6 @@ function init() {
'--template <path-to-template>',
'specify a template for the created project'
)
.option('--use-npm')
.option('--use-pnp')
.allowUnknownOption()
.on('--help', () => {
Expand Down Expand Up @@ -223,19 +226,20 @@ function init() {
console.log();
process.exit(1);
} else {
const useYarn = isUsingYarn();
createApp(
projectName,
program.verbose,
program.scriptsVersion,
program.template,
program.useNpm,
useYarn,
program.usePnp
);
}
});
}

function createApp(name, verbose, version, template, useNpm, usePnp) {
function createApp(name, verbose, version, template, useYarn, usePnp) {
const unsupportedNodeVersion = !semver.satisfies(
// Coerce strings with metadata (i.e. `15.0.0-nightly`).
semver.coerce(process.version),
Expand Down Expand Up @@ -276,7 +280,6 @@ function createApp(name, verbose, version, template, useNpm, usePnp) {
JSON.stringify(packageJson, null, 2) + os.EOL
);

const useYarn = useNpm ? false : shouldUseYarn();
const originalDirectory = process.cwd();
process.chdir(root);
if (!useYarn && !checkThatNpmCanReadCwd()) {
Expand Down Expand Up @@ -351,15 +354,6 @@ function createApp(name, verbose, version, template, useNpm, usePnp) {
);
}

function shouldUseYarn() {
try {
execSync('yarnpkg --version', { stdio: 'ignore' });
return true;
} catch (e) {
return false;
}
}

function install(root, useYarn, usePnp, dependencies, verbose, isOnline) {
return new Promise((resolve, reject) => {
let command;
Expand Down
26 changes: 12 additions & 14 deletions tasks/e2e-installs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,11 @@ cd "$temp_app_path"
npx create-react-app test-app-dist-tag --scripts-version=@latest
cd test-app-dist-tag

# Check corresponding scripts version is installed and no TypeScript is present.
# Check corresponding scripts version is installed and no TypeScript or yarn is present by default
exists node_modules/react-scripts
! exists node_modules/typescript
! exists src/index.tsx
! exists yarn.lock
exists src/index.js
checkDependencies

Expand All @@ -133,16 +134,16 @@ grep '"version": "1.0.17"' node_modules/react-scripts/package.json
checkDependencies

# ******************************************************************************
# Test --use-npm flag
# Test yarn create
# ******************************************************************************

cd "$temp_app_path"
npx create-react-app test-use-npm-flag --use-npm --scripts-version=1.0.17
cd test-use-npm-flag
yarn create react-app test-use-yarn-create --scripts-version=1.0.17
cd test-use-yarn-create

# Check corresponding scripts version is installed.
exists node_modules/react-scripts
[ ! -e "yarn.lock" ] && echo "yarn.lock correctly does not exist"
exists yarn.lock
grep '"version": "1.0.17"' node_modules/react-scripts/package.json
checkDependencies

Expand Down Expand Up @@ -172,10 +173,6 @@ CI=true npm test
# Eject...
echo yes | npm run eject

# Temporary workaround for https://github.com/facebook/create-react-app/issues/6099
rm yarn.lock
yarn add @babel/plugin-transform-react-jsx-source @babel/plugin-syntax-jsx @babel/plugin-transform-react-jsx @babel/plugin-transform-react-jsx-self

# Ensure env file still exists
exists src/react-app-env.d.ts

Expand Down Expand Up @@ -230,8 +227,8 @@ echo '## Hello' > ./test-app-should-remain/README.md
npx create-react-app test-app-should-remain --scripts-version=`date +%s` || true
# confirm the file exist
test -e test-app-should-remain/README.md
# confirm only README.md and error log are the only files in the directory
if [ "$(ls -1 ./test-app-should-remain | wc -l | tr -d '[:space:]')" != "2" ]; then
# confirm only README.md is the only file in the directory
if [ "$(ls -1 ./test-app-should-remain | wc -l | tr -d '[:space:]')" != "1" ]; then
false
fi

Expand Down Expand Up @@ -277,12 +274,13 @@ npm start -- --smoke-test
# Test when PnP is enabled
# ******************************************************************************
cd "$temp_app_path"
npx create-react-app test-app-pnp --use-pnp
yarn create react-app test-app-pnp --use-pnp
cd test-app-pnp
! exists node_modules
exists .pnp.js
npm start -- --smoke-test
npm run build
# TODO: start and build tasks error with --use-pnp
# npm start -- --smoke-test
# npm run build

# Cleanup
cleanup
4 changes: 0 additions & 4 deletions tasks/e2e-kitchensink-eject.sh
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,6 @@ export BROWSERSLIST='ie 9'
# Eject...
echo yes | npm run eject

# Temporary workaround for https://github.com/facebook/create-react-app/issues/6099
rm yarn.lock
yarn add @babel/plugin-transform-react-jsx-source @babel/plugin-syntax-jsx @babel/plugin-transform-react-jsx @babel/plugin-transform-react-jsx-self

# Test the build
REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \
NODE_PATH=src \
Expand Down
4 changes: 0 additions & 4 deletions tasks/e2e-simple.sh
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,6 @@ verify_module_scope
# Eject...
echo yes | npm run eject

# Temporary workaround for https://github.com/facebook/create-react-app/issues/6099
rm yarn.lock
yarn add @babel/plugin-transform-react-jsx-source @babel/plugin-syntax-jsx @babel/plugin-transform-react-jsx @babel/plugin-transform-react-jsx-self

# Test ejected files were staged
test -n "$(git diff --staged --name-only)"

Expand Down
32 changes: 20 additions & 12 deletions test/integration/create-react-app/index.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

const execa = require('execa');
const { mkdirp, remove, writeFileSync } = require('fs-extra');
const { mkdirp, remove, writeFileSync, existsSync } = require('fs-extra');
const { join } = require('path');

const cli = require.resolve('create-react-app/index.js');
Expand All @@ -11,13 +11,20 @@ jest.setTimeout(1000 * 60 * 5);
const projectName = 'test-app';
const genPath = join(__dirname, projectName);

const generatedFiles = ['.gitignore', 'package.json', 'src', 'yarn.lock'];
const generatedFiles = [
'.gitignore',
'package.json',
'src',
'package-lock.json',
];

beforeEach(() => remove(genPath));
afterAll(() => remove(genPath));

const run = (args, options) => execa('node', [cli].concat(args), options);

const genFileExists = f => existsSync(join(genPath, f));

describe('create-react-app', () => {
it('asks to supply an argument if none supplied', async () => {
const { stderr } = await run([], { reject: false });
Expand All @@ -28,7 +35,7 @@ describe('create-react-app', () => {
await run([projectName], { cwd: __dirname });

// Assert for the generated files
generatedFiles.forEach(file => expect(join(genPath, file)).toBeTruthy());
generatedFiles.forEach(file => expect(genFileExists(file)).toBeTruthy());
});

it('warns about conflicting files in path', async () => {
Expand Down Expand Up @@ -58,22 +65,23 @@ describe('create-react-app', () => {
await run(['.'], { cwd: genPath });

// Assert for the generated files
generatedFiles.forEach(file => expect(join(genPath, file)).toBeTruthy());
generatedFiles.forEach(file => expect(genFileExists(file)).toBeTruthy());
});

it('uses npm as the package manager', async () => {
await run([projectName, '--use-npm'], {
it('uses yarn as the package manager', async () => {
await run([projectName], {
cwd: __dirname,
env: { npm_config_user_agent: 'yarn' },
});

// Assert for the generated files
const generatedFilesWithNpm = [
...generatedFiles.filter(file => file !== 'yarn.lock'),
'package-lock.json',
const generatedFilesWithYarn = [
...generatedFiles.filter(file => file !== 'package-lock.json'),
'yarn.lock',
];

generatedFilesWithNpm.forEach(file =>
expect(join(genPath, file)).toBeTruthy()
generatedFilesWithYarn.forEach(file =>
expect(genFileExists(file)).toBeTruthy()
);
});

Expand All @@ -84,7 +92,7 @@ describe('create-react-app', () => {

// Assert for the generated files
[...generatedFiles, 'tsconfig.json'].forEach(file =>
expect(join(genPath, file)).toBeTruthy()
expect(genFileExists(file)).toBeTruthy()
);
});
});