Create an angular library
Creating the project
First we will setup the project using the angular cli.
Library
ng new my-library-name --no-create-application
Then inside the directory we can create the library.
ng generate library my-lib
Documentation / showcase application
I want to also create a application that will display the components, and also allow me to test the library while developing it.
ng generate application doc
I also cleaned the doc application by removing all the default html inside the app.component.html
file.
Configuring scss for the library
By default, the components inside the library will use the css file. If you want to use scss, you will need to configure it.
You can do this by adding the following lines (schematics
section) to the angular.json file in the “my-lib” section.
{
"my-lib": {
"projectType": "library",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
}
}
}
Creating the first component
Cleaning module library
When the project was generated, a component was created inside the library. We will remove it, and remove the references inside the my-lib.module.ts
file.
Here is the list of deleted files:
projects/my-lib/src/lib/my-lib.component.ts
projects/my-lib/src/lib/my-lib.component.spec.ts
projects/my-lib/src/lib/my-lib.service.ts
projects/my-lib/src/lib/my-lib.service.spec.ts
The service and the components were also inside the public-api.ts file, so we will remove them.
Component creation
I will create a button component inside the library, to show how to create a component and then use it inside the doc application.
ng g c my-button --project=my-lib
I will add some html and css to the component to make it look like a button.
<button>My example button</button>
button{
background-color: rgba(51, 51, 51, 0.05);
border-radius: 8px;
border-width: 0;
color: #333333;
cursor: pointer;
display: inline-block;
font-size: 14px;
font-weight: 500;
line-height: 20px;
list-style: none;
margin: 0;
padding: 10px 12px;
text-align: center;
}
To make you component available, you will need to export it inside the module.
@NgModule({
declarations: [
MyButtonComponent
],
imports: [
],
exports: [
MyButtonComponent,
]
})
export class MyLibModule { }
You also need to export the module inside the public-api.ts file.
export * from './lib/my-button/my-button.component';
export * from './lib/my-lib.module';
Then inside the doc application, you can import the module and use the component.
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
MyLibModule, // <-- import the module
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Then inside the app.component.html
file, you can use the component.
<lib-my-button></lib-my-button>
Publishing the library
Tu publish the library I am using github action. I followed this tutorial and adapted the workflow for angular.
Here is the workflow file:
name: Release package
on:
workflow_dispatch:
inputs:
release-type:
description: 'Release type (one of): patch, minor, major, prepatch, preminor, premajor, prerelease'
required: true
jobs:
release:
runs-on: ubuntu-latest
steps:
# Checkout project repository
- name: Checkout
uses: actions/[email protected]
# Setup Node.js environment
- name: Setup Node.js
uses: actions/setup-node@v2
with:
registry-url: https://registry.npmjs.org/
node-version: '18'
- name: Install angular cli
run: npm install -g @angular/cli@latest
- name: Install dependencies
run: npm install
# Configure Git
- name: Git configuration
run: |
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --global user.name "GitHub Actions"
# Bump package version
# Use tag latest
- name: Bump release version
working-directory: ./projects/my-lib
if: startsWith(github.event.inputs.release-type, 'pre') != true
run: |
echo "NEW_VERSION=$(npm --no-git-tag-version version $RELEASE_TYPE)" >> $GITHUB_ENV
echo "RELEASE_TAG=latest" >> $GITHUB_ENV
env:
RELEASE_TYPE: ${{ github.event.inputs.release-type }}
# Bump package pre-release version
# Use tag beta for pre-release versions
- name: Bump pre-release version
working-directory: ./projects/my-lib
if: startsWith(github.event.inputs.release-type, 'pre')
run: |
echo "NEW_VERSION=$(npm --no-git-tag-version --preid=beta version $RELEASE_TYPE)" >> $GITHUB_ENV
echo "RELEASE_TAG=beta" >> $GITHUB_ENV
env:
RELEASE_TYPE: ${{ github.event.inputs.release-type }}
- name: Build library
working-directory: ./projects/my-lib
run: ng build
# Update changelog unreleased section with new version
- name: Update changelog
uses: superfaceai/release-changelog-action@v1
with:
path-to-changelog: CHANGELOG.md
version: ${{ env.NEW_VERSION }}
operation: release
# Commit changes
- name: Commit CHANGELOG.md and package.json changes and create tag
run: |
git add "projects/my-lib/package.json"
git add "CHANGELOG.md"
git commit -m "chore: release ${{ env.NEW_VERSION }}"
git tag ${{ env.NEW_VERSION }}
# Publish version to public repository
- name: Publish
working-directory: ./dist/my-lib
run: npm publish --verbose --access public --tag ${{ env.RELEASE_TAG }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPMJS_ACCESS_TOKEN }}
# Push repository changes
- name: Push changes to repository
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git push origin && git push --tags
# Read version changelog
- id: get-changelog
name: Get version changelog
uses: superfaceai/release-changelog-action@v1
with:
path-to-changelog: CHANGELOG.md
version: ${{ env.NEW_VERSION }}
operation: read
# Update GitHub release with changelog
- name: Update GitHub release documentation
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ env.NEW_VERSION }}
body: ${{ steps.get-changelog.outputs.changelog }}
prerelease: ${{ startsWith(github.event.inputs.release-type, 'pre') }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
You will need to add a CHANGELOG.md
file at the root of the project.
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
To make this workflow work you will need to create a secret inside your repository. The secret will be used to publish the library on npm.
Fist you need to go to npmjs.com in the token section to create a classic token for automation.
Then in the github repository, in the settings -> Secrets -> Actions you can create a new secret named NPMJS_ACCESS_TOKEN
and paste the token you just created.
Before running the workflow, you will need to allow the github action to write on the repository. To do this, you need to go to the settings -> Actions -> General and at the bottom of the page there is Workflow permissions, chose Read and write permissions
Publishing the first version
In the action tab of your repository, you can run the workflow. You will need to enter the release type. I will enter prepatch
to publish the first version.
Locally testing the library
You can test your component inside the doc application, but you also can test it in another project.
I create an app to test the library.
ng new app-test-list
Fist you need to go inside the library directory and run a command to link it.
npm link
Then inside the app-test-list directory, you can run the following command to link the library.
npm link my-lib
Github
The sources are available on github