feat(core): support yarn berry in CNW (#11528)
This commit is contained in:
parent
164111b793
commit
36213b71fb
@ -70,7 +70,37 @@ To publish packages to a local registry, do the following:
|
||||
- Run `cd ./tmp` in Terminal 2
|
||||
- Run `npx create-nx-workspace@999.9.9` in Terminal 2
|
||||
|
||||
If you have problems publishing, make sure you use Node 14 and NPM 6 instead of Node 15 and NPM 7.
|
||||
If you have problems publishing, make sure you use Node 16 and NPM 6 or 8.
|
||||
|
||||
### Publishing for Yarn 2+ (Berry)
|
||||
|
||||
Yarn Berry operates slightly differently than Yarn Classic. In order to publish packages for Berry follow next steps:
|
||||
|
||||
- Run `yarn set version berry` to switch to latest Yarn version.
|
||||
- Create `.yarnrc.yml` in root with following contents:
|
||||
```yml
|
||||
nodeLinker: node-modules
|
||||
npmRegistryServer: 'http://localhost:4873'
|
||||
unsafeHttpWhitelist:
|
||||
- localhost
|
||||
```
|
||||
- Run `yarn local-registry start` in Terminal 1 (keep it running)
|
||||
- If you are creating nx workspace outside of your nx repo, make sure to add npm registry info to your root yarnrc (usually in ~/.yarnrc.yml). The file should look something like this:
|
||||
|
||||
```yml
|
||||
npmRegistries:
|
||||
'https://registry.yarnpkg.com':
|
||||
npmAuthToken: npm_******************
|
||||
yarnPath: .yarn/releases/yarn-3.2.2.cjs
|
||||
|
||||
npmRegistryServer: 'http://localhost:4873'
|
||||
unsafeHttpWhitelist:
|
||||
- localhost
|
||||
```
|
||||
|
||||
- Run `yarn nx-release --local` in Terminal 2 to publish next minor version. If this version already exists, you can bump the minor version in `lerna.json` to toggle the next minor. The output will report the version of published packages.
|
||||
- Go to your target folder (e.g. `cd ./tmp`) in Terminal 2
|
||||
- Run `yarn dlx create-nx-workspace@123.4.5` in Terminal 2 (replace `123.4.5` with the version that got published).
|
||||
|
||||
### Running Unit Tests
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ import {
|
||||
getPackageManagerVersion,
|
||||
PackageManager,
|
||||
packageManagerList,
|
||||
generatePackageManagerFiles,
|
||||
} from './package-manager';
|
||||
import { validateNpmPackage } from './validate-npm-package';
|
||||
import { deduceDefaultBase } from './default-base';
|
||||
@ -720,8 +721,9 @@ async function createSandbox(packageManager: PackageManager) {
|
||||
license: 'MIT',
|
||||
})
|
||||
);
|
||||
generatePackageManagerFiles(tmpDir, packageManager);
|
||||
|
||||
await execAndWait(`${install} --silent --ignore-scripts`, tmpDir);
|
||||
await execAndWait(install, tmpDir);
|
||||
|
||||
installSpinner.succeed();
|
||||
} catch (e) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { execSync } from 'child_process';
|
||||
import { existsSync } from 'fs';
|
||||
import { existsSync, writeFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
/*
|
||||
@ -37,21 +37,27 @@ export function getPackageManagerCommand(
|
||||
install: string;
|
||||
exec: string;
|
||||
} {
|
||||
const [pmMajor, pmMinor] =
|
||||
getPackageManagerVersion(packageManager).split('.');
|
||||
|
||||
switch (packageManager) {
|
||||
case 'yarn':
|
||||
const useBerry = +pmMajor >= 2;
|
||||
const installCommand = 'yarn install --silent';
|
||||
return {
|
||||
install: 'yarn',
|
||||
install: useBerry
|
||||
? installCommand
|
||||
: `${installCommand} --ignore-scripts`,
|
||||
exec: 'yarn',
|
||||
};
|
||||
|
||||
case 'pnpm':
|
||||
const [major, minor] = getPackageManagerVersion('pnpm').split('.');
|
||||
let useExec = false;
|
||||
if ((+major >= 6 && +minor >= 13) || +major >= 7) {
|
||||
if ((+pmMajor >= 6 && +pmMinor >= 13) || +pmMajor >= 7) {
|
||||
useExec = true;
|
||||
}
|
||||
return {
|
||||
install: 'pnpm install --no-frozen-lockfile', // explicitly disable in case of CI
|
||||
install: 'pnpm install --no-frozen-lockfile --silent --ignore-scripts',
|
||||
exec: useExec ? 'pnpm exec' : 'pnpx',
|
||||
};
|
||||
|
||||
@ -59,12 +65,29 @@ export function getPackageManagerCommand(
|
||||
process.env.npm_config_legacy_peer_deps =
|
||||
process.env.npm_config_legacy_peer_deps ?? 'true';
|
||||
return {
|
||||
install: 'npm install',
|
||||
install: 'npm install --silent --ignore-scripts',
|
||||
exec: 'npx',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function generatePackageManagerFiles(
|
||||
root: string,
|
||||
packageManager: PackageManager = detectPackageManager()
|
||||
) {
|
||||
const [pmMajor] = getPackageManagerVersion(packageManager).split('.');
|
||||
switch (packageManager) {
|
||||
case 'yarn':
|
||||
if (+pmMajor >= 2) {
|
||||
writeFileSync(
|
||||
join(root, '.yarnrc.yml'),
|
||||
'nodeLinker: node-modules\nenableScripts: false'
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export function getPackageManagerVersion(
|
||||
packageManager: PackageManager
|
||||
): string {
|
||||
|
||||
@ -13,7 +13,17 @@ import { ProjectConverter } from './project-converter';
|
||||
/**
|
||||
* Don't run actual child_process implementation of installPackagesTask()
|
||||
*/
|
||||
jest.mock('child_process');
|
||||
jest.mock('child_process', () => {
|
||||
return {
|
||||
...jest.requireActual<any>('child_process'),
|
||||
execSync: jest.fn((command: string) => {
|
||||
if (command.includes('yarn --version')) {
|
||||
return '1.22.0';
|
||||
}
|
||||
return;
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Don't run the conversion util, it touches the file system and has its own tests
|
||||
|
||||
@ -4,8 +4,8 @@ import { remove } from 'fs-extra';
|
||||
import { dirname, join } from 'path';
|
||||
import { dirSync } from 'tmp';
|
||||
import { promisify } from 'util';
|
||||
import { readJsonFile, writeJsonFile } from './fileutils';
|
||||
import { PackageJson, readModulePackageJson } from './package-json';
|
||||
import { writeJsonFile } from './fileutils';
|
||||
import { readModulePackageJson } from './package-json';
|
||||
import { gte, lt } from 'semver';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
@ -49,16 +49,23 @@ export function getPackageManagerCommand(
|
||||
packageManager: PackageManager = detectPackageManager()
|
||||
): PackageManagerCommands {
|
||||
const commands: { [pm in PackageManager]: () => PackageManagerCommands } = {
|
||||
yarn: () => ({
|
||||
install: 'yarn',
|
||||
ciInstall: 'yarn --frozen-lockfile',
|
||||
add: 'yarn add -W',
|
||||
addDev: 'yarn add -D -W',
|
||||
rm: 'yarn remove',
|
||||
exec: 'yarn',
|
||||
run: (script: string, args: string) => `yarn ${script} ${args}`,
|
||||
list: 'yarn list',
|
||||
}),
|
||||
yarn: () => {
|
||||
const yarnVersion = getPackageManagerVersion('yarn');
|
||||
const useBerry = gte(yarnVersion, '2.0.0');
|
||||
|
||||
return {
|
||||
install: 'yarn',
|
||||
ciInstall: useBerry
|
||||
? 'yarn install --immutable'
|
||||
: 'yarn install --frozen-lockfile',
|
||||
add: useBerry ? 'yarn add' : 'yarn add -W',
|
||||
addDev: useBerry ? 'yarn add -D' : 'yarn add -D -W',
|
||||
rm: 'yarn remove',
|
||||
exec: useBerry ? 'yarn exec' : 'yarn',
|
||||
run: (script: string, args: string) => `yarn ${script} ${args}`,
|
||||
list: useBerry ? 'yarn info --name-only' : 'yarn list',
|
||||
};
|
||||
},
|
||||
pnpm: () => {
|
||||
const pnpmVersion = getPackageManagerVersion('pnpm');
|
||||
const useExec = gte(pnpmVersion, '6.13.0');
|
||||
|
||||
@ -28,7 +28,7 @@ jobs:
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- script: yarn --frozen-lockfile
|
||||
- script: yarn install --frozen-lockfile
|
||||
displayName: NPM Install Dependencies
|
||||
- script: npx nx-cloud start-agent
|
||||
displayName: Start Nx-Cloud agent
|
||||
@ -38,7 +38,7 @@ jobs:
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- script: yarn --frozen-lockfile
|
||||
- script: yarn install --frozen-lockfile
|
||||
displayName: NPM Install Dependencies
|
||||
- script: yarn nx-cloud start-ci-run
|
||||
displayName: Start CI run
|
||||
@ -75,7 +75,7 @@ jobs:
|
||||
- checkout
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: yarn --frozen-lockfile
|
||||
command: yarn install --frozen-lockfile
|
||||
- run:
|
||||
name: Start the agent << parameters.ordinal >>
|
||||
command: yarn nx-cloud start-agent
|
||||
@ -89,7 +89,7 @@ jobs:
|
||||
- checkout
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: yarn --frozen-lockfile
|
||||
command: yarn install --frozen-lockfile
|
||||
- nx/set-shas:
|
||||
main-branch-name: 'main'
|
||||
- run:
|
||||
|
||||
@ -6,6 +6,8 @@ import {
|
||||
names,
|
||||
writeJson,
|
||||
formatFiles,
|
||||
getPackageManagerVersion,
|
||||
PackageManager,
|
||||
} from '@nrwl/devkit';
|
||||
import { Schema } from './schema';
|
||||
import {
|
||||
@ -94,6 +96,14 @@ function createNpmrc(host: Tree, options: Schema) {
|
||||
);
|
||||
}
|
||||
|
||||
// ensure that yarn (berry) install uses classic node linker
|
||||
function createYarnrcYml(host: Tree, options: Schema) {
|
||||
host.write(
|
||||
join(options.directory, '.yarnrc.yml'),
|
||||
'nodeLinker: node-modules\n'
|
||||
);
|
||||
}
|
||||
|
||||
function formatWorkspaceJson(host: Tree, options: Schema) {
|
||||
const path = join(
|
||||
options.directory,
|
||||
@ -151,8 +161,13 @@ export async function workspaceGenerator(host: Tree, options: Schema) {
|
||||
if (options.cli === 'angular') {
|
||||
decorateAngularClI(host, options);
|
||||
}
|
||||
if (options.packageManager === 'pnpm') {
|
||||
const [packageMajor] = getPackageManagerVersion(
|
||||
options.packageManager as PackageManager
|
||||
).split('.');
|
||||
if (options.packageManager === 'pnpm' && +packageMajor >= 7) {
|
||||
createNpmrc(host, options);
|
||||
} else if (options.packageManager === 'yarn' && +packageMajor >= 2) {
|
||||
createYarnrcYml(host, options);
|
||||
}
|
||||
setPresetProperty(host, options);
|
||||
addNpmScripts(host, options);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user