Giter VIP home page Giter VIP logo

universal's Introduction

Angular Universal

Angular Universal was a project to expand on the core APIs from Angular (platform-server) to enable developers to do server side rendering of Angular applications in a variety of scenarios.

This repository has been merged into the Angular CLI repo

In version 17, Universal has been moved into the Angular CLI repo. Code has been refactored and renamed (mostly under @angular/ssr now), but the core functionality and architecture is unchanged.

Universal features such as server-side rendering and build-time prerendering are now directly supported in Angular CLI and do not require a separate integration with Universal.

As a result, this repository is effectively in maintenance mode and is no longer accepting contributions. Improvements to Angular's SSR/prerendering tooling should be made against the CLI repo directly. Universal versions under long-term support (LTS) are still maintained by the Angular team and will continue to receive security fixes until they fall out of LTS.

universal's People

Contributors

alan-agius4 avatar angular-robot avatar angular-robot[bot] avatar ashsidhu avatar caeruskaru avatar clydin avatar dbabaioff avatar dependabot[bot] avatar devversion avatar dgp1130 avatar frozenpandaz avatar jeffbcross avatar jeffwhelpley avatar johngorter avatar josephperrott avatar kyliau avatar laskoviymishka avatar manekinekko avatar markpieszak avatar notvitaliy avatar patrickjs avatar renovate-bot avatar renovate[bot] avatar steve8708 avatar tamascsaba avatar valorkin avatar vikerman avatar vvakame avatar wagnermaciel avatar wesleycho avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

universal's Issues

Travis

What's an open-source project without travis

Environment or Server service for client/server

A service for server concerns such as but not limited to SEO.
related interface proposals angular/angular#3144 (comment)
Either Environment that's bound by di to Server or Client. There is also an optimization step per environment that will be solved via Webpack build
prior art https://github.com/DerMambo/ms-seo

var robotTxt = `
  User-agent: Twitterbot
  Disallow:

  User-agent: *
  Disallow: /
`;

var metatags = `
  <meta name="twitter:card" content="summary" />
  <meta name="twitter:site" content="@nytimesbits" />
  <meta name="twitter:creator" content="@nickbilton" />
  <meta property="og:url" content="http://bits.blogs.nytimes.com/2011/12/08/a-twitter-for-my-sister/" />
  <meta property="og:title" content="A Twitter for My Sister" />
  <meta property="og:description" content="In the early days, Twitter grew so quickly that it was almost impossible to add new features because engineers spent their time trying to keep the rocket ship from stalling." />
  <meta property="og:image" content="http://graphics8.nytimes.com/images/2011/12/08/technology/bits-newtwitter/bits-newtwitter-tmagArticle.jpg" />
`;

@Component()
@View()
@RouteConfig()
class App {
  constructor(server: Server) {
    server.set('title', 'My home page');
    server.set('robot.txt', robotTxt);
    server.set('metatags', metatags);
  }
}
@Component({
  selector: 'app',
  bindings: [ bind(Environment).toClass(Server) ]
})
@View({
})
class App {
  constructor(env: Environment) {
  }
}

the idea here is replacing express with angular itself for a server framework. Where you have a Server App that has a view which is the Universal app

refactor batter out and use gulp in gulpfile

configuration is not clear. We have configuration living in task file and gulpfile. Having configurations in place place would allow for simpler reasoning on each moving part. Having a task per file limits the ability to compose multiple tasks. The repo doesn't need this level of abstraction just yet and would benefit more by having one gulpfile either requiring the configuration or keeping it inline

focus on <input> cursor position differs between server rendered and client rendered

given an html element

<input value="testing" autofocus [value]="value" (keyup)="value = $event.target.value">

the cursor position is at the beginning [|testing] for server rendered view. Then preboot.js transfers the focus back [testing|] the cursor position is now the latest position and value. Also note that angular doesn't save the cursor position when a user types in a new value. This probably due to setting the [value] on keyup

feat ApplicationRef

attach toString to ApplicationRef that serializes the App

Methods

  • toString(): string
  • disposeToString(): string

Render Angular 2 in backends with languages other than JavaScript

I'm choosing only the most popular framework for each language for now

Backends

  • Scala (Play Framework)
  • Ruby (Rails Framework)
  • Python (Django Framework)
  • Go (Gin Framework)
  • Nginx/Apache (via cli)
  • ASP.NET (via Edge.js)

Work in Progress

@gdi2290: Scala (Play Framework) gdi2290/play-angular2

