We currently use Webpack and npm scripts for our build
Without going into too much detail, the main tools we use in our build are:
- Typescript, which we transpile to ES5.
- Sass as CSS preprocessor.
- Autoprefixer to ensure consistent cross-browser styles.
- webpack as bundler and minifier.
- webpack-dev-server as live development server.
- Jasmine as test framework.
- Karma as test runner, running by default on Headless Chrome.
- TSLint as linter for Typescript.
- clang-format as formatter for Typescript.
- Gemini for screenshot-based css regression tests.
- Docker for running our Gemini css regression tests. In order to run the css regression tests locally, your system must have Docker installed and running.
The following packages are installed globally in development environment. The purpose for each is listed below. You won't need to install these for general development but may wish to do so if you want to run specific scripts that require them:
- @angular/cli: the kitchen sink app (
/src/ks-app
) is an angular-cli app. This app is used to test our npm packages produced by consuming them in an application. - gemini: this is used to run cli commands to run css regression tests.
- html-reporter: plugin for gemini to produce an html report of the css regression tests.
- selenium-standalone: for running css regression tests.
- surge: for publishing static website. We use this to publish the kitchen sink app.
All of our build scripts are defined in package.json
.
This will start up our demo app using webpack-dev-server on port 4200 and watch for file changes for live reload.
This script deletes the dist
folder, which contains all the produced files for bundling.
This script builds npm package candidates for all three packages we currently publish: @clr/angular
, @clr/ui
, and
@clr/icons
under the /dist
folder.
Note that this will also produce bundle files as a result of building and bundling for the demo app. Those can be ignored for the purposes of publishing.
The test
script runs all the unit tests using karma. The entry point for the tests is tests/tests.entry.ts
.
You may locally modify this file to constrain which tests to run if you are testing for specific components and don't want
to run all the tests.
The test:travis
script is used by Travis-CI to run some additional format checks before running the unit tests.
If the code doesn't pass both clang-format checker and tslint, then the build fails before running the unit tests.
We use clang-format as formatter for our code. npm run clang:check
will not
actually format the file but only check if there are any files that would be changed. We do this via a shell script (./scripts/clang-check.sh
),
which runs the clang-format command (with -output-replacements-xml
flag) and greps for any replacement that would be produced.
The npm run clang:format
does the actual formatting according to the rules specified in .clang-format
file.
This script produces the @clr/angular
package using ng-packagr.
However, because of limitations of the tools we supplement this with a pre
and post
script.
The pre
script simply copies over the package.json
template from our npm
folder (this contains templates for package.json
and
README.md
for all of our packages) into src/clr-angular
and sets the correct version number. This is necessary
because
ng-packagr
requires the package.json
to be at the root of the src
(defined in ng-package.json
).
The post
script runs npm pack
on the package to create the tgz file
.
This script produces the clr-icons
package by bundling js files that can be included in consuming app.
The post
script generates the svg files and also zipped up files for the icon sets. Note that this script partially
relies on webpack
as well, since the webpack
script produces the clr-icons.css
and clr-icons.min.css
files.
The webpack
script also processes the package.json
and README.md
files for all of our packages.
This means that running npm build: icons
by itself will NOT produce a complete package.
This is the script that bundles the demo app as well as produce the package for @clr/ui
. Since our demo app
consumes the clr-ui.min.css
, it wasn't necessary to create a separate script for generating the @clr/ui
package. This script also handles tasks common to all packages, such as setting the version and copying over the
package.json
and README.md
files.
This script publishes the kitchen sink app located under src/ks-app
. Note that surge must be globally installed to be able to
publish this app to a CDN. You can still locally test the kitchen sink app by:
cd src/ks-app
npm install
ng serve --preserve-symlinks
The tslint:check
script will run the tslinter and fail if linting fails. The tslint:fix
script is very similar but
is run with the --fix
flag to auto-fix some rules if possible. Some lint rules cannot be auto fixed so you will have
to manually fix those.
These scripts use Docker to start up a container with selenium and chrome to run the Gemini tests. Currently there are 4 sets
in our code base and these are arbitrary sets to parallelize running them in Travis builds. You must pass in the set(s) for both
of these scripts (e.g. npm run cssTest set1 set3
).
Most build-related scripts and config files are either at the root of the project or under /scripts
folder.
The build process itself uses 3 folders:
src/
(version controlled): Of course, the source files. The important part is that the build never writes anything to this folder, as it is version controlled. This folder is used as read-only.dist/
(not version controlled): This is where we output the sample app bundles, sourcemaps and all clarity deliverables. Basically everything. Because of that, it is itself divided into several subfolders:assets/
: The sample app that contains demo components for development and testing.clr-angular/
: This will contain the clarity components compiled using ng-packagr.clr-icons/
: This will contain the compiled js files and d.ts files from clarity icons.clr-ui/
: This will contain the compiled .css files and source .clarity.scss files for @clr/ui.
tests/
: Contains the entry point to running karma tests.
We simply clean up the project before building anything.
- All the HTML files for the sample application are bundled by webpack into js and copied to the
dist/
folder.
- All the SCSS files for the sample application are compiled with Sass and moved to
dist/
, once again respecting their path relative tosrc/
. - All
*.clarity.scss
files found insrc/clr-angular/
are compiled by Sass into a minified bundle and moved todist/clr-ui
. - All other SCSS files in
src/clr-angular/
are considered to be behaviour-driven styles, so they are compiled by Sass and inlined in the Typescript declarations of the components (see below). - Every single CSS file output by Sass goes through Autoprefixer, before potential inlining or bundling.
- All the Typescript files for the demo application are bundled by webpack into js and moved to
dist/
as<number>.js
files. - All the Typescript files for clarity components are packaged by ng-packagr under
dist/clr-angular
. The Typescript declaration files (*.d.ts
) are produced for each of these components. - All
*.spec.ts
and*.mock.ts
files, containing the unit tests and mocks for Clarity's components, are transpiled and used by the webpack config filewebpack.test.config.js
. No output is generated.
Bundling happens only when we run npm run build
. This command bundles and produces all of our packages.
Running npm test
only runs the karma tests. Travis will execute npm test:travis
, which checks for code format and
fails the build if the format check or linter fails.
We use webpack-dev-server for development.
The npm run build
script will produce 3 packages for publishing. This script will also run any dependent scripts, such as
copying over the package.json
template as well as the README.md
from the npm
folder.