|
| 1 | +# Angular RU Universal Starter [](https://t.me/angular_ru) [](https://t.me/angular_universal_ru) [](https://t.me/angular_ro) [](https://t.me/js_ro) |
| 2 | + |
| 3 | +[](https://semaphoreci.com/angularru/angular-universal-starter) |
| 4 | + |
| 5 | +> Repozitoriul Angular CLI și Angular Universal |
| 6 | +
|
| 7 | +**Traduceri**: |
| 8 | +- [Rusă](./README-RU.md) |
| 9 | +- [Engleză](./README.md) |
| 10 | +- [Românesc](./README-RO.md) |
| 11 | + |
| 12 | +**Resurse**: |
| 13 | +- chat public https://t.me/angular_universal_ru |
| 14 | +- http://master-ssr.gorniv.com/ - rendering pe server master |
| 15 | +- http://master-csr.gorniv.com/ - rendering pe client master |
| 16 | + |
| 17 | +# Planuri: |
| 18 | +- [x] Angular 5 |
| 19 | +- [x] `document is not defined` și `window is not defined` - [aici](./defined.md) |
| 20 | +- [x] [Angular Material2](https://material.angular.io/) **UI componente** - [branch aparte](https://github.com/Angular-RU/angular-universal-starter/tree/material2) |
| 21 | +- [x] [Primeng](https://www.primefaces.org/primeng/) **UI компоненты** - [branch aparte](https://github.com/Angular-RU/angular-universal-starter/tree/primeng) |
| 22 | +- [x] importăm modulele în dependență de platformă (`MockServerBrowserModule`) |
| 23 | +- [x] comunicăm cu api pe server `TransferHttp` |
| 24 | +- [x] folosim Cookies pe server `UniversalStorage` |
| 25 | +- [x] folosim **[ngx-meta](https://github.com/fulls1z3/ngx-meta)** pentru SEO (*title, meta tags, and Open Graph tags for social sharing*). |
| 26 | +- [x] folosim ngx-translate pentru i18n |
| 27 | +- [x] folosim ORIGIN_URL - pentru drumuri absolute |
| 28 | +- [ ] @angular/service-worker |
| 29 | +- [ ] Ionic - e nevoie să creăm versiunea web, până când avem probleme [branch aparte](https://github.com/Angular-RU/angular-universal-starter/tree/ionic) |
| 30 | + |
| 31 | +## Cum să pornim? |
| 32 | +- `yarn` sau `npm install` |
| 33 | +- `yarn start` sau `npm run start` - pentru rendering pe client |
| 34 | +- `yarn ssr` sau `npm run ssr` - pentru rendering pe server |
| 35 | +- `yarn build:universal` sau `npm run build:universal` - pentru production |
| 36 | +- `yarn server` sau `npm run server` - pentru a porni serverul |
| 37 | +- `yarn build:prerender` sau `npm run build:prerender` - pentru a genera statica pe `static.paths.ts` |
| 38 | +- cum pornim watch: odată: `yarn ssr:cw` sau `npm run ssr:cw`, odată: `yarn ssr:sw` sau `npm run ssr:sw`, după fiecare modificare: `yarn ssr:server` sau `npm run ssr:server` |
| 39 | + |
| 40 | +## Cum să folosesc repozitoriul în proiectul meu? |
| 41 | +Pentru a adăuga ssr în proiectul dumneavoastră e nevoie de următoarele fișiere: |
| 42 | + - .angular-cli.json |
| 43 | + - server.ts |
| 44 | + - prerender.ts |
| 45 | + - webpack.config.js |
| 46 | + - main.server.ts |
| 47 | + - main.browser.ts |
| 48 | + - modules/* |
| 49 | + - forStorage/* |
| 50 | + - environments/* |
| 51 | + - app.browser.module.ts |
| 52 | + - app.server.module.ts |
| 53 | + |
| 54 | +## Linkuri |
| 55 | +Exemplu oficial în engleză: https://github.com/angular/universal-starter |
| 56 | +Module folosite pentru universal: |
| 57 | +- https://github.com/angular/universal/tree/master/modules/aspnetcore-engine - motorul pentru .net core |
| 58 | +- https://github.com/angular/universal/tree/master/modules/common - TransferHttpCacheModule, la acest moment nu-l folosesc, dar dacă știți pentru ce și unde se poate de-l pus - deschideți o issue sau pull request |
| 59 | +- https://github.com/angular/universal/tree/master/modules/express-engine - Express Engine pentru a porni renderingul pe node, folosim în repozitoriul nostru. Fiți atenți, versiunea acutală nu mai mică de 5.0.0-beta.5 |
| 60 | +- https://github.com/angular/universal/tree/master/modules/hapi-engine - Hapi Engine un motor alternativă. În exemplu nu folosim, în principui nu-i mare diferența în conectare față de express-engine |
| 61 | +- https://github.com/angular/universal/tree/master/modules/module-map-ngfactory-loader - modul pentru LazyLoading - e ceva folositor. Fiți atenți, versiunea actuală nu mai mică de 5.0.0-beta.5 |
| 62 | + |
| 63 | +## Caracteristici (Important) |
| 64 | +- modulul pentru TransferHttp folosește `import { TransferState } from '@angular/platform-browser';` și e nevoie de el pentru a realiza interogările la rest api pe server și pentru a evita dublarea interogărilor (pe client). Uitați-vă la `home.component.ts` (așteptați 3 secunde) |
| 65 | + |
| 66 | +```ts |
| 67 | +this.http.get('https://reqres.in/api/users?delay=3').subscribe(result => { |
| 68 | + this.result = result; |
| 69 | +}); |
| 70 | +``` |
| 71 | +- `export const AppRoutes = RouterModule.forRoot(routes, { initialNavigation: 'enabled' });` - ca pagina să nu clipească! |
| 72 | + |
| 73 | +- pentru a lucra cu cookie e scris `AppStorage`, care cu ajutorul DI ne permite să facem realizare pentru server și browser. Uitați-vă la `server.storage.ts` și `browser.storage.ts` pentru a vedea realizările. În `server.ts` este |
| 74 | +```ts |
| 75 | +providers: [ |
| 76 | + { |
| 77 | + provide: REQUEST, useValue: (req) |
| 78 | + }, |
| 79 | + { |
| 80 | + provide: RESPONSE, useValue: (res) |
| 81 | + } |
| 82 | +] |
| 83 | +``` |
| 84 | +pentru a lucra cu REQUEST și RESPONSE prin DI - asta-i necesar pentru a lucra cu UniversalStorage când folosim cookies. |
| 85 | + |
| 86 | +- webpack.config.js e scris doar ca să strângă fișierul server.ts și server.js, pentru că angular-cli are o [eroare](https://github.com/angular/angular-cli/issues/7200) la 3d dependențele. |
| 87 | +- pentru a rezolva o mare parte din probleme se folosește următorul cod `server.ts` |
| 88 | + |
| 89 | +Rezolvarea problemei cu variabilele globale, inclusiv `document is not defined` și `window is not defined` |
| 90 | +```ts |
| 91 | +const domino = require('domino'); |
| 92 | +const fs = require('fs'); |
| 93 | +const path = require('path'); |
| 94 | +const template = fs.readFileSync(path.join(__dirname, '.', 'dist', 'index.html')).toString(); |
| 95 | +const win = domino.createWindow(template); |
| 96 | +const files = fs.readdirSync(`${process.cwd()}/dist-server`); |
| 97 | +const styleFiles = files.filter(file => file.startsWith('styles')); |
| 98 | +const hashStyle = styleFiles[0].split('.')[1]; |
| 99 | +const style = fs.readFileSync(path.join(__dirname, '.', 'dist-server', `styles.${hashStyle}.bundle.css`)).toString(); |
| 100 | + |
| 101 | +global['window'] = win; |
| 102 | +Object.defineProperty(win.document.body.style, 'transform', { |
| 103 | + value: () => { |
| 104 | + return { |
| 105 | + enumerable: true, |
| 106 | + configurable: true |
| 107 | + }; |
| 108 | + }, |
| 109 | +}); |
| 110 | +global['document'] = win.document; |
| 111 | +global['CSS'] = style; |
| 112 | +// global['XMLHttpRequest'] = require('xmlhttprequest').XMLHttpRequest; |
| 113 | +global['Prism'] = null; |
| 114 | + |
| 115 | +``` |
| 116 | + |
| 117 | +```ts |
| 118 | +global['navigator'] = req['headers']['user-agent']; |
| 119 | +``` |
| 120 | +asta ne permite să excludem o parte din problemele apărute cu `undefined`. |
0 commit comments