Compare commits

...

9 Commits

Author SHA1 Message Date
Jason Jean 097c1ca05f chore(misc): publish 16.3.2 2023-06-02 17:02:07 -04:00
Nicholas Cunningham c24a1c6884 fix(node): When serving using js:node executor NODE_ENV should not be undefined (#17375)
(cherry picked from commit 8f771e023b)
2023-06-02 14:13:07 -04:00
Katerina Skroumpelou 62fb38386f fix(storybook): re-enable x-prompt and remove custom handling (#17360)
(cherry picked from commit 6d147b61c4)
2023-06-02 13:05:04 -04:00
James Henry a9b9cd338d fix(core): do not ship source maps with nx packages (#17389)
(cherry picked from commit 8a7f79f036)
2023-06-02 13:05:00 -04:00
Colum Ferry 7159a03519 fix(angular): dynamic host should not generate webpack.prod.config.js (#17385)
(cherry picked from commit a775325b22)
2023-06-02 13:04:55 -04:00
Craigory Coppola 940a8d7479 fix(core): reorganize global installation check for better clarity (#17373)
(cherry picked from commit 6c843532aa)
2023-06-02 13:04:46 -04:00
Jason Jean eb77820ce4 chore(react): disable failing nx init cra e2e test (#17379)
(cherry picked from commit 28bca77f47)
2023-06-02 13:04:37 -04:00
Leosvel Pérez Espinosa a285367bf0 fix(angular): do not overwrite ng-packagr version if already installed (#17353)
(cherry picked from commit cd0b76d950)
2023-06-01 11:41:37 -04:00
Leosvel Pérez Espinosa 80d1018d3f fix(js): do not overwrite supported typescript version (#17350)
(cherry picked from commit c68b4bfb47)
2023-06-01 11:41:35 -04:00
22 changed files with 189 additions and 79 deletions
@@ -89,6 +89,7 @@
"@storybook/web-components-vite"
],
"aliases": ["storybook7UiFramework"],
"x-prompt": "Choose the Storybook framework that you need to use.",
"x-priority": "important",
"hidden": false
},
+15 -4
View File
@@ -108,17 +108,28 @@ describe('Node Applications', () => {
`apps/${nodeapp}/src/additional-main.ts`,
`console.log('Hello Additional World!');`
);
updateFile(`apps/${nodeapp}/src/main.ts`, `console.log('Hello World!');`);
updateFile(
`apps/${nodeapp}/src/main.ts`,
`console.log('Hello World!');
console.log('env: ' + process.env['NODE_ENV']);
`
);
await runCLIAsync(`build ${nodeapp}`);
checkFilesExist(
`dist/apps/${nodeapp}/main.js`,
`dist/apps/${nodeapp}/additional-main.js`
);
const result = execSync(`node dist/apps/${nodeapp}/main.js`, {
cwd: tmpProjPath(),
}).toString();
const result = execSync(
`NODE_ENV=development && node dist/apps/${nodeapp}/main.js`,
{
cwd: tmpProjPath(),
}
).toString();
expect(result).toContain('Hello World!');
expect(result).toContain('env: development');
const additionalResult = execSync(
`node dist/apps/${nodeapp}/additional-main.js`,
+2 -1
View File
@@ -24,7 +24,8 @@ const pmc = getPackageManagerCommand({
});
describe('nx init (for React)', () => {
it('should convert to an integrated workspace with craco (webpack)', () => {
// TODO(@jaysoo): Please investigate why this test is failing
xit('should convert to an integrated workspace with craco (webpack)', () => {
const appName = 'my-app';
createReactApp(appName);
+1 -1
View File
@@ -1,6 +1,6 @@
{
"packages": ["build/packages/*", "build/packages/nx/native-packages/*"],
"version": "16.3.1",
"version": "16.3.2",
"granularPathspec": false,
"command": {
"publish": {
@@ -1,10 +1,8 @@
import {
addDependenciesToPackageJson,
formatFiles,
GeneratorCallback,
installPackagesTask,
joinPathFragments,
removeDependenciesFromPackageJson,
Tree,
} from '@nx/devkit';
import { jestProjectGenerator } from '@nx/jest';
@@ -16,6 +14,7 @@ import { E2eTestRunner } from '../../utils/test-runners';
import addLintingGenerator from '../add-linting/add-linting';
import setupTailwindGenerator from '../setup-tailwind/setup-tailwind';
import {
addDependenciesToPackageJsonIfDontExist,
getInstalledAngularVersionInfo,
versions,
} from '../utils/version-utils';
@@ -97,8 +96,7 @@ export async function libraryGenerator(
}
if (libraryOptions.buildable || libraryOptions.publishable) {
removeDependenciesFromPackageJson(tree, [], ['ng-packagr']);
addDependenciesToPackageJson(
addDependenciesToPackageJsonIfDontExist(
tree,
{},
{
@@ -1,5 +1,9 @@
import type { Tree } from '@nx/devkit';
import { joinPathFragments, readProjectConfiguration } from '@nx/devkit';
import {
joinPathFragments,
readProjectConfiguration,
updateProjectConfiguration,
} from '@nx/devkit';
import type { Schema } from '../schema';
export function setupHostIfDynamic(tree: Tree, options: Schema) {
@@ -7,12 +11,25 @@ export function setupHostIfDynamic(tree: Tree, options: Schema) {
return;
}
const project = readProjectConfiguration(tree, options.appName);
const pathToMFManifest = joinPathFragments(
readProjectConfiguration(tree, options.appName).sourceRoot,
project.sourceRoot,
'assets/module-federation.manifest.json'
);
if (!tree.exists(pathToMFManifest)) {
tree.write(pathToMFManifest, '{}');
}
const pathToProdWebpackConfig = joinPathFragments(
project.root,
'webpack.prod.config.js'
);
if (tree.exists(pathToProdWebpackConfig)) {
tree.delete(pathToProdWebpackConfig);
}
delete project.targets.build.configurations.production?.customWebpackConfig;
updateProjectConfiguration(tree, options.appName, project);
}
@@ -135,6 +135,20 @@ describe('Init MF', () => {
}
);
it('should not generate a webpack prod file for dynamic host', async () => {
// ACT
await setupMf(tree, {
appName: 'app1',
mfType: 'host',
federationType: 'dynamic',
});
// ASSERT
const { build } = readProjectConfiguration(tree, 'app1').targets;
expect(tree.exists('apps/app1/webpack.prod.config.js')).toBeFalsy();
expect(build.configurations.production.customWebpackConfig).toBeUndefined();
});
it('should generate the remote entry module and component correctly', async () => {
// ACT
await setupMf(tree, {
@@ -36,11 +36,6 @@ export async function setupMf(tree: Tree, rawOptions: Schema) {
const options = normalizeOptions(tree, rawOptions);
const projectConfig = readProjectConfiguration(tree, options.appName);
if (options.mfType === 'host') {
setupHostIfDynamic(tree, options);
updateHostAppRoutes(tree, options);
}
let installTask = () => {};
if (options.mfType === 'remote') {
addRemoteToHost(tree, options);
@@ -63,6 +58,11 @@ export async function setupMf(tree: Tree, rawOptions: Schema) {
fixBootstrap(tree, projectConfig.root, options);
if (options.mfType === 'host') {
setupHostIfDynamic(tree, options);
updateHostAppRoutes(tree, options);
}
if (!options.skipE2E) {
addCypressOnErrorWorkaround(tree, options);
}
@@ -41,7 +41,7 @@ export async function* esbuildExecutor(
_options: EsBuildExecutorOptions,
context: ExecutorContext
) {
process.env.NODE_ENV ??= context.configurationName;
process.env.NODE_ENV ??= context.configurationName ?? 'production';
const options = normalizeOptions(_options, context);
if (options.deleteOutputPath) removeSync(options.outputPath);
+1
View File
@@ -49,6 +49,7 @@
"ignore": "^5.0.4",
"js-tokens": "^4.0.0",
"minimatch": "3.0.5",
"semver": "7.3.4",
"source-map-support": "0.5.19",
"tslib": "^2.3.0",
"@nx/devkit": "file:../devkit",
@@ -36,6 +36,7 @@ export async function* nodeExecutor(
options: NodeExecutorOptions,
context: ExecutorContext
) {
process.env.NODE_ENV ??= context?.configurationName ?? 'development';
const project = context.projectGraph.nodes[context.projectName];
const buildTarget = parseTargetString(
options.buildTarget,
+36 -1
View File
@@ -1,6 +1,7 @@
import { writeJson, readJson, Tree } from '@nx/devkit';
import { writeJson, readJson, Tree, updateJson } from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import init from './init';
import { typescriptVersion } from '../../utils/versions';
describe('js init generator', () => {
let tree: Tree;
@@ -81,4 +82,38 @@ describe('js init generator', () => {
expect(tree.exists('.vscode/extensions.json')).toBeFalsy();
});
it('should install typescript package when it is not already installed', async () => {
await init(tree, {});
const packageJson = readJson(tree, 'package.json');
expect(packageJson.devDependencies['typescript']).toBeDefined();
});
it('should overwrite installed typescript version when is not a supported version', async () => {
updateJson(tree, 'package.json', (json) => {
json.devDependencies = { ...json.devDependencies, typescript: '~4.5.0' };
return json;
});
await init(tree, {});
const packageJson = readJson(tree, 'package.json');
expect(packageJson.devDependencies['typescript']).toBe(typescriptVersion);
});
it('should not overwrite installed typescript version when is a supported version', async () => {
updateJson(tree, 'package.json', (json) => {
json.devDependencies = { ...json.devDependencies, typescript: '~4.7.0' };
return json;
});
await init(tree, {});
const packageJson = readJson(tree, 'package.json');
expect(packageJson.devDependencies['typescript']).toBe('~4.7.0');
expect(packageJson.devDependencies['typescript']).not.toBe(
typescriptVersion
);
});
});
+49 -1
View File
@@ -6,19 +6,58 @@ import {
generateFiles,
GeneratorCallback,
joinPathFragments,
readJson,
stripIndents,
Tree,
updateJson,
writeJson,
} from '@nx/devkit';
import { checkAndCleanWithSemver } from '@nx/devkit/src/utils/semver';
import { readModulePackageJson } from 'nx/src/utils/package-json';
import { satisfies, valid } from 'semver';
import { getRootTsConfigFileName } from '../../utils/typescript/ts-config';
import {
nxVersion,
prettierVersion,
supportedTypescriptVersions,
typescriptVersion,
} from '../../utils/versions';
import { InitSchema } from './schema';
async function getInstalledTypescriptVersion(
tree: Tree
): Promise<string | null> {
const rootPackageJson = readJson(tree, 'package.json');
const tsVersionInRootPackageJson =
rootPackageJson.devDependencies?.['typescript'] ??
rootPackageJson.dependencies?.['typescript'];
if (!tsVersionInRootPackageJson) {
return null;
}
if (valid(tsVersionInRootPackageJson)) {
// it's a pinned version, return it
return tsVersionInRootPackageJson;
}
// it's a version range, check whether the installed version matches it
try {
const tsPackageJson = readModulePackageJson('typescript').packageJson;
const installedTsVersion =
tsPackageJson.devDependencies?.['typescript'] ??
tsPackageJson.dependencies?.['typescript'];
// the installed version matches the package.json version range
if (
installedTsVersion &&
satisfies(installedTsVersion, tsVersionInRootPackageJson)
) {
return installedTsVersion;
}
} finally {
return checkAndCleanWithSemver('typescript', tsVersionInRootPackageJson);
}
}
export async function initGenerator(
tree: Tree,
schema: InitSchema
@@ -36,7 +75,16 @@ export async function initGenerator(
};
if (!schema.js) {
devDependencies['typescript'] = typescriptVersion;
const installedTsVersion = await getInstalledTypescriptVersion(tree);
if (
!installedTsVersion ||
!satisfies(installedTsVersion, supportedTypescriptVersions, {
includePrerelease: true,
})
) {
devDependencies['typescript'] = typescriptVersion;
}
}
// https://prettier.io/docs/en/configuration.html
+9 -1
View File
@@ -8,5 +8,13 @@ export const swcHelpersVersion = '~0.5.0';
export const swcNodeVersion = '~1.4.2';
export const tsLibVersion = '^2.3.0';
export const typesNodeVersion = '18.7.1';
export const typescriptVersion = '~5.0.2';
export const verdaccioVersion = '^5.0.4';
// Typescript
export const typescriptVersion = '~5.0.2';
/**
* The minimum version is currently determined from the lowest version
* that's supported by the lowest Angular supported version, e.g.
* `npm view @angular/compiler-cli@14.0.0 peerDependencies.typescript`
*/
export const supportedTypescriptVersions = '>=4.6.2';
+32 -8
View File
@@ -56,7 +56,7 @@ function main() {
}
if (!workspace) {
handleNoWorkspace();
handleNoWorkspace(GLOBAL_NX_VERSION);
}
if (!localNx) {
@@ -79,7 +79,7 @@ function main() {
}
}
function handleNoWorkspace() {
function handleNoWorkspace(globalNxVersion?: string) {
output.log({
title: `The current directory isn't part of an Nx workspace.`,
bodyLines: [
@@ -94,6 +94,9 @@ function handleNoWorkspace() {
output.note({
title: `For more information please visit https://nx.dev/`,
});
warnIfUsingOutdatedGlobalInstall(globalNxVersion);
process.exit(1);
}
@@ -169,12 +172,10 @@ function warnIfUsingOutdatedGlobalInstall(
return;
}
const isOutdatedGlobalInstall =
globalNxVersion &&
((localNxVersion && major(globalNxVersion) < major(localNxVersion)) ||
(!localNxVersion &&
getLatestVersionOfNx() &&
major(globalNxVersion) < major(getLatestVersionOfNx())));
const isOutdatedGlobalInstall = checkOutdatedGlobalInstallation(
globalNxVersion,
localNxVersion
);
// Using a global Nx Install
if (isOutdatedGlobalInstall) {
@@ -194,6 +195,29 @@ function warnIfUsingOutdatedGlobalInstall(
}
}
function checkOutdatedGlobalInstallation(
globalNxVersion?: string,
localNxVersion?: string
) {
// We aren't running a global install, so we can't know if its outdated.
if (!globalNxVersion) {
return false;
}
if (localNxVersion) {
// If the global Nx install is at least a major version behind the local install, warn.
return major(globalNxVersion) < major(localNxVersion);
}
// No local installation was detected. This can happen if the user is running a global install
// that contains an older version of Nx, which is unable to detect the local installation. The most
// recent case where this would have happened would be when we stopped generating workspace.json by default,
// as older global installations used it to determine the workspace root. This only be hit in rare cases,
// but can provide valuable insights for troubleshooting.
const latestVersionOfNx = getLatestVersionOfNx();
if (latestVersionOfNx && major(globalNxVersion) < major(latestVersionOfNx)) {
return true;
}
}
function getLocalNxVersion(workspace: WorkspaceTypeAndRoot): string | null {
try {
const { packageJson } = readModulePackageJson(
-1
View File
@@ -31,7 +31,6 @@
},
"dependencies": {
"dotenv": "~10.0.0",
"enquirer": "~2.3.6",
"@phenomnomnominal/tsquery": "~5.0.1",
"semver": "7.3.4",
"@nx/cypress": "file:../cypress",
@@ -6,7 +6,6 @@ import {
writeJson,
} from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import * as enquirer from 'enquirer';
import configurationGenerator from './configuration';
import * as workspaceConfiguration from './test-configs/root-workspace-configuration.json';
@@ -19,9 +18,6 @@ jest.mock('nx/src/project-graph/project-graph', () => ({
.mockImplementation(async () => ({ nodes: {}, dependencies: {} })),
}));
jest.mock('enquirer');
// @ts-ignore
enquirer.prompt = jest.fn();
describe('@nx/storybook:configuration for workspaces with Root project', () => {
beforeAll(() => {
process.env.NX_INTERACTIVE = 'true';
@@ -32,10 +28,6 @@ describe('@nx/storybook:configuration for workspaces with Root project', () => {
});
describe('basic functionalities', () => {
let tree: Tree;
// @ts-ignore
enquirer.prompt = jest
.fn()
.mockReturnValue(Promise.resolve({ bundler: 'webpack' }));
beforeEach(async () => {
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
updateJson<NxJsonConfiguration>(tree, 'nx.json', (json) => {
@@ -10,7 +10,6 @@ import {
writeJson,
} from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import * as enquirer from 'enquirer';
import { Linter } from '@nx/linter';
import { libraryGenerator } from '@nx/js';
@@ -26,9 +25,6 @@ jest.mock('nx/src/project-graph/project-graph', () => ({
.fn()
.mockImplementation(async () => ({ nodes: {}, dependencies: {} })),
}));
jest.mock('enquirer');
// @ts-ignore
enquirer.prompt = jest.fn();
describe('@nx/storybook:configuration for Storybook v7', () => {
describe('basic functionalities', () => {
@@ -39,7 +39,6 @@ import {
storybookVersion,
tsNodeVersion,
} from '../../utils/versions';
import { getGeneratorConfigurationOptions } from './lib/user-prompts';
export async function configurationGenerator(
tree: Tree,
@@ -49,10 +48,6 @@ export async function configurationGenerator(
throw new Error(pleaseUpgrade());
}
if (process.env.NX_INTERACTIVE === 'true') {
rawSchema = await getGeneratorConfigurationOptions(rawSchema);
}
const schema = normalizeSchema(rawSchema);
const tasks: GeneratorCallback[] = [];
@@ -1,31 +0,0 @@
import { UiFramework7 } from '../../../utils/models';
import { Constants } from '../../../utils/utilities';
import { prompt } from 'enquirer';
import { StorybookConfigureSchema } from '../schema';
export async function getGeneratorConfigurationOptions(
rawSchema: StorybookConfigureSchema
): Promise<StorybookConfigureSchema> {
if (!rawSchema.uiFramework) {
rawSchema.uiFramework = await getStorybook7Framework();
}
return rawSchema;
}
export async function getStorybook7Framework(): Promise<UiFramework7> {
const a = await prompt<{ UiFramework: UiFramework7 }>([
{
name: 'UiFramework',
message: `Choose the Storybook 7 framework that you need to use`,
type: 'autocomplete',
choices: [
...Constants.uiFrameworks7.map((uiFramework) => ({
name: uiFramework,
message: uiFramework,
})),
],
},
]);
return a.UiFramework;
}
@@ -89,6 +89,7 @@
"@storybook/web-components-vite"
],
"aliases": ["storybook7UiFramework"],
"x-prompt": "Choose the Storybook framework that you need to use.",
"x-priority": "important",
"hidden": false
},
-1
View File
@@ -1,7 +1,6 @@
{
"compilerOptions": {
"target": "es2015",
"sourceMap": true,
"importHelpers": true,
"module": "commonjs",
"moduleResolution": "node",