Angular ライブラリをローカルで開発する方法
やあ !このストーリーでは、Angular ライブラリをローカルで操作し、常にリモート リポジトリにプッシュする必要なく開発する方法を紹介したいと思います :)
DRY - コードの繰り返しを避ける方法
大規模で複雑な Angular プロジェクトに取り組んでいる場合、コードの重複の問題に直面することは間違いありません。例として、アプリケーションの「外観」に注目してみましょう。おそらく、すべてのページに一貫したスタイルを設定する必要があります (ユーザーを混乱させたり、ページごとに異なる外観のボタンを配置したりしたくありません)。わかりました。簡単です。これらの一般的なスタイルをstyles.scss
ファイルに移動するか、7–1 パターンを使用してエレガントな方法でデザインするだけです。
しかし、見た目だけでなく同じように動作する共通のコンポーネントがある場合はどうでしょうか? それは… まだ簡単です!アプリケーションで共有モジュールを作成し、そこでコンポーネントを定義して、モジュール定義でエクスポートするだけです。すごい !
では、より複雑な問題に焦点を当てましょう。会社に複数の Angular アプリケーションがある場合はどうなりますか? また、各アプリケーションは似ている必要があります。次に例を示します。
- ヘッダーとフッターが同じ
- 同じ企業の CSS スタイルを持つ
- フォーム、検証エラー、その他のメッセージを同じ方法で表示する
ライブラリの作成
ここでは、ライブラリの作成に関する公式ドキュメント ページを見つけることができます。そこで説明されている手順に従って、ライブラリを作成しましょう。
ng new my-shared-workspace --no-create-application
cd my-shared-workspace
ng generate library my-buttons
- my-shared-workspaceはライブラリの共通ワークスペースです
- my-buttonsは、他のプロジェクトで再利用できるサンプル ライブラリです。
{
"name": "@my-company/my-buttons",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^14.2.0",
"@angular/core": "^14.2.0"
},
"dependencies": {
"tslib": "^2.3.0"
}
}
my-shared-workspace/projects/my-buttons/src/lib> ng g c fancy-button
コンポーネントが作成されたので、そのテンプレートを更新してボタンを表示できます
<button>fancy-button works!</button>
@NgModule({
declarations: [
MyButtonsComponent,
FancyButtonComponent
],
imports: [
],
exports: [
MyButtonsComponent,
FancyButtonComponent // <-- here
]
})
export class MyButtonsModule { }
/*
* Public API Surface of my-buttons
*/
export * from './lib/my-buttons.service';
export * from './lib/my-buttons.component';
export * from './lib/my-buttons.module';
export * from './lib/fancy-button/fancy-button.component'; // <-- here
ライブラリはすでに作成されているので、次はクライアント アプリケーションを作成します。Angular CLI を使用して生成します: 、アプリケーションの依存関係としてng new my-application
追加します(最後の依存関係、 の後) 。@my-company/my-buttons
package.json
zone.js
{
"name": "my-application",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "^14.2.0",
"@angular/common": "^14.2.0",
"@angular/compiler": "^14.2.0",
"@angular/core": "^14.2.0",
"@angular/forms": "^14.2.0",
"@angular/platform-browser": "^14.2.0",
"@angular/platform-browser-dynamic": "^14.2.0",
"@angular/router": "^14.2.0",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4",
"@my-company/my-buttons": "0.0.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "^14.2.6",
"@angular/cli": "~14.2.6",
"@angular/compiler-cli": "^14.2.0",
"@types/jasmine": "~4.0.0",
"jasmine-core": "~4.3.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.0.0",
"typescript": "~4.7.2"
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { MyButtonsModule } from '@my-company/my-buttons';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
MyButtonsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
<lib-fancy-button></lib-fancy-button>
Error: src/app/app.component.html:1:1 - error NG8001: 'lib-fancy-button' is not a known element:
1. If 'lib-fancy-button' is an Angular component, then verify that it is part of this module.
2. If 'lib-fancy-button' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
1 <lib-fancy-button></lib-fancy-button>
~~~~~~~~~~~~~~~~~~
src/app/app.component.ts:5:16
5 templateUrl: './app.component.html',
~~~~~~~~~~~~~~~~~~~~~~
Error occurs in the template of component AppComponent.
** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
次のようなエラーもいくつか表示されます。
Error: src/app/app.module.ts:3:33 - error TS2307: Cannot find module '@my-company/my-buttons' or its corresponding type declarations.
3 import { MyButtonsModule } from '@my-company/my-buttons';
npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@my-company%2fmy-buttons - Not found
npm ERR! 404
npm ERR! 404 '@my-company/[email protected]' is not in this registry.
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.
Npm link to the rescue
ここでは、完全なnpm linkコマンドのドキュメントを見つけることができます。このコマンドを使用して、ライブ リロードを使用して共有ライブラリをローカルで開発する方法を紹介します。
my-shared-workspace
ディレクトリに戻り、my-buttons
ライブラリをビルドして (フラグ--watch
はライブ リロードを担当します)、ビルドのディレクトリに移動します。
my-shared-workspace> ng build my-buttons --configuration development --watch
Building Angular Package
------------------------------------------------------------------------------
Building entry point '@my-company/my-buttons'
------------------------------------------------------------------------------
✔ Compiling with Angular sources in Ivy full compilation mode.
✔ Writing FESM bundles
✔ Copying assets
✔ Writing package manifest
✔ Built @my-company/my-buttons
------------------------------------------------------------------------------
Built Angular Package
- from: /Users/<user>/<path>/my-shared-workspace/projects/my-buttons
- to: /Users/<user>/<path>/my-shared-workspace/dist/my-buttons
------------------------------------------------------------------------------
my-shared-workspace> cd dist/my-buttons
my-shared-workspace/dist/my-buttons> npm link
added 1 package, and audited 3 packages in 1s
found 0 vulnerabilities
my-application
ディレクトリに、angular.json
もう 1 つのオプションを追加します。preserveSymlinks は、このリンクされたライブラリを使用できるようにします。
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"my-application": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/my-application",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"preserveSymlinks": true,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"outputHashing": "all"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"browserTarget": "my-application:build:production"
},
"development": {
"browserTarget": "my-application:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "my-application:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
}
}
}
}
}
}
my-application> npm link @my-company/my-buttons
added 1 package, removed 1 package, and audited 918 packages in 2s
121 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
その後、ng serve
再度実行します。
my-application> ng serve
✔ Browser application bundle generation complete.
Initial Chunk Files | Names | Raw Size
vendor.js | vendor | 3.30 MB |
polyfills.js | polyfills | 318.02 kB |
styles.css, styles.js | styles | 210.56 kB |
main.js | main | 12.32 kB |
runtime.js | runtime | 6.53 kB |
| Initial Total | 3.84 MB
Build at: 2022-11-24T18:27:00.803Z - Hash: 7669daf65ca2f665 - Time: 4598ms
** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
✔ Compiled successfully.
結果を見てみましょう:
すごい !それでは、fancy-button-component.html で何かを変更してみてください
<button>fancy-button works - live reload!</button>
これで、ライブラリとアプリケーションの両方で不便なく作業できます:)
検証
使用しているライブラリのバージョンを確認するには、次のコマンドを実行できます。
npm list -g
/usr/local/lib
├── @angular/[email protected]
├── @my-company/[email protected]+1669314745555 -> ./../../../Users/<user>/<path>/my-shared-workspace/dist/my-buttons
ローカルでの変更作業が完了したら、次の方法でクライアント アプリケーションでリンクされたライブラリの使用を停止できます。
my-application> npm unlink @my-company/my-buttons --no-save
my-shared-workspace/dist/my-buttons> npm rm -g @my-company/my-buttons
材料
- Sass 7–1 パターン
- Angular ドキュメント - ライブラリの作成
- npm リンク ドキュメント
- https://dgtechboost.com/2022/03/20/test-and-debug-angular-library-using-npm-link/
- https:///@maravondra/angular-component-in-locale-usage-8536d91fc844