Refactor the project to have three separate packages
This commit is contained in:
parent
f852f1f2c2
commit
7377de404d
196
README.md
196
README.md
@ -1,171 +1,35 @@
|
||||
# Nrwl Extensions for Angular
|
||||
# Angular Extensions
|
||||
|
||||
NX (Nrwl Extensions) is a set of libraries and schematics for the Angular framework.
|
||||
* See packages/bazel/README.md
|
||||
* See packages/nx/README.md
|
||||
* See packages/schematics/README.md
|
||||
|
||||
## Development Guide
|
||||
|
||||
### Building the Project
|
||||
|
||||
Running `yarn build` will build all the three packages.
|
||||
|
||||
### Running Unit Tests
|
||||
|
||||
Running `yarn test` will run unit tests for all the projects.
|
||||
|
||||
### Running E2E Tests
|
||||
|
||||
Running `yarn e2e` will run e2e tests for all the projects.
|
||||
|
||||
### Linking
|
||||
|
||||
The bazel package depends on the schematics package. If you make a change in the schematics that you want the bazel package ot pick up, run `yarn link`.
|
||||
|
||||
### Packaging
|
||||
|
||||
Running `yarn package` will create tgz files for all the projects. You can install them via npm.
|
||||
|
||||
### Release
|
||||
|
||||
Running `yarn release` will build the packages and push them to `github.com/nrwl/nx-build`, `github.com/nrwl/schematics-build`, `github.com/nrwl/bazel-build`
|
||||
|
||||
|
||||
|
||||
## Installing
|
||||
|
||||
Add the following dependencies to your project's `package.json` and run `npm install`:
|
||||
|
||||
```
|
||||
{
|
||||
dependencies: {
|
||||
"@ngrx/store": "4.0.2",
|
||||
"@ngrx/effects": "4.0.2",
|
||||
"@nrwl/nx": "https://github.com/nrwl/nx-build",
|
||||
"@angular-devkit/schematics": "0.0.17"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Schematics
|
||||
|
||||
### addNgRxToModule
|
||||
|
||||
#### Root
|
||||
|
||||
Run `schematics @nrwl/nx:addNgRxToModule --module=src/app/app.module.ts --root`, and you will see the following files created:
|
||||
|
||||
```
|
||||
/src/app/+state/app.actions.ts
|
||||
/src/app/+state/app.effects.ts
|
||||
/src/app/+state/app.effects.spec.ts
|
||||
/src/app/+state/app.init.ts
|
||||
/src/app/+state/app.interfaces.ts
|
||||
/src/app/+state/app.reducer.ts
|
||||
/src/app/+state/app.reducer.spec.ts
|
||||
```
|
||||
|
||||
Also, `app.module.ts` will have `StoreModule.forRoot` and `EffectsModule.forRoot` configured.
|
||||
|
||||
#### EmptyRoot
|
||||
|
||||
Run `schematics @nrwl/nx:addNgRxToModule --module=src/app/app.module.ts --emptyRoot` to only add the `StoreModule.forRoot` and `EffectsModule.forRoot` calls.
|
||||
|
||||
#### Feature
|
||||
|
||||
Run `schematics @nrwl/nx:addNgRxToModule --module=src/app/mymodule/mymodule.module.ts `, and you will see the following files created:
|
||||
|
||||
```
|
||||
/src/app/mymodule/+state/app.actions.ts
|
||||
/src/app/mymodule/+state/app.effects.ts
|
||||
/src/app/mymodule/+state/app.effects.spec.ts
|
||||
/src/app/mymodule/+state/app.init.ts
|
||||
/src/app/mymodule/+state/app.interfaces.ts
|
||||
/src/app/mymodule/+state/app.reducer.ts
|
||||
/src/app/mymodule/+state/app.reducer.spec.ts
|
||||
```
|
||||
|
||||
Also, `mymodule.module.ts` will have `StoreModule.forFeature` and `EffectsModule.forFeature` configured.
|
||||
|
||||
#### skipImport
|
||||
|
||||
Add `--skipImport` to generate files without adding imports to the module.
|
||||
|
||||
|
||||
|
||||
## Data Persistence
|
||||
|
||||
Nrwl Extensions come with utilities to simplify data persistence (data fetching, optimistic and pessimistic updates).
|
||||
|
||||
### Optimistic Updates
|
||||
|
||||
```typescript
|
||||
class TodoEffects {
|
||||
@Effect() updateTodo = this.s.optimisticUpdate('UPDATE_TODO', {
|
||||
// provides an action and the current state of the store
|
||||
run(a: UpdateTodo, state: TodosState) {
|
||||
return this.backend(state.user, a.payload);
|
||||
},
|
||||
|
||||
undoAction(a: UpdateTodo, e: any): Action {
|
||||
// dispatch an undo action to undo the changes in the client state
|
||||
return ({
|
||||
type: 'UNDO_UPDATE_TODO',
|
||||
payload: a
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
constructor(private s: DataPersistence<TodosState>, private backend: Backend) {}
|
||||
}
|
||||
```
|
||||
|
||||
### Pessimistic Updates
|
||||
|
||||
```typescript
|
||||
@Injectable()
|
||||
class TodoEffects {
|
||||
@Effect() updateTodo = this.s.pessimisticUpdate('UPDATE_TODO', {
|
||||
// provides an action and the current state of the store
|
||||
run(a: UpdateTodo, state: TodosState) {
|
||||
// update the backend first, and then dispatch an action that will
|
||||
// update the client side
|
||||
return this.backend(state.user, a.payload).map(updated => ({
|
||||
type: 'TODO_UPDATED',
|
||||
payload: updated
|
||||
}));
|
||||
},
|
||||
onError(a: UpdateTodo, e: any) {
|
||||
// we don't need to undo the changes on the client side.
|
||||
// we can dispatch an error, or simply log the error here and return `null`
|
||||
return null;
|
||||
}
|
||||
});
|
||||
constructor(private s: DataPersistence<TodosState>, private backend: Backend) {}
|
||||
}
|
||||
```
|
||||
|
||||
### Date Fetching
|
||||
|
||||
```typescript
|
||||
@Injectable()
|
||||
class TodoEffects {
|
||||
@Effect() loadTodo = this.s.fetch('GET_TODOS', {
|
||||
// provides an action and the current state of the store
|
||||
run(a: GetTodos, state: TodosState) {
|
||||
return this.backend(state.user, a.payload).map(r => ({
|
||||
type: 'TODOS',
|
||||
payload: r
|
||||
});
|
||||
},
|
||||
onError(a: GetTodos, e: any): Action {
|
||||
// dispatch an undo action to undo the changes in the client state
|
||||
// return null;
|
||||
}
|
||||
});
|
||||
constructor(private s: DataPersistence<TodosState>, private backend: Backend) {}
|
||||
}
|
||||
```
|
||||
|
||||
### Date Fetching On Router Navigation
|
||||
|
||||
```typescript
|
||||
@Injectable()
|
||||
class TodoEffects {
|
||||
@Effect() loadTodo = this.s.navigation(TodoComponent, {
|
||||
run: (a: ActivatedRouteSnapshot, state: TodosState) => {
|
||||
return this.backend.fetchTodo(a.params['id']).map(todo => ({
|
||||
type: 'TODO_LOADED',
|
||||
payload: todo
|
||||
}));
|
||||
},
|
||||
onError: (a: ActivatedRouteSnapshot, e: any) => {
|
||||
// we can log and error here and return null
|
||||
// we can also navigate back
|
||||
return null;
|
||||
}
|
||||
});
|
||||
constructor(private s: DataPersistence<TodosState>, private backend: Backend) {}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Testing
|
||||
|
||||
Nrwl Extensions come with utilities to simplify testing Angular applications. See `app.effects.spec.ts`. Read https://github.com/vsavkin/testing_ngrx_effects for more information.
|
||||
|
||||
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from './utils';
|
||||
import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from '../utils';
|
||||
|
||||
describe('application', () => {
|
||||
beforeEach(cleanup);
|
||||
|
||||
it('creates a new application in a workspace', () => {
|
||||
runSchematic('@nrwl/nx:application --name=proj');
|
||||
runSchematic('@nrwl/nx:app --name=myApp', {projectName: 'proj'});
|
||||
fit('creates a new application in a workspace', () => {
|
||||
runSchematic('@nrwl/bazel:application --name=proj');
|
||||
runSchematic('@nrwl/bazel:app --name=myApp', {projectName: 'proj'});
|
||||
|
||||
checkFilesExists(
|
||||
`proj/tsconfig.json`, `proj/WORKSPACE`, `proj/BUILD.bazel`, `proj/apps/my-app/BUILD.bazel`,
|
||||
@ -21,9 +21,9 @@ describe('application', () => {
|
||||
});
|
||||
|
||||
it('creates multiple applications in a workspace', () => {
|
||||
runSchematic('@nrwl/nx:application --name=proj2');
|
||||
runSchematic('@nrwl/nx:app --name=first', {projectName: 'proj2'});
|
||||
runSchematic('@nrwl/nx:app --name=second', {projectName: 'proj2'});
|
||||
runSchematic('@nrwl/bazel:application --name=proj2');
|
||||
runSchematic('@nrwl/bazel:app --name=first', {projectName: 'proj2'});
|
||||
runSchematic('@nrwl/bazel:app --name=second', {projectName: 'proj2'});
|
||||
|
||||
const cliConfig = JSON.parse(readFile('proj2/.angular-cli.json'));
|
||||
expect(cliConfig.apps[0].name).toEqual('first');
|
||||
@ -1,11 +1,11 @@
|
||||
import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from './utils';
|
||||
import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from '../utils';
|
||||
|
||||
describe('library', () => {
|
||||
beforeEach(cleanup);
|
||||
|
||||
it('creates a new library in a workspace', () => {
|
||||
runSchematic('@nrwl/nx:application --name=proj');
|
||||
runSchematic('@nrwl/nx:lib --name=myLib', {projectName: 'proj'});
|
||||
runSchematic('@nrwl/bazel:application --name=proj');
|
||||
runSchematic('@nrwl/bazel:lib --name=myLib', {projectName: 'proj'});
|
||||
|
||||
checkFilesExists(
|
||||
`proj/tsconfig.json`, `proj/WORKSPACE`, `proj/BUILD.bazel`, `proj/libs/my-lib/BUILD.bazel`,
|
||||
@ -1,11 +1,11 @@
|
||||
import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from './utils';
|
||||
import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from '../utils';
|
||||
|
||||
describe('angular library', () => {
|
||||
beforeEach(cleanup);
|
||||
|
||||
it('creates a new angularlibrary in a workspace', () => {
|
||||
runSchematic('@nrwl/nx:application --name=proj');
|
||||
runSchematic('@nrwl/nx:nglib --name=myLib', {projectName: 'proj'});
|
||||
runSchematic('@nrwl/bazel:application --name=proj');
|
||||
runSchematic('@nrwl/bazel:nglib --name=myLib', {projectName: 'proj'});
|
||||
|
||||
checkFilesExists(
|
||||
`proj/tsconfig.json`, `proj/WORKSPACE`, `proj/BUILD.bazel`, `proj/libs/my-lib/BUILD.bazel`,
|
||||
@ -1,10 +1,10 @@
|
||||
import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from './utils';
|
||||
import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from '../utils';
|
||||
|
||||
describe('workspace', () => {
|
||||
beforeEach(cleanup);
|
||||
|
||||
it('creates a new workspace for developing angular applications', () => {
|
||||
runSchematic('@nrwl/nx:application --name=proj --version=0.1');
|
||||
runSchematic('@nrwl/bazel:application --name=proj --version=0.1');
|
||||
|
||||
checkFilesExists(`proj/tsconfig.json`, `proj/WORKSPACE`, `proj/BUILD.bazel`);
|
||||
});
|
||||
@ -1,11 +1,11 @@
|
||||
import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from './utils';
|
||||
import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from '../utils';
|
||||
|
||||
describe('addNgRxToModule', () => {
|
||||
beforeEach(cleanup);
|
||||
|
||||
it('should add root configuration', () => {
|
||||
newApp('new proj --skipInstall');
|
||||
runSchematic('@nrwl/nx:addNgRxToModule --module=src/app/app.module.ts --root', {projectName: 'proj'});
|
||||
runSchematic('@nrwl/schematics:addNgRxToModule --module=src/app/app.module.ts --root', {projectName: 'proj'});
|
||||
|
||||
checkFilesExists(
|
||||
`proj/src/app/+state/app.actions.ts`, `proj/src/app/+state/app.effects.ts`,
|
||||
@ -26,7 +26,7 @@ describe('addNgRxToModule', () => {
|
||||
|
||||
it('should add empty root configuration', () => {
|
||||
newApp('new proj2 --skipInstall');
|
||||
runSchematic('@nrwl/nx:addNgRxToModule --module=src/app/app.module.ts --emptyRoot', {projectName: 'proj2'});
|
||||
runSchematic('@nrwl/schematics:addNgRxToModule --module=src/app/app.module.ts --emptyRoot', {projectName: 'proj2'});
|
||||
|
||||
const contents = readFile('proj2/src/app/app.module.ts');
|
||||
expect(contents).toContain('StoreModule.forRoot');
|
||||
@ -39,7 +39,7 @@ describe('addNgRxToModule', () => {
|
||||
|
||||
it('should add feature configuration', () => {
|
||||
newApp('new proj3 --skipInstall');
|
||||
runSchematic('@nrwl/nx:addNgRxToModule --module=src/app/app.module.ts', {projectName: 'proj3'});
|
||||
runSchematic('@nrwl/schematics:addNgRxToModule --module=src/app/app.module.ts', {projectName: 'proj3'});
|
||||
|
||||
checkFilesExists(
|
||||
`proj3/src/app/+state/app.actions.ts`, `proj3/src/app/+state/app.effects.ts`,
|
||||
@ -54,7 +54,7 @@ describe('addNgRxToModule', () => {
|
||||
|
||||
it('should generate files without importing them', () => {
|
||||
newApp('new proj4 --skipInstall');
|
||||
runSchematic('@nrwl/nx:addNgRxToModule --module=src/app/app.module.ts --skipImport', {projectName: 'proj4'});
|
||||
runSchematic('@nrwl/schematics:addNgRxToModule --module=src/app/app.module.ts --skipImport', {projectName: 'proj4'});
|
||||
|
||||
checkFilesExists(
|
||||
`proj4/src/app/+state/app.actions.ts`, `proj4/src/app/+state/app.effects.ts`,
|
||||
@ -9,7 +9,7 @@ module.exports = function(config) {
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
{ pattern: 'build/test/test.js', watched: false}
|
||||
{ pattern: 'build/test.js', watched: false}
|
||||
],
|
||||
|
||||
// list of files to exclude
|
||||
@ -18,7 +18,7 @@ module.exports = function(config) {
|
||||
// preprocess matching files before serving them to the browser
|
||||
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
|
||||
preprocessors: {
|
||||
'build/test/test.js': ['webpack']
|
||||
'build/test.js': ['webpack']
|
||||
},
|
||||
|
||||
reporters: ['dots'],
|
||||
|
||||
21
package.json
21
package.json
@ -1,12 +1,13 @@
|
||||
{
|
||||
"name": "@nrwl/nx",
|
||||
"version": "0.0.1",
|
||||
"description": "Nrwl Extensions for Angular",
|
||||
"description": "Angular Extensions",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "./scripts/build.sh",
|
||||
"e2e": "yarn build && ./scripts/e2e.sh",
|
||||
"format": "./scripts/format.sh",
|
||||
"link": "./scripts/link.sh",
|
||||
"package": "./scripts/package.sh",
|
||||
"release": "./scripts/release.sh",
|
||||
"test": "yarn build && ./scripts/test.sh"
|
||||
@ -14,18 +15,6 @@
|
||||
"dependencies" :{
|
||||
"jasmine-marbles": "0.1.0"
|
||||
},
|
||||
"peerDependencies" :{
|
||||
"@angular-devkit/schematics": "*",
|
||||
"rxjs": ">5.4.2",
|
||||
"@angular/core": ">4.0.0",
|
||||
"@angular/common": ">4.0.0",
|
||||
"@angular/router": ">4.0.0",
|
||||
"@angular/platform-browser": ">4.0.0",
|
||||
"@ngrx/store": ">4.0.0",
|
||||
"@ngrx/router-store": ">4.0.0",
|
||||
"@ngrx/effects": ">4.0.0"
|
||||
},
|
||||
|
||||
"devDependencies": {
|
||||
"rxjs": "5.4.3",
|
||||
"@angular/core": "4.3.5",
|
||||
@ -41,8 +30,7 @@
|
||||
"@types/node": "8.0.7",
|
||||
"@types/jasmine": "2.5.53",
|
||||
"jest": "20.0.4",
|
||||
"@angular-devkit/schematics": "0.0.17",
|
||||
"@schematics/angular": "git+https://github.com/Brocco/zzz-ng-schematics.git",
|
||||
"@schematics/angular": "0.0.30",
|
||||
"jasmine-core": "~2.6.2",
|
||||
"karma": "~1.7.0",
|
||||
"karma-chrome-launcher": "~2.1.1",
|
||||
@ -57,6 +45,5 @@
|
||||
"tmp",
|
||||
"files"
|
||||
]
|
||||
},
|
||||
"schematics": "schematics/collection.json"
|
||||
}
|
||||
}
|
||||
|
||||
22
packages/bazel/LICENSE
Normal file
22
packages/bazel/LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2017 Narwhal Technologies
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
1
packages/bazel/README.md
Normal file
1
packages/bazel/README.md
Normal file
@ -0,0 +1 @@
|
||||
# Angular Extensions: Bazel Backend for CLI
|
||||
12
packages/bazel/package.json
Normal file
12
packages/bazel/package.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "@nrwl/bazel",
|
||||
"version": "0.0.1",
|
||||
"description": "Angular Extensions: Schematics",
|
||||
"main": "src/index.js",
|
||||
"peerDependencies" :{
|
||||
"@nrwl/schematics": "0.0.1"
|
||||
},
|
||||
"author": "Victor Savkin",
|
||||
"license": "MIT",
|
||||
"schematics": "src/collection.json"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
@ -1,10 +1,9 @@
|
||||
import {apply, chain, mergeWith, move, Rule, externalSchematic, template, url, Tree,} from '@angular-devkit/schematics';
|
||||
import {Schema} from './schema';
|
||||
import {names, toFileName} from '../name-utils';
|
||||
import {names, toFileName, insert} from '@nrwl/schematics';
|
||||
import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
import {addBootstrapToModule, addImportToModule} from '@schematics/angular/utility/ast-utils';
|
||||
import {insert} from '../utility/ast-utils';
|
||||
|
||||
function addBootstrap(path: string): Rule {
|
||||
return (host: Tree) => {
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "nrwl",
|
||||
"name": "bazel",
|
||||
"version": "0.1",
|
||||
"schematics": {
|
||||
"application": {
|
||||
@ -21,11 +21,6 @@
|
||||
"factory": "./nglib",
|
||||
"schema": "./nglib/schema.json",
|
||||
"description": "Create an Angular library."
|
||||
},
|
||||
"addNgRxToModule": {
|
||||
"factory": "./addNgRxToModule",
|
||||
"schema": "./addNgRxToModule/schema.json",
|
||||
"description": "Add NgRx support to a module."
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
import {apply, branchAndMerge, chain, mergeWith, Rule, template, Tree, url} from '@angular-devkit/schematics';
|
||||
import {Schema} from './schema';
|
||||
import * as path from 'path';
|
||||
import {names, toFileName} from '../name-utils';
|
||||
import {names, toFileName} from '@nrwl/schematics';
|
||||
|
||||
function addLibToAngularCliJson(fullPath: string, schema: Schema): Rule {
|
||||
return (host: Tree) => {
|
||||
@ -1,7 +1,7 @@
|
||||
import {apply, branchAndMerge, chain, mergeWith, Rule, template, Tree, url} from '@angular-devkit/schematics';
|
||||
import {Schema} from './schema';
|
||||
import * as path from 'path';
|
||||
import {names, toFileName} from '../name-utils';
|
||||
import {names, toFileName} from '@nrwl/schematics';
|
||||
|
||||
function addLibToAngularCliJson(fullPath: string, schema: Schema): Rule {
|
||||
return (host: Tree) => {
|
||||
@ -20,7 +20,7 @@ module.exports = function(config) {
|
||||
},
|
||||
resolveLoader: {
|
||||
alias: {
|
||||
"template-loader": '@nrwl/nx/bazel/template-loader'
|
||||
"template-loader": '@nrwl/bazel/src/utils/template-loader'
|
||||
}
|
||||
},
|
||||
module: {
|
||||
@ -18,7 +18,7 @@ local_repository(
|
||||
|
||||
local_repository(
|
||||
name = "nrwl",
|
||||
path = "node_modules/@nrwl/nx/bazel",
|
||||
path = "node_modules/@nrwl/bazel/src/utils",
|
||||
)
|
||||
|
||||
git_repository(
|
||||
@ -7,12 +7,12 @@
|
||||
],
|
||||
"test": {
|
||||
"karma": {
|
||||
"config": "node_modules/@nrwl/nx/bazel/karma.conf.js"
|
||||
"config": "node_modules/@nrwl/bazel/src/utils/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
"schematics": {
|
||||
"collection": "@nrwl/nx"
|
||||
"collection": "@nrwl/bazel"
|
||||
},
|
||||
"component": {
|
||||
"spec": true,
|
||||
@ -29,7 +29,7 @@
|
||||
"devDependencies": {
|
||||
"@angular/cli": "https://github.com/nrwl/bazel-cli-build",
|
||||
"@bazel/typescript": "~0.0.7",
|
||||
"@nrwl/nx": "https://github.com/nrwl/nx-build",
|
||||
"@nrwl/bazel": "https://github.com/nrwl/bazel-build",
|
||||
"@angular/bazel": "angular/bazel-builds#6f50535",
|
||||
"@angular/compiler-cli": "angular/compiler-cli-builds#797acb2",
|
||||
"@angular/language-service": "angular/language-service-builds#57583ee",
|
||||
@ -1,6 +1,6 @@
|
||||
import {apply, chain, mergeWith, move, Rule, schematic, template, url,} from '@angular-devkit/schematics';
|
||||
import {Schema} from './schema';
|
||||
import {names} from '../name-utils';
|
||||
import {names} from '@nrwl/schematics';
|
||||
|
||||
export default function(options: Schema): Rule {
|
||||
return chain([mergeWith(apply(
|
||||
22
packages/nx/LICENSE
Normal file
22
packages/nx/LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2017 Narwhal Technologies
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
120
packages/nx/README.md
Normal file
120
packages/nx/README.md
Normal file
@ -0,0 +1,120 @@
|
||||
# Angular Extensions
|
||||
|
||||
Nx (Angular Extensions) is a set of libraries and schematics for the Angular framework.
|
||||
|
||||
## Installing
|
||||
|
||||
Add the following dependencies to your project's `package.json` and run `npm install`:
|
||||
|
||||
```
|
||||
{
|
||||
dependencies: {
|
||||
"@ngrx/store": "4.0.2",
|
||||
"@ngrx/effects": "4.0.2",
|
||||
"@nrwl/nx": "https://github.com/nrwl/nx-build"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Data Persistence
|
||||
|
||||
Nrwl Extensions come with utilities to simplify data persistence (data fetching, optimistic and pessimistic updates).
|
||||
|
||||
### Optimistic Updates
|
||||
|
||||
```typescript
|
||||
class TodoEffects {
|
||||
@Effect() updateTodo = this.s.optimisticUpdate('UPDATE_TODO', {
|
||||
// provides an action and the current state of the store
|
||||
run(a: UpdateTodo, state: TodosState) {
|
||||
return this.backend(state.user, a.payload);
|
||||
},
|
||||
|
||||
undoAction(a: UpdateTodo, e: any): Action {
|
||||
// dispatch an undo action to undo the changes in the client state
|
||||
return ({
|
||||
type: 'UNDO_UPDATE_TODO',
|
||||
payload: a
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
constructor(private s: DataPersistence<TodosState>, private backend: Backend) {}
|
||||
}
|
||||
```
|
||||
|
||||
### Pessimistic Updates
|
||||
|
||||
```typescript
|
||||
@Injectable()
|
||||
class TodoEffects {
|
||||
@Effect() updateTodo = this.s.pessimisticUpdate('UPDATE_TODO', {
|
||||
// provides an action and the current state of the store
|
||||
run(a: UpdateTodo, state: TodosState) {
|
||||
// update the backend first, and then dispatch an action that will
|
||||
// update the client side
|
||||
return this.backend(state.user, a.payload).map(updated => ({
|
||||
type: 'TODO_UPDATED',
|
||||
payload: updated
|
||||
}));
|
||||
},
|
||||
onError(a: UpdateTodo, e: any) {
|
||||
// we don't need to undo the changes on the client side.
|
||||
// we can dispatch an error, or simply log the error here and return `null`
|
||||
return null;
|
||||
}
|
||||
});
|
||||
constructor(private s: DataPersistence<TodosState>, private backend: Backend) {}
|
||||
}
|
||||
```
|
||||
|
||||
### Date Fetching
|
||||
|
||||
```typescript
|
||||
@Injectable()
|
||||
class TodoEffects {
|
||||
@Effect() loadTodo = this.s.fetch('GET_TODOS', {
|
||||
// provides an action and the current state of the store
|
||||
run(a: GetTodos, state: TodosState) {
|
||||
return this.backend(state.user, a.payload).map(r => ({
|
||||
type: 'TODOS',
|
||||
payload: r
|
||||
});
|
||||
},
|
||||
onError(a: GetTodos, e: any): Action {
|
||||
// dispatch an undo action to undo the changes in the client state
|
||||
// return null;
|
||||
}
|
||||
});
|
||||
constructor(private s: DataPersistence<TodosState>, private backend: Backend) {}
|
||||
}
|
||||
```
|
||||
|
||||
### Date Fetching On Router Navigation
|
||||
|
||||
```typescript
|
||||
@Injectable()
|
||||
class TodoEffects {
|
||||
@Effect() loadTodo = this.s.navigation(TodoComponent, {
|
||||
run: (a: ActivatedRouteSnapshot, state: TodosState) => {
|
||||
return this.backend.fetchTodo(a.params['id']).map(todo => ({
|
||||
type: 'TODO_LOADED',
|
||||
payload: todo
|
||||
}));
|
||||
},
|
||||
onError: (a: ActivatedRouteSnapshot, e: any) => {
|
||||
// we can log and error here and return null
|
||||
// we can also navigate back
|
||||
return null;
|
||||
}
|
||||
});
|
||||
constructor(private s: DataPersistence<TodosState>, private backend: Backend) {}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Testing
|
||||
|
||||
Nx comes with utilities to simplify testing Angular applications. Read https://github.com/vsavkin/testing_ngrx_effects for more information.
|
||||
|
||||
|
||||
1
packages/nx/index.ts
Normal file
1
packages/nx/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export {DataPersistence} from './src/data-persistence';
|
||||
22
packages/nx/package.json
Normal file
22
packages/nx/package.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "@nrwl/nx",
|
||||
"version": "0.0.1",
|
||||
"description": "Angular Extensions",
|
||||
"main": "index.js",
|
||||
"dependencies" :{
|
||||
"jasmine-marbles": "0.1.0",
|
||||
"@nrwl/schematics": "0.0.1"
|
||||
},
|
||||
"peerDependencies" :{
|
||||
"rxjs": ">5.4.2",
|
||||
"@angular/core": ">4.0.0",
|
||||
"@angular/common": ">4.0.0",
|
||||
"@angular/router": ">4.0.0",
|
||||
"@angular/platform-browser": ">4.0.0",
|
||||
"@ngrx/store": ">4.0.0",
|
||||
"@ngrx/router-store": ">4.0.0",
|
||||
"@ngrx/effects": ">4.0.0"
|
||||
},
|
||||
"author": "Victor Savkin",
|
||||
"license": "MIT"
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import {DataPersistence} from '../../src/index';
|
||||
import {DataPersistence} from '../index';
|
||||
import {Actions, Effect, EffectsModule} from '@ngrx/effects';
|
||||
import {ActivatedRouteSnapshot, Router} from '@angular/router';
|
||||
import {Store, StoreModule} from '@ngrx/store';
|
||||
@ -11,7 +11,7 @@ import {Observable} from 'rxjs/Observable';
|
||||
import {_throw} from 'rxjs/observable/throw';
|
||||
import {provideMockActions} from '@ngrx/effects/testing';
|
||||
import {Subject} from 'rxjs/Subject';
|
||||
import {readAll} from '../../src/utils/testing';
|
||||
import {readAll} from '../testing';
|
||||
|
||||
// interfaces
|
||||
type Todo = { id: number; user: string; };
|
||||
2
packages/nx/testing.ts
Normal file
2
packages/nx/testing.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export {cold, hot} from 'jasmine-marbles';
|
||||
export {readAll} from './src/testing-utils';
|
||||
22
packages/schematics/LICENSE
Normal file
22
packages/schematics/LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2017 Narwhal Technologies
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
63
packages/schematics/README.md
Normal file
63
packages/schematics/README.md
Normal file
@ -0,0 +1,63 @@
|
||||
# Angular Extensions: Schematics
|
||||
|
||||
Nx (Angular Extensions) is a set of libraries and schematics for the Angular framework.
|
||||
|
||||
|
||||
|
||||
## Installing
|
||||
|
||||
Add the following dependencies to your project's `package.json` and run `npm install`:
|
||||
|
||||
```
|
||||
{
|
||||
dependencies: {
|
||||
"@nrwl/schematics": "https://github.com/nrwl/schematics-build"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Schematics
|
||||
|
||||
### addNgRxToModule
|
||||
|
||||
#### Root
|
||||
|
||||
Run `schematics @nrwl/schematics:addNgRxToModule --module=src/app/app.module.ts --root`, and you will see the following files created:
|
||||
|
||||
```
|
||||
/src/app/+state/app.actions.ts
|
||||
/src/app/+state/app.effects.ts
|
||||
/src/app/+state/app.effects.spec.ts
|
||||
/src/app/+state/app.init.ts
|
||||
/src/app/+state/app.interfaces.ts
|
||||
/src/app/+state/app.reducer.ts
|
||||
/src/app/+state/app.reducer.spec.ts
|
||||
```
|
||||
|
||||
Also, `app.module.ts` will have `StoreModule.forRoot` and `EffectsModule.forRoot` configured.
|
||||
|
||||
#### EmptyRoot
|
||||
|
||||
Run `schematics @nrwl/schematics:addNgRxToModule --module=src/app/app.module.ts --emptyRoot` to only add the `StoreModule.forRoot` and `EffectsModule.forRoot` calls.
|
||||
|
||||
#### Feature
|
||||
|
||||
Run `schematics @nrwl/schematics:addNgRxToModule --module=src/app/mymodule/mymodule.module.ts `, and you will see the following files created:
|
||||
|
||||
```
|
||||
/src/app/mymodule/+state/app.actions.ts
|
||||
/src/app/mymodule/+state/app.effects.ts
|
||||
/src/app/mymodule/+state/app.effects.spec.ts
|
||||
/src/app/mymodule/+state/app.init.ts
|
||||
/src/app/mymodule/+state/app.interfaces.ts
|
||||
/src/app/mymodule/+state/app.reducer.ts
|
||||
/src/app/mymodule/+state/app.reducer.spec.ts
|
||||
```
|
||||
|
||||
Also, `mymodule.module.ts` will have `StoreModule.forFeature` and `EffectsModule.forFeature` configured.
|
||||
|
||||
#### skipImport
|
||||
|
||||
Add `--skipImport` to generate files without adding imports to the module.
|
||||
2
packages/schematics/index.ts
Normal file
2
packages/schematics/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export {names, toClassName, toFileName, toPropertyName} from './src/utility/name-utils';
|
||||
export {addImportToModule, addProviderToModule, insert} from './src/utility/ast-utils';
|
||||
14
packages/schematics/package.json
Normal file
14
packages/schematics/package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "@nrwl/schematics",
|
||||
"version": "0.0.1",
|
||||
"description": "Angular Extensions: Schematics",
|
||||
"main": "index.js",
|
||||
"peerDependencies" :{
|
||||
"rxjs": ">5.4.2",
|
||||
"@angular-devkit/schematics": "0.0.18",
|
||||
"@schematics/angular": "0.0.30"
|
||||
},
|
||||
"author": "Victor Savkin",
|
||||
"license": "MIT",
|
||||
"schematics": "src/collection.json"
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import {apply, branchAndMerge, chain, mergeWith, move, Rule, template, Tree, url} from '@angular-devkit/schematics';
|
||||
|
||||
import {names, toClassName, toFileName, toPropertyName} from '../name-utils';
|
||||
import {names, toClassName, toFileName, toPropertyName} from '../utility/name-utils';
|
||||
import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
import {addImportToModule, addProviderToModule, insert} from '../utility/ast-utils';
|
||||
11
packages/schematics/src/collection.json
Normal file
11
packages/schematics/src/collection.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "nx",
|
||||
"version": "0.1",
|
||||
"schematics": {
|
||||
"addNgRxToModule": {
|
||||
"factory": "./addNgRxToModule",
|
||||
"schema": "./addNgRxToModule/schema.json",
|
||||
"description": "Add NgRx support to a module."
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,4 +2,4 @@
|
||||
|
||||
rm -rf build
|
||||
tsc
|
||||
rsync -a --exclude=*.ts src/ build/src
|
||||
rsync -a --exclude=*.ts packages/ build/packages
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
rm -rf node_modules/@nrwl
|
||||
mkdir -p node_modules/@nrwl
|
||||
cp -r build/src node_modules/@nrwl/nx
|
||||
cp package.json node_modules/@nrwl/nx/package.json
|
||||
|
||||
./scripts/link.sh
|
||||
rm -rf tmp
|
||||
jest --maxWorkers=1 ./build/e2e
|
||||
jest --maxWorkers=1 ./build/e2e/schematics
|
||||
|
||||
6
scripts/link.sh
Executable file
6
scripts/link.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
./scripts/build.sh
|
||||
|
||||
rm -rf node_modules/@nrwl
|
||||
cp -r build/packages node_modules/@nrwl
|
||||
@ -1,6 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
./scripts/build.sh
|
||||
cp package.json build/src/package.json
|
||||
cp README.md build/src/README.md
|
||||
cp LICENSE build/src/LICENSE
|
||||
|
||||
cd build/packages
|
||||
|
||||
tar -czf bazel.tgz bazel
|
||||
tar -czf nx.tgz nx
|
||||
tar -czf schematics.tgz schematics
|
||||
|
||||
@ -1,9 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
./scripts/package.sh
|
||||
cd build/src
|
||||
|
||||
cd build/packages/bazel
|
||||
git init
|
||||
git add .
|
||||
git commit -am 'init commit'
|
||||
git remote add origin git@github.com:nrwl/bazel-build.git
|
||||
git push -f origin master
|
||||
|
||||
cd ../nx
|
||||
git init
|
||||
git add .
|
||||
git commit -am 'init commit'
|
||||
git remote add origin git@github.com:nrwl/nx-build.git
|
||||
git push -f origin master
|
||||
|
||||
cd ../schematics
|
||||
git init
|
||||
git add .
|
||||
git commit -am 'init commit'
|
||||
git remote add origin git@github.com:nrwl/schematics-build.git
|
||||
git push -f origin master
|
||||
|
||||
@ -1 +0,0 @@
|
||||
export {DataPersistence} from './utils/data-persistence';
|
||||
@ -1,2 +0,0 @@
|
||||
export {cold, hot} from 'jasmine-marbles';
|
||||
export {readAll} from './utils/testing';
|
||||
@ -24,7 +24,7 @@ getTestBed().initTestEnvironment(
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
|
||||
const context = (<any>require).context('./', true, /\.spec\.js$/);
|
||||
const context = (<any>require).context('./packages/nx', true, /\.spec\.js$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
// Finally, start Karma to run the tests.
|
||||
@ -12,6 +12,11 @@
|
||||
"es2017"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"@nrwl/schematics": [
|
||||
"packages/schematics/src/index"
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
"tmp",
|
||||
"node_modules"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user