Compare commits

...

36 Commits

Author SHA1 Message Date
Jason Jean 81236abffd Release 13.9.5 2022-03-25 17:23:02 -04:00
Victor Savkin 63cd369df2 fix(core): fix a perf regression in the lint executor 2022-03-25 15:39:16 -04:00
Chau Tran ba2dfc48c2 fix(node): update node migrations to use forEachExecutorOptions (#9471)
Co-authored-by: Chau Tran <ctran@Chaus-MacBook-Pro.local>
2022-03-25 15:38:28 -04:00
Miroslav Jonaš 2f3d80e7c2 fix(core): add missing CNW flags in help report (#9479) 2022-03-25 15:37:46 -04:00
Craigory Coppola a4664552cb fix(js): pin fast-glob to 3.2.7 due to regression in 3.2.8 (#9484) 2022-03-25 15:37:24 -04:00
Craigory Coppola 8fbbe3b45a fix(js): improve inconsistencies with assets in tsc and swc from previous implementation (#9470) 2022-03-25 15:36:21 -04:00
Miroslav Jonaš f5e40edb83 fix(core): fix missing versions from nx report (#9450) 2022-03-25 15:36:05 -04:00
Miroslav Jonaš df5db9d53f fix(web): ensure file server works on windows (#9449) 2022-03-25 15:35:53 -04:00
Chau Tran 1e978f42b0 fix(js): add swc/helpers to js packages on converting to swc (#9467)
* fix(js): add swc/helpers to js packages on converting to swc

* chore(js): update convert to swc unit test

* chore(js): format

Co-authored-by: Chau Tran <ctran@Chaus-MacBook-Pro.local>
2022-03-25 15:35:44 -04:00
Nicholas Cunningham 01f7e0057e fix(react): fix conflicting NODE_ENV values between an application and webpack Plugins (DefinePlugin) (#9460)
ISSUES CLOSED: #7924

Co-authored-by: Nicholas Cunningham <ndcunningham>
2022-03-25 15:35:13 -04:00
Jason Jean f18163a7dc Release 13.9.4 2022-03-21 20:52:39 -04:00
Chau Tran d77834086f fix(js): mimic the behavior of tsc compilation for runTypeCheck (#9240)
* fix(js): mimic the behavior of tsc compilation for runTypeCheck

ISSUES CLOSED: #9203

* chore(js): add check for type defs files in e2e

Co-authored-by: Chau Tran <ctran@Chaus-MacBook-Pro.local>
2022-03-21 18:51:37 -04:00
Craigory Coppola ddb10e1320 fix(js): return success false if tsc compilation fails (#9438) 2022-03-21 18:51:32 -04:00
Giora Guttsait 3940027adf fix(nx-plugin): use importPath as package.json name when passed (#9430) 2022-03-21 18:51:26 -04:00
Giora Guttsait 263e19f5a0 fix(nx-plugin): remove broken reference to e2e tsconfig (#9409) 2022-03-21 18:51:15 -04:00
Miroslav Jonaš d614434e1a fix(angular): change mfe schema port type to number (#9420) 2022-03-21 18:51:04 -04:00
Craigory Coppola b380597a02 fix(core): projects inferrred in apps directory should be inferred as an application (#9379)
* fix(core): projects inferrred in apps directory should be inferred as an application

* chore(repo): add jest setup back for `nx`
2022-03-21 18:50:52 -04:00
Craigory Coppola d7172f5d3f fix(core): ngcli-adapter should work on windows without workspace.json present (#9163) 2022-03-21 18:50:46 -04:00
hellivan f24af57e6d fix(node): npm modules are not resolved correctly (#9284)
The current implementation of the node executor resolves all npm
modules that are referenced by the application from the root
node_modules folder. This behavior leads to runtime errors if any of
the project dependencies requires a different version of a package
than the project itself.

For example, if we have a project that depends on `express` in version
`4.17.3` (which on the other hand depends on `path-to-regexp` version
`0.1.7`) as well as on `path-to-regexp` in version `6.2.0`. In such
case `express` will throw a runtime error since it would load
`path-to-regexp` version `6.2.0` which is not API compatible.

For this reason, this commit changes the behavior of the node-executor
so that it completely ignores npm dependencies when calculating
resolve mappings.
2022-03-21 18:50:38 -04:00
Matthias Stemmler 5a4b8e35ee fix(web): fix handling of buildLibsFromSource: false in dev-server executor (#9326)
* modify buildOptions.tsConfig before creating Webpack config
* do not join buildOptions.tsConfig to root path as it is already an absolute path
2022-03-21 18:50:26 -04:00
Sorin Davidoi 78d27f5dc8 fix(core): don't allow arbitrary code execution when manipulating cache (#9329)
The Node documentation for `exec` states:

> Never pass unsanitized user input to this function. Any input containing shell metacharacters may be used to trigger arbitrary command execution.

The `folder` variable comes directly from the `NX_CACHE_DIRECTORY` environment variable (or from `nx.json`). Careful crafting of this variable can result in NX executing arbitrary commands.

This patch fixes this by using `execFile`, which does not spawn a shell.
2022-03-21 18:50:20 -04:00
Sorin Davidoi b3782c0e92 fix(web): don't allow arbitrary code execution in file-server (#9330)
The Node documentation for `exec` states:

> Never pass unsanitized user input to this function. Any input containing shell metacharacters may be used to trigger arbitrary command execution.

The `outputPath`, `options.buildTarget` and `options.maxParallel` come from `nx.json`. Careful crafting of these fields can result in NX executing arbitrary commands.

This patch fixes this by using `execFile`, which does not spawn a shell.
2022-03-21 18:50:20 -04:00
Craigory Coppola 1ff9cb318f fix(core): targets referred to by targetDependencies should be optional by default (#9344) 2022-03-21 18:50:20 -04:00
Katerina Skroumpelou 67ed0b4673 fix(storybook): when building set node_env (#9390)
ISSUES CLOSED: #8403
2022-03-21 18:48:45 -04:00
Colum Ferry 7b5664b4eb fix(angular): set tsconfig path correctly (#9386) 2022-03-21 18:48:45 -04:00
Emily Xiong ae4036451b bugfix(storybook): should add @storybook/react-native to devDependencies (#9364) 2022-03-21 18:47:55 -04:00
Emily Xiong e43748c7dd bugfix(react-native): add ENTRY_FILE relative to PROJECT_DIR in iOS shell script (#9222) 2022-03-21 18:47:55 -04:00
Miroslav Jonaš 8681d12547 fix(linter): ensure eslint fixes are stored before results are filtered (#9348) 2022-03-21 18:47:55 -04:00
Miroslav Jonaš f172ac6487 fix(linter): check for both nrwl/nx and eslint for terminal runs (#9340) 2022-03-21 18:47:55 -04:00
Jason Jean 0261e1f308 Release 13.9.3 2022-03-18 12:24:18 -04:00
Jason Jean 0e46ee9db2 fix(core): remove @nrwl/cli bin setting (#9394) 2022-03-18 12:18:01 -04:00
Jason Jean eaf868f59a Release 13.9.2 2022-03-16 17:30:44 -04:00
Jason Jean 755917c86f chore(core): fix snapshots 2022-03-16 17:28:41 -04:00
Jason Jean f99e1d33b7 fix(core): undo removal of @nrwl/cli and add warning when it is imported (#9370) 2022-03-16 17:28:41 -04:00
Jason Jean af66f02777 Release 13.9.1 2022-03-16 11:25:15 -04:00
Leosvel Pérez Espinosa 7e7f04ad4c fix(core): fix migrate command to properly handle the packages consolidation (#9352) 2022-03-16 11:22:04 -04:00
58 changed files with 365 additions and 224 deletions
@@ -55,6 +55,6 @@ The name of the host app to attach this host app to.
### port
Type: `string`
Type: `number`
The port on which this app should be served.
@@ -55,6 +55,6 @@ The name of the host app to attach this remote app to.
### port
Type: `string`
Type: `number`
The port on which this app should be served.
+24
View File
@@ -297,4 +297,28 @@ describe('Angular Projects', () => {
expect(err).toBeFalsy();
}
}, 300000);
it('MFE - should build the host app successfully', async () => {
// ARRANGE
const port1 = 4205;
const port2 = 4206;
const hostApp = uniq('app');
const remoteApp1 = uniq('remote');
// generate host app
runCLI(
`generate @nrwl/angular:host ${hostApp} -- --port=${port1} --no-interactive`
);
// generate remote apps
runCLI(
`generate @nrwl/angular:remote ${remoteApp1} -- --host=${hostApp} --port=${port2} --no-interactive`
);
// ACT
const buildOutput = runCLI(`build ${hostApp}`);
// ASSERT
expect(buildOutput).toContain('Successfully ran target build');
}, 300000);
});
+15 -5
View File
@@ -48,7 +48,9 @@ describe('js e2e', () => {
`dist/libs/${lib}/README.md`,
`dist/libs/${lib}/package.json`,
`dist/libs/${lib}/src/index.js`,
`dist/libs/${lib}/src/lib/${lib}.js`
`dist/libs/${lib}/src/lib/${lib}.js`,
`dist/libs/${lib}/src/index.d.ts`,
`dist/libs/${lib}/src/lib/${lib}.d.ts`
);
updateJson(`libs/${lib}/project.json`, (json) => {
@@ -105,7 +107,9 @@ describe('js e2e', () => {
checkFilesExist(
`dist/libs/${parentLib}/package.json`,
`dist/libs/${parentLib}/src/index.js`,
`dist/libs/${parentLib}/src/lib/${parentLib}.js`
`dist/libs/${parentLib}/src/lib/${parentLib}.js`,
`dist/libs/${parentLib}/src/index.d.ts`,
`dist/libs/${parentLib}/src/lib/${parentLib}.d.ts`
);
const tsconfig = readJson(`tsconfig.base.json`);
@@ -117,6 +121,7 @@ describe('js e2e', () => {
updateFile(`libs/${parentLib}/src/index.ts`, () => {
return `
import { ${lib} } from '@${scope}/${lib}'
export * from './lib/${parentLib}';
`;
});
@@ -144,7 +149,9 @@ describe('js e2e', () => {
checkFilesExist(
`dist/libs/${lib}/package.json`,
`dist/libs/${lib}/src/index.js`,
`dist/libs/${lib}/src/lib/${lib}.js`
`dist/libs/${lib}/src/lib/${lib}.js`,
`dist/libs/${lib}/src/index.d.ts`,
`dist/libs/${lib}/src/lib/${lib}.d.ts`
);
const parentLib = uniq('parentlib');
@@ -164,7 +171,9 @@ describe('js e2e', () => {
checkFilesExist(
`dist/libs/${parentLib}/package.json`,
`dist/libs/${parentLib}/src/index.js`,
`dist/libs/${parentLib}/src/lib/${parentLib}.js`
`dist/libs/${parentLib}/src/lib/${parentLib}.js`,
`dist/libs/${parentLib}/src/index.d.ts`,
`dist/libs/${parentLib}/src/lib/${parentLib}.d.ts`
);
const tsconfig = readJson(`tsconfig.base.json`);
@@ -175,7 +184,8 @@ describe('js e2e', () => {
updateFile(`libs/${parentLib}/src/index.ts`, () => {
return `
import { ${lib} } from '@${scope}/${lib}'
import { ${lib} } from '@${scope}/${lib}';
export * from './lib/${parentLib}';
`;
});
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@nrwl/nx-source",
"version": "13.9.0",
"version": "13.9.5",
"description": "Smart, Fast and Extensible Build System",
"homepage": "https://nx.dev",
"private": true,
@@ -275,7 +275,7 @@
"@tailwindcss/typography": "^0.5.0",
"classnames": "^2.3.1",
"core-js": "^3.6.5",
"fast-glob": "^3.2.7",
"fast-glob": "3.2.7",
"framer-motion": "^4.1.17",
"glob": "7.1.4",
"gray-matter": "^4.0.2",
@@ -113,8 +113,8 @@ function run(
result.target.data.root,
dependencies
);
process.env.NX_TSCONFIG_PATH = options.tsConfig;
}
process.env.NX_TSCONFIG_PATH = options.tsConfig;
return of(
!options.buildLibsFromSource
@@ -25,7 +25,7 @@
"description": "The name of the host app to attach this host app to."
},
"port": {
"type": "string",
"type": "number",
"description": "The port on which this app should be served."
}
},
@@ -25,7 +25,7 @@
"description": "The name of the host app to attach this remote app to."
},
"port": {
"type": "string",
"type": "number",
"description": "The port on which this app should be served."
}
},
+7
View File
@@ -1,2 +1,9 @@
#!/usr/bin/env node
import { logger } from 'nx/src/shared/logger';
import { getPackageManagerCommand } from 'nx/src/shared/package-manager';
logger.warn('Please update your global install of Nx');
logger.warn(`- ${getPackageManagerCommand().addGlobal} nx`);
require('nx/bin/nx');
-3
View File
@@ -18,9 +18,6 @@
"Cypress",
"CLI"
],
"bin": {
"nx": "./bin/nx.js"
},
"author": "Victor Savkin",
"license": "MIT",
"bugs": {
@@ -196,11 +196,14 @@ function showHelp() {
cli CLI to power the Nx workspace (options: "nx", "angular")
style Default style option to be used when a non-empty preset is selected
options: ("css", "scss", "less") plus ("styl") for all non-Angular and ("styled-components", "@emotion/styled", "styled-jsx") for React, Next.js
options: ("css", "scss", "less") plus ("styl") for all non-Angular and ("styled-components", "@emotion/styled", "styled-jsx") for React, Next.js
interactive Enable interactive mode when using presets (boolean)
packageManager Package manager to use (npm, yarn, pnpm)
packageManager Package manager to use (alias: "pm")
options: ("npm", "yarn", "pnpm")
defaultBase Name of the main branch (default: "main")
nx-cloud Use Nx Cloud (boolean)
`);
+1 -1
View File
@@ -37,7 +37,7 @@
"@nrwl/linter": "*",
"@parcel/watcher": "2.0.4",
"chalk": "4.1.0",
"fast-glob": "^3.2.7",
"fast-glob": "3.2.7",
"fs-extra": "^9.1.0",
"ignore": "^5.0.4",
"js-tokens": "^4.0.0",
@@ -47,5 +47,8 @@ describe('convert to swc', () => {
)
).toEqual(true);
expect(tree.read('package.json', 'utf-8')).toContain('@swc/core');
expect(tree.read('libs/tsc-lib/package.json', 'utf-8')).toContain(
'@swc/helpers'
);
});
});
@@ -1,4 +1,5 @@
import {
addDependenciesToPackageJson,
convertNxGenerator,
installPackagesTask,
ProjectConfiguration,
@@ -10,6 +11,7 @@ import {
import { join } from 'path';
import { addSwcConfig } from '../../utils/swc/add-swc-config';
import { addSwcDependencies } from '../../utils/swc/add-swc-dependencies';
import { swcHelpersVersion } from '../../utils/versions';
import { ConvertToSwcGeneratorSchema } from './schema';
export async function convertToSwcGenerator(
@@ -25,7 +27,6 @@ export async function convertToSwcGenerator(
options.project,
options.targets
);
return checkSwcDependencies(tree, projectConfiguration);
}
@@ -66,10 +67,20 @@ function checkSwcDependencies(
);
const packageJson = readJson(tree, 'package.json');
const projectPackageJsonPath = join(
projectConfiguration.root,
'package.json'
);
const projectPackageJson = readJson(tree, projectPackageJsonPath);
const hasSwcDependency =
packageJson.dependencies && packageJson.dependencies['@swc/core'];
if (isSwcrcPresent && hasSwcDependency) return;
const hasSwcHelpers =
projectPackageJson.dependencies &&
projectPackageJson.dependencies['@swc/helpers'];
if (isSwcrcPresent && hasSwcDependency && hasSwcHelpers) return;
if (!isSwcrcPresent) {
addSwcConfig(tree, projectConfiguration.root);
@@ -79,6 +90,17 @@ function checkSwcDependencies(
addSwcDependencies(tree);
}
if (!hasSwcHelpers) {
addDependenciesToPackageJson(
tree,
{
'@swc/helpers': swcHelpersVersion,
},
{},
projectPackageJsonPath
);
}
return () => {
if (!hasSwcDependency) {
installPackagesTask(tree);
@@ -42,6 +42,7 @@ describe('AssetInputOutputHandler', () => {
output: 'docs',
ignore: ['ignore.md', '**/nested-ignore.md'],
},
'LICENSE',
],
});
});
@@ -49,6 +50,8 @@ describe('AssetInputOutputHandler', () => {
test('watchAndProcessOnAssetChange', async () => {
const dispose = await sut.watchAndProcessOnAssetChange();
fse.writeFileSync(path.join(rootDir, 'LICENSE'), 'license');
await wait(100);
fse.writeFileSync(path.join(projectDir, 'README.md'), 'readme');
await wait(100); // give watch time to react
fse.writeFileSync(path.join(projectDir, 'docs/test1.md'), 'test');
@@ -72,6 +75,15 @@ describe('AssetInputOutputHandler', () => {
await wait(100);
expect(callback.mock.calls).toEqual([
[
[
{
type: 'create',
src: path.join(rootDir, 'LICENSE'),
dest: path.join(rootDir, 'dist/mylib/LICENSE'),
},
],
],
[
[
{
@@ -130,6 +142,7 @@ describe('AssetInputOutputHandler', () => {
});
test('processAllAssetsOnce', async () => {
fse.writeFileSync(path.join(rootDir, 'LICENSE'), 'license');
fse.writeFileSync(path.join(projectDir, 'README.md'), 'readme');
fse.writeFileSync(path.join(projectDir, 'docs/test1.md'), 'test');
fse.writeFileSync(path.join(projectDir, 'docs/test2.md'), 'test');
@@ -144,6 +157,15 @@ describe('AssetInputOutputHandler', () => {
await sut.processAllAssetsOnce();
expect(callback.mock.calls).toEqual([
[
[
{
type: 'create',
src: path.join(rootDir, 'LICENSE'),
dest: path.join(rootDir, 'dist/mylib/LICENSE'),
},
],
],
[
[
{
+7 -11
View File
@@ -120,14 +120,12 @@ export class CopyAssetsHandler {
!ag.ignore?.some((ig) => minimatch(src, ig)) &&
!this.ignore.ignores(src)
) {
const relPath = path.relative(ag.input, src);
const dest = relPath.startsWith('..') ? src : relPath;
acc.push({
type: 'create',
src: path.join(this.rootDir, src),
dest: path.join(
this.rootDir,
ag.output,
path.relative(ag.input, src)
),
dest: path.join(this.rootDir, ag.output, dest),
});
}
return acc;
@@ -140,7 +138,7 @@ export class CopyAssetsHandler {
async watchAndProcessOnAssetChange(): Promise<() => Promise<void>> {
const watcher = await import('@parcel/watcher');
const subscription = await watcher.subscribe(
this.projectDir,
this.rootDir,
(err, events) => {
if (err) {
logger.error(`Watch error: ${err?.message ?? 'Unknown'}`);
@@ -163,14 +161,12 @@ export class CopyAssetsHandler {
!ag.ignore?.some((ig) => minimatch(pathFromRoot, ig)) &&
!this.ignore.ignores(pathFromRoot)
) {
const relPath = path.relative(ag.input, pathFromRoot);
const destPath = relPath.startsWith('..') ? pathFromRoot : relPath;
fileEvents.push({
type: event.type,
src: path.join(this.rootDir, pathFromRoot),
dest: path.join(
this.rootDir,
ag.output,
path.relative(ag.input, pathFromRoot)
),
dest: path.join(this.rootDir, ag.output, destPath),
});
// Match first entry and skip the rest for this file.
break;
+2 -1
View File
@@ -20,8 +20,9 @@ function getTypeCheckOptions(normalizedOptions: NormalizedSwcExecutorOptions) {
const typeCheckOptions: TypeCheckOptions = {
mode: 'emitDeclarationOnly',
tsConfigPath: tsConfig,
outDir: outputPath.replace(`/${projectRoot}`, ''),
outDir: outputPath,
workspaceRoot: root,
rootDir: projectRoot,
};
if (watch) {
@@ -19,6 +19,7 @@ interface BaseTypeCheckOptions {
tsConfigPath: string;
cacheDir?: string;
incremental?: boolean;
rootDir?: string;
}
type Mode = NoEmitMode | EmitDeclarationOnlyMode;
@@ -116,7 +117,8 @@ export async function runTypeCheck(
async function setupTypeScript(options: TypeCheckOptions) {
const ts = await import('typescript');
const { workspaceRoot, tsConfigPath, cacheDir, incremental } = options;
const { workspaceRoot, tsConfigPath, cacheDir, incremental, rootDir } =
options;
const config = readTsConfig(tsConfigPath);
if (config.errors.length) {
throw new Error(`Invalid config file: ${config.errors}`);
@@ -132,6 +134,7 @@ async function setupTypeScript(options: TypeCheckOptions) {
skipLibCheck: true,
...emitOptions,
incremental,
rootDir: rootDir || config.options.rootDir,
};
return { ts, workspaceRoot, cacheDir, config, compilerOptions };
@@ -99,6 +99,9 @@ Please see https://nx.dev/guides/eslint for full guidance on how to resolve this
);
}
// output fixes to disk, if applicable based on the options
await projectESLint.ESLint.outputFixes(lintResults);
// if quiet, only show errors
if (options.quiet) {
console.debug('Quiet mode enabled - filtering out warnings\n');
@@ -110,9 +113,6 @@ Please see https://nx.dev/guides/eslint for full guidance on how to resolve this
let totalErrors = 0;
let totalWarnings = 0;
// output fixes to disk, if applicable based on the options
await projectESLint.ESLint.outputFixes(lintResults);
for (const result of lintResults) {
if (result.errorCount || result.warningCount) {
totalErrors += result.errorCount;
@@ -72,10 +72,9 @@ function calculateResolveMappings(
parsed.configuration
);
return dependencies.reduce((m, c) => {
if (!c.outputs[0] && c.node.type === 'npm') {
c.outputs[0] = `node_modules/${c.node.data.packageName}`;
if (c.node.type !== 'npm' && c.outputs[0] != null) {
m[c.name] = joinPathFragments(context.root, c.outputs[0]);
}
m[c.name] = joinPathFragments(context.root, c.outputs[0]);
return m;
}, {});
}
@@ -1,20 +1,21 @@
import {
formatFiles,
getProjects,
readProjectConfiguration,
Tree,
updateProjectConfiguration,
} from '@nrwl/devkit';
import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils';
export default async function update(host: Tree) {
const projects = getProjects(host);
for (const [name, config] of projects.entries()) {
if (config?.targets?.build?.executor !== '@nrwl/node:build') continue;
config.targets.build.executor = '@nrwl/node:webpack';
updateProjectConfiguration(host, name, config);
}
forEachExecutorOptions(
host,
'@nrwl/node:build',
(_, projectName, targetName) => {
const projectConfiguration = readProjectConfiguration(host, projectName);
projectConfiguration.targets[targetName].executor = '@nrwl/node:webpack';
updateProjectConfiguration(host, projectName, projectConfiguration);
}
);
await formatFiles(host);
}
@@ -1,20 +1,21 @@
import {
formatFiles,
getProjects,
readProjectConfiguration,
Tree,
updateProjectConfiguration,
} from '@nrwl/devkit';
import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils';
export default async function update(host: Tree) {
const projects = getProjects(host);
export default async function update(tree: Tree) {
forEachExecutorOptions(
tree,
'@nrwl/node:execute',
(_, projectName, targetName) => {
const projectConfiguration = readProjectConfiguration(tree, projectName);
projectConfiguration.targets[targetName].executor = '@nrwl/node:node';
updateProjectConfiguration(tree, projectName, projectConfiguration);
}
);
for (const [name, config] of projects.entries()) {
if (config?.targets?.serve?.executor !== '@nrwl/node:execute') continue;
config.targets.serve.executor = '@nrwl/node:node';
updateProjectConfiguration(host, name, config);
}
await formatFiles(host);
await formatFiles(tree);
}
@@ -2,29 +2,36 @@ import {
addDependenciesToPackageJson,
formatFiles,
getProjects,
readProjectConfiguration,
Tree,
updateProjectConfiguration,
} from '@nrwl/devkit';
import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils';
import { nxVersion } from '@nrwl/workspace/src/utils/versions';
export default async function update(host: Tree) {
const projects = getProjects(host);
let installNeeded = false;
for (const [name, config] of projects.entries()) {
if (config?.targets?.build?.executor !== '@nrwl/node:package') continue;
forEachExecutorOptions(
host,
'@nrwl/node:package',
(_, projectName, targetName) => {
installNeeded = true;
const projectConfiguration = readProjectConfiguration(host, projectName);
config.targets.build.executor = '@nrwl/js:tsc';
projectConfiguration.targets[targetName].executor = '@nrwl/js:tsc';
const transformers = config.targets.build.options?.tsPlugins;
if (transformers) {
delete config.targets.build.options.tsPlugins;
config.targets.build.options.transformers = transformers;
const transformers =
projectConfiguration.targets[targetName].options?.tsPlugins;
if (transformers) {
delete projectConfiguration.targets[targetName].options.tsPlugins;
projectConfiguration.targets[targetName].options.transformers =
transformers;
}
updateProjectConfiguration(host, projectName, projectConfiguration);
}
installNeeded = true;
updateProjectConfiguration(host, name, config);
}
);
const task = installNeeded
? addDependenciesToPackageJson(
@@ -2,9 +2,5 @@
"extends": "<%= rootTsConfigPath %>",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.e2e.json"
}
]
"references": []
}
@@ -1,14 +1,15 @@
import type { Tree } from '@nrwl/devkit';
import {
readProjectConfiguration,
names,
convertNxGenerator,
generateFiles,
updateJson,
getWorkspaceLayout,
names,
readJson,
readProjectConfiguration,
updateJson,
} from '@nrwl/devkit';
import type { Tree } from '@nrwl/devkit';
import type { Schema } from './schema';
import * as path from 'path';
import type { Schema } from './schema';
interface NormalizedSchema extends Schema {
fileName: string;
@@ -26,7 +27,10 @@ function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
const { root: projectRoot, sourceRoot: projectSourceRoot } =
readProjectConfiguration(host, options.project);
const npmPackageName = `@${npmScope}/${options.project}`;
const npmPackageName = readJson<{ name: string }>(
host,
path.join(projectRoot, 'package.json')
).name;
let description: string;
if (options.description) {
@@ -1,5 +1,10 @@
import { pluginGenerator } from './plugin';
import { Tree, readProjectConfiguration } from '@nrwl/devkit';
import {
Tree,
readProjectConfiguration,
readJson,
joinPathFragments,
} from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { Schema } from './schema';
import { Linter } from '@nrwl/linter';
@@ -168,4 +173,33 @@ describe('NxPlugin Plugin Generator', () => {
expect(build.executor).toEqual('@nrwl/js:swc');
});
});
describe('--importPath', () => {
it('should use the workspace npmScope by default for the package.json', async () => {
await pluginGenerator(tree, getSchema());
const { root } = readProjectConfiguration(tree, 'my-plugin');
const { name } = readJson<{ name: string }>(
tree,
joinPathFragments(root, 'package.json')
);
expect(name).toEqual('@proj/my-plugin');
});
it('should use importPath as the package.json name', async () => {
await pluginGenerator(
tree,
getSchema({ importPath: '@my-company/my-plugin' })
);
const { root } = readProjectConfiguration(tree, 'my-plugin');
const { name } = readJson<{ name: string }>(
tree,
joinPathFragments(root, 'package.json')
);
expect(name).toEqual('@my-company/my-plugin');
});
});
});
@@ -46,7 +46,8 @@ function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
const parsedTags = options.tags
? options.tags.split(',').map((s) => s.trim())
: [];
const npmPackageName = `@${npmScope}/${name}`;
const npmPackageName = options.importPath || `@${npmScope}/${name}`;
return {
...options,
@@ -128,8 +129,9 @@ export async function pluginGenerator(host: Tree, schema: Schema) {
...schema,
config: options.standaloneConfig !== false ? 'project' : 'workspace',
buildable: true,
importPath: schema.importPath ?? options.npmPackageName,
importPath: options.npmPackageName,
});
tasks.push(libraryTask);
const installTask = addDependenciesToPackageJson(
+5 -1
View File
@@ -6,7 +6,11 @@ import { output } from '../src/cli/output';
import { detectPackageManager } from '../src/shared/package-manager';
import { Workspace } from '../src/cli/workspace';
if (process.argv[2] === 'new' || process.argv[2] === '_migrate') {
if (
process.argv[2] === 'new' ||
process.argv[2] === '_migrate' ||
process.argv[2] === 'migrate'
) {
require('../src/cli/index');
} else {
const workspace = findWorkspaceRoot(process.cwd());
+3 -2
View File
@@ -1,9 +1,10 @@
module.exports = {
name: 'cli',
preset: '../../jest.config.js',
preset: '../../jest.preset.js',
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
displayName: 'nx',
testEnvironment: 'node',
};
+8
View File
@@ -78,6 +78,14 @@
]
},
"outputs": ["{options.outputFile}"]
},
"test": {
"executor": "@nrwl/jest:jest",
"options": {
"jestConfig": "packages/nx/jest.config.js",
"passWithNoTests": true
},
"outputs": ["coverage/packages/nx"]
}
}
}
+1
View File
@@ -51,6 +51,7 @@ export async function invokeCommand(
commandArgs,
isVerbose
);
case 'migrate':
case '_migrate':
return (await import('../commands/migrate')).migrate(
root,
-1
View File
@@ -369,7 +369,6 @@ describe('Migration', () => {
migrations: [],
packageJson: {
'@nrwl/workspace': { version: '2.0.0', addToPackageJson: false },
'@nrwl/cli': { version: '2.0.0', addToPackageJson: false },
'@nrwl/angular': { version: '2.0.0', addToPackageJson: false },
'@nrwl/cypress': { version: '2.0.0', addToPackageJson: false },
'@nrwl/devkit': { addToPackageJson: false, version: '2.0.0' },
+9 -37
View File
@@ -54,7 +54,7 @@ export async function scheduleTarget(
} = require('@angular-devkit/architect/node');
const logger = getTargetLogger(opts.executor, verbose);
const fsHost = new NxScopedHost(normalize(root));
const fsHost = new NxScopedHost(root);
const { workspace } = await workspaces.readWorkspace(
workspaceConfigName(root),
workspaces.createWorkspaceHost(fsHost)
@@ -214,8 +214,8 @@ type AngularJsonConfiguration = WorkspaceJsonConfiguration &
export class NxScopedHost extends virtualFs.ScopedHost<any> {
protected __nxInMemoryWorkspace: WorkspaceJsonConfiguration | null;
constructor(root: Path) {
super(new NodeJsSyncHost(), root);
constructor(private root: string) {
super(new NodeJsSyncHost(), normalize(root));
}
protected __readWorkspaceConfiguration = (
@@ -243,7 +243,7 @@ export class NxScopedHost extends virtualFs.ScopedHost<any> {
.read(configFileName)
.pipe(map((data) => parseJson(Buffer.from(data).toString())));
} else {
const staticProjects = globForProjectFiles(this._root);
const staticProjects = globForProjectFiles(this.root);
this.__nxInMemoryWorkspace = buildWorkspaceConfigurationFromGlobs(
nxJson,
staticProjects.filter((x) => basename(x) !== 'package.json')
@@ -569,33 +569,8 @@ type ChangeContext = {
isNewFormat: boolean;
};
/**
* This host contains the workaround needed to run Angular migrations
*/
export class NxScopedHostForMigrations extends NxScopedHost {
constructor(root: Path) {
super(root);
}
read(path: Path): Observable<FileBuffer> {
if (isWorkspaceConfigPath(path)) {
return super.read(path).pipe(map(processConfigWhenReading));
} else {
return super.read(path);
}
}
write(path: Path, content: FileBuffer) {
if (isWorkspaceConfigPath(path)) {
return super.write(path, processConfigWhenWriting(content));
} else {
return super.write(path, content);
}
}
}
export class NxScopeHostUsedForWrappedSchematics extends NxScopedHost {
constructor(root: Path, private readonly host: Tree) {
constructor(root: string, private readonly host: Tree) {
super(root);
}
@@ -835,7 +810,7 @@ export async function generate(
verbose: boolean
) {
const logger = getLogger(verbose);
const fsHost = new NxScopedHost(normalize(root));
const fsHost = new NxScopedHost(root);
const workflow = createWorkflow(fsHost, root, opts);
const collection = getCollection(workflow, opts.collectionName);
const schematic = collection.createSchematic(opts.generatorName, true);
@@ -921,7 +896,7 @@ export async function runMigration(
isVerbose: boolean
) {
const logger = getLogger(isVerbose);
const fsHost = new NxScopedHost(normalize(root));
const fsHost = new NxScopedHost(root);
const workflow = createWorkflow(fsHost, root, {});
const collection = resolveMigrationsCollection(packageName);
return workflow
@@ -1131,10 +1106,7 @@ export function wrapAngularDevkitSchematic(
}
};
const fsHost = new NxScopeHostUsedForWrappedSchematics(
normalize(host.root),
host
);
const fsHost = new NxScopeHostUsedForWrappedSchematics(host.root, host);
const options = {
generatorOptions,
@@ -1186,7 +1158,7 @@ export async function invokeNew(
verbose: boolean
) {
const logger = getLogger(verbose);
const fsHost = new NxScopedHost(normalize(root));
const fsHost = new NxScopedHost(root);
const workflow = createWorkflow(fsHost, root, opts);
const collection = getCollection(workflow, opts.collectionName);
const schematic = collection.createSchematic('new', true);
@@ -1,12 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Tao Logger should color the NX prefix 1`] = `
exports[`Logger should color the NX prefix 1`] = `
"
>  NX  some Nx message!
"
`;
exports[`Tao Logger should log the full stack trace when an object is being passed 1`] = `
exports[`Logger should log the full stack trace when an object is being passed 1`] = `
"TypeError: Cannot read property 'target' of undefined
 at /someuser/node_modules/@storybook/angular/dist/ts3.9/server/angular-devkit-build-webpack.js:145:49
 at step (/someuser/node_modules/@storybook/angular/dist/ts3.9/server/angular-devkit-build-webpack.js:69:23)
@@ -8,6 +8,7 @@ export interface PackageManagerCommands {
install: string;
add: string;
addDev: string;
addGlobal: string;
rm: string;
exec: string;
list: string;
@@ -44,6 +45,7 @@ export function getPackageManagerCommand(
install: 'yarn',
add: 'yarn add -W',
addDev: 'yarn add -D -W',
addGlobal: 'yarn global add',
rm: 'yarn remove',
exec: 'yarn',
run: (script: string, args: string) => `yarn ${script} ${args}`,
@@ -59,6 +61,7 @@ export function getPackageManagerCommand(
install: 'pnpm install --no-frozen-lockfile', // explicitly disable in case of CI
add: 'pnpm add',
addDev: 'pnpm add -D',
addGlobal: 'pnpm add -g',
rm: 'pnpm rm',
exec: useExec ? 'pnpm exec' : 'pnpx',
run: (script: string, args: string) => `pnpm run ${script} -- ${args}`,
@@ -72,6 +75,7 @@ export function getPackageManagerCommand(
install: 'npm install',
add: 'npm install',
addDev: 'npm install -D',
addGlobal: 'npm install -g',
rm: 'npm rm',
exec: 'npx',
run: (script: string, args: string) => `npm run ${script} -- ${args}`,
+3 -1
View File
@@ -14,6 +14,7 @@ const libConfig = (name) => ({
const packageLibConfig = (root) => ({
root,
sourceRoot: root,
projectType: 'library',
});
describe('Workspaces', () => {
@@ -102,7 +103,7 @@ describe('Workspaces', () => {
expect(libResults).toEqual('directory-my-lib');
});
it('should custom directories from beginning', () => {
it('should trim custom directories from beginning', () => {
const nxJson: NxJsonConfiguration = {
npmScope: '',
workspaceLayout: {
@@ -161,6 +162,7 @@ describe('Workspaces', () => {
expect(resolved.projects['my-package']).toEqual({
root: 'packages/my-package',
sourceRoot: 'packages/my-package',
projectType: 'library',
});
});
});
+6
View File
@@ -803,6 +803,12 @@ function buildProjectConfigurationFromPackageJson(
root: directory,
sourceRoot: directory,
name,
projectType:
nxJson.workspaceLayout?.appsDir != nxJson.workspaceLayout?.libsDir &&
nxJson.workspaceLayout?.appsDir &&
directory.startsWith(nxJson.workspaceLayout.appsDir)
? 'application'
: 'library',
};
}
@@ -23,7 +23,7 @@ export async function reactNativeApplicationGenerator(
host: Tree,
schema: Schema
): Promise<GeneratorCallback> {
const options = normalizeOptions(host, schema);
const options = normalizeOptions(schema);
createApplicationFiles(host, options);
addProject(host, options);
@@ -79,7 +79,7 @@ import com.android.build.OutputFile
*/
project.ext.react = [
entryFile: "<%= entryFile %>",
entryFile: "<%= entryFileRelativeToRoot %>",
enableHermes: false, // clean and rebuild if changing
]
@@ -212,7 +212,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -e\n\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
shellScript = "set -e\n\nexport NODE_BINARY=node\nexport ENTRY_FILE=${PROJECT_DIR}/..<%= entryFile %>\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
};
589CD817700AC23390FB1CF7 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
@@ -56,7 +56,7 @@ function getTargets(options: NormalizedSchema) {
executor: '@nrwl/react-native:bundle',
outputs: [`${options.appProjectRoot}/build`],
options: {
entryFile: options.entryFile,
entryFile: options.entryFileRelativeToRoot,
platform: 'ios',
bundleOutput: `dist/${options.appProjectRoot}/ios/main.jsbundle`,
},
@@ -79,7 +79,7 @@ function getTargets(options: NormalizedSchema) {
architect['bundle-android'] = {
executor: '@nrwl/react-native:bundle',
options: {
entryFile: options.entryFile,
entryFile: options.entryFileRelativeToRoot,
platform: 'android',
bundleOutput: `dist/${options.appProjectRoot}/android/main.jsbundle`,
},
@@ -1,23 +1,15 @@
import { Tree } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { Linter } from '@nrwl/linter';
import { Schema } from '../schema';
import { normalizeOptions } from './normalize-options';
describe('Normalize Options', () => {
let appTree: Tree;
beforeEach(() => {
appTree = createTreeWithEmptyWorkspace();
});
it('should normalize options with name in kebab case', () => {
const schema: Schema = {
name: 'my-app',
linter: Linter.EsLint,
e2eTestRunner: 'none',
};
const options = normalizeOptions(appTree, schema);
const options = normalizeOptions(schema);
expect(options).toEqual({
androidProjectRoot: 'apps/my-app/android',
appProjectRoot: 'apps/my-app',
@@ -29,8 +21,8 @@ describe('Normalize Options', () => {
parsedTags: [],
projectName: 'my-app',
linter: Linter.EsLint,
entryFile: 'apps/my-app/src/main.tsx',
entryFileAbsolutePath: '/virtual/apps/my-app/src/main.tsx',
entryFile: '/src/main.tsx',
entryFileRelativeToRoot: 'apps/my-app/src/main.tsx',
e2eTestRunner: 'none',
unitTestRunner: 'jest',
});
@@ -41,7 +33,7 @@ describe('Normalize Options', () => {
name: 'myApp',
e2eTestRunner: 'none',
};
const options = normalizeOptions(appTree, schema);
const options = normalizeOptions(schema);
expect(options).toEqual({
androidProjectRoot: 'apps/my-app/android',
appProjectRoot: 'apps/my-app',
@@ -52,8 +44,8 @@ describe('Normalize Options', () => {
name: 'my-app',
parsedTags: [],
projectName: 'my-app',
entryFile: 'apps/my-app/src/main.tsx',
entryFileAbsolutePath: '/virtual/apps/my-app/src/main.tsx',
entryFile: '/src/main.tsx',
entryFileRelativeToRoot: 'apps/my-app/src/main.tsx',
e2eTestRunner: 'none',
unitTestRunner: 'jest',
});
@@ -65,7 +57,7 @@ describe('Normalize Options', () => {
directory: 'directory',
e2eTestRunner: 'none',
};
const options = normalizeOptions(appTree, schema);
const options = normalizeOptions(schema);
expect(options).toEqual({
androidProjectRoot: 'apps/directory/my-app/android',
appProjectRoot: 'apps/directory/my-app',
@@ -77,8 +69,8 @@ describe('Normalize Options', () => {
directory: 'directory',
parsedTags: [],
projectName: 'directory-my-app',
entryFile: 'apps/directory/my-app/src/main.tsx',
entryFileAbsolutePath: '/virtual/apps/directory/my-app/src/main.tsx',
entryFile: '/src/main.tsx',
entryFileRelativeToRoot: 'apps/directory/my-app/src/main.tsx',
e2eTestRunner: 'none',
unitTestRunner: 'jest',
});
@@ -89,7 +81,7 @@ describe('Normalize Options', () => {
name: 'directory/my-app',
e2eTestRunner: 'none',
};
const options = normalizeOptions(appTree, schema);
const options = normalizeOptions(schema);
expect(options).toEqual({
androidProjectRoot: 'apps/directory/my-app/android',
appProjectRoot: 'apps/directory/my-app',
@@ -100,8 +92,8 @@ describe('Normalize Options', () => {
name: 'directory/my-app',
parsedTags: [],
projectName: 'directory-my-app',
entryFile: 'apps/directory/my-app/src/main.tsx',
entryFileAbsolutePath: '/virtual/apps/directory/my-app/src/main.tsx',
entryFile: '/src/main.tsx',
entryFileRelativeToRoot: 'apps/directory/my-app/src/main.tsx',
e2eTestRunner: 'none',
unitTestRunner: 'jest',
});
@@ -113,7 +105,7 @@ describe('Normalize Options', () => {
displayName: 'My App',
e2eTestRunner: 'none',
};
const options = normalizeOptions(appTree, schema);
const options = normalizeOptions(schema);
expect(options).toEqual({
androidProjectRoot: 'apps/my-app/android',
appProjectRoot: 'apps/my-app',
@@ -124,8 +116,8 @@ describe('Normalize Options', () => {
name: 'my-app',
parsedTags: [],
projectName: 'my-app',
entryFile: 'apps/my-app/src/main.tsx',
entryFileAbsolutePath: '/virtual/apps/my-app/src/main.tsx',
entryFile: '/src/main.tsx',
entryFileRelativeToRoot: 'apps/my-app/src/main.tsx',
e2eTestRunner: 'none',
unitTestRunner: 'jest',
});
@@ -11,13 +11,10 @@ export interface NormalizedSchema extends Schema {
androidProjectRoot: string;
parsedTags: string[];
entryFile: string;
entryFileAbsolutePath: string;
entryFileRelativeToRoot: string;
}
export function normalizeOptions(
host: Tree,
options: Schema
): NormalizedSchema {
export function normalizeOptions(options: Schema): NormalizedSchema {
const { fileName, className } = names(options.name);
const directoryName = options.directory
@@ -37,12 +34,8 @@ export function normalizeOptions(
? options.tags.split(',').map((s) => s.trim())
: [];
const entryFile = join(
appProjectRoot,
options.js ? '/src/main.js' : '/src/main.tsx'
);
const entryFileAbsolutePath = join(host.root, entryFile);
const entryFile = options.js ? '/src/main.js' : '/src/main.tsx';
const entryFileRelativeToRoot = join(appProjectRoot, entryFile);
/**
* if options.name is "my-app"
@@ -64,6 +57,6 @@ export function normalizeOptions(
androidProjectRoot,
parsedTags,
entryFile,
entryFileAbsolutePath,
entryFileRelativeToRoot,
};
}
@@ -44,7 +44,13 @@ export default async function buildStorybookExecutor(
}
function runInstance(options: StorybookBuilderOptions): Promise<void> {
return build({ ...options, ci: true });
const env = process.env.NODE_ENV ?? 'production';
process.env.NODE_ENV = env;
return build({
...options,
ci: true,
configType: env.toUpperCase(),
});
}
function storybookOptionMapper(
+1 -1
View File
@@ -119,7 +119,7 @@ function determineStorybookWorkspaceVersion(packageJsonContents) {
}
if (packageJsonContents['devDependencies']['@storybook/react-native']) {
workspaceStorybookVersion =
packageJsonContents['dependencies']['@storybook/react-native'];
packageJsonContents['devDependencies']['@storybook/react-native'];
}
}
@@ -1,7 +1,6 @@
import * as webpack from 'webpack';
import {
ExecutorContext,
joinPathFragments,
parseTargetString,
readTargetOptions,
} from '@nrwl/devkit';
@@ -51,6 +50,23 @@ export default async function* devServerExecutor(
context.root,
sourceRoot
);
if (!buildOptions.buildLibsFromSource) {
const { target, dependencies } = calculateProjectDependencies(
readCachedProjectGraph(),
context.root,
context.projectName,
'build', // should be generalized
context.configurationName
);
buildOptions.tsConfig = createTmpTsConfig(
buildOptions.tsConfig,
context.root,
target.data.root,
dependencies
);
}
let webpackConfig = getDevServerConfig(
context.root,
projectRoot,
@@ -71,22 +87,6 @@ export default async function* devServerExecutor(
});
}
if (!buildOptions.buildLibsFromSource) {
const { target, dependencies } = calculateProjectDependencies(
readCachedProjectGraph(),
context.root,
context.projectName,
'build', // should be generalized
context.configurationName
);
buildOptions.tsConfig = createTmpTsConfig(
joinPathFragments(context.root, buildOptions.tsConfig),
context.root,
target.data.root,
dependencies
);
}
return yield* eachValueFrom(
runWebpackDevServer(webpackConfig, webpack, WebpackDevServer).pipe(
tap(({ stats }) => {
@@ -1,42 +1,46 @@
import { exec, execSync } from 'child_process';
import { execFile, execFileSync } from 'child_process';
import { ExecutorContext, joinPathFragments } from '@nrwl/devkit';
import ignore from 'ignore';
import { readFileSync } from 'fs';
import { Schema } from './schema';
import { watch } from 'chokidar';
import { workspaceLayout } from '@nrwl/workspace/src/core/file-utils';
import { platform } from 'os';
// platform specific command name
const pmCmd = platform() === 'win32' ? `npx.cmd` : 'npx';
function getHttpServerArgs(options: Schema) {
const args = ['-c-1'];
if (options.port) {
args.push(`-p ${options.port}`);
args.push(`-p=${options.port}`);
}
if (options.host) {
args.push(`-a ${options.host}`);
args.push(`-a=${options.host}`);
}
if (options.ssl) {
args.push(`-S`);
}
if (options.sslCert) {
args.push(`-C ${options.sslCert}`);
args.push(`-C=${options.sslCert}`);
}
if (options.sslKey) {
args.push(`-K ${options.sslKey}`);
args.push(`-K=${options.sslKey}`);
}
if (options.proxyUrl) {
args.push(`-P ${options.proxyUrl}`);
args.push(`-P=${options.proxyUrl}`);
}
if (options.proxyOptions) {
Object.keys(options.proxyOptions).forEach((key) => {
args.push(`--proxy-options.${key}`, options.proxyOptions[key]);
args.push(`--proxy-options.${key}=options.proxyOptions[key]`);
});
}
return args;
}
function getBuildTargetCommand(options: Schema) {
const cmd = [`npx nx run ${options.buildTarget}`];
const cmd = ['nx', 'run', options.buildTarget];
if (options.withDeps) {
cmd.push(`--with-deps`);
}
@@ -46,7 +50,7 @@ function getBuildTargetCommand(options: Schema) {
if (options.maxParallel) {
cmd.push(`--maxParallel=${options.maxParallel}`);
}
return cmd.join(' ');
return cmd;
}
function getBuildTargetOutputPath(options: Schema, context: ExecutorContext) {
@@ -115,7 +119,8 @@ export default async function* fileServerExecutor(
if (!running) {
running = true;
try {
execSync(getBuildTargetCommand(options), {
const args = getBuildTargetCommand(options);
execFileSync(pmCmd, args, {
stdio: [0, 1, 2],
});
} catch {}
@@ -131,8 +136,12 @@ export default async function* fileServerExecutor(
const outputPath = getBuildTargetOutputPath(options, context);
const args = getHttpServerArgs(options);
const serve = exec(`npx http-server ${outputPath} ${args.join(' ')}`, {
const serve = execFile(pmCmd, ['http-server', outputPath, ...args], {
cwd: context.root,
env: {
FORCE_COLOR: 'true',
...process.env,
},
});
const processExitListener = () => {
serve.kill();
@@ -143,7 +143,14 @@ export async function* run(
);
}
process.env.NODE_ENV ||= 'production';
const isScriptOptimizeOn =
typeof options.optimization === 'boolean'
? options.optimization
: options.optimization && options.optimization.scripts
? options.optimization.scripts
: false;
process.env.NODE_ENV ||= isScriptOptimizeOn ? 'production' : 'development';
const metadata = context.workspace.projects[context.projectName];
+3 -3
View File
@@ -42,11 +42,11 @@
"cli": "nx",
"implementation": "./src/migrations/update-13-9-0/update-decorate-cli"
},
"13-9-0-replace-tao-and-cli-with-nx": {
"13-9-0-replace-tao-with-nx": {
"version": "13.9.0-beta.0",
"description": "Replace @nrwl/tao and @nrwl/cli with nx",
"description": "Replace @nrwl/tao with nx",
"cli": "nx",
"implementation": "./src/migrations/update-13-9-0/replace-tao-and-cli-with-nx"
"implementation": "./src/migrations/update-13-9-0/replace-tao-with-nx"
}
},
"packageJsonUpdates": {
@@ -97,12 +97,8 @@ export function readPackageJson(p: string) {
}
}
export function readPackageVersion(p: string) {
let status = 'Not Found';
try {
status = readPackageJson(p).version;
} catch {}
return status;
export function readPackageVersion(p: string): string {
return readPackageJson(p).version || 'Not Found';
}
export function findInstalledCommunityPlugins(): {
@@ -6,6 +6,7 @@ Object {
"@nrwl/angular": "*",
},
"devDependencies": Object {
"@nrwl/cli": "*",
"@nrwl/workspace": "*",
"@types/node": "16.11.7",
"nx": "*",
@@ -28,6 +29,7 @@ exports[`new --preset empty should generate necessary npm dependencies 1`] = `
Object {
"dependencies": Object {},
"devDependencies": Object {
"@nrwl/cli": "*",
"@nrwl/workspace": "*",
"@types/node": "16.11.7",
"nx": "*",
@@ -50,6 +52,7 @@ exports[`new --preset react should generate necessary npm dependencies 1`] = `
Object {
"dependencies": Object {},
"devDependencies": Object {
"@nrwl/cli": "*",
"@nrwl/react": "*",
"@nrwl/workspace": "*",
"@types/node": "16.11.7",
@@ -105,6 +105,7 @@ describe('@nrwl/workspace:npm-package', () => {
expect(tree.exists('packages/my-package/project.json')).toBeFalsy();
expect(tree.exists('packages/my-package/package.json')).toBeTruthy();
expect(readProjectConfiguration(tree, 'my-package')).toEqual({
projectType: 'library',
root: 'packages/my-package',
sourceRoot: 'packages/my-package',
});
@@ -10,6 +10,7 @@
"devDependencies": {
<% if(cli === 'angular') { %>"@angular/cli": "<%= angularCliVersion %>",<% } %>
"nx": "<%= nxVersion %>",
"@nrwl/cli": "<%= nxVersion %>",
"@nrwl/workspace": "<%= nxVersion %>",
"@types/node": "16.11.7",
"typescript": "<%= typescriptVersion %>",
@@ -1,22 +1,21 @@
import { Tree, updateJson } from '@nrwl/devkit';
export function replaceTaoAndCLIWithNx(host: Tree) {
export function replaceTaoWithNx(host: Tree) {
updateJson(host, 'package.json', (json: any) => {
if (json.dependencies['@nrwl/workspace']) {
json.dependencies['nx'] = json.dependencies['@nrwl/workspace'];
} else if (json.devDependencies['@nrwl/workspace']) {
json.devDependencies['nx'] = json.devDependencies['@nrwl/workspace'];
}
removeTaoAndCLI(json.dependencies);
removeTaoAndCLI(json.devDependencies);
removeTao(json.dependencies);
removeTao(json.devDependencies);
return json;
});
}
function removeTaoAndCLI(json: any) {
function removeTao(json: any) {
if (!json) return;
json['@nrwl/tao'] = undefined;
json['@nrwl/cli'] = undefined;
}
export default replaceTaoAndCLIWithNx;
export default replaceTaoWithNx;
+3 -3
View File
@@ -14,7 +14,7 @@ import {
} from 'fs-extra';
import { dirname, join, resolve, sep } from 'path';
import { DefaultTasksRunnerOptions } from './default-tasks-runner';
import { spawn, exec } from 'child_process';
import { spawn, execFile } from 'child_process';
import { cacheDir } from '../utilities/cache-directory';
import { platform } from 'os';
@@ -190,7 +190,7 @@ export class Cache {
}
return new Promise((res, rej) => {
exec(`cp -a "${src}" "${dirname(directory)}"`, (error) => {
execFile('cp', ['-a', src, dirname(directory)], (error) => {
if (!error) {
res();
} else {
@@ -207,7 +207,7 @@ export class Cache {
}
return new Promise<void>((res, rej) => {
exec(`rm -rf "${folder}"`, (error) => {
execFile('rm', ['-rf', folder], (error) => {
if (!error) {
res();
} else {
@@ -3,6 +3,7 @@ import { join } from 'path';
import { appRootPath } from 'nx/src/utils/app-root';
import type {
NxJsonConfiguration,
ProjectConfiguration,
ProjectGraph,
ProjectGraphProjectNode,
TargetDependencyConfig,
@@ -347,7 +348,7 @@ export function createTask({
}
function addTasksForProjectDependencyConfig(
project: ProjectGraphProjectNode,
project: ProjectGraphProjectNode<ProjectConfiguration>,
{
target,
configuration,
@@ -428,7 +429,7 @@ function addTasksForProjectDependencyConfig(
}
}
}
} else {
} else if (projectHasTarget(project, dependencyConfig.target)) {
addTasksForProjectTarget(
{
project,
@@ -171,7 +171,7 @@ function createProgram(
}
);
logger.error(diagnostics);
throw new Error(diagnostics);
return { success: false };
} else {
logger.info(
`Done compiling TypeScript files for project "${projectName}".`
@@ -304,10 +304,14 @@ export function mapProjectGraphFiles<T>(
};
}
const ESLINT_REGEX = /node_modules.*\/eslint$/;
const NRWL_CLI_REGEX = /nx\/bin\/run-executor\.js$/;
export function isTerminalRun(): boolean {
return (
process.argv.length > 1 &&
!!process.argv[1].match(/@nrwl\/cli\/lib\/run-cli\.js$/)
(!!process.argv[1].match(NRWL_CLI_REGEX) ||
!!process.argv[1].match(ESLINT_REGEX))
);
}