feat(challenge25): extends Nx custom library

This commit is contained in:
thomas
2023-06-19 22:09:54 +02:00
parent bcf44956f9
commit c9efdea85e
48 changed files with 333 additions and 35 deletions

View File

@@ -78,6 +78,8 @@ If you would like to propose a challenge, this project is open source, so feel f
</br>
<img src="https://img.shields.io/badge/Nx--gray?logo=nx" alt="nx"/>
<a href="./libs/custom-plugin/src/generators/custom-library/README.md"><img src="https://img.shields.io/badge/25-Extends Nx Library generator-red" alt="Create harness"/></a>
## Contributors ✨
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
@@ -86,7 +88,7 @@ If you would like to propose a challenge, this project is open source, so feel f
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://medium.com/@thomas.laforge"><img src="https://avatars.githubusercontent.com/u/30832608?s…00&u=6f0ad9676792f29fd7fe6e113df06213d384a813&v=4" width="100px;" alt="Thomas Laforge"/><br /><sub><b>Thomas Laforge</b></sub></a><br />24 🧩</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://medium.com/@thomas.laforge"><img src="https://avatars.githubusercontent.com/u/30832608?s…00&u=6f0ad9676792f29fd7fe6e113df06213d384a813&v=4" width="100px;" alt="Thomas Laforge"/><br /><sub><b>Thomas Laforge</b></sub></a><br />25 🧩</a></td>
</tr>
</tbody>
</table>

View File

@@ -15,7 +15,7 @@ You begin with an application that has basic navigation and anchor navigation in
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve anchor-scrolling`
5. _...work on it_
6. Commit your work

View File

@@ -36,7 +36,7 @@ But in this part, we can pass to ListComponent, a list of **any object**. And we
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. **nx serve context-outlet-type**
5. _...work On it_
6. Commit your work

View File

@@ -41,7 +41,7 @@ Good luck !!! 💪
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve create-harness`
5. _...work on it_
6. Commit your work

View File

@@ -26,10 +26,7 @@ What you will need to do:
this.todos[todoUpdated.id - 1] = todoUpdated;
// Prefer something like this, but need to be improved because we still want the same order
this.todos = [
...this.todos.filter((t) => t.id !== todoUpdated.id),
todoUpdated,
];
this.todos = [...this.todos.filter((t) => t.id !== todoUpdated.id), todoUpdated];
```
- Use **ChangeDectection.OnPush**
@@ -53,7 +50,7 @@ this.todos = [
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. **nx serve crud**
5. _...work On it_
6. Commit your work

View File

@@ -18,7 +18,7 @@
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. **nx serve declarative-to-reactive**
5. _...work on it_
6. Commit your work

View File

@@ -23,7 +23,7 @@ One way to achieve this is by adding a second argument to the pipe, but this is
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve di`
5. _...work on it_
6. Commit your work

View File

@@ -38,7 +38,7 @@ The goal is to **improve the ngFor directive**
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. **nx serve ngfor-enhancement**
5. _...work On it_
6. Commit your work

View File

@@ -28,7 +28,7 @@ In NgRx, **selectors** is a very powerful tool often **misused**. You should use
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. **nx serve ngrx-1**
5. _...work On it_
6. Commit your work

View File

@@ -29,7 +29,7 @@ the application contain a root route, a lazy loaded route and a component with a
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. **nx serve ngrx-notification**
5. _...work on it_
6. Commit your work

View File

@@ -20,7 +20,7 @@ To achieve this, we will use overload functions.
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. **`npx nx serve overload`**
5. _...work on it_
6. Commit your work

View File

@@ -51,7 +51,7 @@ In **Routes.ts**, route all user to the correct **DashboardComponent** using **C
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. **nx serve permissions**
5. _...work on it_
6. Commit your work

View File

@@ -18,7 +18,7 @@ In this first exercice, you add calling a simple function inside your template.
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve pipe-easy`
5. _...work on it_
6. Commit your work

View File

@@ -18,7 +18,7 @@ In this third exercice, you want to access utils functions. Currently we cannot
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve pipe-hard`
5. _...work on it_
6. Commit your work

View File

@@ -19,7 +19,7 @@ The goal is to create a `wrapFn` pipe to wrap your callback function though a pi
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve pipe-intermediate`
5. _...work on it_
6. Commit your work

View File

@@ -18,7 +18,7 @@ Implement the City card.
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. **nx serve projection**
5. _...work on it_
6. Commit your work

View File

@@ -10,7 +10,7 @@ In this small application, you can pass data though routing to `TestComponent`.
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve router-input`
5. _...work on it_
6. Commit your work

View File

@@ -26,7 +26,7 @@ The QA team reports a **bug**. The UI shows **All [topic] have been deleted** al
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve rxjs-pipe-bug`
5. _...work on it_
6. Commit your work

View File

@@ -24,7 +24,7 @@ WATCH MODE : `npx nx component-test rxjs-race-condition --watch`
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve rxjs-race-condition`
5. _...work on it_
6. Commit your work