I'm currently working on a Scala (Play Framework) example of rendering an Angular 2 app in my personal github then promote the example to the examples/once proof of concept is met. At the moment I'm running the app in a NodeEnvironment.

Blocked due to a problem trying to load a bundled version of commonjs Angular 2

e2e test for ServerDomRenderer and with preboot.js

We need e2e tests for

Server:

  • default values for input value and checkbox
  • focus an input element during Server rendering that adds autofocus

Server+Client:

  • default values for input value and checkbox
  • focus an input element during Server rendering that adds autofocus

Server+Client+Preboot.js

  • default values for input value and checkbox
  • focus an input element during Server rendering that adds autofocus
  • selection is correct placement in an input
  • selection is correct placement in an input during bootstrap

ngPreboot

built on top of preboot.js, pre-compile a mini angular for server view to recreate actions where the code path doesn't hit a call to the server or 3rd party module. The goal is to allow features such as two-way data binding and simple functionality such as NgIf

stages (may need more research and/or exploratory programming)

  • parse a class
  • figure out it's methods
  • figure out which methods with code paths do not hit a server call or 3rd party module
  • compile the ngTemplate using Angular's ngCompiler
  • match methods
  • recreate methods using vanilla js
  • recreate simple logic such as two-way data binding using vanilla js
  • proof of concept

Fix travis tests

At the moment travis us running gulp test rather than npm test

move examples/ to root level

Examples should be isolated and shouldn't be in modules since it's not a module. This also requires the webpack build system to simplify configuration. We also need an index page that would link to each example and this would also help with protractor e2e

decouple Document Token

scope

change in angular

problem(s)

  • Renderer still coupled to document
    • styleHost coupled to DocumentToken
    • appElement coupled to DocumentToken
    • hostElement from createRootHostView coupled to Document token
  • Trouble bootstrapping more than one app instance (of the same app) on the document

goal

  • decouple appElement, hostElement, and styleHost from document
  • possibly remove DocumentToken or provide it as default
  • more control over appElement

suggestions/options

  1. allow passing appElement rather than searching for it in hostElement
  2. decouple styleHost by providing a styleHost token (default one can require document then provide doc.head)

current workarounds/solutions

we create a document once then an element during each request to append it to the document and remove it afterwards.

benefits

  • easier to bootstrap more than one app instance (of the same app) on the document without recreating bootstrap
  • easier to control where styles should be in the document
  • easier to refactor angular1 apps by replacing leaf component nodes with angular2 apps (having reference to the element)
  • improve testing by not having to create document

description/backstory

There is no reason why we need the whole document on the server on each request unless the use mutates the document outside of the app (which is why we have been reusing one instance). At the moment we're creating the app element for each request and appending it to our document to render then removing it. This is due to createRootHostView

createRootHostView() {
  var element = DOM.querySelector(this._document, hostElementSelector);
}

this is limiting since you need a host element with the app element and to overwrite ShadowDomStrategy with the correct styleHost.

    bind(ShadowDomStrategy).toFactory(doc => {
      return new EmulatedUnscopedShadowDomStrategy(doc.head);
    }, [DOCUMENT_TOKEN]),

badges

What's an open-source project without them. Blocked since we need travis

  • Issue Stats
  • NPM
  • Travis
  • Gitter

Include Karma

It will be a good idea to have a Test Runner like Karma for testing Server. Include Karma with a unit test in the test folder

use Webpack for building

Working with gulp it would be great to use Webpack when building our TypeScript files to commonjs

upgrade npm scripts to a task manager

npm scripts can only go so far and we should also handle different environments (windows/osx). Being able to clean the repo on a failed install would be handy to prevent unintended errors. Expanding the current gulpfile.js with tasks from package.json would be ideal. For example rm -rf doesn't work in Windows which is why we have the gulp-rimraf plugin

Create initial e2e test for a todo app

Using protractor npm module. Should test:

  • Render a page on server
  • Click on a button that that would change the ui (e.g. remove an item from a list)
  • Assert that the change was done correctly

To make the test more robust, we might want to defer the client bootstrap until we click a special extra button, so we are sure we can do asserts on the server rendered version and then on the version that was replaced by the client.

decouple ng2Engine/render into 3 stages

decouple the current toString rendering process

prior art:
yahoo/fluxible

Server Life Cycle

init:

  • stateless app (create injector)

