RxJS اکنون جزئی از پروژههای گوگل است
توسعه دهندهی اصلی RxJS یا همان Ben Lesh اکنون به گوگل پیوستهاست و جزو تیم Angular است. بنابراین در آینده شاهد یکپارچگی بهتر این دو با هم خواهیم بود. البته RxJS هنوز هم به عنوان یک پروژهی مستقل از Angular مدیریت خواهد شد.
آشنایی با تغییرات RxJS 5.5 جهت مهاجرت به RxJS 6.0 ضروری است
در مطلب «کاهش حجم قابل ملاحظهی برنامههای Angular با استفاده از RxJS 5.5» با pipe-able operators آشنا شدیم و این موارد پایههای مهاجرت به RxJS 6.0 هستند. بنابراین پیش از مطالعهی ادامهی بحث نیاز است این مطلب را به خوبی مطالعه و بررسی کنید.
تغییر رفتار خطاهای مدیریت نشده در RxJS 6.0
تا پیش از RxJS 6.0 اگر خطای مدیریت نشدهای رخ میداد، این خطا به صورت synchronous به فراخوان صادر میشد. این رفتار در نگارش 6 تغییر کرده و صدور آن اینبار asynchronous شدهاست.
برای مثال یک چنین کدی تا پیش از RxJS 6.0 کار میکرد:
try { source$.subscribe(nextFn, undefined, completeFn); } catch (err) { handleError(err); }
برای اصلاح این کد در نگارش 6، همان پارامتر دوم متد را مقدار دهی کنید و try/catch را در صورت وجود حذف نمائید.
تغییرات مهم importها در RxJS 6.0
همانطور که در مطلب «کاهش حجم قابل ملاحظهی برنامههای Angular با استفاده از RxJS 5.5» نیز بررسی کردیم، تا نگارش 5 این کتابخانه، importها به صورت زیر بودند:
import 'rxjs/add/operator/map';
import { map } from 'rxjs/operators';
import { timer } from 'rxjs/observable/timer'; import { of } from 'rxjs/observable/of'; import { from } from 'rxjs/observable/from'; import { range } from 'rxjs/observable/range';
import { interval, of } from 'rxjs'; import { filter, mergeMap, scan } from 'rxjs/operators';
البته RxJS 6.0 در کل به همراه 4 گروه کلی importها است که در زیر مشاهده میکنید (در اینجا مواردی که کمتر در برنامههای Angular به صورت مستقیم استفاده میشوند مانند ajax آن و یا webSocket هم قابل مشاهده هستند):
rxjs rxjs/operators rxjs/testing rxjs/webSocket rxjs/ajax
مواردی که از RxJS 6.0 حذف شدهاند
برای کاهش حجم کتابخانهی RxJS و همچنین جلوگیری از بکارگیری متدهایی که نمیبایستی خارج از کدهای اصلی خود RxJS استفاده شوند، تعداد زیادی از متدهای قدیمی آن و روشهای کار پیشین با RxJS حذف شدهاند. برای مثال شما در RxJS 5.5 میتوانید برای کار با عملگر of، یا آنرا از مسیر rxjs/add/observable/of دریافت کنید (همان روش وصله کردن تا پیش از RxJS 5.5) و یا آنرا از مسیر rxjs/observable/of به روش مخصوص ES 6.0 به برنامه اضافه کنید و یا حتی امکان دریافت آن از مسیر rxjs/observable/fromArray نیز میسر است.
در RxJS 6.0 تمام اینها حذف شدهاند و فقط روش زیر باقی ماندهاست:
import { of } from 'rxjs';
معرفی بستهی rxjs-compat
در مطلب «ارتقاء به Angular 6: بررسی تغییرات Angular CLI» روش ارتقاء وابستگیهای پروژه به نگارش 6 را بررسی کردیم. یکی از مراحل آن اجرای دستور زیر بود:
ng update rxjs
پس از آن اگر پروژه را کامپایل کنید، پر خواهد بود از خطاهای rxjs، مانند:
ERROR in node_modules/ng2-slim-loading-bar/src/slim-loading-bar.service.d.ts(1,10): error TS2305: Module '"/node_modules/rxjs/Observable"' has no exported member 'Observable'.
برای رفع این مشکل و ارائهی راهحلی کوتاه مدت، بستهای به نام rxjs-compat ارائه شدهاست که سبب هدایت تعاریف قدیمی به تعاریف جدید میشود و به این ترتیب کدهای کتابخانهی ثالث، بدون مشکل با نگارش 6 نیز قابل استفاده خواهند بود.
برای نصب آن نیاز است دستور زیر را صادر کنید:
npm i rxjs-compat --save
البته دقت داشته باشید از rxjs-compat به عنوان یک راه حل موقت باید استفاده کرد و نیاز است ابتدا کدهای خود را به روش pipe-able operators بازنویسی کنید و مسیرهای importها را اصلاح کنید و در آخر بستههای جدید وابستگیهای ثالث را که از RxJS6 استفاده میکنند، نصب نمائید. در نهایت rxjs-compat را حذف کنید.
خودکار سازی اصلاح importها در برنامههای پیشین، جهت مهاجرت به RxJS 6.0
با توجه به این تغییرات و حذف و اضافه شدنها در نگارش 6، تقریبا دیگر هیچکدام از importهای قبلی شما کار نمیکنند! و اصلاح آنها نیاز به زمان زیادی خواهد داشت. به همین جهت تیم RxJS ابزاری را طراحی کردهاند که با اجرای آن بر روی پروژه، به صورت خودکار تمام importهای قبلی را به نگارش جدید تبدیل میکند. برای اینکار ابتدا ابزار rxjs-tslint را نصب کنید:
npm i -g rxjs-tslint
{ "rulesDirectory": [ "node_modules/rxjs-tslint" ], "rules": { "rxjs-collapse-imports": true, "rxjs-pipeable-operators-only": true, "rxjs-no-static-observable-methods": true, "rxjs-proper-imports": true } }
rxjs-5-to-6-migrate -p src/tsconfig.app.json
البته توصیه شدهاست این ابزار را بیش از یکبار نیاز است اجرا کنید.
خلاصهی روش مهاجرت به RxJS 6x
ابتدا آخرین نگارش rxjs را نصب کنید:
ng update rxjs
npm i rxjs-compat --save
npm i -g rxjs-tslint rxjs-5-to-6-migrate -p src/tsconfig.app.json
یافتن معادلهای جدید دستورات قدیمی
در حین تبدیل کدهای قدیمی به جدید نیاز خواهید داشت تا معادلها را بیابید. برای این منظور به مستندات رسمی این مهاجرت مراجعه کنید:
https://github.com/ReactiveX/rxjs/blob/master/MIGRATION.md
برای مثال در اینجا مشاهده خواهید کرد که معادل Observable.throw حذف شده، اکنون throwError است و همینطور برای مابقی.
یک مثال واقعی تغییر یافته
مخزن کد تمام مثالهای سایت جاری که پیشتر منتشر شدهاند، به نسخهی 6 ارتقاء داده شد. ریز تغییرات RxJS 6.0 آنها را در اینجا میتوانید مشاهده کنید.