View File

@@ -27,7 +27,7 @@ You cannot opt-out of zone.js. If this code is part of a large project and you o
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. **nx serve scroll-cd**
5. _...work on it_
6. Commit your work

View File

@@ -18,7 +18,7 @@ In this challenge, you will need to use both CSS variables and :host-context to
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. **nx serve styling**
5. _...work on it_
6. Commit your work

View File

@@ -22,7 +22,7 @@ I created some `it` blocks but feel free to add more test if you like to. -->
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve testing-forms` to play with the application
5. `npx nx test testing-forms` to test your application with Testing Library
6. `npx nx component-test testing-forms --watch` to test your application with Cypress

View File

@@ -17,7 +17,7 @@ Documentation for Angular Material component is [here](https://material.angular.
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve testing-harness` to play with the application
5. `npx nx test testing-harness` to test your application with Testing Library
6. _...work on it_

View File

@@ -19,7 +19,7 @@ I created some `it` blocks but feel free to add more test if you like to.
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve testing-input-output` to play with the application
5. `npx nx test testing-input-output` to test your application with Testing Library
6. `npx nx component-test testing-input-output --watch` to test your application with Cypress

View File

@@ -22,7 +22,7 @@ I created some `it` blocks but feel free to add more test if you like to.
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve testing-modal` to play with the application
5. `npx nx test testing-modal` to test your application with Testing Library
6. `npx nx component-test testing-modal --watch` to test your application with Cypress

View File

@@ -20,7 +20,7 @@ I created some `it` blocks but feel free to add more test if you like to.
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve testing-nested` to play with the application
5. `npx nx test testing-nested` to test your application with Testing Library
6. `npx nx component-test testing-nested --watch` to test your application with Cypress

View File

@@ -26,7 +26,7 @@ I created some `it` blocks but feel free to add more test if you like to.
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve testing-router-outlet` to play with the application
5. `npx nx test testing-router-outlet` to test your application with Testing Library
6. `npx nx component-test testing-router-outlet --watch` to test your application with Cypress

View File

@@ -22,7 +22,7 @@ I created some `it` blocks but feel free to add more test if you like to. -->
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve testing-table` to play with the application
5. `npx nx test testing-table` to test your application with Testing Library
6. `npx nx component-test testing-table --watch` to test your application with Cypress

View File

@@ -22,7 +22,7 @@ I created some `it` blocks but feel free to add more test if you like to. -->
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve testing-todos-list` to play with the application
5. `npx nx test testing-todos-list` to test your application with Testing Library
6. `npx nx component-test testing-todos-list --watch` to test your application with Cypress

View File

@@ -25,7 +25,7 @@
1. Fork the project
2. clone it
3. npm install
3. npm ci
<!-- TODO: add you project app name directory -->
4. `npx nx serve {project app name}`
5. _...work on it_

View File

@@ -18,7 +18,7 @@
1. Fork the project
2. clone it
3. npm install
3. npm ci
4. `npx nx serve <%= projectName %>`
5. _...work on it_
6. Commit your work

View File

@@ -0,0 +1,25 @@
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
},
{
"files": ["./package.json", "./generators.json"],
"parser": "jsonc-eslint-parser",
"rules": {
"@nx/nx-plugin-checks": "error"
}
}
]
}

View File

@@ -0,0 +1,11 @@
# custom-plugin
This library was generated with [Nx](https://nx.dev).
## Building
Run `nx build custom-plugin` to build the library.
## Running unit tests
Run `nx test custom-plugin` to execute the unit tests via [Jest](https://jestjs.io).

View File

@@ -0,0 +1,9 @@
{
"generators": {
"lib": {
"factory": "./src/generators/custom-library/generator",
"schema": "./src/generators/custom-library/schema.json",
"description": "extends library from nx/cli"
}
}
}

View File

@@ -0,0 +1,10 @@
/* eslint-disable */
export default {
displayName: 'custom-plugin',
preset: '../../jest.preset.js',
transform: {
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/libs/custom-plugin',
};

View File

@@ -0,0 +1,6 @@
{
"name": "@angular-challenges/custom-plugin",
"version": "0.0.1",
"type": "commonjs",
"generators": "./generators.json"
}

View File

@@ -0,0 +1,66 @@
{
"name": "custom-plugin",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/custom-plugin/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nx/js:tsc",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/custom-plugin",
"main": "libs/custom-plugin/src/index.ts",
"tsConfig": "libs/custom-plugin/tsconfig.lib.json",
"assets": [
"libs/custom-plugin/*.md",
{
"input": "./libs/custom-plugin/src",
"glob": "**/!(*.ts)",
"output": "./src"
},
{
"input": "./libs/custom-plugin/src",
"glob": "**/*.d.ts",
"output": "./src"
},
{
"input": "./libs/custom-plugin",
"glob": "generators.json",
"output": "."
},
{
"input": "./libs/custom-plugin",
"glob": "executors.json",
"output": "."
}
]
}
},
"lint": {
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": [
"libs/custom-plugin/**/*.ts",
"libs/custom-plugin/package.json",
"libs/custom-plugin/generators.json"
]
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/custom-plugin/jest.config.ts",
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
}
},
"tags": []
}

