This repository was archived by the owner on Nov 22, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 474
feat(express-engine): add schematics #1051
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
40215b9
feat(express-engine): add schematics
CaerusKaru 8de4339
fixup! feat(express-engine): add schematics
CaerusKaru a00703a
fixup! feat(express-engine): add schematics
CaerusKaru dc6f9c7
fixup! feat(express-engine): add schematics
CaerusKaru 362c6ed
fixup! feat(express-engine): add schematics
CaerusKaru 99b5593
fixup! feat(express-engine): add schematics
CaerusKaru 8e9fc18
fixup! feat(express-engine): add schematics
CaerusKaru a7a96dc
fixup! feat(express-engine): add schematics
CaerusKaru 29cda31
fixup! feat(express-engine): add schematics
CaerusKaru 575ddbc
fixup! feat(express-engine): add schematics
CaerusKaru fb3e8e5
fixup! feat(express-engine): add schematics
CaerusKaru ca9d2b6
fixup! feat(express-engine): add schematics
CaerusKaru ee90d72
fixup! feat(express-engine): add schematics
CaerusKaru File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| package(default_visibility = ["//visibility:public"]) | ||
|
|
||
| load("//tools:defaults.bzl", "ts_library", "npm_package") | ||
| load("@build_bazel_rules_nodejs//:defs.bzl", "jasmine_node_test") | ||
|
|
||
| filegroup( | ||
| name = "schematics_assets", | ||
| srcs = glob([ | ||
| "**/files/**/*", | ||
| "**/*.json", | ||
| ]) + [ | ||
| "README.md", | ||
| ], | ||
| ) | ||
|
|
||
| ts_library( | ||
| name = "schematics", | ||
| srcs = glob( | ||
| ["**/*.ts"], | ||
| exclude = [ | ||
| "**/*.spec.ts", | ||
| "**/files/**/*", | ||
| "test-setup/**/*", | ||
| ], | ||
| ), | ||
| module_name = "@nguniversal/express-engine/schematics", | ||
| tsconfig = ":tsconfig.json", | ||
| ) | ||
|
|
||
| # This package is intended to be combined into the main @nguniversal/express-engine package as a dep. | ||
| npm_package( | ||
| name = "npm_package", | ||
| srcs = [":schematics_assets"], | ||
| deps = [":schematics"], | ||
| ) | ||
|
|
||
| ### Testing rules | ||
|
|
||
| jasmine_node_test( | ||
| name = "unit_tests", | ||
| srcs = [":schematics_test_sources"], | ||
| data = [":schematics_assets"], | ||
| ) | ||
|
|
||
| ts_library( | ||
| name = "schematics_test_sources", | ||
| testonly = True, | ||
| srcs = glob( | ||
| [ | ||
| "**/*.spec.ts", | ||
| "test-setup/**/*.ts", | ||
| ], | ||
| exclude = ["**/files/**/*"], | ||
| ), | ||
| tsconfig = ":tsconfig.json", | ||
| deps = [":schematics"], | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # Angular Universal Express-Engine Schematics | ||
| A collection of Schematics for Angular Universal Express-Engine. | ||
|
|
||
| ## Collection | ||
|
|
||
| ### Install | ||
| Adds Angular Universal Express Engine and its dependencies and pre-configures the application. | ||
|
|
||
| - Runs the default Angular Universal schematic to add Universal capabilities to an application | ||
| - Adds Express-Engine, NgModule-Factory-Loader, ts-loader, and webpack to `package.json` | ||
| - Adds a sample Express server file | ||
|
|
||
| Command: `ng add @nguniversal/express-engine` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json", | ||
| "schematics": { | ||
| "ng-add": { | ||
| "description": "Adds Angular Universal Express Engine to the application without affecting any templates", | ||
| "factory": "./install", | ||
| "schema": "./install/schema.json", | ||
| "aliases": ["express-engine-shell"] | ||
| }, | ||
| } | ||
| } |
50 changes: 50 additions & 0 deletions
50
modules/express-engine/schematics/install/files/root/__serverFileName@stripTsExtension__.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| import 'zone.js/dist/zone-node'; | ||
| import 'reflect-metadata'; | ||
| import {enableProdMode} from '@angular/core'; | ||
| // Express Engine | ||
| import {ngExpressEngine} from '@nguniversal/express-engine'; | ||
| // Import module map for lazy loading | ||
| import {provideModuleMap} from '@nguniversal/module-map-ngfactory-loader'; | ||
|
|
||
| import * as express from 'express'; | ||
| import {join} from 'path'; | ||
|
|
||
| // Faster server renders w/ Prod mode (dev mode never needed) | ||
| enableProdMode(); | ||
|
|
||
| // Express server | ||
| const app = express(); | ||
|
|
||
| const PORT = process.env.PORT || <%= serverPort %>; | ||
| const DIST_FOLDER = join(process.cwd(), 'dist'); | ||
|
|
||
| // * NOTE :: leave this as require() since this file is built Dynamically from webpack | ||
| const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./server/main'); | ||
|
|
||
| // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine) | ||
| app.engine('html', ngExpressEngine({ | ||
| bootstrap: AppServerModuleNgFactory, | ||
| providers: [ | ||
| provideModuleMap(LAZY_MODULE_MAP) | ||
| ] | ||
| })); | ||
|
|
||
| app.set('view engine', 'html'); | ||
| app.set('views', join(DIST_FOLDER, 'browser')); | ||
|
|
||
| // Example Express Rest API endpoints | ||
| // app.get('/api/**', (req, res) => { }); | ||
| // Server static files from /browser | ||
| app.get('*.*', express.static(join(DIST_FOLDER, 'browser'), { | ||
| maxAge: '1y' | ||
| })); | ||
|
|
||
| // All regular routes use the Universal engine | ||
| app.get('*', (req, res) => { | ||
| res.render('index', { req }); | ||
| }); | ||
|
|
||
| // Start up the Node server | ||
| app.listen(PORT, () => { | ||
| console.log(`Node Express server listening on http://localhost:${PORT}`); | ||
| }); |
20 changes: 20 additions & 0 deletions
20
...ss-engine/schematics/install/files/root/__serverFileName@stripTsExtension__.tsconfig.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| { | ||
| "compileOnSave": false, | ||
| "compilerOptions": { | ||
| "outDir": "./dist", | ||
| "sourceMap": true, | ||
| "declaration": false, | ||
| "moduleResolution": "node", | ||
| "emitDecoratorMetadata": true, | ||
| "experimentalDecorators": true, | ||
| "target": "es5", | ||
| "typeRoots": [ | ||
| "node_modules/@types" | ||
| ], | ||
| "lib": [ | ||
| "es2017", | ||
| "dom" | ||
| ] | ||
| }, | ||
| "include": ["<%= stripTsExtension(serverFileName) %>.ts"] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| /** | ||
| * @license | ||
| * Copyright Google Inc. All Rights Reserved. | ||
| * | ||
| * Use of this source code is governed by an MIT-style license that can be | ||
| * found in the LICENSE file at https://angular.io/license | ||
| */ | ||
| import {SchematicTestRunner} from '@angular-devkit/schematics/testing'; | ||
| import {Schema as UniversalOptions} from './schema'; | ||
| import {collectionPath, createTestApp} from '../test-setup/test-app'; | ||
| import {Tree} from '@angular-devkit/schematics'; | ||
|
|
||
| describe('Universal Schematic', () => { | ||
| const defaultOptions: UniversalOptions = { | ||
| clientProject: 'bar', | ||
| }; | ||
|
|
||
| let schematicRunner: SchematicTestRunner; | ||
| let appTree: Tree; | ||
|
|
||
| beforeEach(() => { | ||
| appTree = createTestApp(); | ||
| schematicRunner = new SchematicTestRunner('schematics', collectionPath); | ||
| }); | ||
|
|
||
| it('should add dependency: @nguniversal/module-map-ngfactory-loader', () => { | ||
| const tree = schematicRunner.runSchematic('ng-add', defaultOptions, appTree); | ||
| const filePath = '/package.json'; | ||
| const contents = tree.readContent(filePath); | ||
| expect(contents).toMatch(/\"@nguniversal\/module-map-ngfactory-loader\": \"/); | ||
| }); | ||
|
|
||
| it('should add dependency: @nguniversal/express-engine', () => { | ||
| const tree = schematicRunner.runSchematic('ng-add', defaultOptions, appTree); | ||
| const filePath = '/package.json'; | ||
| const contents = tree.readContent(filePath); | ||
| expect(contents).toMatch(/\"@nguniversal\/express-engine\": \"/); | ||
| }); | ||
|
|
||
| it('should add dependency: express', () => { | ||
| const tree = schematicRunner.runSchematic('ng-add', defaultOptions, appTree); | ||
| const filePath = '/package.json'; | ||
| const contents = tree.readContent(filePath); | ||
| expect(contents).toMatch(/\"express\": \"/); | ||
| }); | ||
|
|
||
| it('should install npm dependencies', () => { | ||
| schematicRunner.runSchematic('ng-add', defaultOptions, appTree); | ||
| expect(schematicRunner.tasks.length).toBe(2); | ||
| expect(schematicRunner.tasks[0].name).toBe('node-package'); | ||
| expect((schematicRunner.tasks[0].options as {command: string}).command).toBe('install'); | ||
| }); | ||
| }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| /** | ||
| * @license | ||
| * Copyright Google LLC All Rights Reserved. | ||
| * | ||
| * Use of this source code is governed by an MIT-style license that can be | ||
| * found in the LICENSE file at https://angular.io/license | ||
| */ | ||
| import { | ||
| basename, | ||
| experimental, | ||
| join, | ||
| normalize, | ||
| parseJson, | ||
| strings, | ||
| } from '@angular-devkit/core'; | ||
| import { | ||
| Rule, | ||
| SchematicContext, | ||
| SchematicsException, | ||
| Tree, | ||
| apply, | ||
| chain, | ||
| mergeWith, | ||
| move, | ||
| template, | ||
| url, | ||
| noop, | ||
| filter, | ||
| externalSchematic, | ||
| } from '@angular-devkit/schematics'; | ||
| import {NodePackageInstallTask} from '@angular-devkit/schematics/tasks'; | ||
| import {getWorkspace} from '@schematics/angular/utility/config'; | ||
| import {Schema as UniversalOptions} from './schema'; | ||
|
|
||
|
|
||
| function getClientProject( | ||
| host: Tree, options: UniversalOptions, | ||
| ): experimental.workspace.WorkspaceProject { | ||
| const workspace = getWorkspace(host); | ||
| const clientProject = workspace.projects[options.clientProject]; | ||
| if (!clientProject) { | ||
| throw new SchematicsException(`Client app ${options.clientProject} not found.`); | ||
| } | ||
|
|
||
| return clientProject; | ||
| } | ||
|
|
||
| function getClientArchitect( | ||
| host: Tree, | ||
| options: UniversalOptions, | ||
| ): experimental.workspace.WorkspaceTool { | ||
| const clientArchitect = getClientProject(host, options).architect; | ||
|
|
||
| if (!clientArchitect) { | ||
| throw new Error('Client project architect not found.'); | ||
| } | ||
|
|
||
| return clientArchitect; | ||
| } | ||
|
|
||
| function addDependenciesAndScripts(options: UniversalOptions): Rule { | ||
| return (host: Tree) => { | ||
|
|
||
| const pkgPath = '/package.json'; | ||
| const buffer = host.read(pkgPath); | ||
| if (buffer === null) { | ||
| throw new SchematicsException('Could not find package.json'); | ||
| } | ||
|
|
||
| const pkg = JSON.parse(buffer.toString()); | ||
|
|
||
| pkg.dependencies['@nguniversal/express-engine'] = '0.0.0-PLACEHOLDER'; | ||
| pkg.dependencies['@nguniversal/module-map-ngfactory-loader'] = '0.0.0-PLACEHOLDER'; | ||
| pkg.dependencies['express'] = 'EXPRESS_VERSION'; | ||
|
|
||
| pkg.scripts['serve:ssr'] = 'node dist/server'; | ||
| pkg.scripts['build:ssr'] = 'npm run build:client-and-server-bundles && npm run compile:server'; | ||
| pkg.scripts['build:client-and-server-bundles'] = | ||
| `ng build --prod && ng run ${options.clientProject}:server:production`; | ||
| pkg.scripts['compile:server'] = | ||
| `tsc -p ${options.serverFileName.replace(/\.ts$/, '')}.tsconfig.json`; | ||
|
|
||
| host.overwrite(pkgPath, JSON.stringify(pkg, null, 2)); | ||
|
|
||
| return host; | ||
| }; | ||
| } | ||
|
|
||
| export default function (options: UniversalOptions): Rule { | ||
| return (host: Tree, context: SchematicContext) => { | ||
| const clientProject = getClientProject(host, options); | ||
| if (clientProject.projectType !== 'application') { | ||
| throw new SchematicsException(`Universal requires a project type of "application".`); | ||
| } | ||
| const clientArchitect = getClientArchitect(host, options); | ||
| const tsConfigExtends = basename(clientArchitect.build.options.tsConfig); | ||
| const rootInSrc = clientProject.root === ''; | ||
| const tsConfigDirectory = join(normalize(clientProject.root), rootInSrc ? 'src' : ''); | ||
|
|
||
| if (!options.skipInstall) { | ||
| context.addTask(new NodePackageInstallTask()); | ||
| } | ||
|
|
||
| const rootSource = apply(url('./files/root'), [ | ||
| options.skipServer ? filter(path => !path.startsWith('__serverFileName')) : noop(), | ||
| template({ | ||
| ...strings, | ||
| ...options as object, | ||
| stripTsExtension: (s: string) => { return s.replace(/\.ts$/, ''); }, | ||
| tsConfigExtends, | ||
| rootInSrc, | ||
| }), | ||
| move(tsConfigDirectory), | ||
| ]); | ||
|
|
||
| return chain([ | ||
| externalSchematic('@schematics/angular', 'universal', options), | ||
| mergeWith(rootSource), | ||
| addDependenciesAndScripts(options), | ||
| ]); | ||
| }; | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More tests will be needed as behavior is finalized. These are the default tests, plus some added dependency checks. Will also need test runners that work with Bazel (Material has this already)