مرحبا ، اسمي مكسيم. منذ عدة سنوات ، كنت أقوم بتطوير الواجهة الأمامية. غالبًا ما يتعين عليّ التعامل مع تخطيط قوالب HTML المختلفة. في عملي اليومي ، عادةً ما أستخدم أداة إنشاء حزمة الويب مع محرك قالب الصلصال المخصص ، وأستخدم أيضًا منهجية BEM. من أجل جعل حياتي أسهل يمكنني استخدام حزمة رائعة .
في الآونة الأخيرة ، كنت بحاجة إلى إنشاء مشروع صغير على Angular ، وبما أنني اعتدت على العمل مع أدواتي المفضلة ، لم أكن أريد العودة إلى html العارية. في هذا الصدد ، نشأت مشكلة كيفية تكوين صداقات bempug مع زاوي ، وليس فقط تكوين صداقات ، ولكن أيضًا إنشاء مكونات من cli بالهيكل الذي احتاجه.
من يهتم كيف فعلت كل شيء ، مرحبا بكم في القط.
للبدء ، قم بإنشاء مشروع اختبار الذي سنختبر قالبنا عليه.
ننفذ في سطر الأوامر:
ng g test-project
.
في الإعدادات ، اخترت المعالج الأولي لـ scss ، لأنه أكثر ملاءمة بالنسبة لي للعمل معه.
تم إنشاء المشروع ، ولكن قوالب المكونات الافتراضية في html لدينا ، قم بإصلاحه الآن. بادئ ذي بدء ، تحتاج إلى تكوين صداقات الزوايا CLI مع محرك القالب الصلصال ، لذلك أنا استخدم حزمة لودر نانوغرام cli
تثبيت الحزمة ، لهذا ، انتقل إلى مجلد المشروع وتنفيذه:
ng add ng-cli-pug-loader
.
الآن يمكنك استخدام ملفات قالب الصلصال. بعد ذلك ، نعيد كتابة مصمم جذر مكون AppComponent إلى:
@Component({ selector: 'app-root', templateUrl: './app.component.pug', styleUrls: ['./app.component.scss'] })
وفقًا لذلك ، نقوم بتغيير ملحق الملف app.component.html إلى app.component.pug ، ويتم كتابة المحتوى في بناء جملة القالب. في هذا الملف ، قمت بحذف كل شيء ما عدا جهاز التوجيه.
أخيرًا ، لنبدأ في إنشاء مولد المكون الخاص بنا!
لإنشاء قوالب ، نحتاج إلى إنشاء مخطط خاص بنا. أنا أستخدم حزمة المخططات - cli من @ angular-devkit. قم بتثبيت الحزمة على مستوى العالم باستخدام الأمر:
npm install -g @angular-devkit/schematics-cli
.
قمت بإنشاء المخطط في دليل منفصل خارج المشروع باستخدام الأمر:
schematics blank --name=bempug-component
.
نذهب إلى المخطط الذي تم إنشاؤه ، ونحن مهتمون الآن بملف src / collection.json. يبدو مثل هذا:
"$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json", "schematics": { "bempug-component": { "description": "A blank schematic.", "factory": "./bempug-component/index#bempugComponent" } } }
هذا ملف وصف لمخططنا ، حيث تكون المعلمة "factory": "./bempug-component/index#bempugComponent": هذا هو وصف الوظيفة الرئيسية لـ "factory" لمولدنا.
في البداية ، يبدو مثل هذا:
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
يمكنك جعل الدالة تقوم بالتصدير افتراضيًا ، ثم يمكن إعادة كتابة المعلمة "factory" كـ "./bempug-component/index".
بعد ذلك ، في دليل مخططنا ، أنشئ ملف schema.json ، وسوف يصف جميع معلمات مخططنا.
{ "$schema": "http://json-schema.org/schema", "id": "SchemanticsForMenu", "title": "Bempug Schema", "type": "object", "properties": { "name": { "type": "string", "$default": { "$source": "argv", "index": 0 } }, "path": { "type": "string", "format": "path", "description": "The path to create the component.", "visible": false }, "project": { "type": "string", "description": "The name of the project.", "$default": { "$source": "projectName" } } } }
المعلمات في الخصائص ، وهي:
- اسم اسم الكيان (في حالتنا سيكون مكونًا) ؛
- المسار هو المسار الذي سينشئ به المولد ملفات المكونات ؛
- المشروع هو المشروع نفسه ، حيث سيتم إنشاء المكون ؛
أضف المزيد من المعلمات إلى الملف الذي ستكون هناك حاجة إليه في المستقبل.
"module": { "type": "string", "description": "The declaring module.", "alias": "m" }, "componentModule": { "type": "boolean", "default": true, "description": "Patern module per Component", "alias": "mc" }, "export": { "type": "boolean", "default": false, "description": "Export component from module?" }
- الوحدة النمطية هنا سيتم تخزين رابط إلى الوحدة النمطية التي سيتم إدراج المكون فيها ، أو بالأحرى الوحدة النمطية للمكون ؛
- componentModule هناك علامة على ما إذا كان سيتم إنشاء للمكون الوحدة النمطية الخاصة به (ثم توصلت إلى استنتاج أنه سيتم دائمًا إنشاؤه وتعيينه إلى true) ؛
- تصدير: هذا هو العلم سواء للتصدير من الوحدة النمطية التي نستورد بها الوحدة النمطية للمكونات الخاصة بنا ؛
بعد ذلك ، نقوم بإنشاء واجهة بمعلمات مخطط ملف المكون الخاص بنا.
export interface BemPugOptions { name: string; project?: string; path?: string; module?: string; componentModule?: boolean; module?: string; export?: boolean; bemPugMixinPath?: string; }
في ذلك ، خصائص مكررة خصائص من schema.json. بعد ذلك ، قم بإعداد المصنع ، انتقل إلى ملف index.ts. في ذلك ، نقوم بإنشاء دالتين filterTemplates ، والتي ستكون مسؤولة عن إنشاء وحدة نمطية لمكون بناءً على قيمة componentModule ، و setupOptions ، التي تحدد المعلمات اللازمة للمصنع.
function filterTemplates(options: BemPugOptions): Rule { if (!options.componentModule) { return filter(path => !path.match(/\.module\.ts$/) && !path.match(/-item\.ts$/) && !path.match(/\.bak$/)); } return filter(path => !path.match(/\.bak$/)); } function setupOptions(options: BemPugOptions, host: Tree): void { const workspace = getWorkspace(host); if (!options.project) { options.project = Object.keys(workspace.projects)[0]; } const project = workspace.projects[options.project]; if (options.path === undefined) { const projectDirName = project.projectType === 'application' ? 'app' : 'lib'; options.path = `/${project.root}/src/${projectDirName}`; } const parsedPath = parseName(options.path, options.name); options.name = parsedPath.name; options.path = parsedPath.path; }
بعد ذلك ، نكتب في الوظيفة الرئيسية:
export function bempugComponent(options: BemPugOptions): Rule { return (host: Tree, context: SchematicContext) => { setupOptions(options, host); const templateSource = apply(url('./files'), [ filterTemplates(options), template({ ...strings, ...options }), move(options.path || '') ]); const rule = chain([ branchAndMerge(chain([ mergeWith(templateSource), ])) ]); return rule(host, context); } }
المصنع جاهز ويمكنه بالفعل إنشاء ملفات مكونة من خلال معالجة القوالب من مجلد الملفات ، والذي لم يتوفر بعد. لا يهم ، فنحن ننشئ مجلد ملفات bempug في مجلد مخططنا في حالتي. في مجلد الملفات ، قم بإنشاء المجلد __name@dasherize__
، أثناء __name@dasherize__
، __name@dasherize__
المصنع __name@dasherize__
باسم المكون.
بعد ذلك ، داخل __name@dasherize__
بإنشاء ملفات
__name@dasherize__
.component.pug قالب مكون الصلصال__name@dasherize__
.component.spec.ts ملف اختبار الوحدة للمكون__name@dasherize__
.component.ts ملف المكون نفسه__name@dasherize__
dasherize__ - مكون الوحدة النمطية. المكون. الوحدة__name@dasherize__
-component.scss ورقة أنماط المكون
سنضيف الآن دعمًا لتحديث الوحدات النمطية لمصنعنا ، لذلك سننشئ ملف الوظيفة الإضافية إلى سياق. لتخزين المعلمات التي سيحتاج المصنع إلى العمل بها مع الوحدة النمطية.
import * as ts from 'typescript'; export class AddToModuleContext {
إضافة دعم وحدة للمصنع.
const stringUtils = { dasherize, classify };
الآن ، عند إضافة المعلمة -m <مرجع الوحدة النمطية> إلى أمر cli ، ستضيف الوحدة المكونة لدينا الاستيراد إلى الوحدة النمطية المحددة وإضافة التصدير منها عند إضافة علامة التصدير. بعد ذلك نضيف دعم BEM. للقيام بذلك ، أخذت مصادر حزمة bmpug npm وقمت بإنشاء الكود في ملف bempugMixin.pug ، والذي قمت بوضعه في المجلد المشترك وفي داخل مجلد مشترك آخر بحيث يتم نسخ mixin إلى المجلد المشترك في المشروع على الزاوي.
مهمتنا هي أن هذا mixin متصل في كل من ملفات القوالب الخاصة بنا ، وليس مكررة عند إنشاء مكونات جديدة ، لذلك سنضيف هذه الوظيفة إلى المصنع.
import { Rule, SchematicContext, Tree, filter, apply, template, move, chain, branchAndMerge, mergeWith, url, SchematicsException } from '@angular-devkit/schematics'; import {BemPugOptions} from "./schema"; import {getWorkspace} from "@schematics/angular/utility/config"; import {parseName} from "@schematics/angular/utility/parse-name"; import {normalize, strings} from "@angular-devkit/core"; import { AddToModuleContext } from './add-to-module-context'; import * as ts from 'typescript'; import {classify, dasherize} from "@angular-devkit/core/src/utils/strings"; import {buildRelativePath, findModuleFromOptions, ModuleOptions} from "@schematics/angular/utility/find-module"; import {addExportToModule, addImportToModule} from "@schematics/angular/utility/ast-utils"; import {InsertChange} from "@schematics/angular/utility/change"; const stringUtils = { dasherize, classify };
حان الوقت للبدء في ملء ملفات القوالب الخاصة بنا.
__name@dasherize__.component.pug
:
include <%= bemPugMixinPath %> +b('<%= name %>') +e('item', {m:'test'}) | <%= name %> works
سيتم تحديد ما هو محدد في <٪ =٪> أثناء التوليد باسم المكون.
__name@dasherize__.component.spec.ts:
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import {NO_ERRORS_SCHEMA} from '@angular/core'; import { <%= classify(name) %>ComponentModule } from './<%= name %>-component.module'; import { <%= classify(name) %>Component } from './<%= name %>.component'; describe('<%= classify(name) %>Component', () => { let component: <%= classify(name) %>Component; let fixture: ComponentFixture<<%= classify(name) %>Component>; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [<%= classify(name) %>ComponentModule], declarations: [], schemas: [ NO_ERRORS_SCHEMA ] }) .compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(<%= classify(name) %>Component); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); });
في هذه الحالة ، يتم استخدام <٪ = class (name)٪> لإلقاء الاسم على CamelCase.
__name@dasherize__.component.ts:
import { Component, OnInit, ViewEncapsulation} from '@angular/core'; @Component({ selector: 'app-<%=dasherize(name)%>-component', templateUrl: '<%=dasherize(name)%>.component.pug', styleUrls: ['./<%=dasherize(name)%>-component.scss'], encapsulation: ViewEncapsulation.None }) export class <%= classify(name) %>Component implements OnInit { constructor() {} ngOnInit(): void { } }
__name@dasherize__-component.module.ts:
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import {<%= classify(name) %>Component} from './<%= name %>.component'; @NgModule({ declarations: [ <%= classify(name) %>Component, ], imports: [ CommonModule ], exports: [ <%= classify(name) %>Component, ] }) export class <%= classify(name) %>ComponentModule { }
__name@dasherize__-component.scss:
.<%= name %>{ }
نجعل بناء مخططنا باستخدام الأمر `npm run build``.
كل شيء جاهز لتوليد مكونات في المشروع!
للتحقق ، عد إلى مشروعنا الزاوي وقم بإنشاء وحدة نمطية.
ng gm test-schema
بعد ذلك ، نقوم بـ "ارتباط npm <المسار المطلق إلى مجلد المشروع مع مخططنا>" ، من أجل إضافة مخططنا إلى وحدات عقدة المشروع.
ng g bempug-component:bempug-component test -m /src/app/test-schema/test-schema.module.ts –export
الدائرة باستخدام الأمر ng g bempug-component:bempug-component test -m /src/app/test-schema/test-schema.module.ts –export
.
سيقوم مخططنا بإنشاء مكون وإضافته إلى الوحدة النمطية المحددة مع التصدير.
المخطط جاهز ، يمكنك البدء في عمل التطبيق على تقنيات مألوفة.
تستطيع أن ترى النسخة النهائية هنا ، وكذلك الحزمة متوفرة في npm .
عند إنشاء مخطط استخدمت مقالات حول هذا الموضوع ، أعرب عن امتناني للمؤلفين.
شكرا لك على اهتمامك ، كل من قرأ حتى النهاية ، أنت الأفضل!
وهناك مشروع آخر مثير ينتظرني. اراك قريبا!