Yeoman generator to bootstrap :rocket: your Angular library creation and publication.
Here are live examples of some Angular libraries developed with the generator:
These are some that i know of. Want your project listed here ? Drop me a line.
These are the main features of the generator:
If you find next sections way too long, here is a quick summary for you:
npm install -g yo gulp-cli @angular/cli
npm install -g generator-ngx-library
yo ngx-library [project-folder]
gulp test
gulp build
gulp build:watch
gulp build:watch-fast
gulp release --version=[major|minor|patch]
gulp serve:demo
gulp serve:demo-hmr
gulp serve:demo-ssr
gulp build:demo
gulp build:demo-ssr
You should already have the following dependencies installed: Node.js(npm), Yeoman , Gulp and Angular CLI. if not:
npm install -g yo
npm install -g gulp-cli
npm install -g @angular/cli
Otherwise, install directly the generator via:
$ npm install -g generator-ngx-library
Once installed, simply run the following command:
$ yo ngx-library [project-folder]
Notice that you can optionally provide the folder where to generate files into, otherwise current one is used.
And answer the questions you are prompted to.
The following options can be passed to customize the generator.
The syntax is:
$ yo ngx-library [project-folder] --<option-name>
Name | Purpose |
---|---|
skip-install | skips the automatic installation of project dependencies at the end of the generator |
skip-checks | skips the checks of required tools (yarn, angular-cli) prior to generation |
skip-cache | forces the regeneration on an exising project (ignore previous answers) |
skip-demo | skips the generation of the demo application |
skip-styles | skips the generation of style inlining related code (in case you don’t use styles) |
skip-sample | skips the generation of the sample library |
skip-travis | skips the integration with Travis CI |
skip-coveralls | skips the integration with Coveralls (code coverage) |
skip-gh-releasing | skips the releasing of the library on Github |
del-excluded-files | deletes excluded files that have been found in the file system (from previous generation for example) |
npm | forces usage of npm to install dependencies |
At a high level, the generated structure looks exactly like this:
my-ngx-library/
|- .git/
|- src/
| | |- component/
| | | |- lib.component.html
| | | |- lib.component.scss
| | | |- lib.component.spec.ts
| | | |- lib.component.ts
| | |- component/
| | | |- lib.service.spec.ts
| | | |- lib.service.ts
| | |- index.ts
| | |- lib.module.ts
| | |- tsconfig.lib.es5.ts # if targeting Angular v4.x.x
| | |- tsconfig.lib.json
| | |- tsconfig.spec.json
|- config/
| | |- helpers.js
| | |- karma-test-shim.js
| | |- karma.conf.js
| | |- webpack.test.js
|- demo/
| |- # <angular-cli files> + <following additional files>:
| |- src/
| | |- app/
| | | |- getting-started/
| | | | |- getting-started-routing.module.ts
| | | | |- getting-started.component.html
| | | | |- getting-started.component.scss
| | | | |- getting-started.component.ts
| | | | |- getting-started.component.spec.ts
| | | | |- getting-started.module.ts
| | | |- home/
| | | | |- home-routing.module.ts
| | | | |- home.component.html
| | | | |- home.component.scss
| | | | |- home.component.ts
| | | | |- home.component.spec.ts
| | | | |- home.module.ts
| | | |- shared/
| | | |- app-rooting.module.ts
| | |- assets/
| | | |- logo.svg
| | |- testing/
| | | |- index.ts
| | | |- router-stubs.ts
| | |- tsconfig.server.json # for universal (server side rendering)
| |- prerender.ts # for universal (server side rendering)
| |- server.ts # for universal (server side rendering)
| |- webpack.server.config.js # for universal (server side rendering)
|- .editorconfig
|- .gitignore
|- .travis.yml
|- CHANGELOG.md
|- gulpfile.js
|- karma.conf.js
|- LICENSE
|- package.json
|- tsconfig.json
|- tslint.json
|- webpack.config.js
Here are the main files and folders:
File / Folder | Purpose |
---|---|
gulpfile.js |
The gulp configuration file to manage the whole project build lifecycle (from testing to releasing) |
tslint.json |
This file contains rules to lint your library based on codelyzer |
tsconfig.json |
The typescript configuration file used for editors (VSCode, …) |
src/tsconfig.lib.es5.json |
The typescript configuration file used to compile your library in an AoT compatible way, as ESM/ES5 module (only available when targeting Angular v4.x.x) |
src/tsconfig.lib.json |
The typescript configuration file used to compile your library in an AoT compatible way, either as ESM/ES2015 module (when targeting Angular v4.x.x) or as ESM/ES5 module (when targeting Angular v2.x.x) |
src/tsconfig.spec.json |
The typescript configuration file used for tests |
src/ |
This folder will contain all the files of your library |
config/ |
This folder contains the configuration files for tools used to test your lib (Webpack & Karma or Jest ) |
demo/ |
This folder contains an integrated demo application, to showcase your library. The demo app is built with angular-cli, so everything you know about the CLI is applicable inside this folder. |
dist/ (generated) |
This generated folder contains everything that will be published as part of your package to npm registry. It contains only necessary files and is built via gulp build command |
Note :
The demo app has a dependency on your local package, that is post-installed vianpm link <YOUR_PACKAGE_NAME>
and point to the generateddist/
folder (from project root). This way, you can be sure you are using the library as final users will, without having to publish it first.Besides, any changes to the files in the
dist/
folder will immediately affect the global<YOUR_PACKAGE_NAME>
package, allowing you to quickly test any changes you make to your library.
npm link
is very similar to npm install -g except that instead of downloading the package from the repo, the just builtdist/
folder becomes the global package.
Depending on the minimal version of Angular your library targets (2.x.x or 4.x.x), the distributed package files are different, but both are AOT compatible:
The published package follows the official Angular Package Format v4.0
dist/
|- bundles/ # Directory that contains all bundles (UMD/ES5)
| |- my-ngx-library.umd.js # UMD bundle
| |- my-ngx-library.umd.js.map # UMD bundle sourcemap
| |- my-ngx-library.umd.min.js # Minified UMD bundle
| |- my-ngx-library.umd.min.js.map # Minified UMD bundle sourcemap
|- module/ #
| |- component/ #
| | |- lib.component.d.ts # Type definitions
| |- service/ #
| | |- lib.service.d.ts # Type definitions
|- CHANGELOG.md #
|- my-ngx-library.d.ts # Type definitions
|- my-ngx-library.metadata.json # Metadata used by AOT compiler
|- [esm5]/ # Optional Directory containing ESM5 files (for ng >=v5 only)
| |- my-ngx-library.es5.js # ESM+ES5 flat module (FESM5)
| |- my-ngx-library.es5.js.map # ESM+ES5 flat module (FESM5) sourcemap
|- [esm2015]/ # Optional Directory containing ESM2015 files (for ng >=v5 only)
| |- my-ngx-library.js # ESM+ES2015 flat module (FESM15)
| |- my-ngx-library.js.map # ESM+ES2015 flat module (FESM15) sourcemap
|- LICENSE #
|- lib.module.d.ts # Type definitions
|- package.json # Package.json, with just the right dependencies & peerDependencies
|- README.md #
The published package also follows the format of Angular core packages (prior to v4.0.0), but contrary to v4, there is no official(or publicly available) documentation about that format.
dist/
|- bundles/ # Directory that contains all bundles (UMD/ES5)
| |- my-ngx-library.umd.js # UMD bundle
| |- my-ngx-library.umd.js.map # UMD bundle sourcemap
| |- my-ngx-library.umd.min.js # Minified UMD bundle
| |- my-ngx-library.umd.min.js.map # Minified UMD bundle sourcemap
|- module/ #
| |- component/ #
| | |- lib.component.d.ts # Type definitions
| | |- lib.component.js # ES5 file
| | |- lib.component.js.map # ES5 sourcemap
| | |- lib.component.metadata.json # Metadata used by AOT compiler
| |- service/ #
| | |- lib.service.d.ts # Type definitions
| | |- lib.service.js # ES5 file
| | |- lib.service.js.map # ES5 sourcemap
| | |- lib.service.metadata.json # Metadata used by AOT compiler
|- CHANGELOG.md #
|- index.d.ts # Type definitions
|- index.js # ES5 entrypoint
|- index.js.map # ES5 sourcemap
|- index.metadata.json #
|- LICENSE #
|- lib.module.d.ts # Type definitions
|- lib.module.metadata.json # Metadata used by AOT compiler
|- package.json # Package.json, with just the right dependencies & peerDependencies
|- README.md #
It’s now up to you to write your kick-ass Angular library by adding your components, directives, pipes, services… and tests in src/
.
It doesn’t matter how you organize files inside the folder, but it is important to keep the index.ts
at the root, and to export every file that must be publicly available in your package.
Here are the most important gulp
tasks to use during your development workflow:
Task | Purpose |
---|---|
gulp build |
Builds and packages your library under the dist/ folder. |
gulp build:watch |
Watches the source files (*.ts, *.html and *.scss) and re-builds your library upon changes (useful for live refresh of demo app during development). |
gulp build:watch-fast |
Watches the source files (*.ts, *.html and *.scss) and re-builds your library upon changes (without running tests). |
gulp test |
Launches the tests (*.spec.ts ) you wrote in src/ and run code coverage on them. The coverage report can be found in coverage/ folder |
gulp test:watch |
Launches tests in watch mode. Every changes in *.spec.ts |
gulp test:watch-no-cc |
Same as gulp test:watch but files do not get instrumented for code coverage (useful for debugging) |
gulp test:demo 1 |
Launches demo application tests(same as running ng test from demo/ ). |
gulp build:demo 1 |
Builds demo application for production. |
gulp build:demo-ssr 1 |
Builds demo application for universal (server side rendering) testing. |
gulp serve:demo 1 |
Serves demo application (same as running ng serve from demo/ ). |
gulp serve:demo-hmr 1 |
Serves demo application with HMR (hot module replacement) |
gulp serve:demo-ssr 1 |
Serves demo application for universal (server side rendering) testing. |
gulp serve:doc 2 |
Serves the generated compodoc documentation (from dist/doc folder) at https://localhost:8080. |
Note About consuming locally linked library :
In case you encounter the following : ‘Error: Unexpected value ‘[object Object]’ imported by the module ‘AppModule’. Please add a @NgModule annotation’, try adding
--preserve-symlinks
to your launch command (eg:ng serve --preserve-symlinks
, for Angular CLI projects). In fact, this flag is needed to consume locally built/linked libraries (vianpm link
) withpeerDependencies
. See this post for more information.
Note About compodoc and demo application :
compodoc documentation is only available if you chose to use compodoc during generator setup.
When serving demo app (via
gulp serve:demo
), in order to access documenation files (which are available at URL/doc/
),
be sure to also serve compodoc’s generated documentation files (viagulp serve:doc
).In development, the url
/doc/
is proxied to redirect to that locally running server for compodoc files (at https://localhost:8080)In production, the generated documentations files are deployed along with the demo application and are available at same url (
/doc/
) from rootindex.html
1 = This task is only available if you chose not to skip demo app generation during generator setup
2 = This task is only available if you chose to use compodoc during generator setup
Some useful recipes to help you during the development process can be found here
When a new version of the generator is available, you can take advantage of the new features/bug fixes it brings by updating your globally installed version and by re-running it again (from your project root folder).
$ npm install -g generator-ngx-library
$ yo ngx-library
Please make sure to read CHANGELOG first, to take all necessary actions for a seamless upgrade.
The generator can enforce (via Commitplease) that all your commit messages follow Angular guidelines.
This convention helps making your git mesages more readable and meaningful, in addtion of keeping each commit simple and well focused on a certain scope.
The generator also takes full advantage of the convention to autogenerate project’s CHANGELOG.md
and Github release notes from Git metadata. Only relevant commit messages are considered (commits about new features, fixes, performance, and breaking changes).
You can tweak or deactivate (😱) the convention by editing the "commitplease"
section in package.json
. See here.
A set of checks is automatically performed for you prior to releasing (during gulp release
), to ensure that you are indeed ready for it. Right now, we check that:
master
branch is passingmaster
branch--version
has been provided to gulp release
task, with value: major
, minor
or patch
--ghToken
has been provided or env variable CONVENTIONAL_GITHUB_RELEASER_TOKEN
is setYou can also run the gulp pre-release
task alone, to solely perform these checks without actually releasing anything.
Note: if you provided --skip-travis
option (resp. --skip-gh-releasing
) when running the generator, the Travis build (resp. releasing on Github) will be ignored/skipped.
Once your killer library is done, then it is time unleash the beast!
Nothing is simpler 😛
$ gulp release --version=[major|minor|patch] [--ghToken=YOUR_GITHUB_TOKEN]
As you can see above, the releasing task can take 2 parameters:
patch
, minor
, and major
CONVENTIONAL_GITHUB_RELEASER_TOKEN
.How to setup Github Token : Go to create a new token and set your environment variable
CONVENTIONAL_GITHUB_RELEASER_TOKEN
to the token you just created. You can google How to set environment variable. The scopes for the token you need ispublic_repo
orrepo
(if you need to access private repos). More details.
Running this task will (in that order) :
package.json
CHANGELOG.md
file based on your commit messages (provided they follow the angular git message convention)master
branchCONVENTIONAL_GITHUB_RELEASER_TOKEN
)demo/dist
to gh-pages
branchThe demo application will be available at : https://USERNAME.github.io/REPO_NAME/
(provided you chose to generate one).
The documentation will be available at : https://USERNAME.github.io/REPO_NAME/doc/
(provided you chose to generate one) or
at https://USERNAME.github.io/REPO_NAME/
, if you chose to skip demo application generation.
See most common problems, and how to solve them here.
Having trouble using the generator? Want to discuss about new features to add? Come and join the project’s Gitter to chat about it!
Copyright © 2018 Tine Kondo. Licensed under the MIT License (MIT)