request:

  • create stateful app (create RootElement)
  • inject cache data
  • detect changes
  • serialize (toString)
  • dispose stateful app
  • inject serialized app into html
  • send html app to client

3 Stages

  • Explicit: dev is able to have full control over the life cycle
    • init:
      • stateless app
      • server bindings
    • request:
      • create stateful app
      • inject cache data
      • detect changes
      • serialize
      • dispose stateful app
      • inject serialized app into html
      • send html app to client
  • Render: A small abstraction that would expose injecting cache/bindings
    • init:
      • stateless app
      • server bindings
    • request:
      • inject cache data
      • inject serialized app into html
      • send html app to client
  • Fullstack: use angular server app to build precompiled angular client app
    • init:
      • server bindings
    • request:
      • optionally inject preload cache

allow the developer to maintain app instance via ApplicationRef

scope

optional change(s) in angular (We could implement ourselves).

problem(s)

we currently don't allow the developer to buildCache, clearCache, remove Injector, rebuildBindings, or any sort of way to change the state of the Application Instance

goal

  • give the developer an api for them to manage AppInject, AppHost, AppElement, CompilerCache, ChangeDetection.
  • allow any part of the app to be disposed and to be created on next request

suggestions/options

  • extend ApplicationRef with more ways to manage the state of our Application Instance
  • ApplicationRef.toString would stringify the app

current workarounds/solutions

extend ApplicationRef ourselves and maintain it as it's out of sync with the one created in Angular

benefits

Give the developer a lot more control over the lifecycle of our Application on the server. We're unable to predict any sort of optimizations developers would do with their system.

description/backstory

Allow the developer to have more control (for example)

import {bootstrap} from 'angular2/universal/server';
import {App} from 'universal/App';
import {server} from 'server/server';

var appRef = bootstrap(App, [serverServiceBindings]);

appRef.getClientRoutes().forEach(setNoJavaScriptRoutes(setServerRoutes(server)));

server.get('/', (req, res) => {
  // prepare stateful app
  var statefulApp = appRef.createStateful();

  // async data would be solved by checking cache first as microtask
  statefulApp.cache(req.jsonData);
  var Service = statefulApp.injector.get(Service);
  Service.cache(req.jsonData);
  statefulApp.router.setState(req.url, req.params, req.body);

  // trigger routes or actions
  statefulApp.tick();

  // serialize
  var content = statefulApp.toString();
  statefulApp.dispose();
  res.send(content);
});

easier example

import {bootstrap, setNoJavaScriptRoutes, setServerRoutes} from 'angular2/universal/server';
import {App} from 'universal/App';
import {server} from 'server/express_server';

var appRef = bootstrap(App, [serverServiceBindings]);

setNoJavaScriptRoutes(setServerRoutes(appRef.getClientRoutes, server)));

server.get('/', (req, res) => {
  var appJson = {url: req.url, params: req.params, data: req.jsonData};
  res.send(appRef.createStateful(appJson).disposeToString());
});

ideas to leverage server environment to provide a better "developer experience"

Angular 2 now is able to run on the server so what's the next step?
We can now take advantage of the benefits of having this control over the client's environment. We can create a small server layer that uses any of the underlying Node Frameworks such as ExpressJS, Hapi.js, or Koa.js. Doing so would be a great way for, normally client only developers, to be introduced to the backend.

Having full control over the client's environment allows us to dramatically improve the developer experience with features such as:

  • TypeScript inline script tags
  • ES6 features such as and SystemJS
  • allow users to write a component DSL (such as JSX, RiotJS, or jsBlocks)
  • better control over testing/development/production environments
  • better logging
  • live app configuration
  • default jwt setup
  • asset pipeline
  • inject ES6 polyfills
  • inject RxJS as Observable
  • can be front-end agnostic
  • removing unnecessary Angular imports for each file (like Rails)

prior art
https://github.com/yahoo/fluxible
https://muut.com/riotjs
https://github.com/astoilkov/jsblocks
https://github.com/linnovate/mean
https://github.com/meteor/meteor
https://github.com/rails/rails
https://github.com/django/django
https://github.com/playframework/playframework
https://github.com/elierotenberg/react-nexus
https://github.com/facebook/relay

the Universal app is <app> while the Server app is the html document itself that we can call an <html> component.

<html>
  <head>
    <title>Fullstack Angular 2</title>
    <meta></meta>
  </head>
  <body>
    <app></app>
    <!-- app-scripts -->
  </body>
</html>

currently <doctype> needs to be injected after the fact

