mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Merge pull request #82 from wwelling/opaque-config
Opaque config: this connects to #64 and this connects to #79
This commit is contained in:
365
README.md
365
README.md
@@ -1,4 +1,8 @@
|
||||
# dspace-angular
|
||||
[](https://travis-ci.org/DSpace/dspace-angular) [](https://github.com/angular/universal)
|
||||
|
||||
dspace-angular
|
||||
==============
|
||||
|
||||
> The next UI for DSpace, based on Angular 2 Universal.
|
||||
|
||||
This project is currently in pre-alpha.
|
||||
@@ -7,7 +11,9 @@ You can find additional information on the [wiki](https://wiki.duraspace.org/dis
|
||||
|
||||
If you're looking for the 2016 Angular 2 DSpace UI prototype, you can find it [here](https://github.com/DSpace-Labs/angular2-ui-prototype)
|
||||
|
||||
## Quick start
|
||||
Quick start
|
||||
-----------
|
||||
|
||||
**Ensure you're running [Node](https://nodejs.org) >= `v5.x`, [npm](https://www.npmjs.com/) >= `v3.x` and [yarn](https://yarnpkg.com) >= `v0.20.x`**
|
||||
|
||||
```bash
|
||||
@@ -26,72 +32,95 @@ yarn install
|
||||
# start the server
|
||||
yarn start
|
||||
```
|
||||
|
||||
Then go to [http://localhost:3000](http://localhost:3000) in your browser
|
||||
|
||||
NOTE: currently there's not much to see at that URL. We really do need your help. If you're interested in jumping in, and you've made it this far, please look at the [the project board (waffle.io)](https://waffle.io/DSpace/dspace-angular), grab a card, and get to work. Thanks!
|
||||
|
||||
Not sure where to start? watch the training videos linked in the [Introduction to the technology](#introduction-to-the-technology) section below.
|
||||
|
||||
## Table of Contents
|
||||
* [Introduction to the technology](#introduction-to-the-technology)
|
||||
* [Requirements](#requirements)
|
||||
* [Installing](#installing)
|
||||
* [Configuring](#configuring)
|
||||
* [Running the app](#running-the-app)
|
||||
* [Running in production mode](#running-in-production-mode)
|
||||
* [Cleaning](#cleaning)
|
||||
* [Testing](#testing)
|
||||
* [Documentation](#documentation)
|
||||
* [Other commands](#other-commands)
|
||||
* [Recommended Editors/IDEs](#recommended-editorsides)
|
||||
* [Collaborating](#collaborating)
|
||||
* [File Structure](#file-structure)
|
||||
* [3rd Party Library Installation](#3rd-party-library-installation)
|
||||
* [Frequently asked questions](#frequently-asked-questions)
|
||||
* [License](#license)
|
||||
Table of Contents
|
||||
-----------------
|
||||
|
||||
- [Introduction to the technology](#introduction-to-the-technology)
|
||||
- [Requirements](#requirements)
|
||||
- [Installing](#installing)
|
||||
- [Configuring](#configuring)
|
||||
- [Running the app](#running-the-app)
|
||||
- [Running in production mode](#running-in-production-mode)
|
||||
- [Cleaning](#cleaning)
|
||||
- [Testing](#testing)
|
||||
- [Documentation](#documentation)
|
||||
- [Other commands](#other-commands)
|
||||
- [Recommended Editors/IDEs](#recommended-editorsides)
|
||||
- [Collaborating](#collaborating)
|
||||
- [File Structure](#file-structure)
|
||||
- [3rd Party Library Installation](#3rd-party-library-installation)
|
||||
- [Frequently asked questions](#frequently-asked-questions)
|
||||
- [License](#license)
|
||||
|
||||
Introduction to the technology
|
||||
------------------------------
|
||||
|
||||
## Introduction to the technology
|
||||
You can find more information on the technologies used in this project (Angular 2, Typescript, Angular Universal, RxJS, etc) on the [DuraSpace wiki](https://wiki.duraspace.org/display/DSPACE/DSpace+7+UI+Technology+Stack)
|
||||
|
||||
## Requirements
|
||||
* [Node.js](https://nodejs.org), [npm](https://www.npmjs.com/), and [yarn](https://yarnpkg.com)
|
||||
* Ensure you're running node >= `v5.x`, npm >= `v3.x` and yarn >= `v0.20.x`
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- [Node.js](https://nodejs.org), [npm](https://www.npmjs.com/), and [yarn](https://yarnpkg.com)
|
||||
- Ensure you're running node >= `v5.x`, npm >= `v3.x` and yarn >= `v0.20.x`
|
||||
|
||||
If you have [`nvm`](https://github.com/creationix/nvm#install-script) or [`nvm-windows`](https://github.com/coreybutler/nvm-windows) installed, which is highly recommended, you can run `nvm install --lts && nvm use` to install and start using the latest Node LTS.
|
||||
|
||||
## Installing
|
||||
* `yarn run global` to install the required global dependencies
|
||||
* `yarn install` to install the local dependencies
|
||||
Installing
|
||||
----------
|
||||
|
||||
- `yarn run global` to install the required global dependencies
|
||||
- `yarn install` to install the local dependencies
|
||||
|
||||
Configuring
|
||||
-----------
|
||||
|
||||
## Configuring
|
||||
Default configuration file is located in `config/` folder.
|
||||
|
||||
To change the default configuration values, create local files that override the parameters you need to change:
|
||||
* Create a new `environment.dev.js` file in `config/` for `devel` environment;
|
||||
* Create a new `environment.prod.js` file in `config/` for `production` environment;
|
||||
|
||||
- Create a new `environment.dev.js` file in `config/` for `devel` environment;
|
||||
- Create a new `environment.prod.js` file in `config/` for `production` environment;
|
||||
|
||||
To use the configuration parameters in your component:
|
||||
|
||||
```bash
|
||||
import { GlobalConfig } from "../config";
|
||||
```
|
||||
|
||||
## Running the app
|
||||
Running the app
|
||||
---------------
|
||||
|
||||
After you have installed all dependencies you can now run the app. Run `yarn run watch:dev` to start a local server which will watch for changes, rebuild the code, and reload the server for you. You can visit it at `http://localhost:3000`.
|
||||
|
||||
## Running in production mode
|
||||
Running in production mode
|
||||
--------------------------
|
||||
|
||||
When building for production we're using Ahead of Time (AoT) compilation. With AoT, the browser downloads a pre-compiled version of the application, so it can render the application immediately, without waiting to compile the app first. The compiler is roughly half the size of Angular itself, so omitting it dramatically reduces the application payload.
|
||||
|
||||
To build the app for production and start the server run:
|
||||
|
||||
```bash
|
||||
yarn start
|
||||
```
|
||||
|
||||
If you only want to build for production, without starting, run:
|
||||
|
||||
```bash
|
||||
yarn run build:prod:ngc:json
|
||||
```
|
||||
|
||||
This will build the application and put the result in the `dist` folder
|
||||
|
||||
## Cleaning
|
||||
Cleaning
|
||||
--------
|
||||
|
||||
```bash
|
||||
# clean everything, including node_modules. You'll need to run yarn install again afterwards.
|
||||
yarn run clean
|
||||
@@ -103,129 +132,160 @@ yarn run clean:prod
|
||||
yarn run clean:dist
|
||||
```
|
||||
|
||||
## Testing
|
||||
### Unit Test
|
||||
Unit tests use Karma. You can find the configuration file at the same level of this README file:
|
||||
`./karma.conf.js`
|
||||
If you are going to use a remote test enviroment you need to edit the './karma.conf.js'. Follow the instructions you will find inside it.
|
||||
To executing tests whenever any file changes you can modify the 'autoWatch' option to 'true' and 'singleRun' option to 'false'.
|
||||
A coverage report is also available at:
|
||||
http://localhost:9876/
|
||||
after you run:
|
||||
`yarn run coverage`.
|
||||
Testing
|
||||
-------
|
||||
|
||||
To correctly run the tests you need to run the build once with:
|
||||
`yarn run build`.
|
||||
### Unit Test
|
||||
|
||||
Unit tests use Karma. You can find the configuration file at the same level of this README file:`./karma.conf.js` If you are going to use a remote test enviroment you need to edit the './karma.conf.js'. Follow the instructions you will find inside it. To executing tests whenever any file changes you can modify the 'autoWatch' option to 'true' and 'singleRun' option to 'false'. A coverage report is also available at: http://localhost:9876/ after you run:`yarn run coverage`.
|
||||
|
||||
To correctly run the tests you need to run the build once with:`yarn run build`.
|
||||
|
||||
The default browser is Google Chrome.
|
||||
|
||||
Place your tests in the same location of the application source code files that they test.
|
||||
|
||||
and run:
|
||||
`yarn run test`
|
||||
and run:`yarn run test`
|
||||
|
||||
### E2E test
|
||||
E2E tests use Protractor + Selenium server + browsers. You can find the configuration file at the same level of this README file:
|
||||
`./protractor.conf.js`
|
||||
Protractor is installed as 'local' as a dev dependency.
|
||||
|
||||
E2E tests use Protractor + Selenium server + browsers. You can find the configuration file at the same level of this README file:`./protractor.conf.js` Protractor is installed as 'local' as a dev dependency.
|
||||
|
||||
If you are going to use a remote test enviroment you need to edit the './protractor.conf.js'. Follow the instructions you will find inside it.
|
||||
|
||||
The default browser is Google Chrome.
|
||||
|
||||
Protractor needs a functional instance of the DSpace interface to run the E2E tests, so you need to run:
|
||||
`yarn run watch:dev`
|
||||
Protractor needs a functional instance of the DSpace interface to run the E2E tests, so you need to run:`yarn run watch:dev`
|
||||
|
||||
or any command that bring up the DSpace interface.
|
||||
|
||||
Place your tests at the following path:
|
||||
`./e2e`
|
||||
Place your tests at the following path:`./e2e`
|
||||
|
||||
and run:
|
||||
`yarn run e2e`
|
||||
and run:`yarn run e2e`
|
||||
|
||||
### Continuous Integration (CI) Test
|
||||
To run all the tests (e.g.: to run tests with Continuous Integration software) you can execute:
|
||||
`yarn run ci`
|
||||
Keep in mind that this command prerequisites are the sum of unit test and E2E tests.
|
||||
|
||||
##Documentation
|
||||
To build the code documentation we use [TYPEDOC](http://typedoc.org). TYPEDOC is a documentation generator for TypeScript projects.
|
||||
It extracts informations from properly formatted comments that can be written within the code files.
|
||||
Follow the instructions [here](http://typedoc.org/guides/doccomments/) to know how to make those comments.
|
||||
To run all the tests (e.g.: to run tests with Continuous Integration software) you can execute:`yarn run ci` Keep in mind that this command prerequisites are the sum of unit test and E2E tests.
|
||||
|
||||
Run:
|
||||
`yarn run docs`
|
||||
to produce the documentation that will be available in the 'doc' folder.
|
||||
##Documentation To build the code documentation we use [TYPEDOC](http://typedoc.org). TYPEDOC is a documentation generator for TypeScript projects. It extracts informations from properly formatted comments that can be written within the code files. Follow the instructions [here](http://typedoc.org/guides/doccomments/) to know how to make those comments.
|
||||
|
||||
Run:`yarn run docs` to produce the documentation that will be available in the 'doc' folder.
|
||||
|
||||
Other commands
|
||||
--------------
|
||||
|
||||
## Other commands
|
||||
There are many more commands in the `scripts` section of `package.json`. Most of these are executed by one of the commands mentioned above.
|
||||
|
||||
A command with a name that starts with `pre` or `post` will be executed automatically before or after the script with the matching name. e.g. if you type `yarn run start` the `prestart` script will run first, then the `start` script will trigger.
|
||||
|
||||
Recommended Editors/IDEs
|
||||
------------------------
|
||||
|
||||
## Recommended Editors/IDEs
|
||||
To get the most out of TypeScript, you'll need a TypeScript-aware editor. We've had good experiences using these editors:
|
||||
|
||||
* Free
|
||||
* [Visual Studio Code](https://code.visualstudio.com/)
|
||||
* [Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome)
|
||||
* [Atom](https://atom.io/)
|
||||
* [TypeScript plugin](https://atom.io/packages/atom-typescript)
|
||||
* Paid
|
||||
* [Webstorm](https://www.jetbrains.com/webstorm/download/) or [IntelliJ IDEA Ultimate](https://www.jetbrains.com/idea/)
|
||||
* [Sublime Text](http://www.sublimetext.com/3)
|
||||
* [Typescript-Sublime-Plugin](https://github.com/Microsoft/Typescript-Sublime-plugin#installation)
|
||||
- Free
|
||||
- [Visual Studio Code](https://code.visualstudio.com/)
|
||||
- [Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome)
|
||||
- [Atom](https://atom.io/)
|
||||
- [TypeScript plugin](https://atom.io/packages/atom-typescript)
|
||||
- Paid
|
||||
- [Webstorm](https://www.jetbrains.com/webstorm/download/) or [IntelliJ IDEA Ultimate](https://www.jetbrains.com/idea/)
|
||||
- [Sublime Text](http://www.sublimetext.com/3)
|
||||
- [Typescript-Sublime-Plugin](https://github.com/Microsoft/Typescript-Sublime-plugin#installation)
|
||||
|
||||
Collaborating
|
||||
-------------
|
||||
|
||||
## Collaborating
|
||||
See [the guide on the wiki](https://wiki.duraspace.org/display/DSPACE/DSpace+7+-+Angular+2+UI#DSpace7-Angular2UI-Howtocontribute)
|
||||
|
||||
## File Structure
|
||||
File Structure
|
||||
--------------
|
||||
|
||||
```
|
||||
dspace-angular
|
||||
├── README.md * This document
|
||||
├── app.json * Application manifest file
|
||||
├── config * Folder for configuration files
|
||||
│ └── environment.default.js * Default configuration files
|
||||
├── e2e * Folder for e2e test files
|
||||
├── karma.conf.js * Unit Test configuration file
|
||||
├── nodemon.json * Nodemon (https://nodemon.io/) configuration
|
||||
├── package.json * This file describes the npm package for this project, its dependencies, scripts, etc.
|
||||
├── postcss.config.json * PostCSS (http://postcss.org/) configuration file
|
||||
├── protractor.conf.js * E2E tests configuration file
|
||||
├── resources * Folder for static resources
|
||||
│ ├── i18n * Folder for i18n translations
|
||||
│ └── images * Folder for images
|
||||
├── rollup-client.js * Rollup (http://rollupjs.org/) configuration for the client
|
||||
├── rollup-server.js * Rollup (http://rollupjs.org/) configuration for the server
|
||||
├── src * The source of the application
|
||||
│ ├── app * The location of the app module, and root of the application shared by client and server
|
||||
│ ├── backend * Folder containing a mock of the REST API, hosted by the express server
|
||||
│ ├── browser.module.ts * The root module for the client
|
||||
│ ├── client.aot.ts * The bootstrap file for the client, in production
|
||||
│ ├── client.ts * The bootstrap file for the client, during development
|
||||
│ ├── config.ts * File that loads environmental and shareable settings and makes them available to app components
|
||||
│ ├── index-aot.html * The index.html file, for production
|
||||
│ ├── index.html * The index.html file, for development
|
||||
│ ├── node.module.ts * The root module for the server
|
||||
│ ├── server.aot.ts * The express (http://expressjs.com/) config and bootstrap file for the server, in production
|
||||
│ ├── server.routes.ts * The routes file for the server
|
||||
│ ├── server.ts * The express (http://expressjs.com/) config and bootstrap file for the server, during development
|
||||
│ ├── styles * Folder containing global styles.
|
||||
│ │ ├── main.scss * Global scss file
|
||||
│ │ └── variables.scss * Global sass variables file
|
||||
│ └── typings.d.ts * File that allows you to add custom typings for libraries without TypeScript support
|
||||
├── tsconfig.aot.json * TypeScript config for production builds
|
||||
├── tsconfig.json * TypeScript config for development build
|
||||
├── tslint.json * TSLint (https://palantir.github.io/tslint/) configuration
|
||||
├── typedoc.json * TYPEDOC configuration
|
||||
├── yarn.lock * Yarn lockfile (https://yarnpkg.com/en/docs/yarn-lock)
|
||||
├── webpack.config.ts * Webpack (https://webpack.github.io/) config for development builds
|
||||
├── webpack.test.config.ts * Webpack (https://webpack.github.io/) config for testing
|
||||
└── webpack.prod.config.ts * Webpack (https://webpack.github.io/) config for production builds
|
||||
├── README.md * This document
|
||||
├── app.json * Application manifest file
|
||||
├── config * Folder for configuration files
|
||||
│ └── environment.default.js * Default configuration files
|
||||
├── dist * Folder for e2e test files
|
||||
├── e2e *
|
||||
│ ├── app.e2e-spec.ts *
|
||||
│ ├── app.po.ts *
|
||||
│ ├── pagenotfound *
|
||||
│ │ ├── pagenotfound.e2e-spec.ts *
|
||||
│ │ └── pagenotfound.po.ts *
|
||||
│ └── tsconfig.json *
|
||||
├── empty.js *
|
||||
├── helpers.js *
|
||||
├── karma.conf.js * Unit Test configuration file
|
||||
├── nodemon.json * Nodemon (https://nodemon.io/) configuration
|
||||
├── package.json * This file describes the npm package for this project, its dependencies, scripts, etc.
|
||||
├── postcss.config.json * PostCSS (http://postcss.org/) configuration file
|
||||
├── protractor.conf.js * E2E tests configuration file
|
||||
├── resources * Folder for static resources
|
||||
│ ├── i18n * Folder for i18n translations
|
||||
│ │ └── en.json *
|
||||
│ └── images * Folder for images
|
||||
│ └── dspace_logo.png *
|
||||
├── rollup-client.js * Rollup (http://rollupjs.org/) configuration for the client
|
||||
├── rollup-server.js * Rollup (http://rollupjs.org/) configuration for the server
|
||||
├── spec-bundle.js *
|
||||
├── src * The source of the application
|
||||
│ ├── app * The location of the app module, and root of the application shared by client and server
|
||||
│ │ ├── app-routing.module.ts *
|
||||
│ │ ├── app.component.html *
|
||||
│ │ ├── app.component.scss *
|
||||
│ │ ├── app.component.spec.ts *
|
||||
│ │ ├── app.component.ts *
|
||||
│ │ ├── app.effects.ts *
|
||||
│ │ ├── app.module.ts *
|
||||
│ │ ├── app.reducers.ts *
|
||||
│ │ ├── core *
|
||||
│ │ ├── header *
|
||||
│ │ ├── home *
|
||||
│ │ ├── pagenotfound *
|
||||
│ │ ├── shared *
|
||||
│ │ └── store.actions.ts *
|
||||
│ ├── backend * Folder containing a mock of the REST API, hosted by the express server
|
||||
│ │ ├── api.ts *
|
||||
│ │ ├── bitstreams.ts *
|
||||
│ │ ├── bundles.ts *
|
||||
│ │ ├── cache.ts *
|
||||
│ │ ├── collections.ts *
|
||||
│ │ ├── db.ts *
|
||||
│ │ ├── items.ts *
|
||||
│ │ └── metadata.ts *
|
||||
│ ├── client.aot.ts * The bootstrap file for the client, in production
|
||||
│ ├── client.ts * The bootstrap file for the client, during development
|
||||
│ ├── config.ts * File that loads environmental and shareable settings and makes them available to app components
|
||||
│ ├── index.html * The index.html file
|
||||
│ ├── platform *
|
||||
│ │ ├── angular2-meta.ts *
|
||||
│ │ ├── modules *
|
||||
│ │ │ ├── browser.module.ts * The root module for the client
|
||||
│ │ │ └── node.module.ts * The root module for the server
|
||||
│ │ └── workarounds *
|
||||
│ │ ├── __workaround.browser.ts *
|
||||
│ │ └── __workaround.node.ts *
|
||||
│ ├── server.aot.ts * The express (http://expressjs.com/) config and bootstrap file for the server, in production
|
||||
│ ├── server.routes.ts * The routes file for the server
|
||||
│ ├── server.ts * The express (http://expressjs.com/) config and bootstrap file for the server, during development
|
||||
│ ├── styles * Folder containing global styles.
|
||||
│ │ ├── main.scss * Global scss file
|
||||
│ │ └── variables.scss * Global sass variables file
|
||||
│ └── typings.d.ts * File that allows you to add custom typings for libraries without TypeScript support
|
||||
├── tsconfig.aot.json * TypeScript config for production builds
|
||||
├── tsconfig.json * TypeScript config for development build
|
||||
├── tslint.json * TSLint (https://palantir.github.io/tslint/) configuration
|
||||
├── typedoc.json * TYPEDOC configuration
|
||||
├── webpack.config.ts * Webpack (https://webpack.github.io/) config for development builds
|
||||
├── webpack.prod.config.ts * Webpack (https://webpack.github.io/) config for production builds
|
||||
├── webpack.test.config.js * Webpack (https://webpack.github.io/) config for testing
|
||||
└── yarn.lock * Yarn lockfile (https://yarnpkg.com/en/docs/yarn-lock)
|
||||
```
|
||||
|
||||
## 3rd Party Library Installation
|
||||
3rd Party Library Installation
|
||||
------------------------------
|
||||
|
||||
Install your library via `yarn add lib-name --save` and import it in your code. `--save` will add it to `package.json`.
|
||||
|
||||
@@ -236,57 +296,60 @@ yarn add d3 --save
|
||||
yarn add @types/d3 --save-dev
|
||||
```
|
||||
|
||||
If the library doesn't have typings available at `@types/`, you can still use it by
|
||||
manually adding typings for it:
|
||||
If the library doesn't have typings available at `@types/`, you can still use it by manually adding typings for it:
|
||||
|
||||
1. In `src/typings.d.ts`, add the following code:
|
||||
1. In `src/typings.d.ts`, add the following code:
|
||||
|
||||
```typescript
|
||||
declare module 'typeless-package';
|
||||
```
|
||||
```typescript
|
||||
declare module 'typeless-package';
|
||||
```
|
||||
|
||||
2. Then, in the component or file that uses the library, add the following code:
|
||||
2. Then, in the component or file that uses the library, add the following code:
|
||||
|
||||
```typescript
|
||||
import * as typelessPackage from 'typeless-package';
|
||||
typelessPackage.method();
|
||||
```
|
||||
```typescript
|
||||
import * as typelessPackage from 'typeless-package';
|
||||
typelessPackage.method();
|
||||
```
|
||||
|
||||
Done. Note: you might need or find useful to define more typings for the library that you're trying to use.
|
||||
|
||||
|
||||
If you're importing a module that uses CommonJS you need to import as
|
||||
|
||||
```typescript
|
||||
import * as _ from 'lodash';
|
||||
```
|
||||
|
||||
## yarn lockfile
|
||||
yarn lockfile
|
||||
-------------
|
||||
|
||||
This project makes use of yarn to ensure that the exact same dependency versions are used every time you install it.
|
||||
|
||||
yarn creates the file [`yarn.lock`](https://yarnpkg.com/en/docs/yarn-lock) to track those versions. That file is updated automatically every time you install a new dependency from the commandline (by using `yarn add some-lib --save` or `yarn add some-lib --save-dev`).
|
||||
|
||||
If you manually add a package or change a version in `package.json` you'll have to update yarn's lock file as well. You can do so by running `yarn upgrade`
|
||||
|
||||
## Frequently asked questions
|
||||
* Why is my service, aka provider, is not injecting a parameter correctly?
|
||||
* Please use `@Injectable()` for your service for typescript to correctly attach the metadata
|
||||
* Where do I write my tests?
|
||||
* You can write your tests next to your component files. e.g. for `src/app/home/home.component.ts` call it `src/app/home/home.component.spec.ts`
|
||||
* How do I start the app when I get `EACCES` and `EADDRINUSE` errors?
|
||||
* The `EADDRINUSE` error means the port `3000` is currently being used and `EACCES` is lack of permission to build files to `./dist/`
|
||||
* What are the naming conventions for Angular 2?
|
||||
* See [the official angular 2 style guide](https://angular.io/styleguide)
|
||||
* Why is the size of my app larger in development?
|
||||
* The production build uses a whole host of techniques (ahead-of-time compilation, rollup to remove unreachable code, minification, etc.) to reduce the size, that aren't used during development in the intrest of build speed.
|
||||
* node-pre-gyp ERR in yarn install (Windows)
|
||||
* install Python x86 version between 2.5 and 3.0 on windows. See [this issue](https://github.com/AngularClass/angular2-webpack-starter/issues/626)
|
||||
* How do I handle merge conflicts in yarn.lock?
|
||||
* first check out the yarn.lock file from the branch you're merging in to yours: e.g. `git checkout --theirs yarn.lock`
|
||||
* now run `yarn install` again. Yarn will create a new lockfile that contains both sets of changes.
|
||||
* then run `git add yarn.lock` to stage the lockfile for commit
|
||||
* and `git commit` to conclude the merge
|
||||
Frequently asked questions
|
||||
--------------------------
|
||||
|
||||
- Why is my service, aka provider, is not injecting a parameter correctly?
|
||||
- Please use `@Injectable()` for your service for typescript to correctly attach the metadata
|
||||
- Where do I write my tests?
|
||||
- You can write your tests next to your component files. e.g. for `src/app/home/home.component.ts` call it `src/app/home/home.component.spec.ts`
|
||||
- How do I start the app when I get `EACCES` and `EADDRINUSE` errors?
|
||||
- The `EADDRINUSE` error means the port `3000` is currently being used and `EACCES` is lack of permission to build files to `./dist/`
|
||||
- What are the naming conventions for Angular 2?
|
||||
- See [the official angular 2 style guide](https://angular.io/styleguide)
|
||||
- Why is the size of my app larger in development?
|
||||
- The production build uses a whole host of techniques (ahead-of-time compilation, rollup to remove unreachable code, minification, etc.) to reduce the size, that aren't used during development in the intrest of build speed.
|
||||
- node-pre-gyp ERR in yarn install (Windows)
|
||||
- install Python x86 version between 2.5 and 3.0 on windows. See [this issue](https://github.com/AngularClass/angular2-webpack-starter/issues/626)
|
||||
- How do I handle merge conflicts in yarn.lock?
|
||||
- first check out the yarn.lock file from the branch you're merging in to yours: e.g. `git checkout --theirs yarn.lock`
|
||||
- now run `yarn install` again. Yarn will create a new lockfile that contains both sets of changes.
|
||||
- then run `git add yarn.lock` to stage the lockfile for commit
|
||||
- and `git commit` to conclude the merge
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
## License
|
||||
http://www.dspace.org/license
|
||||
|
@@ -1,22 +1,28 @@
|
||||
module.exports = {
|
||||
"production": false,
|
||||
// The REST API Location.
|
||||
// The REST API server settings.
|
||||
"rest": {
|
||||
"ssl": false,
|
||||
"address": "localhost",
|
||||
"port": 3000,
|
||||
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
|
||||
"nameSpace": "/api",
|
||||
"baseURL": "http://localhost:3000"
|
||||
"nameSpace": "/api"
|
||||
},
|
||||
// Path and Port in use for this Angular2 UI
|
||||
// Angular2 UI server settings.
|
||||
"ui": {
|
||||
"nameSpace": "/",
|
||||
"baseURL": "http://localhost:3000"
|
||||
"ssl": false,
|
||||
"address": "localhost",
|
||||
"port": 3000,
|
||||
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
|
||||
"nameSpace": "/"
|
||||
},
|
||||
"cache": {
|
||||
// how long should objects be cached for by default
|
||||
"msToLive": 15 * 60 * 1000, //15 minutes
|
||||
"msToLive": 15 * 60 * 1000, // 15 minute
|
||||
"control": "max-age=60" // revalidate browser
|
||||
},
|
||||
"universal": {
|
||||
//on the client: start with the state on the server
|
||||
"shouldRehydrate": true
|
||||
// Angular Universal settings
|
||||
"preboot": true,
|
||||
"async": true
|
||||
}
|
||||
};
|
||||
|
@@ -6,7 +6,7 @@ import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component';
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{ path: '', redirectTo: '/home', pathMatch: 'full' },
|
||||
{ path: '**', pathMatch: 'full', component: PageNotFoundComponent},
|
||||
{ path: '**', pathMatch: 'full', component: PageNotFoundComponent },
|
||||
])
|
||||
],
|
||||
})
|
||||
|
@@ -6,8 +6,10 @@
|
||||
<div class="container-fluid">
|
||||
<p>{{ 'example.with.data' | translate:data }}</p>
|
||||
<p>{{ example }}</p>
|
||||
<h2 *ngIf="!env" style="color:green">development</h2>
|
||||
<h2 *ngIf="env" style="color:red">production</h2>
|
||||
<h2 [ngClass]="{ 'red': EnvConfig.production, 'green': !EnvConfig.production }">
|
||||
<span *ngIf="!EnvConfig.production">development</span>
|
||||
<span *ngIf="EnvConfig.production">production</span>
|
||||
</h2>
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</main>
|
||||
|
@@ -1,5 +1,4 @@
|
||||
// Sticky Footer
|
||||
|
||||
.outer-wrapper {
|
||||
display: flex;
|
||||
margin: 0;
|
||||
@@ -16,3 +15,11 @@
|
||||
.main-content {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
h2.red {
|
||||
color: red;
|
||||
}
|
||||
|
||||
h2.green {
|
||||
color: green;
|
||||
}
|
||||
|
@@ -21,6 +21,8 @@ import { HostWindowState } from "./shared/host-window.reducer";
|
||||
import { HostWindowResizeAction } from "./shared/host-window.actions";
|
||||
import { MockTranslateLoader } from "./shared/testing/mock-translate-loader";
|
||||
|
||||
import { GLOBAL_CONFIG, EnvConfig } from '../config';
|
||||
|
||||
let comp: AppComponent;
|
||||
let fixture: ComponentFixture<AppComponent>;
|
||||
let de: DebugElement;
|
||||
@@ -37,6 +39,7 @@ describe('App component', () => {
|
||||
})],
|
||||
declarations: [AppComponent], // declare the test component
|
||||
providers: [
|
||||
{ provide: GLOBAL_CONFIG, useValue: EnvConfig },
|
||||
AppComponent
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
Component,
|
||||
ChangeDetectionStrategy,
|
||||
Inject,
|
||||
ViewEncapsulation,
|
||||
OnDestroy,
|
||||
OnInit, HostListener
|
||||
@@ -9,7 +10,8 @@ import { TranslateService } from "ng2-translate";
|
||||
import { HostWindowState } from "./shared/host-window.reducer";
|
||||
import { Store } from "@ngrx/store";
|
||||
import { HostWindowResizeAction } from "./shared/host-window.actions";
|
||||
import { GlobalConfig } from "../config";
|
||||
|
||||
import { GLOBAL_CONFIG, GlobalConfig } from '../config';
|
||||
|
||||
@Component({
|
||||
changeDetection: ChangeDetectionStrategy.Default,
|
||||
@@ -28,13 +30,8 @@ export class AppComponent implements OnDestroy, OnInit {
|
||||
recipient: 'World'
|
||||
};
|
||||
|
||||
env: string = GlobalConfig.production;
|
||||
|
||||
styles = {
|
||||
color: 'red'
|
||||
};
|
||||
|
||||
constructor(
|
||||
@Inject(GLOBAL_CONFIG) public EnvConfig: GlobalConfig,
|
||||
private translate: TranslateService,
|
||||
private store: Store<HostWindowState>
|
||||
) {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Inject, Injectable } from "@angular/core";
|
||||
import { DataEffects } from "./data.effects";
|
||||
import { Serializer } from "../serializer";
|
||||
import { Collection } from "../shared/collection.model";
|
||||
@@ -9,15 +9,18 @@ import { Actions, Effect } from "@ngrx/effects";
|
||||
import { RequestCacheFindAllAction, RequestCacheFindByIDAction } from "../cache/request-cache.actions";
|
||||
import { CollectionDataService } from "./collection-data.service";
|
||||
|
||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
|
||||
|
||||
@Injectable()
|
||||
export class CollectionDataEffects extends DataEffects<Collection> {
|
||||
constructor(
|
||||
@Inject(GLOBAL_CONFIG) EnvConfig: GlobalConfig,
|
||||
actions$: Actions,
|
||||
restApi: DSpaceRESTv2Service,
|
||||
cache: ObjectCacheService,
|
||||
dataService: CollectionDataService
|
||||
) {
|
||||
super(actions$, restApi, cache, dataService);
|
||||
super(EnvConfig, actions$, restApi, cache, dataService);
|
||||
}
|
||||
|
||||
protected getFindAllEndpoint(action: RequestCacheFindAllAction): string {
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import { Inject } from "@angular/core";
|
||||
import { Actions } from "@ngrx/effects";
|
||||
import { Observable } from "rxjs";
|
||||
import { DSpaceRESTV2Response } from "../dspace-rest-v2/dspace-rest-v2-response.model";
|
||||
import { DSpaceRESTv2Service } from "../dspace-rest-v2/dspace-rest-v2.service";
|
||||
import { ObjectCacheService } from "../cache/object-cache.service";
|
||||
import { GlobalConfig } from "../../../config";
|
||||
import { CacheableObject } from "../cache/object-cache.reducer";
|
||||
import { Serializer } from "../serializer";
|
||||
import {
|
||||
@@ -13,17 +13,20 @@ import {
|
||||
import { DataService } from "./data.service";
|
||||
import { hasNoValue } from "../../shared/empty.util";
|
||||
|
||||
import { GlobalConfig } from '../../../config';
|
||||
|
||||
export abstract class DataEffects<T extends CacheableObject> {
|
||||
protected abstract getFindAllEndpoint(action: RequestCacheFindAllAction): string;
|
||||
protected abstract getFindByIdEndpoint(action: RequestCacheFindByIDAction): string;
|
||||
protected abstract getSerializer(): Serializer<T>;
|
||||
|
||||
constructor(
|
||||
private EnvConfig: GlobalConfig,
|
||||
private actions$: Actions,
|
||||
private restApi: DSpaceRESTv2Service,
|
||||
private objectCache: ObjectCacheService,
|
||||
private dataService: DataService<T>
|
||||
) {}
|
||||
) { }
|
||||
|
||||
// TODO, results of a findall aren't retrieved from cache yet
|
||||
protected findAll = this.actions$
|
||||
@@ -38,11 +41,11 @@ export abstract class DataEffects<T extends CacheableObject> {
|
||||
if (hasNoValue(t) || hasNoValue(t.uuid)) {
|
||||
throw new Error('The server returned an invalid object');
|
||||
}
|
||||
this.objectCache.add(t, GlobalConfig.cache.msToLive);
|
||||
this.objectCache.add(t, this.EnvConfig.cache.msToLive);
|
||||
});
|
||||
})
|
||||
.map((ts: Array<T>) => ts.map(t => t.uuid))
|
||||
.map((ids: Array<string>) => new RequestCacheSuccessAction(action.payload.key, ids, new Date().getTime(), GlobalConfig.cache.msToLive))
|
||||
.map((ids: Array<string>) => new RequestCacheSuccessAction(action.payload.key, ids, new Date().getTime(), this.EnvConfig.cache.msToLive))
|
||||
.catch((error: Error) => Observable.of(new RequestCacheErrorAction(action.payload.key, error.message)));
|
||||
});
|
||||
|
||||
@@ -56,9 +59,9 @@ export abstract class DataEffects<T extends CacheableObject> {
|
||||
if (hasNoValue(t) || hasNoValue(t.uuid)) {
|
||||
throw new Error('The server returned an invalid object');
|
||||
}
|
||||
this.objectCache.add(t, GlobalConfig.cache.msToLive);
|
||||
this.objectCache.add(t, this.EnvConfig.cache.msToLive);
|
||||
})
|
||||
.map((t: T) => new RequestCacheSuccessAction(action.payload.key, [t.uuid], new Date().getTime(), GlobalConfig.cache.msToLive))
|
||||
.map((t: T) => new RequestCacheSuccessAction(action.payload.key, [t.uuid], new Date().getTime(), this.EnvConfig.cache.msToLive))
|
||||
.catch((error: Error) => Observable.of(new RequestCacheErrorAction(action.payload.key, error.message)));
|
||||
});
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Inject, Injectable } from "@angular/core";
|
||||
import { DataEffects } from "./data.effects";
|
||||
import { Serializer } from "../serializer";
|
||||
import { Item } from "../shared/item.model";
|
||||
@@ -9,15 +9,18 @@ import { Actions, Effect } from "@ngrx/effects";
|
||||
import { RequestCacheFindAllAction, RequestCacheFindByIDAction } from "../cache/request-cache.actions";
|
||||
import { ItemDataService } from "./item-data.service";
|
||||
|
||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
|
||||
|
||||
@Injectable()
|
||||
export class ItemDataEffects extends DataEffects<Item> {
|
||||
constructor(
|
||||
@Inject(GLOBAL_CONFIG) EnvConfig: GlobalConfig,
|
||||
actions$: Actions,
|
||||
restApi: DSpaceRESTv2Service,
|
||||
cache: ObjectCacheService,
|
||||
dataService: ItemDataService
|
||||
) {
|
||||
super(actions$, restApi, cache, dataService);
|
||||
super(EnvConfig, actions$, restApi, cache, dataService);
|
||||
}
|
||||
|
||||
protected getFindAllEndpoint(action: RequestCacheFindAllAction): string {
|
||||
|
@@ -1,14 +1,16 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Http, RequestOptionsArgs } from '@angular/http';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { RESTURLCombiner } from "../url-combiner/rest-url-combiner";
|
||||
|
||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
|
||||
|
||||
/**
|
||||
* Service to access DSpace's REST API
|
||||
*/
|
||||
@Injectable()
|
||||
export class DSpaceRESTv2Service {
|
||||
constructor(public _http: Http) {
|
||||
constructor(private http: Http, @Inject(GLOBAL_CONFIG) private EnvConfig: GlobalConfig) {
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +25,7 @@ export class DSpaceRESTv2Service {
|
||||
* An Observablse<string> containing the response from the server
|
||||
*/
|
||||
get(relativeURL: string, options?: RequestOptionsArgs): Observable<string> {
|
||||
return this._http.get(new RESTURLCombiner(relativeURL).toString(), options)
|
||||
return this.http.get(new RESTURLCombiner(this.EnvConfig, relativeURL).toString(), options)
|
||||
.map(res => res.json())
|
||||
.catch(err => {
|
||||
console.log('Error: ', err);
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { URLCombiner } from "./url-combiner";
|
||||
import { GlobalConfig } from "../../../config";
|
||||
|
||||
import { GlobalConfig } from '../../../config';
|
||||
|
||||
/**
|
||||
* Combines a variable number of strings representing parts
|
||||
@@ -7,8 +8,8 @@ import { GlobalConfig } from "../../../config";
|
||||
*
|
||||
* TODO write tests once GlobalConfig becomes injectable
|
||||
*/
|
||||
export class RESTURLCombiner extends URLCombiner{
|
||||
constructor(...parts:Array<string>) {
|
||||
super(GlobalConfig.rest.baseURL, GlobalConfig.rest.nameSpace, ...parts);
|
||||
export class RESTURLCombiner extends URLCombiner {
|
||||
constructor(EnvConfig: GlobalConfig, ...parts: Array<string>) {
|
||||
super(EnvConfig.rest.baseUrl, EnvConfig.rest.nameSpace, ...parts);
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<div class="page-not-found">
|
||||
<h1>404</h1>
|
||||
<h2><small>{{"404.page-not-found" | translate}}</small></h2>
|
||||
<br>
|
||||
<br/>
|
||||
<p>{{"404.help" | translate}}</p>
|
||||
<br>
|
||||
<br/>
|
||||
<p class="text-center">
|
||||
<a routerLink="/home" class="btn btn-primary">{{"404.link.home-page" | translate}}</a>
|
||||
</p>
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'ds-pagenotfound',
|
||||
styleUrls: ['./pagenotfound.component.css'],
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// the polyfills must be the first thing imported
|
||||
import 'angular2-universal-polyfills';
|
||||
import 'ts-helpers';
|
||||
import './__workaround.browser'; // temporary until 2.1.1 things are patched in Core
|
||||
import './platform/workarounds/__workaround.browser'; // temporary until 2.1.1 things are patched in Core
|
||||
|
||||
// Angular 2
|
||||
import { enableProdMode } from '@angular/core';
|
||||
@@ -15,7 +15,7 @@ import { load as loadWebFont } from 'webfontloader';
|
||||
// enable prod for faster renders
|
||||
enableProdMode();
|
||||
|
||||
import { MainModuleNgFactory } from './browser.module.ngfactory';
|
||||
import { MainModuleNgFactory } from './platform/modules/browser.module.ngfactory';
|
||||
|
||||
export const platformRef = platformBrowser();
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// the polyfills must be the first thing imported
|
||||
import 'angular2-universal-polyfills';
|
||||
import 'ts-helpers';
|
||||
import './__workaround.browser'; // temporary until 2.1.1 things are patched in Core
|
||||
import './platform/workarounds/__workaround.browser'; // temporary until 2.1.1 things are patched in Core
|
||||
|
||||
// Angular 2
|
||||
import { enableProdMode } from '@angular/core';
|
||||
@@ -10,10 +10,14 @@ import { bootloader } from '@angularclass/bootloader';
|
||||
|
||||
import { load as loadWebFont } from 'webfontloader';
|
||||
|
||||
// enable prod for faster renders
|
||||
// enableProdMode();
|
||||
import { EnvConfig } from './config';
|
||||
|
||||
import { MainModule } from './browser.module';
|
||||
if (EnvConfig.production) {
|
||||
// enable prod for faster renders
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
import { MainModule } from './platform/modules/browser.module';
|
||||
|
||||
export const platformRef = platformUniversalDynamic();
|
||||
|
||||
|
@@ -1,34 +1,78 @@
|
||||
// Look in ./config folder for config
|
||||
import { OpaqueToken } from '@angular/core';
|
||||
|
||||
const path = require('path');
|
||||
|
||||
let configContext = require.context("../config", false, /js$/);
|
||||
let EnvConfig : any = {};
|
||||
let EnvConfigFile : string;
|
||||
let DefaultConfig : any = {};
|
||||
|
||||
try {
|
||||
DefaultConfig = configContext('./environment.default.js');
|
||||
} catch (e) {
|
||||
throw new Error(`Cannot find file "${path.resolve('config', './environment.default.js')}"`);
|
||||
interface ServerConfig {
|
||||
"ssl": boolean;
|
||||
"address": string;
|
||||
"port": number;
|
||||
"nameSpace": string;
|
||||
"baseUrl": string;
|
||||
}
|
||||
|
||||
interface GlobalConfig {
|
||||
"production": boolean;
|
||||
"rest": ServerConfig;
|
||||
"ui": ServerConfig;
|
||||
"cache": {
|
||||
"msToLive": number,
|
||||
"control": string
|
||||
};
|
||||
"universal": {
|
||||
"preboot": boolean,
|
||||
"async": boolean
|
||||
};
|
||||
}
|
||||
|
||||
const GLOBAL_CONFIG = new OpaqueToken('config');
|
||||
|
||||
let configContext = require.context("../config", false, /js$/);
|
||||
|
||||
let EnvConfig: GlobalConfig;
|
||||
let EnvConfigFile: string;
|
||||
|
||||
let production: boolean = false;
|
||||
|
||||
// check process.env.NODE_ENV to determine which environment config to use
|
||||
// process.env.NODE_ENV is defined by webpack, else assume development
|
||||
switch (process.env.NODE_ENV) {
|
||||
case 'prod':
|
||||
case 'production':
|
||||
// webpack.prod.config.ts defines process.env.NODE_ENV = 'production'
|
||||
EnvConfigFile = './environment.prod.js';
|
||||
production = true;
|
||||
break;
|
||||
case 'test':
|
||||
// webpack.test.config.ts defines process.env.NODE_ENV = 'test'
|
||||
EnvConfigFile = './environment.test.js';
|
||||
break;
|
||||
case 'dev':
|
||||
case 'development':
|
||||
default:
|
||||
// if not using webpack.prod.config.ts or webpack.test.config.ts, it must be development
|
||||
EnvConfigFile = './environment.dev.js';
|
||||
}
|
||||
|
||||
try {
|
||||
EnvConfig = configContext(EnvConfigFile);
|
||||
EnvConfig = configContext('./environment.default.js');
|
||||
} catch (e) {
|
||||
EnvConfig = {};
|
||||
throw new Error("Cannot find file environment.default.js");
|
||||
}
|
||||
|
||||
const GlobalConfig = Object.assign(DefaultConfig, EnvConfig);
|
||||
// if EnvConfigFile set try to get configs
|
||||
if (EnvConfigFile) {
|
||||
try {
|
||||
EnvConfig = <GlobalConfig>Object.assign(EnvConfig, configContext(EnvConfigFile));
|
||||
} catch (e) {
|
||||
console.warn("Cannot find file " + EnvConfigFile.substring(2, EnvConfigFile.length), "Using default environment.");
|
||||
}
|
||||
}
|
||||
|
||||
export {GlobalConfig}
|
||||
// set base url if property is object with ssl, address, and port. i.e. ServerConfig
|
||||
for (let key in EnvConfig) {
|
||||
if (EnvConfig[key].ssl !== undefined && EnvConfig[key].address && EnvConfig[key].port) {
|
||||
EnvConfig[key].baseUrl = [EnvConfig[key].ssl ? 'https://' : 'http://', EnvConfig[key].address, (EnvConfig[key].port !== 80) ? ':' + EnvConfig[key].port : ''].join('');
|
||||
}
|
||||
}
|
||||
|
||||
// set config for whether running in production
|
||||
EnvConfig.production = production;
|
||||
|
||||
export { GLOBAL_CONFIG, GlobalConfig, EnvConfig }
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Inject, NgModule } from '@angular/core';
|
||||
import { Http } from '@angular/http';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { RouterModule } from '@angular/router';
|
||||
@@ -8,21 +8,22 @@ import { IdlePreload, IdlePreloadModule } from '@angularclass/idle-preload';
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { TranslateLoader, TranslateModule, TranslateStaticLoader } from 'ng2-translate';
|
||||
|
||||
import { AppModule, AppComponent } from './app/app.module';
|
||||
import { SharedModule } from './app/shared/shared.module';
|
||||
import { CoreModule } from "./app/core/core.module";
|
||||
import { AppModule, AppComponent } from '../../app/app.module';
|
||||
import { SharedModule } from '../../app/shared/shared.module';
|
||||
import { CoreModule } from '../../app/core/core.module';
|
||||
|
||||
import { StoreModule, Store } from "@ngrx/store";
|
||||
import { RouterStoreModule } from "@ngrx/router-store";
|
||||
import { StoreDevtoolsModule } from "@ngrx/store-devtools";
|
||||
import { rootReducer, NGRX_CACHE_KEY, AppState } from './app/app.reducers';
|
||||
import { effects } from './app/app.effects';
|
||||
import { rootReducer, NGRX_CACHE_KEY, AppState } from '../../app/app.reducers';
|
||||
import { effects } from '../../app/app.effects';
|
||||
|
||||
// Will be merged into @angular/platform-browser in a later release
|
||||
// see https://github.com/angular/angular/pull/12322
|
||||
import { Meta } from './angular2-meta';
|
||||
import { RehydrateStoreAction } from "./app/store.actions";
|
||||
import { GlobalConfig } from "./config";
|
||||
import { Meta } from '../angular2-meta';
|
||||
import { RehydrateStoreAction } from "../../app/store.actions";
|
||||
|
||||
import { GLOBAL_CONFIG, GlobalConfig, EnvConfig } from '../../config';
|
||||
|
||||
// import * as LRU from 'modern-lru';
|
||||
|
||||
@@ -44,7 +45,6 @@ export function getResponse() {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE';
|
||||
|
||||
@NgModule({
|
||||
@@ -72,6 +72,8 @@ export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE';
|
||||
effects
|
||||
],
|
||||
providers: [
|
||||
{ provide: GLOBAL_CONFIG, useValue: EnvConfig },
|
||||
|
||||
{ provide: 'isBrowser', useValue: isBrowser },
|
||||
{ provide: 'isNode', useValue: isNode },
|
||||
|
||||
@@ -80,21 +82,21 @@ export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE';
|
||||
|
||||
{ provide: 'LRU', useFactory: getLRU, deps: [] },
|
||||
|
||||
Meta,
|
||||
Meta
|
||||
|
||||
// { provide: AUTO_PREBOOT, useValue: false } // turn off auto preboot complete
|
||||
]
|
||||
})
|
||||
export class MainModule {
|
||||
constructor(public store: Store<AppState>) {
|
||||
constructor( @Inject(GLOBAL_CONFIG) private EnvConfig: GlobalConfig, public store: Store<AppState>) {
|
||||
// TODO(gdi2290): refactor into a lifecycle hook
|
||||
this.doRehydrate();
|
||||
}
|
||||
|
||||
doRehydrate() {
|
||||
if (GlobalConfig.universal.shouldRehydrate) {
|
||||
let defaultValue = {};
|
||||
let serverCache = this._getCacheValue(NGRX_CACHE_KEY, defaultValue);
|
||||
let defaultValue = {};
|
||||
let serverCache = this._getCacheValue(NGRX_CACHE_KEY, defaultValue);
|
||||
if (this.EnvConfig.universal.preboot) {
|
||||
this.store.dispatch(new RehydrateStoreAction(serverCache));
|
||||
}
|
||||
}
|
@@ -7,19 +7,21 @@ import { UniversalModule, isBrowser, isNode } from 'angular2-universal/node'; //
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { TranslateLoader, TranslateModule, TranslateStaticLoader } from 'ng2-translate';
|
||||
|
||||
import { AppModule, AppComponent } from './app/app.module';
|
||||
import { SharedModule } from './app/shared/shared.module';
|
||||
import { CoreModule } from "./app/core/core.module";
|
||||
import { AppModule, AppComponent } from '../../app/app.module';
|
||||
import { SharedModule } from '../../app/shared/shared.module';
|
||||
import { CoreModule } from "../../app/core/core.module";
|
||||
|
||||
import { StoreModule, Store } from "@ngrx/store";
|
||||
import { RouterStoreModule } from "@ngrx/router-store";
|
||||
import { StoreDevtoolsModule } from "@ngrx/store-devtools";
|
||||
import { rootReducer, AppState, NGRX_CACHE_KEY } from './app/app.reducers';
|
||||
import { effects } from './app/app.effects';
|
||||
import { rootReducer, AppState, NGRX_CACHE_KEY } from '../../app/app.reducers';
|
||||
import { effects } from '../../app/app.effects';
|
||||
|
||||
// Will be merged into @angular/platform-browser in a later release
|
||||
// see https://github.com/angular/angular/pull/12322
|
||||
import { Meta } from './angular2-meta';
|
||||
import { Meta } from '../angular2-meta';
|
||||
|
||||
import { GLOBAL_CONFIG, EnvConfig } from '../../config';
|
||||
|
||||
export function createTranslateLoader(http: Http) {
|
||||
return new TranslateStaticLoader(http, './assets/i18n', '.json');
|
||||
@@ -61,6 +63,8 @@ export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE';
|
||||
effects
|
||||
],
|
||||
providers: [
|
||||
{ provide: GLOBAL_CONFIG, useValue: EnvConfig },
|
||||
|
||||
{ provide: 'isBrowser', useValue: isBrowser },
|
||||
{ provide: 'isNode', useValue: isNode },
|
||||
|
||||
@@ -69,7 +73,8 @@ export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE';
|
||||
|
||||
{ provide: 'LRU', useFactory: getLRU, deps: [] },
|
||||
|
||||
Meta,
|
||||
Meta
|
||||
|
||||
]
|
||||
})
|
||||
export class MainModule {
|
@@ -4,7 +4,7 @@
|
||||
// if you are including modules that modify Promise, such as NewRelic,, you must include them before polyfills
|
||||
import 'angular2-universal-polyfills';
|
||||
import 'ts-helpers';
|
||||
import './__workaround.node'; // temporary until 2.1.1 things are patched in Core
|
||||
import './platform/workarounds/__workaround.node'; // temporary until 2.1.1 things are patched in Core
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
@@ -20,11 +20,13 @@ import { enableProdMode } from '@angular/core';
|
||||
import { createEngine } from 'angular2-express-engine';
|
||||
|
||||
// App
|
||||
import { MainModuleNgFactory } from './node.module.ngfactory';
|
||||
import { MainModuleNgFactory } from './platform/modules/node.module.ngfactory';
|
||||
|
||||
// Routes
|
||||
import { routes } from './server.routes';
|
||||
|
||||
import { EnvConfig } from './config';
|
||||
|
||||
// enable prod for faster renders
|
||||
enableProdMode();
|
||||
|
||||
@@ -42,8 +44,9 @@ app.engine('.html', createEngine({
|
||||
// stateless providers only since it's shared
|
||||
]
|
||||
}));
|
||||
app.set('port', process.env.PORT || 3000);
|
||||
app.set('address', process.env.ADDRESS || '127.0.0.1');
|
||||
|
||||
app.set('port', process.env.PORT || EnvConfig.ui.port || 3000);
|
||||
app.set('address', process.env.ADDRESS || EnvConfig.ui.address || '127.0.0.1');
|
||||
app.set('views', __dirname);
|
||||
app.set('view engine', 'html');
|
||||
app.set('json spaces', 2);
|
||||
@@ -61,16 +64,16 @@ app.use(morgan('common', {
|
||||
|
||||
function cacheControl(req, res, next) {
|
||||
// instruct browser to revalidate in 60 seconds
|
||||
res.header('Cache-Control', 'max-age=60');
|
||||
res.header('Cache-Control', EnvConfig.cache.control || 'max-age=60');
|
||||
next();
|
||||
}
|
||||
|
||||
// Serve static files
|
||||
app.use('/assets', cacheControl, express.static(path.join(__dirname, 'assets'), { maxAge: 30 }));
|
||||
app.use('/styles', cacheControl, express.static(path.join(__dirname, 'styles'), { maxAge: 30 }));
|
||||
|
||||
app.use(cacheControl, express.static(path.join(ROOT, 'dist/client'), { index: false }));
|
||||
|
||||
//
|
||||
/////////////////////////
|
||||
// ** Example API
|
||||
// Notice API should be in a separate process
|
||||
@@ -93,11 +96,11 @@ function ngApp(req, res) {
|
||||
res,
|
||||
// use this to determine what part of your app is slow only in development
|
||||
// time: true,
|
||||
async: true,
|
||||
preboot: true,
|
||||
baseUrl: '/',
|
||||
async: EnvConfig.universal.async,
|
||||
preboot: EnvConfig.universal.preboot,
|
||||
baseUrl: EnvConfig.ui.nameSpace,
|
||||
requestUrl: req.originalUrl,
|
||||
originUrl: `http://${app.get('address')}:${app.get('port')}`
|
||||
originUrl: EnvConfig.ui.baseUrl
|
||||
});
|
||||
});
|
||||
|
||||
@@ -112,7 +115,6 @@ routes.forEach(route => {
|
||||
app.get(`/${route}/*`, ngApp);
|
||||
});
|
||||
|
||||
|
||||
app.get('*', function(req, res) {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
var pojo = { status: 404, message: 'No Content' };
|
||||
@@ -121,6 +123,6 @@ app.get('*', function(req, res) {
|
||||
});
|
||||
|
||||
// Server
|
||||
let server = app.listen(app.get('port'), () => {
|
||||
console.log(`Listening on: http://${server.address().address}:${server.address().port}`);
|
||||
let server = app.listen(app.get('port'), app.get('address'), () => {
|
||||
console.log(`Listening on: ${EnvConfig.ui.ssl ? 'https://' : 'http://'}://${server.address().address}:${server.address().port}`);
|
||||
});
|
||||
|
@@ -4,7 +4,7 @@
|
||||
// if you are including modules that modify Promise, such as NewRelic,, you must include them before polyfills
|
||||
import 'angular2-universal-polyfills';
|
||||
import 'ts-helpers';
|
||||
import './__workaround.node'; // temporary until 2.1.1 things are patched in Core
|
||||
import './platform/workarounds/__workaround.node'; // temporary until 2.1.1 things are patched in Core
|
||||
|
||||
import * as path from 'path';
|
||||
import * as morgan from 'morgan';
|
||||
@@ -19,13 +19,17 @@ import { enableProdMode } from '@angular/core';
|
||||
import { createEngine } from 'angular2-express-engine';
|
||||
|
||||
// App
|
||||
import { MainModule } from './node.module';
|
||||
import { MainModule } from './platform/modules/node.module';
|
||||
|
||||
// Routes
|
||||
import { routes } from './server.routes';
|
||||
|
||||
// enable prod for faster renders
|
||||
enableProdMode();
|
||||
import { EnvConfig } from './config';
|
||||
|
||||
if (EnvConfig.production) {
|
||||
// enable prod for faster renders
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
const app = express();
|
||||
const ROOT = path.join(path.resolve(__dirname, '..'));
|
||||
@@ -40,8 +44,9 @@ app.engine('.html', createEngine({
|
||||
// stateless providers only since it's shared
|
||||
]
|
||||
}));
|
||||
app.set('port', process.env.PORT || 3000);
|
||||
app.set('address', process.env.ADDRESS || '127.0.0.1');
|
||||
|
||||
app.set('port', process.env.PORT || EnvConfig.ui.port || 3000);
|
||||
app.set('address', process.env.ADDRESS || EnvConfig.ui.address || '127.0.0.1');
|
||||
app.set('views', __dirname);
|
||||
app.set('view engine', 'html');
|
||||
app.set('json spaces', 2);
|
||||
@@ -54,16 +59,16 @@ app.use(morgan('dev'));
|
||||
|
||||
function cacheControl(req, res, next) {
|
||||
// instruct browser to revalidate in 60 seconds
|
||||
res.header('Cache-Control', 'max-age=60');
|
||||
res.header('Cache-Control', EnvConfig.cache.control || 'max-age=60');
|
||||
next();
|
||||
}
|
||||
|
||||
// Serve static files
|
||||
app.use('/assets', cacheControl, express.static(path.join(__dirname, 'assets'), { maxAge: 30 }));
|
||||
app.use('/styles', cacheControl, express.static(path.join(__dirname, 'styles'), { maxAge: 30 }));
|
||||
|
||||
app.use(cacheControl, express.static(path.join(ROOT, 'dist/client'), { index: false }));
|
||||
|
||||
//
|
||||
/////////////////////////
|
||||
// ** Example API
|
||||
// Notice API should be in aseparate process
|
||||
@@ -85,11 +90,11 @@ function ngApp(req, res) {
|
||||
req,
|
||||
res,
|
||||
// time: true, // use this to determine what part of your app is slow only in development
|
||||
async: true,
|
||||
preboot: true,
|
||||
baseUrl: '/',
|
||||
async: EnvConfig.universal.async,
|
||||
preboot: EnvConfig.universal.preboot,
|
||||
baseUrl: EnvConfig.ui.nameSpace,
|
||||
requestUrl: req.originalUrl,
|
||||
originUrl: `http://${app.get('address')}:${app.get('port')}`
|
||||
originUrl: EnvConfig.ui.baseUrl
|
||||
});
|
||||
});
|
||||
|
||||
@@ -112,6 +117,6 @@ app.get('*', function(req, res) {
|
||||
});
|
||||
|
||||
// Server
|
||||
let server = app.listen(app.get('port'), () => {
|
||||
console.log(`Listening on: http://${server.address().address}:${server.address().port}`);
|
||||
let server = app.listen(app.get('port'), app.get('address'), () => {
|
||||
console.log(`Listening on: ${EnvConfig.ui.ssl ? 'https://' : 'http://'}://${server.address().address}:${server.address().port}`);
|
||||
});
|
||||
|
@@ -94,7 +94,6 @@ export var clientConfig = {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Server.
|
||||
export var serverPlugins = [
|
||||
|
||||
@@ -133,9 +132,6 @@ export default [
|
||||
webpackMerge(clone(commonConfig), serverConfig, { plugins: serverPlugins.concat(commonPlugins) })
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
// Helpers
|
||||
export function includeClientPackages(packages, localModule?: string[]) {
|
||||
return function(context, request, cb) {
|
||||
|
33
yarn.lock
33
yarn.lock
@@ -2104,15 +2104,12 @@ fs-extra@^0.26.4:
|
||||
path-is-absolute "^1.0.0"
|
||||
rimraf "^2.2.8"
|
||||
|
||||
fs-extra@^0.30.0:
|
||||
version "0.30.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0"
|
||||
fs-extra@^2.0.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-2.1.2.tgz#046c70163cef9aad46b0e4a7fa467fb22d71de35"
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
jsonfile "^2.1.0"
|
||||
klaw "^1.0.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
rimraf "^2.2.8"
|
||||
|
||||
fs-extra@~1.0.0:
|
||||
version "1.0.0"
|
||||
@@ -5654,13 +5651,13 @@ typedarray@~0.0.5:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
|
||||
typedoc-default-themes@^0.4.0:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.4.2.tgz#640b854fd7ef19e6774496ea7741ec31a0dcaddc"
|
||||
typedoc-default-themes@^0.4.2:
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.4.3.tgz#39014c515585f27e59773d29e8921a5b8b89d4c0"
|
||||
|
||||
typedoc@0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.5.1.tgz#150f92bdc4a36d8e114b27f1d296329d27e837dd"
|
||||
typedoc@0.5.7:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.5.7.tgz#f2998dbb5909cb3f02db5fecb85e2a4377189e2a"
|
||||
dependencies:
|
||||
"@types/fs-extra" "0.0.33"
|
||||
"@types/handlebars" "^4.0.31"
|
||||
@@ -5669,7 +5666,7 @@ typedoc@0.5.1:
|
||||
"@types/marked" "0.0.28"
|
||||
"@types/minimatch" "^2.0.29"
|
||||
"@types/shelljs" "^0.3.32"
|
||||
fs-extra "^0.30.0"
|
||||
fs-extra "^2.0.0"
|
||||
handlebars "4.0.5"
|
||||
highlight.js "^9.0.0"
|
||||
lodash "^4.13.1"
|
||||
@@ -5677,16 +5674,16 @@ typedoc@0.5.1:
|
||||
minimatch "^3.0.0"
|
||||
progress "^1.1.8"
|
||||
shelljs "^0.7.0"
|
||||
typedoc-default-themes "^0.4.0"
|
||||
typescript "2.0.6"
|
||||
typedoc-default-themes "^0.4.2"
|
||||
typescript "2.1.6"
|
||||
|
||||
typescript@2.0.10, typescript@~2.0.3:
|
||||
version "2.0.10"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.0.10.tgz#ccdd4ed86fd5550a407101a0814012e1b3fac3dd"
|
||||
|
||||
typescript@2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.0.6.tgz#5385499ac9811508c2c43e0ea07a1ddca435e111"
|
||||
typescript@2.1.6:
|
||||
version "2.1.6"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.1.6.tgz#40c7e6e9e5da7961b7718b55505f9cac9487a607"
|
||||
|
||||
uglify-js@2.7.x, uglify-js@^2.6, uglify-js@^2.6.1, uglify-js@~2.7.3:
|
||||
version "2.7.5"
|
||||
|
Reference in New Issue
Block a user