forked from ngxs/store
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(integration): add HMR for integration example with docs (ngxs#660)
* feat(integration): add HMR for integration example with docs * chore: update yarn.lock
- Loading branch information
1 parent
57e8ee4
commit 6149cec
Showing
12 changed files
with
501 additions
and
246 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
# Hot Module Replacement | ||
|
||
Hot Module Replacement (HMR) is a WebPack feature to update code in a running app without rebuilding it. This results in faster updates and less full page-reloads. | ||
In order to get HMR working with Angular CLI we first need to add a new environment and enable it. | ||
|
||
### Add environment for HMR | ||
|
||
In this step will configure the Angular CLI environments and define in which environment we enable HMR. | ||
We will start out by adding and changing files in the `src/environments/` directory. | ||
First we create a file called `src/environments/environment.hmr.ts` with the following contents: | ||
|
||
```ts | ||
export const environment = { | ||
production: false, | ||
hmr: true | ||
}; | ||
``` | ||
|
||
Update `src/environments/environment.prod.ts` and add the hmr: false flag to the environment: | ||
|
||
```ts | ||
export const environment = { | ||
production: true, | ||
hmr: false | ||
}; | ||
``` | ||
|
||
Lastly we edit `src/environments/environment.ts` and change the environment to: | ||
|
||
```ts | ||
export const environment = { | ||
production: false, | ||
hmr: false | ||
}; | ||
``` | ||
|
||
Update angular.json to include an hmr environment as explained here and add configurations within build and serve to enable hmr. | ||
Note that <project-name> here represents the name of the project you are adding this configuration to in angular.json. | ||
|
||
```text | ||
"build": { | ||
"configurations": { | ||
... | ||
"hmr": { | ||
"fileReplacements": [ | ||
{ | ||
"replace": "src/environments/environment.ts", | ||
"with": "src/environments/environment.hmr.ts" | ||
} | ||
] | ||
} | ||
} | ||
}, | ||
... | ||
"serve": { | ||
"configurations": { | ||
... | ||
"hmr": { | ||
"hmr": true, | ||
"browserTarget": "<project-name>:build:hmr" | ||
} | ||
} | ||
} | ||
``` | ||
|
||
Add the necessary types to src/tsconfig.app.json | ||
|
||
```text | ||
{ | ||
... | ||
"compilerOptions": { | ||
... | ||
"types": ["node"] | ||
}, | ||
} | ||
``` | ||
|
||
Run ng serve with the flag --configuration hmr to enable hmr and select the new environment: | ||
|
||
```bash | ||
ng serve --configuration hmr | ||
``` | ||
|
||
Create a shortcut for this by updating package.json and adding an entry to the script object: | ||
|
||
```bash | ||
"scripts": { | ||
... | ||
"hmr": "ng serve --configuration hmr" | ||
} | ||
``` | ||
|
||
### Add dependency for @angularclass/hmr and configure app | ||
|
||
In order to get HMR working we need to install the dependency and configure our app to use it. | ||
|
||
Install the @angularclass/hmr module as a dev-dependency | ||
|
||
Create a file called src/hmr.ts with the following content: | ||
|
||
```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(); | ||
}); | ||
}; | ||
``` | ||
|
||
Update src/main.ts to use the file we just created: | ||
|
||
```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'; | ||
|
||
if (environment.production) { | ||
enableProdMode(); | ||
} | ||
|
||
const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule); | ||
|
||
if (environment.hmr) { | ||
if (module[ 'hot' ]) { | ||
hmrBootstrap(module, bootstrap); | ||
} else { | ||
console.error('HMR is not enabled for webpack-dev-server!'); | ||
console.log('Are you using the --hmr flag for ng serve?'); | ||
} | ||
} else { | ||
bootstrap().catch(err => console.log(err)); | ||
} | ||
``` | ||
|
||
### Starting the development environment with HMR enabled | ||
|
||
Now that everything is set up we can run the new configuration: | ||
|
||
```bash | ||
npm run hmr | ||
``` | ||
|
||
When starting the server Webpack will tell you that it’s enabled: | ||
|
||
```bash | ||
NOTICE Hot Module Replacement (HMR) is enabled for the dev server. | ||
``` | ||
|
||
Now if you make changes to one of your components they changes should be visible automatically without a complete browser refresh. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export const environment = { | ||
production: false, | ||
hmr: true | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export const environment = { | ||
production: true | ||
production: true, | ||
hmr: false | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,4 @@ | ||
// The file contents for the current environment will overwrite these during build. | ||
// The build system defaults to the dev environment which uses `environment.ts`, but if you do | ||
// `ng build --env=prod` then `environment.prod.ts` will be used instead. | ||
// The list of which env maps to which file can be found in `.angular-cli.json`. | ||
|
||
export const environment = { | ||
production: false | ||
production: false, | ||
hmr: false | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
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(); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.