-
Notifications
You must be signed in to change notification settings - Fork 137
Create a new Component in Fundamental‐NGX
Fundamental-NGX Library is a fairly standard NX workspace, with some customizations.
In NX world a project is an encapsulated unit of code. Projects can be Applications and Libraries.
The Application is the main entry point for a runnable application and it depends on the Libraries. In Fundamental-NGX case, this is the website documentation that runs the components examples. It's located in the apps folder.
The Libraries are isolated units of code that can be shared code, features, buildable packages for distribution, etc. They are located in the libs folder. The subfolders cdk, core, platform, fn, etc. are libraries that are used for the npm packages. The individual components, such as button, input field, avatar, etc., are also NX buildable projects, but they don't end up as a separate npm project.

Let's add a new component called Generic Tag to Fundamental-NGX Core library.
index.tsng-package.json
Go to the tsconfig.base.json file of the root project and add the index.ts to the paths object of compilerOptions.
"@fundamental-ngx/core/generic-tag": ["libs/core/src/lib/generic-tag/index.ts"],
In the ng-package.json file add the following code:
{
"$schema": "../../../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../../../dist/libs/core/generic-tag",
"lib": {
"entryFile": "./index.ts"
}
}
With this step, the new component is included in the Angular eco-system.
project.json tells NX that this component folder is now an NX project.
{
"name": "core-generic-tag",
"$schema": "../../../../../node_modules/nx/schemas/project-schema.json",
"projectType": "library",
"sourceRoot": "libs/core/src/lib/generic-tag",
"prefix": "fd",
"targets": {
"build": {
"executor": "@nx/angular:ng-packagr-lite",
"outputs": ["{workspaceRoot}/dist/libs/core/generic-tag"],
"options": {
"tsConfig": "libs/core/src/lib/generic-tag/tsconfig.lib.json",
"project": "libs/core/src/lib/generic-tag/ng-package.json",
"updateBuildableProjectDepsInPackageJson": false
},
"configurations": {
"production": {
"tsConfig": "libs/core/src/lib/generic-tag/tsconfig.lib.prod.json"
}
}
},
"lint": {
"executor": "@nx/linter:eslint",
"options": {
"lintFilePatterns": ["libs/core/src/lib/generic-tag/**/*.ts", "libs/core/src/lib/generic-tag/**/*.html"]
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/core/src/lib/generic-tag/jest.config.ts",
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
}
},
"tags": ["type:lib", "scope:fd"]
}
This step includes Generic Tag in the NX eco-system.
The configuration will create 3 targets for NX: build, lint and test.
Each target specifies the executor (the code that executes/runs the target) with a specific set of options.
-
Outputs tell Nx where the target is going to create file artifacts that Nx should cache.
For example,
"outputs": ["{workspaceRoot}/dist/libs/core/generic-tag"]tells Nx where the build target is going to create file artifacts. - Options is an object that contains any configuration defaults for the executor. These options vary from executor to executor.
- Configurations allows you to create presets of options for different scenarios. All the configurations start with the properties defined in options as a baseline and then overwrite those options.
-
Tags are used for expressing constraints on project dependencies. You can check the base configuration in the
.eslintrc.jsonfile in thedepConstraintsarray.
From another component in the fundamental-ngx/libs/core/src/lib folder copy the following 4 configuration files:
-
tsconfig.json- specifies the root files and the compiler options required to compile the project tsconfig.lib.jsontsconfig.lib.prod.jsontsconfig.spec.json
Like for the tsconfig files, copy this file from another projects. It's identical for all components and is used for defining the configuration structure of ESLint. This file will overwrite the parent .eslintrc.json file
{
"name": "@fundamental-ngx/core/generic-tag",
"version": "VERSION_PLACEHOLDER",
"peerDependencies": {
"@angular/common": "ANGULAR_VER_PLACEHOLDER",
"@angular/core": "ANGULAR_VER_PLACEHOLDER"
},
"dependencies": {
"tslib": "^2.0.0"
}
}
-
generic-tag.component.scss- the component CSS file. Imports the CSS code from Fundamental-stylesdistfolder
@import 'fundamental-styles/dist/generic-tag';
-
generic-tag.component.html- the component markup
<div class="fd-generic-tag">Test</div>
-
generic-tag.component.spec.ts- unit tests file -
generic-tag.component.ts- component logic file
import { Component, ViewEncapsulation, ChangeDetectionStrategy } from '@angular/core';
import { FD_GENERIC_TAG_COMPONENT } from './tokens';
@Component({
selector: 'fd-generic-tag',
templateUrl: './generic-tag.component.html',
styleUrls: ['./generic-tag.component.scss'],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
{
provide: FD_GENERIC_TAG_COMPONENT,
useExisting: GenericTagComponent
}
]
})
export class GenericTagComponent {
}
-
generic-tag.module.ts- component module file
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { GenericTagComponent } from './generic-tag.component';
@NgModule({
imports: [CommonModule],
exports: [GenericTagComponent],
declarations: [GenericTagComponent]
})
export class GenericTagModule {}
-
tokens.ts- Component Injection Token file
import { InjectionToken } from '@angular/core';
export const FD_GENERIC_TAG_COMPONENT = new InjectionToken('FdGenericTagComponent');
Now in the index.ts export the component logic, its module and token:
export * from './generic-tag.module';
export * from './generic-tag.component';
export * from './tokens';
Note: please note that this example is very simplified for illustration purposes. Your component folder can contain services, directives, etc.
import baseConfig from '../../../../../jest.config.base';
export default {
...baseConfig,
displayName: 'core-generic-tag',
preset: '../../../../../jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts', '../../../../../jest-extended-matchers.ts'],
coverageDirectory: '../../../../../dist/coverage/core-generic-tag'
};
You can copy the README.md file from another component and modify it per your needs.
Your final file structure should look something like this: