Contents of this file:
- Requirements
- Dependency Management
- Angular Module Architecture
- Developing against the Hab Studio
- Project History
- Best Practices for developing in Automate-UI
- Creating a new component
- Running tests
- Fixing typescript lint errors
- CSS, SCSS & Styling
- Getting sample data into your Automate-UI instance
- Build
- Further help
- Troubleshooting
-
node. We currently use node 12.13.1, but the current version number is always present in the .nvmrc file. Use NVM to install node.
-
npm. We currently use npm 6.12.1 which ships with node 12.13.1 so no additional installation should be necessary.
-
direnv. This can be installed with
brew install direnv
. With this installed, once you enter the project directory you'll be prompted to rundirenv allow
. -
To ensure you're using the correct version of node, run
nvm use
from/automate-ui
and install the correct version if necessary. -
Once everything is setup correctly you should be able to
npm install
without any permission errors.
Having a Github token in .netrc
allows some command line utilities (including
git) to access private repositories in a secure way that is more granularly
revokable than using ssh or a password. Read more about
accessing git and Github with tokens in this post from the Github blog..
Certain packages in package.json are constrained for the reasons detailed here. At any future moment though, the reasons for constraint here could be invalidated, so this should be updated as needed when package.json is updated. While it is problematic to document this information due to the maintenance burden, the value of having this in one place outweighs that burden.
awaiting the release of ngrx 11. Until then, we will get incompatible peer dependencies if we try to update to latest.
"@angular-devkit/build-angular" has an incompatible peer dependency to Karma which requires ~5.1.0.
"@angular-devkit/build-angular" has an incompatible peer dependency to typescript which requires ~4.0.0
Newer versions of jwt_decode introduce a new import format, which is breaking some of our testing.
Reason: Later releases are release candidates; should only be using production-releases.
Per chef#1867, future versions have made a breaking change so it breaks our code base.
Per: https://www.npmjs.com/package/zone.js?activeTab=readme, Starting with v0.11.1, A breaking change is introduced for legacy browsers such as IE11. If we are no longer supporting IE 11, we are safe to upgrade, otherwise we can instead import 'zone.js/dist/zone';
There is a also an incompatible peer dependency with angular/core that will be cleared up in Angular 11.1.0 re: angular/angular#39094 (comment)
As a very brief introduction to the Angular architecture, it all starts with app.module.ts, shown at the top of the diagram. There are a variety of submodules included in that root module, and then just a couple that are the shared modules, ChefComponents and ChefPipes. Note that this does not show the external, Stencil component library.
Please see the extensive "getting started" docs for developing against the habitat dev env.
You may notice that the npm command for running against habitat has a weird public-host flag.
That is because webpack makes some strange decisions when proxies are in play. I followed
this example
and explicitly added sockjs-node
to the proxy and things seemed to work.
Much of our git history was lost when we migrated to the Angular CLI tool.
If you would like to access git history for older components, you can use
the tag git-blame
.
- Locally:
git checkout -b git-blame git-blame
- On GitHub: https://github.com/chef/automate-ui/tree/git-blame
Please familiarize yourself with the best practices of this repo. Additional clarifying documents can be found in the docs folder adjacent to this file.
Angular CLI has a great scaffolding tool -- no need to copy/paste minimal components!
Run ng generate component PATH/TO/COMPONENT-NAME
to generate a new component;
this creates a directory named with the COMPONENT-NAME, with four boilerplate
files in it name-spaced correctly. These files are
COMPONENT-NAME.component.ts
, COMPONENT-NAME.component.html
,
COMPONENT-NAME.component.scss
, COMPONENT-NAME.component.spec.ts
.
For components, the generate
command also updates the appropriate module file to
inject the component itself into the application, so you don't need to add anything
extra to make sure the app knows about your new component!
Our components that are not page views but are specific to a page are currently kept
in /page-components
directory. Components that are generic to the app are kept in
the /components
directory.
So if you were making a new page component--say, an ice-cream picker component--you'd
run: ng generate component page-components/ice-cream-picker --module app
and it would be put in the correct place. The --module app
option makes sure the
component is injected in the app.module.ts file.
Similarly to create a new generic component--say, an ice-cream name generator--you'd
run: ng generate component components/ice-cream-name-generator --prefix chef --export true
.
Note the --export
and --prefix
bits. Since generic components are meant to be used all
over this app, and potentially other future apps, they have a different prefix and must
be exported in order to work properly. Due to the absence of a --module
option the component
will be injected into the nearest module (chef-components.module.ts), which is the correct one.
You can also use ng generate directive|pipe|service|class|guard|interface|enum|module. However, this does not necessarily update the module file; you may have to manually import and inject your new service, etc.
Generating components happens often, so to help with the most common use cases there are a few additional make targets that you can use.
make component/<component name>
will generate a standard reusable component. Equivalent tong generate component components/<component name> --prefix chef --export true
.make page-component/<component name>
will generate a page specific component. Equivalent tong generate component page-components/<component name> --module app
.make demo/<component name>
will generate a demo component for the component library. Equivalent tong generate component pages/component-library/demos/demo-<component name> --spec false
. Note that this does not add a new route to the component library router. You will still need to do that on your own.
There are a plethora of choices for running unit tests and linters, most detailed here.
make unit
to run unit tests NON-interactively on Chrome (actually, a headless Chrome)make unit-all-browsers
to run unit tests NON-interactively on Chrome, Firefox, and Safari simultaneouslymake e2e
to run e2e tests (we currently have nearly none of those)make test
to run bothunit
ande2e
testsmake lint-typescript
to run the typescript lintermake lint-sass
to run the scss/sass lintermake lint-html
to run the HTML lintermake lint
to run all linters
A couple notable options:
-
During development, when you want to do edit-test cycles frequently, use
npm run test:watch
to run unit tests interactively in Chrome. This will keep the Chrome window open and re-run the tests whenever you save a file. If you prefer command-line,npm run test -- --watch=true
will not launch a separate browser window but will still watch for file changes and then re-run your tests. -
When you are readying a pull request, use
make pr-ready
to run all available checks.
Sourcemaps are disabled by default when running tests because they add to the
app's compilation time and can obscure the source of errors. While debugging test failures
in the browser it can be useful to have sourcemaps enabled;
run the tests with npm test -- --sourcemaps=true
to enable them for a test run.
Test execution also generates code coverage data, reporting on how much of
the code base is covered by the unit tests. After running make unit
or make test
the coverage results will be immediately available in /coverage/index.html
.
See the Engineering Excellence wiki
for further details about code coverage in Automate-UI.
Using any of the above unit test runners will execute all the unit tests.
If you wish to have a quicker turn around append an f
to any describe
or it
blocks in the test files. Then just those tests will run.
(See Jasmine's Focused Specs
for further details.)
You can run tests and perform other tasks at several different "layers":
from the makefile, from npm
, and from ng
(Angular) itself.
So, for example, if you want to use arguments other than the defaults for
a makefile operation, you can go to the layer beneath, and provide custom arguments.
The figure shows the structure and the associated configuration file for those
3 layers and more.
If the typescript linter is generating errors, you can run npm run lint -- --fix
to have the linter automatically fix some types of lint problems.
npm start
runs ng serve --proxy-config proxy.conf.js
which reroutes api
requests to the appropriate service.
Once the Automate Gateway is up and running, your Automate-UI dev environment
should have data in both the converge and compliance tabs!
make build
is the canonical way to build the production version of the project with Habitat.npm run build
will build a development version of the project.- For more information on the difference between production and development builds, see Angular CLI's wiki page on the build command
- With either method the build artifacts will be stored in the
dist/
directory.
To get more help on the Angular CLI use ng help
or the Angular CLI README.
When running ng-serve
if you get this error:
constructor(_configPath, schema, configJson, fallbacks = []) {
^
SyntaxError: Unexpected token =
you are probably running the wrong version of npm/node. Please ensure you have the correct versions and try again.
If you get ng: command not found
when running npm start
,
try running rm -rf node_modules
followed by npm install
. Then try running npm start
again.