Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f997744b4d | |||
| 04a38649b3 | |||
| c351b34f62 | |||
| f111580f28 | |||
| bf9844ec72 | |||
| 6c86cb770c | |||
| c06edd9426 | |||
| 1c7406379b | |||
| f1de248ff7 | |||
| 5ba8d5aa12 | |||
| 18ff2dbcd4 | |||
| e9a59d60af | |||
| 908cf41d74 | |||
| 2f8ca66797 |
@@ -21,6 +21,13 @@
|
||||
"description": "Do not add dependencies to `package.json`.",
|
||||
"x-priority": "internal"
|
||||
},
|
||||
"testEnvironment": {
|
||||
"type": "string",
|
||||
"enum": ["jsdom", "node", "none"],
|
||||
"description": "The test environment for jest. This controls which jest-environment-* package is installed",
|
||||
"default": "jsdom",
|
||||
"x-priority": "important"
|
||||
},
|
||||
"js": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
},
|
||||
"testEnvironment": {
|
||||
"type": "string",
|
||||
"enum": ["jsdom", "node"],
|
||||
"enum": ["jsdom", "node", "none"],
|
||||
"description": "The test environment for jest.",
|
||||
"default": "jsdom",
|
||||
"x-priority": "important"
|
||||
|
||||
@@ -42,7 +42,7 @@ Sometimes broad configurations like `> 0.5%, not IE 11` can lead to surprising r
|
||||
|
||||
To see what browsers your configuration is supporting, run `npx browserslist` in the application's directory to get an output of browsers and versions to support.
|
||||
|
||||
```{% command="npx browserlist" %}
|
||||
```{% command="npx browserslist" %}
|
||||
and_chr 61
|
||||
chrome 83
|
||||
edge 83
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
uniq,
|
||||
updateFile,
|
||||
updateProjectConfig,
|
||||
removeFile,
|
||||
} from '../../utils';
|
||||
import { names } from '@nrwl/devkit';
|
||||
|
||||
@@ -19,154 +20,15 @@ describe('Angular Cypress Component Tests', () => {
|
||||
|
||||
beforeAll(async () => {
|
||||
projectName = newProject({ name: uniq('cy-ng') });
|
||||
runCLI(`generate @nrwl/angular:app ${appName} --no-interactive`);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:component fancy-component --project=${appName} --no-interactive`
|
||||
);
|
||||
runCLI(`generate @nrwl/angular:lib ${usedInAppLibName} --no-interactive`);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:component btn --project=${usedInAppLibName} --inlineTemplate --inlineStyle --export --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:component btn-standalone --project=${usedInAppLibName} --inlineTemplate --inlineStyle --export --standalone --no-interactive`
|
||||
);
|
||||
updateFile(
|
||||
`libs/${usedInAppLibName}/src/lib/btn/btn.component.ts`,
|
||||
`
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: '${projectName}-btn',
|
||||
template: '<button class="text-green-500">{{text}}</button>',
|
||||
styles: []
|
||||
})
|
||||
export class BtnComponent {
|
||||
@Input() text = 'something';
|
||||
}
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
`libs/${usedInAppLibName}/src/lib/btn-standalone/btn-standalone.component.ts`,
|
||||
`
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
@Component({
|
||||
selector: '${projectName}-btn-standalone',
|
||||
standalone: true,
|
||||
imports: [CommonModule],
|
||||
template: '<button class="text-green-500">standlone-{{text}}</button>',
|
||||
styles: [],
|
||||
})
|
||||
export class BtnStandaloneComponent {
|
||||
@Input() text = 'something';
|
||||
}
|
||||
`
|
||||
);
|
||||
// use lib in the app
|
||||
createFile(
|
||||
`apps/${appName}/src/app/app.component.html`,
|
||||
`
|
||||
<${projectName}-btn></${projectName}-btn>
|
||||
<${projectName}-btn-standalone></${projectName}-btn-standalone>
|
||||
<${projectName}-nx-welcome></${projectName}-nx-welcome>
|
||||
`
|
||||
);
|
||||
const btnModuleName = names(usedInAppLibName).className;
|
||||
updateFile(
|
||||
`apps/${appName}/src/app/app.component.scss`,
|
||||
`
|
||||
@use 'styleguide' as *;
|
||||
createApp(appName);
|
||||
|
||||
h1 {
|
||||
@include headline;
|
||||
}`
|
||||
);
|
||||
updateFile(
|
||||
`apps/${appName}/src/app/app.module.ts`,
|
||||
`
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import {${btnModuleName}Module} from "@${projectName}/${usedInAppLibName}";
|
||||
createLib(projectName, appName, usedInAppLibName);
|
||||
useLibInApp(projectName, appName, usedInAppLibName);
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { NxWelcomeComponent } from './nx-welcome.component';
|
||||
createBuildableLib(projectName, buildableLibName);
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent, NxWelcomeComponent],
|
||||
imports: [BrowserModule, ${btnModuleName}Module],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {}
|
||||
`
|
||||
);
|
||||
|
||||
runCLI(
|
||||
`generate @nrwl/angular:lib ${buildableLibName} --buildable --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:component input --project=${buildableLibName} --inlineTemplate --inlineStyle --export --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:component input-standalone --project=${buildableLibName} --inlineTemplate --inlineStyle --export --standalone --no-interactive`
|
||||
);
|
||||
updateFile(
|
||||
`libs/${buildableLibName}/src/lib/input/input.component.ts`,
|
||||
`
|
||||
import {Component, Input} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: '${projectName}-input',
|
||||
template: \`<label class="text-green-500">Email: <input class="border-blue-500" type="email" [readOnly]="readOnly"></label>\`,
|
||||
styles : []
|
||||
})
|
||||
export class InputComponent{
|
||||
@Input() readOnly = false;
|
||||
}
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
`libs/${buildableLibName}/src/lib/input-standalone/input-standalone.component.ts`,
|
||||
`
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
@Component({
|
||||
selector: '${projectName}-input-standalone',
|
||||
standalone: true,
|
||||
imports: [CommonModule],
|
||||
template: \`<label class="text-green-500">Email: <input class="border-blue-500" type="email" [readOnly]="readOnly"></label>\`,
|
||||
styles : []
|
||||
})
|
||||
export class InputStandaloneComponent{
|
||||
@Input() readOnly = false;
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
// make sure assets from the workspace root work.
|
||||
createFile('libs/assets/data.json', JSON.stringify({ data: 'data' }));
|
||||
createFile(
|
||||
'assets/styles/styleguide.scss',
|
||||
`
|
||||
@mixin headline {
|
||||
font-weight: bold;
|
||||
color: darkkhaki;
|
||||
background: lightcoral;
|
||||
font-weight: 24px;
|
||||
}
|
||||
`
|
||||
);
|
||||
updateProjectConfig(appName, (config) => {
|
||||
config.targets['build'].options.stylePreprocessorOptions = {
|
||||
includePaths: ['assets/styles'],
|
||||
};
|
||||
config.targets['build'].options.assets.push({
|
||||
glob: '**/*',
|
||||
input: 'libs/assets',
|
||||
output: 'assets',
|
||||
});
|
||||
return config;
|
||||
});
|
||||
useWorkspaceAssetsInApp(appName);
|
||||
});
|
||||
|
||||
afterAll(() => cleanupProject());
|
||||
@@ -200,9 +62,226 @@ import {CommonModule} from '@angular/common';
|
||||
`generate @nrwl/angular:cypress-component-configuration --project=${buildableLibName} --generate-tests --no-interactive`
|
||||
);
|
||||
}).toThrow();
|
||||
createFile(
|
||||
|
||||
updateTestToAssertTailwindIsNotApplied(buildableLibName);
|
||||
|
||||
runCLI(
|
||||
`generate @nrwl/angular:cypress-component-configuration --project=${buildableLibName} --generate-tests --build-target=${appName}:build --no-interactive`
|
||||
);
|
||||
if (runCypressTests()) {
|
||||
expect(runCLI(`component-test ${buildableLibName} --no-watch`)).toContain(
|
||||
'All specs passed!'
|
||||
);
|
||||
}
|
||||
// add tailwind
|
||||
runCLI(
|
||||
`generate @nrwl/angular:setup-tailwind --project=${buildableLibName}`
|
||||
);
|
||||
updateFile(
|
||||
`libs/${buildableLibName}/src/lib/input/input.component.cy.ts`,
|
||||
`
|
||||
(content) => {
|
||||
// text-green-500 should now apply
|
||||
return content.replace('rgb(0, 0, 0)', 'rgb(34, 197, 94)');
|
||||
}
|
||||
);
|
||||
updateFile(
|
||||
`libs/${buildableLibName}/src/lib/input-standalone/input-standalone.component.cy.ts`,
|
||||
(content) => {
|
||||
// text-green-500 should now apply
|
||||
return content.replace('rgb(0, 0, 0)', 'rgb(34, 197, 94)');
|
||||
}
|
||||
);
|
||||
|
||||
if (runCypressTests()) {
|
||||
expect(runCLI(`component-test ${buildableLibName} --no-watch`)).toContain(
|
||||
'All specs passed!'
|
||||
);
|
||||
checkFilesDoNotExist(`tmp/libs/${buildableLibName}/ct-styles.css`);
|
||||
}
|
||||
}, 300_000);
|
||||
|
||||
it('should test lib with implicit dep on buildTarget', () => {
|
||||
// creates graph like buildableLib -> lib -> app
|
||||
// updates the apps styles and they should apply to the buildableLib
|
||||
// even though app is not directly connected to buildableLib
|
||||
useBuildableLibInLib(projectName, buildableLibName, usedInAppLibName);
|
||||
|
||||
updateBuilableLibTestsToAssertAppStyles(appName, buildableLibName);
|
||||
|
||||
if (runCypressTests()) {
|
||||
expect(runCLI(`component-test ${buildableLibName} --no-watch`)).toContain(
|
||||
'All specs passed!'
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function createApp(appName: string) {
|
||||
runCLI(`generate @nrwl/angular:app ${appName} --no-interactive`);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:component fancy-component --project=${appName} --no-interactive`
|
||||
);
|
||||
}
|
||||
|
||||
function createLib(projectName: string, appName: string, libName: string) {
|
||||
runCLI(`generate @nrwl/angular:lib ${libName} --no-interactive`);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:component btn --project=${libName} --inlineTemplate --inlineStyle --export --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:component btn-standalone --project=${libName} --inlineTemplate --inlineStyle --export --standalone --no-interactive`
|
||||
);
|
||||
updateFile(
|
||||
`libs/${libName}/src/lib/btn/btn.component.ts`,
|
||||
`
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: '${projectName}-btn',
|
||||
template: '<button class="text-green-500">{{text}}</button>',
|
||||
styles: []
|
||||
})
|
||||
export class BtnComponent {
|
||||
@Input() text = 'something';
|
||||
}
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
`libs/${libName}/src/lib/btn-standalone/btn-standalone.component.ts`,
|
||||
`
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
@Component({
|
||||
selector: '${projectName}-btn-standalone',
|
||||
standalone: true,
|
||||
imports: [CommonModule],
|
||||
template: '<button class="text-green-500">standlone-{{text}}</button>',
|
||||
styles: [],
|
||||
})
|
||||
export class BtnStandaloneComponent {
|
||||
@Input() text = 'something';
|
||||
}
|
||||
`
|
||||
);
|
||||
}
|
||||
|
||||
function createBuildableLib(projectName: string, libName: string) {
|
||||
// create lib
|
||||
runCLI(`generate @nrwl/angular:lib ${libName} --buildable --no-interactive`);
|
||||
// create cmp for lib
|
||||
runCLI(
|
||||
`generate @nrwl/angular:component input --project=${libName} --inlineTemplate --inlineStyle --export --no-interactive`
|
||||
);
|
||||
// create standlone cmp for lib
|
||||
runCLI(
|
||||
`generate @nrwl/angular:component input-standalone --project=${libName} --inlineTemplate --inlineStyle --export --standalone --no-interactive`
|
||||
);
|
||||
// update cmp implmentation to use tailwind clasasserting in tests
|
||||
updateFile(
|
||||
`libs/${libName}/src/lib/input/input.component.ts`,
|
||||
`
|
||||
import {Component, Input} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: '${projectName}-input',
|
||||
template: \`<label class="text-green-500">Email: <input class="border-blue-500" type="email" [readOnly]="readOnly"></label>\`,
|
||||
styles : []
|
||||
})
|
||||
export class InputComponent{
|
||||
@Input() readOnly = false;
|
||||
}
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
`libs/${libName}/src/lib/input-standalone/input-standalone.component.ts`,
|
||||
`
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
@Component({
|
||||
selector: '${projectName}-input-standalone',
|
||||
standalone: true,
|
||||
imports: [CommonModule],
|
||||
template: \`<label class="text-green-500">Email: <input class="border-blue-500" type="email" [readOnly]="readOnly"></label>\`,
|
||||
styles : []
|
||||
})
|
||||
export class InputStandaloneComponent{
|
||||
@Input() readOnly = false;
|
||||
}
|
||||
`
|
||||
);
|
||||
}
|
||||
|
||||
function useLibInApp(projectName: string, appName: string, libName: string) {
|
||||
createFile(
|
||||
`apps/${appName}/src/app/app.component.html`,
|
||||
`
|
||||
<${projectName}-btn></${projectName}-btn>
|
||||
<${projectName}-btn-standalone></${projectName}-btn-standalone>
|
||||
<${projectName}-nx-welcome></${projectName}-nx-welcome>
|
||||
`
|
||||
);
|
||||
const btnModuleName = names(libName).className;
|
||||
updateFile(
|
||||
`apps/${appName}/src/app/app.component.scss`,
|
||||
`
|
||||
@use 'styleguide' as *;
|
||||
|
||||
h1 {
|
||||
@include headline;
|
||||
}`
|
||||
);
|
||||
updateFile(
|
||||
`apps/${appName}/src/app/app.module.ts`,
|
||||
`
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import {${btnModuleName}Module} from "@${projectName}/${libName}";
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { NxWelcomeComponent } from './nx-welcome.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent, NxWelcomeComponent],
|
||||
imports: [BrowserModule, ${btnModuleName}Module],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {}
|
||||
`
|
||||
);
|
||||
}
|
||||
|
||||
function useWorkspaceAssetsInApp(appName: string) {
|
||||
// make sure assets from the workspace root work.
|
||||
createFile('libs/assets/data.json', JSON.stringify({ data: 'data' }));
|
||||
createFile(
|
||||
'assets/styles/styleguide.scss',
|
||||
`
|
||||
@mixin headline {
|
||||
font-weight: bold;
|
||||
color: darkkhaki;
|
||||
background: lightcoral;
|
||||
font-weight: 24px;
|
||||
}
|
||||
`
|
||||
);
|
||||
updateProjectConfig(appName, (config) => {
|
||||
config.targets['build'].options.stylePreprocessorOptions = {
|
||||
includePaths: ['assets/styles'],
|
||||
};
|
||||
config.targets['build'].options.assets.push({
|
||||
glob: '**/*',
|
||||
input: 'libs/assets',
|
||||
output: 'assets',
|
||||
});
|
||||
return config;
|
||||
});
|
||||
}
|
||||
|
||||
function updateTestToAssertTailwindIsNotApplied(libName: string) {
|
||||
createFile(
|
||||
`libs/${libName}/src/lib/input/input.component.cy.ts`,
|
||||
`
|
||||
import { MountConfig } from 'cypress/angular';
|
||||
import { InputComponent } from './input.component';
|
||||
|
||||
@@ -229,11 +308,11 @@ describe(InputComponent.name, () => {
|
||||
});
|
||||
});
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
createFile(
|
||||
`libs/${buildableLibName}/src/lib/input-standalone/input-standalone.component.cy.ts`,
|
||||
`
|
||||
createFile(
|
||||
`libs/${libName}/src/lib/input-standalone/input-standalone.component.cy.ts`,
|
||||
`
|
||||
import { MountConfig } from 'cypress/angular';
|
||||
import { InputStandaloneComponent } from './input-standalone.component';
|
||||
|
||||
@@ -260,39 +339,50 @@ describe(InputStandaloneComponent.name, () => {
|
||||
});
|
||||
});
|
||||
`
|
||||
);
|
||||
);
|
||||
}
|
||||
function useBuildableLibInLib(
|
||||
projectName: string,
|
||||
buildableLibName: string,
|
||||
libName: string
|
||||
) {
|
||||
const buildLibNames = names(buildableLibName);
|
||||
// use the buildable lib in lib so now buildableLib has an indirect dep on app
|
||||
updateFile(
|
||||
`libs/${libName}/src/lib/btn-standalone/btn-standalone.component.ts`,
|
||||
`
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { InputStandaloneComponent } from '@${projectName}/${buildLibNames.fileName}';
|
||||
@Component({
|
||||
selector: '${projectName}-btn-standalone',
|
||||
standalone: true,
|
||||
imports: [CommonModule, InputStandaloneComponent],
|
||||
template: '<button class="text-green-500">standlone-{{text}}</button>${projectName} <${projectName}-input-standalone></${projectName}-input-standalone>',
|
||||
styles: [],
|
||||
})
|
||||
export class BtnStandaloneComponent {
|
||||
@Input() text = 'something';
|
||||
}
|
||||
`
|
||||
);
|
||||
}
|
||||
|
||||
runCLI(
|
||||
`generate @nrwl/angular:cypress-component-configuration --project=${buildableLibName} --generate-tests --build-target=${appName}:build --no-interactive`
|
||||
);
|
||||
if (runCypressTests()) {
|
||||
expect(runCLI(`component-test ${buildableLibName} --no-watch`)).toContain(
|
||||
'All specs passed!'
|
||||
);
|
||||
function updateBuilableLibTestsToAssertAppStyles(
|
||||
appName: string,
|
||||
buildableLibName: string
|
||||
) {
|
||||
updateFile(
|
||||
`apps/${appName}/src/styles.css`,
|
||||
`label {color: pink !important;}`
|
||||
);
|
||||
|
||||
removeFile(`libs/${buildableLibName}/src/lib/input/input.component.cy.ts`);
|
||||
updateFile(
|
||||
`libs/${buildableLibName}/src/lib/input-standalone/input-standalone.component.cy.ts`,
|
||||
(content) => {
|
||||
// app styles should now apply
|
||||
return content.replace('rgb(34, 197, 94)', 'rgb(255, 192, 203)');
|
||||
}
|
||||
|
||||
// add tailwind
|
||||
runCLI(
|
||||
`generate @nrwl/angular:setup-tailwind --project=${buildableLibName}`
|
||||
);
|
||||
updateFile(
|
||||
`libs/${buildableLibName}/src/lib/input/input.component.cy.ts`,
|
||||
(content) => {
|
||||
// text-green-500 should now apply
|
||||
return content.replace('rgb(0, 0, 0)', 'rgb(34, 197, 94)');
|
||||
}
|
||||
);
|
||||
updateFile(
|
||||
`libs/${buildableLibName}/src/lib/input-standalone/input-standalone.component.cy.ts`,
|
||||
(content) => {
|
||||
// text-green-500 should now apply
|
||||
return content.replace('rgb(0, 0, 0)', 'rgb(34, 197, 94)');
|
||||
}
|
||||
);
|
||||
|
||||
expect(runCLI(`component-test ${buildableLibName} --no-watch`)).toContain(
|
||||
'All specs passed!'
|
||||
);
|
||||
checkFilesDoNotExist(`tmp/libs/${buildableLibName}/ct-styles.css`);
|
||||
}, 300_000);
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { execSync } from 'child_process';
|
||||
import { writeFileSync } from 'fs-extra';
|
||||
import {
|
||||
checkFilesDoNotExist,
|
||||
checkFilesExist,
|
||||
@@ -21,7 +23,9 @@ describe('js e2e', () => {
|
||||
scope = newProject();
|
||||
});
|
||||
|
||||
afterEach(() => cleanupProject());
|
||||
afterEach(() => {
|
||||
cleanupProject();
|
||||
});
|
||||
|
||||
it('should create libs with js executors (--compiler=swc)', async () => {
|
||||
const lib = uniq('lib');
|
||||
@@ -116,4 +120,50 @@ describe('js e2e', () => {
|
||||
'peerDependencies.@swc/helpers'
|
||||
);
|
||||
}, 240_000);
|
||||
|
||||
it('should handle swcrc path mappings', async () => {
|
||||
const lib = uniq('lib');
|
||||
runCLI(`generate @nrwl/js:lib ${lib} --compiler=swc --no-interactive`);
|
||||
|
||||
// add a dummy x.ts file for path mappings
|
||||
updateFile(
|
||||
`libs/${lib}/src/x.ts`,
|
||||
`
|
||||
export function x() {
|
||||
console.log('x');
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
// update .swcrc to use path mappings
|
||||
updateJson(`libs/${lib}/.swcrc`, (json) => {
|
||||
json.jsc.paths = {
|
||||
'src/*': ['src/*'],
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
// update lib.ts to use x
|
||||
updateFile(`libs/${lib}/src/lib/${lib}.ts`, () => {
|
||||
return `
|
||||
// @ts-ignore
|
||||
import { x } from 'src/x';
|
||||
|
||||
export function myLib() {
|
||||
console.log(x());
|
||||
}
|
||||
|
||||
myLib();
|
||||
`;
|
||||
});
|
||||
|
||||
// now run build
|
||||
runCLI(`build ${lib}`);
|
||||
|
||||
// invoke the lib with node
|
||||
const result = execSync(`node dist/libs/${lib}/src/lib/${lib}.js`, {
|
||||
cwd: tmpProjPath(),
|
||||
}).toString();
|
||||
expect(result).toContain('x');
|
||||
}, 240_000);
|
||||
});
|
||||
|
||||
@@ -180,8 +180,6 @@ describe('Nx Affected and Graph Tests', () => {
|
||||
mylib = uniq('mylib');
|
||||
const nxJson: NxJsonConfiguration = readJson('nx.json');
|
||||
|
||||
delete nxJson.implicitDependencies;
|
||||
|
||||
updateFile('nx.json', JSON.stringify(nxJson));
|
||||
runCommand(`git init`);
|
||||
runCommand(`git config user.email "test@test.com"`);
|
||||
@@ -266,6 +264,24 @@ describe('Nx Affected and Graph Tests', () => {
|
||||
implicitDependencies: [],
|
||||
}));
|
||||
});
|
||||
|
||||
it('should handle file renames', () => {
|
||||
generateAll();
|
||||
|
||||
// Move file
|
||||
updateFile(
|
||||
`apps/${myapp2}/src/index.html`,
|
||||
readFile(`apps/${myapp}/src/index.html`)
|
||||
);
|
||||
removeFile(`apps/${myapp}/src/index.html`);
|
||||
|
||||
const affectedProjects = runCLI(
|
||||
'print-affected --uncommitted --select projects'
|
||||
).split(', ');
|
||||
|
||||
expect(affectedProjects).toContain(myapp);
|
||||
expect(affectedProjects).toContain(myapp2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('print-affected', () => {
|
||||
|
||||
@@ -535,6 +535,10 @@ export function runCypressTests() {
|
||||
if (process.env.NX_E2E_RUN_CYPRESS === 'true') {
|
||||
ensureCypressInstallation();
|
||||
return true;
|
||||
} else {
|
||||
console.warn(
|
||||
'Not running Cypress because NX_E2E_RUN_CYPRESS is not set to true.'
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"packages": ["build/packages/*", "build/packages/nx/native-packages/*"],
|
||||
"version": "15.8.1",
|
||||
"version": "15.8.2",
|
||||
"granularPathspec": false,
|
||||
"command": {
|
||||
"publish": {
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
"requires": {
|
||||
"@angular/core": ">=15.0.0"
|
||||
},
|
||||
"description": "Remove browserlist config as it's handled by build-angular",
|
||||
"description": "Remove browserslist config as it's handled by build-angular",
|
||||
"factory": "./src/migrations/update-15-2-0/remove-browserlist-config"
|
||||
},
|
||||
"update-typescript-target": {
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
workspaceRoot,
|
||||
} from '@nrwl/devkit';
|
||||
import { existsSync, lstatSync, mkdirSync, writeFileSync } from 'fs';
|
||||
import { dirname, join, relative } from 'path';
|
||||
import { dirname, join, relative, sep } from 'path';
|
||||
import type { BrowserBuilderSchema } from '../src/builders/webpack-browser/webpack-browser.impl';
|
||||
|
||||
/**
|
||||
@@ -168,13 +168,22 @@ function normalizeBuildTargetOptions(
|
||||
);
|
||||
const buildOptions = withSchemaDefaults(options);
|
||||
|
||||
// polyfill entries might be local files or files that are resolved from node_modules
|
||||
// like zone.js.
|
||||
// prevents error from webpack saying can't find <offset>/zone.js.
|
||||
const handlePolyfillPath = (polyfill: string) => {
|
||||
const maybeFullPath = join(workspaceRoot, polyfill.split('/').join(sep));
|
||||
if (existsSync(maybeFullPath)) {
|
||||
return joinPathFragments(offset, polyfill);
|
||||
}
|
||||
return polyfill;
|
||||
};
|
||||
// paths need to be unix paths for angular devkit
|
||||
buildOptions.polyfills =
|
||||
Array.isArray(buildOptions.polyfills) && buildOptions.polyfills.length > 0
|
||||
? (buildOptions.polyfills as string[]).map((p) =>
|
||||
joinPathFragments(offset, p)
|
||||
)
|
||||
: joinPathFragments(offset, buildOptions.polyfills as string);
|
||||
? (buildOptions.polyfills as string[]).map((p) => handlePolyfillPath(p))
|
||||
: handlePolyfillPath(buildOptions.polyfills as string);
|
||||
|
||||
buildOptions.main = joinPathFragments(offset, buildOptions.main);
|
||||
buildOptions.index =
|
||||
typeof buildOptions.index === 'string'
|
||||
@@ -197,6 +206,7 @@ function normalizeBuildTargetOptions(
|
||||
// then we don't want to have the assets/scripts/styles be included to
|
||||
// prevent inclusion of unintended stuff like tailwind
|
||||
if (
|
||||
buildContext.projectName === ctContext.projectName ||
|
||||
isCtProjectUsingBuildProject(
|
||||
ctContext.projectGraph,
|
||||
buildContext.projectName,
|
||||
|
||||
@@ -39,20 +39,36 @@ export function getTempTailwindPath(context: ExecutorContext) {
|
||||
}
|
||||
|
||||
/**
|
||||
* also returns true if the ct project and build project are the same.
|
||||
* i.e. component testing inside an app.
|
||||
*/
|
||||
* Checks if the childProjectName is a decendent of the parentProjectName
|
||||
* in the project graph
|
||||
**/
|
||||
export function isCtProjectUsingBuildProject(
|
||||
graph: ProjectGraph,
|
||||
parentProjectName: string,
|
||||
childProjectName: string
|
||||
) {
|
||||
return (
|
||||
parentProjectName === childProjectName ||
|
||||
graph.dependencies[parentProjectName].some(
|
||||
(p) => p.target === childProjectName
|
||||
)
|
||||
): boolean {
|
||||
const isProjectDirectDep = graph.dependencies[parentProjectName].some(
|
||||
(p) => p.target === childProjectName
|
||||
);
|
||||
if (isProjectDirectDep) {
|
||||
return true;
|
||||
}
|
||||
const maybeIntermediateProjects = graph.dependencies[
|
||||
parentProjectName
|
||||
].filter((p) => !graph.externalNodes[p.target]);
|
||||
|
||||
for (const maybeIntermediateProject of maybeIntermediateProjects) {
|
||||
if (
|
||||
isCtProjectUsingBuildProject(
|
||||
graph,
|
||||
maybeIntermediateProject.target,
|
||||
childProjectName
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getProjectConfigByPath(
|
||||
|
||||
@@ -202,6 +202,13 @@ export function getRelativeImportPath(exportedMember, filePath, basePath) {
|
||||
dirname(filePath),
|
||||
`${modulePath}.ts`
|
||||
);
|
||||
if (!existsSync(moduleFilePath)) {
|
||||
// might be a tsx file
|
||||
moduleFilePath = joinPathFragments(
|
||||
dirname(filePath),
|
||||
`${modulePath}.tsx`
|
||||
);
|
||||
}
|
||||
if (!existsSync(moduleFilePath)) {
|
||||
// might be a index.ts
|
||||
moduleFilePath = joinPathFragments(
|
||||
|
||||
@@ -131,6 +131,40 @@ export default {
|
||||
expect(packageJson.devDependencies['@types/jest']).toBeDefined();
|
||||
expect(packageJson.devDependencies['ts-jest']).toBeDefined();
|
||||
expect(packageJson.devDependencies['ts-node']).toBeDefined();
|
||||
expect(packageJson.devDependencies['jest-environment-jsdom']).toBeDefined();
|
||||
expect(
|
||||
packageJson.devDependencies['jest-environment-node']
|
||||
).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should add dependencies --testEnvironment=node', async () => {
|
||||
await jestInitGenerator(tree, { testEnvironment: 'node' });
|
||||
const packageJson = readJson(tree, 'package.json');
|
||||
expect(packageJson.devDependencies.jest).toBeDefined();
|
||||
expect(packageJson.devDependencies['@nrwl/jest']).toBeDefined();
|
||||
expect(packageJson.devDependencies['@types/jest']).toBeDefined();
|
||||
expect(packageJson.devDependencies['ts-jest']).toBeDefined();
|
||||
expect(packageJson.devDependencies['ts-node']).toBeDefined();
|
||||
expect(packageJson.devDependencies['jest-environment-node']).toBeDefined();
|
||||
expect(
|
||||
packageJson.devDependencies['jest-environment-jsdom']
|
||||
).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should add dependencies --testEnvironment=none', async () => {
|
||||
await jestInitGenerator(tree, { testEnvironment: 'none' });
|
||||
const packageJson = readJson(tree, 'package.json');
|
||||
expect(packageJson.devDependencies.jest).toBeDefined();
|
||||
expect(packageJson.devDependencies['@nrwl/jest']).toBeDefined();
|
||||
expect(packageJson.devDependencies['@types/jest']).toBeDefined();
|
||||
expect(packageJson.devDependencies['ts-jest']).toBeDefined();
|
||||
expect(packageJson.devDependencies['ts-node']).toBeDefined();
|
||||
expect(
|
||||
packageJson.devDependencies['jest-environment-jsdom']
|
||||
).not.toBeDefined();
|
||||
expect(
|
||||
packageJson.devDependencies['jest-environment-node']
|
||||
).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should make js jest files', async () => {
|
||||
|
||||
@@ -33,6 +33,7 @@ const schemaDefaults = {
|
||||
compiler: 'tsc',
|
||||
js: false,
|
||||
rootProject: false,
|
||||
testEnvironment: 'jsdom',
|
||||
} as const;
|
||||
|
||||
function generateGlobalConfig(tree: Tree, isJS: boolean) {
|
||||
@@ -146,7 +147,6 @@ function updateDependencies(tree: Tree, options: NormalizedSchema) {
|
||||
const devDeps = {
|
||||
'@nrwl/jest': nxVersion,
|
||||
jest: jestVersion,
|
||||
'jest-environment-jsdom': jestVersion,
|
||||
|
||||
// because the default jest-preset uses ts-jest,
|
||||
// jest will throw an error if it's not installed
|
||||
@@ -154,6 +154,10 @@ function updateDependencies(tree: Tree, options: NormalizedSchema) {
|
||||
'ts-jest': tsJestVersion,
|
||||
};
|
||||
|
||||
if (options.testEnvironment !== 'none') {
|
||||
devDeps[`jest-environment-${options.testEnvironment}`] = jestVersion;
|
||||
}
|
||||
|
||||
if (!options.js) {
|
||||
devDeps['ts-node'] = tsNodeVersion;
|
||||
devDeps['@types/jest'] = jestTypesVersion;
|
||||
|
||||
@@ -2,6 +2,7 @@ export interface JestInitSchema {
|
||||
compiler?: 'tsc' | 'babel' | 'swc';
|
||||
js?: boolean;
|
||||
skipPackageJson?: boolean;
|
||||
testEnvironment?: 'node' | 'jsdom' | 'none';
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,13 @@
|
||||
"description": "Do not add dependencies to `package.json`.",
|
||||
"x-priority": "internal"
|
||||
},
|
||||
"testEnvironment": {
|
||||
"type": "string",
|
||||
"enum": ["jsdom", "node", "none"],
|
||||
"description": "The test environment for jest. This controls which jest-environment-* package is installed",
|
||||
"default": "jsdom",
|
||||
"x-priority": "important"
|
||||
},
|
||||
"js": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
|
||||
@@ -18,15 +18,13 @@ const schemaDefaults = {
|
||||
skipSetupFile: false,
|
||||
skipSerializers: false,
|
||||
rootProject: false,
|
||||
testEnvironment: 'jsdom',
|
||||
} as const;
|
||||
|
||||
function normalizeOptions(options: JestProjectSchema) {
|
||||
if (!options.testEnvironment) {
|
||||
options.testEnvironment = 'jsdom';
|
||||
}
|
||||
if (options.testEnvironment === 'jsdom') {
|
||||
options.testEnvironment = '';
|
||||
}
|
||||
|
||||
if (!options.hasOwnProperty('supportTsx')) {
|
||||
options.supportTsx = false;
|
||||
|
||||
@@ -31,6 +31,11 @@ export function createFiles(tree: Tree, options: JestProjectSchema) {
|
||||
generateFiles(tree, join(__dirname, filesFolder), projectConfig.root, {
|
||||
tmpl: '',
|
||||
...options,
|
||||
// jsdom is the default
|
||||
testEnvironment:
|
||||
options.testEnvironment === 'none' || options.testEnvironment === 'jsdom'
|
||||
? ''
|
||||
: options.testEnvironment,
|
||||
transformer,
|
||||
transformerOptions,
|
||||
js: !!options.js,
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ export interface JestProjectSchema {
|
||||
skipSetupFile?: boolean;
|
||||
setupFile?: 'angular' | 'web-components' | 'none';
|
||||
skipSerializers?: boolean;
|
||||
testEnvironment?: 'node' | 'jsdom' | '';
|
||||
testEnvironment?: 'node' | 'jsdom' | 'none';
|
||||
/**
|
||||
* @deprecated use compiler: "babel" instead
|
||||
*/
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
},
|
||||
"testEnvironment": {
|
||||
"type": "string",
|
||||
"enum": ["jsdom", "node"],
|
||||
"enum": ["jsdom", "node", "none"],
|
||||
"description": "The test environment for jest.",
|
||||
"default": "jsdom",
|
||||
"x-priority": "important"
|
||||
|
||||
@@ -42,7 +42,7 @@ module.exports = function (api: any, options: NxWebBabelPresetOptions = {}) {
|
||||
process.env.NODE_ENV === 'test'
|
||||
? { targets: { node: 'current' }, loose: true }
|
||||
: {
|
||||
// Allow importing core-js in entrypoint and use browserlist to select polyfills.
|
||||
// Allow importing core-js in entrypoint and use browserslist to select polyfills.
|
||||
useBuiltIns: options.useBuiltIns ?? 'entry',
|
||||
corejs: 3,
|
||||
// Do not transform modules to CJS
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ExecutorContext } from '@nrwl/devkit';
|
||||
import { ExecutorContext, readJsonFile, writeJsonFile } from '@nrwl/devkit';
|
||||
import {
|
||||
assetGlobsToFiles,
|
||||
FileInputOutput,
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
import { compileSwc, compileSwcWatch } from '../../utils/swc/compile-swc';
|
||||
import { getSwcrcPath } from '../../utils/swc/get-swcrc-path';
|
||||
import { generateTmpSwcrc } from '../../utils/swc/inline';
|
||||
import type { Options } from '@swc/core';
|
||||
|
||||
export function normalizeOptions(
|
||||
options: SwcExecutorOptions,
|
||||
@@ -68,7 +69,21 @@ export function normalizeOptions(
|
||||
// default to current directory if projectRootParts is [].
|
||||
// Eg: when a project is at the root level, outside of layout dir
|
||||
const swcCwd = projectRootParts.join('/') || '.';
|
||||
const swcrcPath = getSwcrcPath(options, contextRoot, projectRoot);
|
||||
let swcrcPath = getSwcrcPath(options, contextRoot, projectRoot);
|
||||
|
||||
try {
|
||||
const swcrcContent = readJsonFile(swcrcPath) as Options;
|
||||
// if we have path mappings setup but baseUrl isn't specified, then we're proceeding with the following logic
|
||||
if (
|
||||
swcrcContent.jsc &&
|
||||
swcrcContent.jsc.paths &&
|
||||
!swcrcContent.jsc.baseUrl
|
||||
) {
|
||||
swcrcContent.jsc.baseUrl = `./${projectDir}`;
|
||||
swcrcPath = getSwcrcPath(options, contextRoot, projectRoot, true);
|
||||
writeJsonFile(swcrcPath, swcrcContent);
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
const swcCliOptions = {
|
||||
srcPath: projectDir,
|
||||
@@ -190,7 +205,7 @@ export async function* swcExecutor(
|
||||
}
|
||||
|
||||
function removeTmpSwcrc(swcrcPath: string) {
|
||||
if (swcrcPath.startsWith('tmp/')) {
|
||||
if (swcrcPath.includes('tmp/') && swcrcPath.includes('.generated.swcrc')) {
|
||||
removeSync(dirname(swcrcPath));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,14 @@ import { SwcExecutorOptions } from '../schema';
|
||||
export function getSwcrcPath(
|
||||
options: SwcExecutorOptions,
|
||||
contextRoot: string,
|
||||
projectRoot: string
|
||||
projectRoot: string,
|
||||
temp = false
|
||||
) {
|
||||
return options.swcrc
|
||||
? join(contextRoot, options.swcrc)
|
||||
: join(contextRoot, projectRoot, '.swcrc');
|
||||
let swcrcPath = options.swcrc ?? join(projectRoot, '.swcrc');
|
||||
|
||||
if (temp) {
|
||||
swcrcPath = join('tmp', swcrcPath.replace('.swcrc', '.generated.swcrc'));
|
||||
}
|
||||
|
||||
return join(contextRoot, swcrcPath);
|
||||
}
|
||||
|
||||
@@ -267,6 +267,7 @@ export async function addLintingToApplication(
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
skipFormat: true,
|
||||
setParserOptionsProject: options.setParserOptionsProject,
|
||||
rootProject: options.rootProject,
|
||||
});
|
||||
|
||||
return lintTask;
|
||||
|
||||
@@ -47,7 +47,9 @@ export async function initGenerator(tree: Tree, schema: Schema) {
|
||||
})
|
||||
);
|
||||
if (options.unitTestRunner === 'jest') {
|
||||
tasks.push(await jestInitGenerator(tree, schema));
|
||||
tasks.push(
|
||||
await jestInitGenerator(tree, { ...schema, testEnvironment: 'node' })
|
||||
);
|
||||
}
|
||||
|
||||
tasks.push(updateDependencies(tree));
|
||||
|
||||
@@ -49,6 +49,12 @@ describe('lib', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(
|
||||
readJson(tree, 'package.json').devDependencies['jest-environment-jsdom']
|
||||
).not.toBeDefined();
|
||||
expect(
|
||||
readJson(tree, 'package.json').devDependencies['jest-environment-node']
|
||||
).toBeDefined();
|
||||
});
|
||||
|
||||
it('adds srcRootForCompilationRoot', async () => {
|
||||
|
||||
@@ -62,6 +62,10 @@ if (
|
||||
|
||||
// this file is already in the local workspace
|
||||
if (localNx === resolveNx(null)) {
|
||||
if (localNx.includes('.nx') && !process.env.NX_WRAPPER_SET) {
|
||||
const nxWrapperPath = localNx.replace(/\.nx.*/, '.nx/') + 'nxw.js';
|
||||
require(nxWrapperPath);
|
||||
}
|
||||
initLocal(workspace);
|
||||
} else {
|
||||
// Nx is being run from globally installed CLI - hand off to the local
|
||||
|
||||
@@ -47,6 +47,12 @@
|
||||
"version": "15.0.12-beta.1",
|
||||
"description": "Set project names in project.json files",
|
||||
"implementation": "./src/migrations/update-15-1-0/set-project-names"
|
||||
},
|
||||
"15.8.2-update-nx-wrapper": {
|
||||
"cli": "nx",
|
||||
"version": "15.8.2-beta.0",
|
||||
"description": "Updates the nx wrapper in encapsulated repos.",
|
||||
"implementation": "./src/migrations/update-15-8-2/update-nxw"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,11 @@ function findVersion(
|
||||
) {
|
||||
return snapshot.resolution.slice(packageName.length + 1);
|
||||
}
|
||||
if (!isBerry && !satisfies(snapshot.version, versionRange)) {
|
||||
if (
|
||||
!isBerry &&
|
||||
snapshot.resolved &&
|
||||
!satisfies(snapshot.version, versionRange)
|
||||
) {
|
||||
return snapshot.resolved;
|
||||
}
|
||||
// otherwise it's a standard version
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import {
|
||||
getNxWrapperContents,
|
||||
nxWrapperPath,
|
||||
} from 'nx/src/nx-init/encapsulated/add-nx-scripts';
|
||||
import { normalizePath } from '../../utils/path';
|
||||
import { Tree } from '../../generators/tree';
|
||||
|
||||
export default async function (tree: Tree) {
|
||||
const wrapperPath = normalizePath(nxWrapperPath());
|
||||
if (tree.exists(wrapperPath)) {
|
||||
tree.write(wrapperPath, getNxWrapperContents());
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from '../../generators/tree';
|
||||
import { writeJson } from '../../generators/utils/json';
|
||||
|
||||
const nxWrapperPath = (p: typeof import('path') = path) =>
|
||||
export const nxWrapperPath = (p: typeof import('path') = path) =>
|
||||
p.join('.nx', 'nxw.js');
|
||||
|
||||
const NODE_MISSING_ERR =
|
||||
@@ -36,7 +36,7 @@ export function generateEncapsulatedNxSetup(version?: string) {
|
||||
const host = new FsTree(process.cwd(), false);
|
||||
writeMinimalNxJson(host, version);
|
||||
updateGitIgnore(host);
|
||||
host.write(nxWrapperPath(), getNodeScriptContents());
|
||||
host.write(nxWrapperPath(), getNxWrapperContents());
|
||||
host.write('nx.bat', BATCH_SCRIPT_CONTENTS);
|
||||
host.write('nx', SHELL_SCRIPT_CONTENTS, {
|
||||
mode: FsConstants.S_IXUSR | FsConstants.S_IRUSR | FsConstants.S_IWUSR,
|
||||
@@ -75,7 +75,7 @@ export function updateGitIgnore(host: Tree) {
|
||||
);
|
||||
}
|
||||
|
||||
function getNodeScriptContents() {
|
||||
export function getNxWrapperContents() {
|
||||
// Read nxw.js, but remove any empty comments or comments that start with `//#: `
|
||||
// This removes the sourceMapUrl since it is invalid, as well as any internal comments.
|
||||
return readFileSync(path.join(__dirname, 'nxw.js'), 'utf-8').replace(
|
||||
|
||||
@@ -99,7 +99,8 @@ function ensureUpToDateInstallation() {
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
if (require.main === module && !process.env.NX_WRAPPER_SET) {
|
||||
process.env.NX_WRAPPER_SET = 'true';
|
||||
ensureUpToDateInstallation();
|
||||
require('./installation/node_modules/nx/bin/nx');
|
||||
}
|
||||
|
||||
+3
@@ -116,16 +116,19 @@ describe('explicit package json dependencies', () => {
|
||||
sourceProjectName: 'proj',
|
||||
targetProjectName: 'proj2',
|
||||
sourceProjectFile: 'libs/proj/package.json',
|
||||
type: 'static',
|
||||
},
|
||||
{
|
||||
sourceProjectFile: 'libs/proj/package.json',
|
||||
sourceProjectName: 'proj',
|
||||
targetProjectName: 'npm:external',
|
||||
type: 'static',
|
||||
},
|
||||
{
|
||||
sourceProjectName: 'proj',
|
||||
targetProjectName: 'proj3',
|
||||
sourceProjectFile: 'libs/proj/package.json',
|
||||
type: 'static',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
+7
-1
@@ -1,6 +1,10 @@
|
||||
import { defaultFileRead } from '../file-utils';
|
||||
import { join } from 'path';
|
||||
import { ProjectFileMap, ProjectGraph } from '../../config/project-graph';
|
||||
import {
|
||||
DependencyType,
|
||||
ProjectFileMap,
|
||||
ProjectGraph,
|
||||
} from '../../config/project-graph';
|
||||
import { parseJson } from '../../utils/json';
|
||||
import { getImportPath, joinPathFragments } from '../../utils/path';
|
||||
import { ProjectsConfigurations } from '../../config/workspace-json-project-json';
|
||||
@@ -88,12 +92,14 @@ function processPackageJson(
|
||||
sourceProjectName: sourceProject,
|
||||
targetProjectName: packageNameMap[d],
|
||||
sourceProjectFile: fileName,
|
||||
type: DependencyType.static,
|
||||
});
|
||||
} else if (graph.externalNodes[`npm:${d}`]) {
|
||||
collectedDeps.push({
|
||||
sourceProjectName: sourceProject,
|
||||
targetProjectName: `npm:${d}`,
|
||||
sourceProjectFile: fileName,
|
||||
type: DependencyType.static,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -222,7 +222,7 @@ export function parseFiles(options: NxArgs): { files: string[] } {
|
||||
}
|
||||
|
||||
function getUncommittedFiles(): string[] {
|
||||
return parseGitOutput(`git diff --name-only --relative HEAD .`);
|
||||
return parseGitOutput(`git diff --name-only --no-renames --relative HEAD .`);
|
||||
}
|
||||
|
||||
``;
|
||||
@@ -249,7 +249,7 @@ function getFilesUsingBaseAndHead(base: string, head: string): string[] {
|
||||
.trim();
|
||||
}
|
||||
return parseGitOutput(
|
||||
`git diff --name-only --relative "${mergeBase}" "${head}"`
|
||||
`git diff --name-only --no-renames --relative "${mergeBase}" "${head}"`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -203,6 +203,7 @@ export function registerPluginTSTranspiler() {
|
||||
lib: ['es2021'],
|
||||
module: ts.ModuleKind.CommonJS,
|
||||
target: ts.ScriptTarget.ES2021,
|
||||
inlineSourceMap: true,
|
||||
esModuleInterop: true,
|
||||
skipLibCheck: true,
|
||||
experimentalDecorators: true,
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vite": "^4.0.1",
|
||||
"vitest": "^0.25.8"
|
||||
"vitest": ">=0.25.8 <1.0.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@@ -19,6 +19,7 @@ import { ViteDevServerExecutorOptions } from '../executors/dev-server/schema';
|
||||
import { VitePreviewServerExecutorOptions } from '../executors/preview-server/schema';
|
||||
import replaceFiles from '../../plugins/rollup-replace-files.plugin';
|
||||
import { ViteBuildExecutorOptions } from '../executors/build/schema';
|
||||
import * as path from 'path';
|
||||
|
||||
/**
|
||||
* Returns the path to the vite config file or undefined when not found.
|
||||
@@ -70,9 +71,14 @@ export function getViteSharedConfig(
|
||||
const projectRoot =
|
||||
context.projectsConfigurations.projects[context.projectName].root;
|
||||
|
||||
const root = path.relative(
|
||||
context.cwd,
|
||||
joinPathFragments(context.root, projectRoot)
|
||||
);
|
||||
|
||||
return {
|
||||
mode: options.mode,
|
||||
root: projectRoot,
|
||||
root,
|
||||
base: options.base,
|
||||
configFile: normalizeViteConfigFilePath(projectRoot, options.configFile),
|
||||
plugins: [replaceFiles(options.fileReplacements) as PluginOption],
|
||||
|
||||
Reference in New Issue
Block a user