![require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages](https://cdn.sanity.io/images/cgdhsj6q/production/be8ab80c8efa5907bc341c6fefe9aa20d239d890-1600x1097.png?w=400&fit=max&auto=format)
Security News
require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
- 组件:xxx-xxx.component.ts
- 样式:xxx-xxx.component.scss
- 模板:xxx-xxx.component.html
- 服务:xxx-xxx.service.ts
- 枚举:xxx-xxx.enum.ts
- 模型:xxx-xxx.model.ts
- 接口:xxx-xxx.interface.ts
- 类:xxx-xxx.class.ts
- 配置:xxx-xxx.config.ts
D: 文件夹 F: 文件
新模块 D
├── 创建页 D
├── 详情页 D
├── 列表页 D
├── 修改页 D
├── 模块定义 F
├── 模块路由 F
├── 模块中使用的模型 F
└── 模块服务 F
示例
src/app/user
├── create
│ ├── create.component.html
│ ├── create.component.scss
│ ├── create.component.spec.ts
│ └── create.component.ts
├── details
│ ├── details.component.html
│ ├── details.component.scss
│ ├── details.component.spec.ts
│ └── details.component.ts
├── list
│ ├── list.component.html
│ ├── list.component.scss
│ ├── list.component.spec.ts
│ └── list.component.ts
├── update
│ ├── update.component.html
│ ├── update.component.scss
│ ├── update.component.spec.ts
│ └── update.component.ts
├── user-routing.module.ts
├── user.model.ts 存放模型
├── user.module.ts
└── user.service.ts 模块级 service
如果模块中包含子模块,遵循同样的结构。
const routes = [
// 用户模块
{
path: 'user',
children: [
// 用户列表
{ path: 'list', component: UserListComponent },
// 用户详情
{ path: 'details/:id', component: UserDetailsComponent },
// 用户信息更新
{ path: 'update/:id', component: UserUpdateComponent },
// 新增用户
{ path: 'create', component: UserCreateComponent }
]
}
];
base-component.class.ts
export abstract class BaseComponent extends Base {
protected constructor(protected injector: Injector) {
super(injector);
}
}
not-a-page.component.ts
import { Component, Injector, OnInit } from '@angular/core';
import { BaseComponent } from '../public-api';
import { interval } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'lib-not-a-page',
template: `
{{ count }}
`
})
export class NotAPageComponent extends BaseComponent implements OnInit {
count: number;
constructor(protected injector: Injector) {
super(injector);
}
ngOnInit() {
interval(1000)
.pipe(takeUntil(this.destroy$))
.subscribe(value => (this.count = value));
}
}
base-page.class.ts
export abstract class BasePage extends BaseComponent {
protected abstract moduleService: BaseModuleService;
protected route: ActivatedRoute;
protected router: Router;
constructor(protected injector: Injector) {
super(injector);
this.route = injector.get(ActivatedRoute);
this.router = injector.get(Router);
}
}
a-page.component.ts
@Component({
selector: 'lib-a-page',
template: ``
})
export class APageComponent extends BasePage implements OnInit {
users: IUser[] = [];
constructor(
protected injector: Injector,
protected moduleService: DemoService
) {
super(injector);
}
ngOnInit() {
this.moduleService.getUsers().subscribe(users => (this.users = users));
}
}
如果属性是数组类型,则赋值空数组。如果属性是空对象,则赋值为空对象。
@Component({
selector: 'lib-a-page',
template: ``
})
export class APageComponent extends BasePage implements OnInit {
users: IUser[] = [];
details = {} as IUser;
constructor(
protected injector: Injector,
protected moduleService: DemoService
) {
super(injector);
}
ngOnInit() {
this.moduleService.getUsers().subscribe(users => (this.users = users));
}
}
@Component({
selector: 'lib-not-a-page',
template: `
{{ count }}
`
})
export class NotAPageComponent extends BaseComponent implements OnInit {
count: number;
constructor(protected injector: Injector) {
super(injector);
}
ngOnInit() {
interval(1000)
.pipe(takeUntil(this.destroy$)) // takeUntil在组件销毁时自动取消订阅
.subscribe(value => (this.count = value));
}
}
export class NotAPageComponent extends BaseComponent implements OnDestroy {
constructor(protected injector: Injector) {
super(injector);
}
ngOnDestroy() {
console.log('NotAPageComponent destroyed.');
super.ngOnDestroy();
}
}
import { Base } from './base.class';
import { Injector } from '@angular/core';
export abstract class BaseService extends Base {
constructor(protected injector: Injector) {
super(injector);
}
}
import { BaseService } from './base-service.class';
import { Injector } from '@angular/core';
import { HttpClient } from '@angular/common/http';
/**
* Service uses httpClient should extend this class.
*/
export abstract class BaseApiService extends BaseService {
protected http: HttpClient;
constructor(protected injector: Injector) {
super(injector);
this.http = injector.get(HttpClient);
}
}
import { BaseApiService } from './base-api-service.class';
import { Injector } from '@angular/core';
export abstract class BaseModuleService extends BaseApiService {
protected constructor(protected injector: Injector) {
super(injector);
}
}
A
├──dist
├──projects
│ ├── project1
│ ├── project2
│ ├── project3
│ └── common (git 子模块)
├──src
FAQs
esunny cli
The npm package esunny-cli receives a total of 1 weekly downloads. As such, esunny-cli popularity was classified as not popular.
We found that esunny-cli demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
Security News
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.