code samples
https://gist.github.com/gdi2290/efa2061467c92243ca58
https://gist.github.com/gdi2290/f07fd579c6ec911d2305
https://gist.github.com/gdi2290/7c2280655dbf50450444

modules:
mincer
RxJS Next
polyfills
bunyan
vantage
webpack
webpack-require
autopolyfiller

related:
ngScripts #72
Environment Service #44

Stream serialized server rendered app to client

support stream rendering on the server to client

There are a few best practices for web mobile development and one of them is streaming the HTML down to the client. Also consider movements such as JSON.stringifyAsync which brings up the same point of sending the results. We could stream down the serialized server rendered app via
stringifyElement => stringifyElementAsync

Make PreloadCache for server/client

There needs to be a way for developers to preload their json data on the server to be sent to the client for to grab out of the preloaded cache.

<module import="/preloadCache.js"></module>
<script>window.preloadCache.setRef('request');</script>

<app></app>
<module import="/preboot.js"></module>

<module>
  import {bootstrap} from '@angular/angular';
  import {App} from './app';

  bootstrap(App, []);
</module>
<script>window.preloadCache.complete('request', { data: 'serverData' });</script>

It's important that the PreloadCache can happen after bootstrap as the serialized data could be a large data set that is being streamed down to the client with the html

  • PreloadCache #93
  • NgPreloadCacheServer
  • NgPreloadCacheClient
  • Http Server/Client with PreloadCache

ngScripts

this replaces build_scripts.ts

prior art:
riot/compiler

create directives that emulates <module import="angular2/angular2"><module> and also allow inline scripts such as

<script type="text/typescript">
  class App {}
</script>

and also inject dep angular with type="angular"

<module type="angular">
  @Component({ selector: 'app' })
  @View({ template: '<div>hello world</div>' })
  class App {}
</module>

we can also inject systemjs and es6 module loader.

We should also allow for app state management from build_scripts where we are able to control how the application is ran on the client. Or leave that feature for another module such as ngAppState

<ng-component> element

<ng-component name="app">
  <style>

  </style>

  <template view="app">

  </template>

  <module>
    import {Component, View} from '@angular/angular';
    @Component({

    })
    @View({

    })
    class App {
      constructor() {

      }
    }
  </module>
<ng-component>
  • allow Typescript/Babel(ES6/ES7)/CoffeeScript script tags
  • allow module elements
  • allow angular type module/script
  • allow element
  • use Angular 2's compiler

Git submodule update failed!

Hi,

I have some free time and decided to contribute ^^
However, when trying to npm install, I had some issues with git not able to clone the angular submodule (see screenshot below).

ng2-universal-git-submodule-issue

My git version is 2.3.5

But good news is I fixed this issue by adding git submodule init && at the beginning of the NPM angular-submodule task.

I will submit the corresponding PR soon.

ServerDomRenderer

Create a subclass of angular's DomRenderer that has special handling for setElementProperty and invokeElementMethod, so that the state of the UI is completely contained within attributes of elements. With that, serializing the DOM at the end of processing it via angular is just a matter of serializing the DOM nodes. I.e. we can reuse the existing DOM adapters of Angular.

E.g.

setElementProperty should translates changes to properties to changes to attributes. E.g.

  • set property value on an input should set the attribute value on the element.
  • set property checked on input with a boolean should add/remove the checked attribute on the element
  • ...

invokeElementMethod should also translate methods into changes to attributes. E.g.

  • call method focus should result in adding the attribute autofocus to this element and removing the attribute from the previously focussed one.

Notes:

  • please implement this in a way that does not rely on parse5 but use the DOM adapter instead. With this, we can make this work even for Dart...
  • when we have a working prototype, please create a PR for the angular/angular repo to move the renderer to there.

NoJS, allow forms to work with JavaScript turned off

The app needs to be able to work with JavaScript turned off. This is to allow older browsers (legacy) to function or large enterprise companies with crazy restrictions. Currently the links should be able to work with no problem. formDirectives(server)

this is done via action attribute in the <form> tag which makes a post request

  • Decorate for <form> tags with action and method attributes
  • Provide a way to pass data from the post request to the server
  • Provide a way to invoke the correct method via submit event on the server
  • Provide a way to only send down markup
  • Improve developer API

Create Node version for Router

The router needs to be able to run on the server. History and other services needs to be replaced with Server versions. First let's create a version that works using the Mock version before converting it.
Similar to #50

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.