【初始angular 】angular项目创建过程中需要注意的细节
安装angular-cli工具
yarn global add @angular/cli
当前使用版本:Angular CLI: 7.3.1
如果是一些企业级项目的话,本人推荐使用的版本比最新版小一个主版本号,防止最新版的一些发现的问题
设置包管理工具为yarn
ng config cli.packageManager yarn -g
设置cli的包管理工具,这一步可有可无,你也可以用默认的npm
创建项目
ng new ng-project
ng 命令介绍
angular-cli
有两个选项,根据需求选择,以下是当前操作
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? Sass [ http://sass-lang.com ]
热更新
- 添加@angularclass/hmr包
yarn add @angularclass/hmr --dev
创建src/hmr.ts文件
import { NgModuleRef, ApplicationRef } from '@angular/core'; import { createNewHosts } from '@angularclass/hmr'; export const hmrBootstrap = ( module: any, bootstrap: () => Promise<NgModuleRef<any>> ) => { let ngModule: NgModuleRef<any>; module.hot.accept(); bootstrap().then(mod => (ngModule = mod)); module.hot.dispose(() => { const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef); const elements = appRef.components.map(c => c.location.nativeElement); const makeVisible = createNewHosts(elements); ngModule.destroy(); makeVisible(); }); };
修改src/main.ts
import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; import { hmrBootstrap } from './hmr'; declare var module: any; if (environment.production) { enableProdMode(); } const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule); if ((environment as any).hmr) { if (module.hot) { hmrBootstrap(module, bootstrap); } else { console.error('HMR is not enabled for webpack-dev-job!'); console.log('Are you using the --hmr flag for ng serve?'); } } else { document.addEventListener('DOMContentLoaded', () => { bootstrap().catch(err => console.log(err)); }); }
创建src/environments/environment.hmr.ts
export const environment = { production: false, hmr: true };
修改angular.json文件
在angular.json的对象
projects.architect.build.configurations
添加以下内容"hmr": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.hmr.ts" } ] }
在angular.json的对象
projects.architect.serve.configurations
添加以下内容"hmr": { "browserTarget": "ng-project:build:hmr", "hmr": true }
添加热更新启动命令行
在package.json的scripts中添加以下内容
"start:hmr": "ng serve -c hmr"
多项目支持
ng generate application ng-project2
这个命令会在根目录下生产一个projects文件夹,所有生成的项目都在这个文件夹下
通过npm模块的方式引用外部依赖
比如ng-project项目和ng-project2需要共用api接口,我们想在在项目中以 @apis/user、@apis/permissions这样的方式使用api接口,两步:
- 创建apis类库
ng generate library apis
在tsconfig.json中compilerOptions下添加
"paths": { "@apis/*": [ "dist/apis/*" ] }
服务端渲染
ng add @nguniversal/express-engine --clientProject ng-project --appId ng-project-universal
-
yarn add mutation-observer
// 有些库需要比如:ng-zorro-antd 替换 server.ts
import 'zone.js/dist/zone-node'; import 'reflect-metadata'; import { enableProdMode } from '@angular/core'; // Express Engine import { ngExpressEngine } from '@nguniversal/express-engine'; // Import module map for lazy loading import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader'; import * as express from 'express'; import { join } from 'path'; const domino = require('domino'); const fs = require('fs'); const template = fs.readFileSync(join(process.cwd(), 'dist/browser/index.html')).toString(); const win = domino.createWindow(template); global['window'] = win; global['MutationObserver'] = require('mutation-observer'); Object.defineProperty(win.document.body.style, 'transform', { value: () => { return { enumerable: true, configurable: true }; }, }); global['document'] = win.document; global['CSS'] = null; // Faster server renders w/ Prod mode (dev mode never needed) enableProdMode(); // Express server const app = express(); const PORT = process.env.PORT || 4000; const DIST_FOLDER = join(process.cwd(), 'dist/browser'); // * NOTE :: leave this as require() since this file is built Dynamically from webpack const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main'); // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine) app.engine('html', ngExpressEngine({ bootstrap: AppServerModuleNgFactory, providers: [ provideModuleMap(LAZY_MODULE_MAP) ] })); app.set('view engine', 'html'); app.set('views', DIST_FOLDER); // Example Express Rest API endpoints // app.get('/api/**', (req, res) => { }); // Server static files from /browser app.get('*.*', express.static(DIST_FOLDER, { maxAge: '1y' })); // All regular routes use the Universal engine app.get('*', (req, res) => { global['navigator'] = req['headers']['user-agent']; res.render('index', {req}); }); // Start up the Node server app.listen(PORT, () => { console.log(`Node Express server listening on http://localhost:${PORT}`); });
替换src/app/app.server.module.ts
import { NgModule } from '@angular/core'; import { ServerModule, ServerTransferStateModule } from '@angular/platform-server'; import { AppModule } from './app.module'; import { AppComponent } from './app.component'; import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader'; @NgModule({ imports: [ AppModule, ServerModule, ModuleMapLoaderModule, ServerTransferStateModule, ], bootstrap: [AppComponent], }) export class AppServerModule {}
- 构建
yarn build:ssr
- 运行
serve:ssr
通过命令生产的 server.ts 不能解决一些浏览器报错的问题,以上的server.ts已经把大部分问题包含了
提供参考项目源码 https://github.com/loopbless/btf-factoring-manager
至此,一个逼格较高的angular项目就建好了!