View File

@@ -0,0 +1,64 @@
<h1>Create a generator to extends @nx/angular-lib</h1>
> Author: Thomas Laforge
### Information
Welcome to the marvelous world of Nx generators.
Generators are awesome tools that can help you and your team generate code more quickly, especially for pieces of code that you use frequently. While using Nx, you create libraries regularly, but sometimes the default generator doesn't perfectly meet your needs.
### Statement
The goal of this challenge is to create a generator that extends the default library generator of Nx. You will need to override the default `jest.config.ts` and a `eslintrc.json` with a custom one.
You can either use all the default parameters of the Nx library generator or choose to modify some and keep others as defaults. The choice is yours.
### Constraints:
You should only override the jest configuration is the `unitTestRunner` option is set at `JEST`, and you should only update the eslint configuration if the `linter` is set to `eslint`.
---
`jest.config.ts`
```ts
/* eslint-disable */
export default {
displayName: '< libName >', // 👈 lib name
preset: '../../../jest.preset.js', // 👈 be careful with the path
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
transform: {
'^.+\\.(ts|mjs|js|html)$': [
'jest-preset-angular',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
},
],
},
transformIgnorePatterns: ['node_modules/(?!(.*\\.mjs$|lodash-es))'],
};
```
---
`eslintrc.json`
add this rule `"@typescript-eslint/member-ordering": "off"` inside the rules properties of ts files.
### Submitting your work
1. Fork the project
2. clone it
3. npm ci
4. _...work on it_
5. Commit your work
6. Submit a PR with a title beginning with **Answer:25** that I will review and other dev can review.
<a href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A25+label%3Aanswer"><img src="https://img.shields.io/badge/-Solutions-green" alt="extends-lib"/></a>
<a href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A25+label%3A"answer+author"'><img src="https://img.shields.io/badge/-Author solution-important" alt="extends-lib solution author"/></a>
<!-- <a href="{Blog post url}" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/-Blog post explanation-blue" alt="extends-lib blog article"/></a> -->
_You can ask any question on_ <a href="https://twitter.com/laforge_toma" target="_blank" rel="noopener noreferrer"><img src="./../../../../../logo/twitter.svg" height=20px alt="twitter"/></a>

View File

@@ -0,0 +1 @@
const variable = "<%= name %>";

View File

@@ -0,0 +1,20 @@
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { Tree, readProjectConfiguration } from '@nx/devkit';
import { customLibraryGenerator } from './generator';
import { CustomLibraryGeneratorSchema } from './schema';
describe('custom-library generator', () => {
let tree: Tree;
const options: CustomLibraryGeneratorSchema = { name: 'test' };
beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});
it('should run successfully', async () => {
await customLibraryGenerator(tree, options);
const config = readProjectConfiguration(tree, 'test');
expect(config).toBeDefined();
});
});

View File

@@ -0,0 +1,25 @@
import {
addProjectConfiguration,
formatFiles,
generateFiles,
Tree,
} from '@nx/devkit';
import * as path from 'path';
import { CustomLibraryGeneratorSchema } from './schema';
export async function customLibraryGenerator(
tree: Tree,
options: CustomLibraryGeneratorSchema
) {
const projectRoot = `libs/${options.name}`;
addProjectConfiguration(tree, options.name, {
root: projectRoot,
projectType: 'library',
sourceRoot: `${projectRoot}/src`,
targets: {},
});
generateFiles(tree, path.join(__dirname, 'files'), projectRoot, options);
await formatFiles(tree);
}
export default customLibraryGenerator;

View File

@@ -0,0 +1,3 @@
export interface CustomLibraryGeneratorSchema {
name: string;
}

View File

@@ -0,0 +1,18 @@
{
"$schema": "http://json-schema.org/schema",
"$id": "CustomLibrary",
"title": "",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "What name would you like to use?"
}
},
"required": ["name"]
}

View File

View File

@@ -0,0 +1,16 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"module": "commonjs"
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}

View File

@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"declaration": true,
"types": ["node"]
},
"include": ["src/**/*.ts"],
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
}

View File

@@ -0,0 +1,14 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"jest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}

View File

@@ -16,6 +16,7 @@
"baseUrl": ".",
"paths": {
"@angular-challenges/cli": ["libs/cli/src/index.ts"],
"@angular-challenges/custom-plugin": ["libs/custom-plugin/src/index.ts"],
"@angular-challenges/ngrx-notification/backend": [
"libs/ngrx-notification/backend/src/index.ts"
],