├── example-cli ├── ext-app1 │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── styles.css │ │ ├── favicon.ico │ │ ├── tsconfig.app.json │ │ ├── main.prod.ts │ │ ├── app │ │ │ ├── app.states.ts │ │ │ ├── welcome.component.ts │ │ │ ├── app.external.module.ts │ │ │ ├── app.module.ts │ │ │ ├── app.common.module.ts │ │ │ └── ext.component.ts │ │ ├── index.html │ │ ├── tsconfig.spec.json │ │ ├── tslint.json │ │ ├── browserslist │ │ ├── main.ts │ │ ├── test.ts │ │ ├── karma.conf.js │ │ └── polyfills.ts │ ├── e2e │ │ ├── src │ │ │ ├── app.po.ts │ │ │ └── app.e2e-spec.ts │ │ ├── tsconfig.e2e.json │ │ └── protractor.conf.js │ ├── .editorconfig │ ├── tsconfig.json │ ├── extra-webpack.config.js │ ├── .gitignore │ ├── extra-webpack.prod.config.js │ ├── README.md │ ├── package.json │ ├── tslint.json │ └── angular.json └── shell-app │ ├── src │ ├── assets │ │ └── .gitkeep │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── app1.component.ts │ │ ├── app.component.ts │ │ ├── select.component.ts │ │ ├── app.states.ts │ │ ├── app.module.ts │ │ ├── app.component.spec.ts │ │ └── sLoader.ts │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── styles.css │ ├── favicon.ico │ ├── tsconfig.app.json │ ├── index.html │ ├── tsconfig.spec.json │ ├── tslint.json │ ├── browserslist │ ├── main.ts │ ├── test.ts │ ├── karma.conf.js │ └── polyfills.ts │ ├── e2e │ ├── src │ │ ├── app.po.ts │ │ └── app.e2e-spec.ts │ ├── tsconfig.e2e.json │ └── protractor.conf.js │ ├── .editorconfig │ ├── extra-webpack.config.js │ ├── tsconfig.json │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── tslint.json │ └── angular.json ├── .npmignore ├── .gitattributes ├── example ├── ext-app-1 │ ├── app │ │ ├── main.ts │ │ ├── index.html │ │ ├── vendor.ts │ │ ├── welcome.component.ts │ │ ├── ext.prod.module.ts │ │ ├── ext.module.ts │ │ └── ext.component.ts │ ├── tsconfig.json │ ├── webpack.prod.config.js │ ├── webpack.dev.config.js │ └── package.json └── shell-app │ ├── app │ ├── main.ts │ ├── index.html │ ├── app1.component.ts │ ├── vendor.ts │ ├── select.component.ts │ ├── app.component.ts │ ├── app.states.ts │ ├── app.module.ts │ └── sLoader.ts │ ├── tsconfig.json │ ├── webpack.config.js │ └── package.json ├── package.json ├── .gitignore ├── README.md └── index.js /example-cli/ext-app1/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | example 2 | example-cli 3 | .idea 4 | *.iml 5 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | package-lock.json -diff 2 | * text=auto 3 | bin/* eol=lf -------------------------------------------------------------------------------- /example-cli/shell-app/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | :host{ 2 | background: green; 3 | display: block; 4 | } -------------------------------------------------------------------------------- /example-cli/ext-app1/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrFrankel/share-loader/HEAD/example-cli/ext-app1/src/favicon.ico -------------------------------------------------------------------------------- /example-cli/shell-app/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrFrankel/share-loader/HEAD/example-cli/shell-app/src/favicon.ico -------------------------------------------------------------------------------- /example-cli/shell-app/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |
2 |

The App Lives!

3 |

{{ message }}

4 | 5 |
-------------------------------------------------------------------------------- /example/ext-app-1/app/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | import {ExtModule} from './ext.module'; 3 | 4 | platformBrowserDynamic().bootstrapModule(ExtModule); -------------------------------------------------------------------------------- /example/shell-app/app/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | import { AppModule } from './app.module'; 3 | 4 | platformBrowserDynamic().bootstrapModule(AppModule); -------------------------------------------------------------------------------- /example/ext-app-1/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Webpack App 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/shell-app/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Webpack App 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "es2015", 6 | "types": [] 7 | }, 8 | "exclude": [ 9 | "src/test.ts", 10 | "**/*.spec.ts" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /example/shell-app/app/app1.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'my-app1', 5 | styles: [` 6 | 7 | `], 8 | template: ` 9 |

I am an internal component

10 | ` 11 | }) 12 | export class App1Component { 13 | } -------------------------------------------------------------------------------- /example-cli/ext-app1/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /example-cli/shell-app/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/app/app1.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'my-app1', 5 | styles: [` 6 | 7 | `], 8 | template: ` 9 |

I am an internal component

10 | ` 11 | }) 12 | export class App1Component { 13 | } -------------------------------------------------------------------------------- /example-cli/shell-app/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "es2015", 6 | "types": [], 7 | 8 | }, 9 | "exclude": [ 10 | "src/test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/main.prod.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | 3 | import { AppModule } from './app/app.external.module'; 4 | try { 5 | platformBrowserDynamic().bootstrapModule(AppModule); 6 | } 7 | catch(e){ 8 | console.log('ok') 9 | } 10 | -------------------------------------------------------------------------------- /example-cli/ext-app1/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /example-cli/shell-app/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /example-cli/shell-app/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { 9 | message = 'This is the sample message.'; 10 | } 11 | -------------------------------------------------------------------------------- /example-cli/ext-app1/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/app/app.states.ts: -------------------------------------------------------------------------------- 1 | import {ExtComponent} from './ext.component' 2 | import {WelcomeComponent} from './welcome.component' 3 | 4 | export const appStates = [ 5 | { 6 | path: '', 7 | component: ExtComponent 8 | }, 9 | { 10 | path: 'welcome', 11 | component: WelcomeComponent 12 | } 13 | ] 14 | -------------------------------------------------------------------------------- /example-cli/shell-app/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ExtApp1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ShellApp 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example/shell-app/app/vendor.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js'; 3 | 4 | import '@angular/common'; 5 | import '@angular/compiler'; 6 | import '@angular/core'; 7 | import '@angular/platform-browser'; 8 | import '@angular/platform-browser-dynamic'; 9 | import '@angular/http'; 10 | import '@angular/router'; 11 | import 'rxjs'; 12 | 13 | import '@uirouter/angular'; 14 | import '@uirouter/rx'; -------------------------------------------------------------------------------- /example/shell-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": false, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "outDir": "dist", 12 | "lib": [ "es2015", "dom" ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /example-cli/ext-app1/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('workspace-project App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('Welcome to ext-app1!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "types": [ 7 | "jasmine", 8 | "node" 9 | ] 10 | }, 11 | "files": [ 12 | "test.ts", 13 | "polyfills.ts" 14 | ], 15 | "include": [ 16 | "**/*.spec.ts", 17 | "**/*.d.ts" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /example-cli/shell-app/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('workspace-project App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('Welcome to shell-app!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "types": [ 7 | "jasmine", 8 | "node" 9 | ] 10 | }, 11 | "files": [ 12 | "test.ts", 13 | "polyfills.ts" 14 | ], 15 | "include": [ 16 | "**/*.spec.ts", 17 | "**/*.d.ts" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "app", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "app", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "app", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "app", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /example/ext-app-1/app/vendor.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js'; 3 | 4 | import '@angular/common'; 5 | import '@angular/compiler'; 6 | import '@angular/core'; 7 | import '@angular/platform-browser'; 8 | import '@angular/platform-browser-dynamic'; 9 | import '@angular/upgrade'; 10 | import '@angular/http'; 11 | import '@angular/router'; 12 | import 'rxjs'; 13 | 14 | import '@uirouter/angular'; 15 | import '@uirouter/rx'; -------------------------------------------------------------------------------- /example-cli/ext-app1/src/browserslist: -------------------------------------------------------------------------------- 1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | # For IE 9-11 support, please uncomment the last line of the file and adjust as needed 5 | > 0.5% 6 | last 2 versions 7 | Firefox ESR 8 | not dead 9 | # IE 9-11 -------------------------------------------------------------------------------- /example-cli/shell-app/src/browserslist: -------------------------------------------------------------------------------- 1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | # For IE 9-11 support, please uncomment the last line of the file and adjust as needed 5 | > 0.5% 6 | last 2 versions 7 | Firefox ESR 8 | not dead 9 | # IE 9-11 -------------------------------------------------------------------------------- /example-cli/shell-app/extra-webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | module: { 3 | rules: [ 4 | { 5 | test: /\.js?$/, 6 | use: 7 | [{ 8 | loader: 'share-loader', 9 | options: { 10 | modules: [/@angular/], 11 | exclude: [/@angular-devkit/], 12 | namespace: 'container-app' 13 | } 14 | }] 15 | }] 16 | } 17 | }; -------------------------------------------------------------------------------- /example-cli/ext-app1/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.log(err)); 13 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.log(err)); 13 | -------------------------------------------------------------------------------- /example/shell-app/app/select.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'my-select', 5 | styles: [` 6 | 7 | `], 8 | template: ` 9 |
10 | internal component 11 | external app 12 | 13 |
14 | ` 15 | }) 16 | export class SelectComponent { 17 | } -------------------------------------------------------------------------------- /example-cli/shell-app/src/app/select.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'my-select', 5 | styles: [` 6 | 7 | `], 8 | template: ` 9 |
10 | internal component 11 | external app 12 | 13 |
14 | ` 15 | }) 16 | export class SelectComponent { 17 | } -------------------------------------------------------------------------------- /example/ext-app-1/app/welcome.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'ext-welcome', 5 | styles: [` 6 | :host{ 7 | display: block; 8 | background: blue; 9 | color: white; 10 | } 11 | 12 | `], 13 | template: ` 14 |
15 |

{{ message }}

16 |
17 | ` 18 | }) 19 | export class WelcomeComponent { 20 | message = 'this is a nested routed external component'; 21 | } -------------------------------------------------------------------------------- /example-cli/ext-app1/src/app/welcome.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'ext-welcome', 5 | styles: [` 6 | :host{ 7 | display: block; 8 | background: blue; 9 | color: white; 10 | } 11 | 12 | `], 13 | template: ` 14 |
15 |

{{ message }}

16 |
17 | ` 18 | }) 19 | export class WelcomeComponent { 20 | message = 'this is a nested routed external component'; 21 | } -------------------------------------------------------------------------------- /example-cli/ext-app1/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "node_modules/@types" 14 | ], 15 | "lib": [ 16 | "es2017", 17 | "dom" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example-cli/shell-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "node_modules/@types" 14 | ], 15 | "lib": [ 16 | "es2017", 17 | "dom" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example/shell-app/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'my-app', 5 | styles: [` 6 | :host{ 7 | background: green; 8 | display: block; 9 | } 10 | `], 11 | template: ` 12 |
13 |

The App Lives!

14 |

{{ message }}

15 | 16 |
17 | ` 18 | }) 19 | export class AppComponent { 20 | message = 'This is the sample message.'; 21 | } -------------------------------------------------------------------------------- /example/ext-app-1/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "skipLibCheck": true, 6 | "moduleResolution": "node", 7 | "types": ["node"], 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "sourceMap": false, 11 | "lib": [ 12 | "es7", 13 | "dom", 14 | "es2017.object", 15 | "es2015.iterable", 16 | "ScriptHost" 17 | ] 18 | }, 19 | "include": [ 20 | "./app" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /example-cli/ext-app1/extra-webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const {Externals} = require('share-loader'); 3 | module.exports = { 4 | externals: [ 5 | Externals({ 6 | namespace: 'container-app', 7 | modules: [/@angular/] 8 | }) 9 | ], 10 | output: { 11 | filename: '[name].js', 12 | path: path.resolve('./dist'), 13 | chunkFilename: '[name].js', 14 | library: 'extapp', 15 | libraryTarget: 'umd' 16 | }, 17 | optimization: { 18 | runtimeChunk: false, 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/app/app.external.module.ts: -------------------------------------------------------------------------------- 1 | import {CommonModule} from '@angular/common' 2 | import {NgModule} from '@angular/core' 3 | import {RouterModule} from '@angular/router' 4 | import {appStates} from './app.states' 5 | import {AppCommonModule} from "./app.common.module"; 6 | @NgModule({ 7 | imports: [AppCommonModule, CommonModule, RouterModule.forChild(appStates)], 8 | declarations: [], 9 | bootstrap: [], 10 | entryComponents: [], 11 | providers: [], 12 | exports: [RouterModule] 13 | }) 14 | 15 | export class AppModule { 16 | } 17 | 18 | -------------------------------------------------------------------------------- /example/shell-app/app/app.states.ts: -------------------------------------------------------------------------------- 1 | import {loadScript} from './sLoader'; 2 | import {App1Component} from './app1.component'; 3 | 4 | export const app1State = { 5 | path: 'app1', 6 | component: App1Component 7 | }; 8 | 9 | export const app2State = { 10 | path: 'ext', 11 | 12 | /** Replace <%path-to-server-host%> with a server the will host the external application js**/ 13 | loadChildren: () => { 14 | return loadScript('<%path-to-ext-app-1-server-host%>/ext1.js', 'extapp', 'ExtModule'); 15 | } 16 | }; 17 | 18 | export const APP_STATES = [ 19 | app1State, 20 | app2State 21 | ]; -------------------------------------------------------------------------------- /example-cli/ext-app1/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core' 2 | import {RouterModule} from '@angular/router' 3 | import {AppCommonModule} from './app.common.module' 4 | import {appStates} from './app.states' 5 | import {CommonModule} from "@angular/common"; 6 | import {ExtComponent} from "./ext.component"; 7 | 8 | @NgModule({ 9 | imports: [AppCommonModule, CommonModule, RouterModule.forRoot(appStates)], 10 | declarations: [], 11 | bootstrap: [ExtComponent], 12 | entryComponents: [], 13 | providers: [], 14 | exports: [RouterModule] 15 | }) 16 | 17 | export class AppModule {} 18 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/app/app.states.ts: -------------------------------------------------------------------------------- 1 | import {loadScript} from './sLoader'; 2 | import {App1Component} from './app1.component'; 3 | 4 | export const app1State = { 5 | path: 'app1', 6 | component: App1Component 7 | }; 8 | 9 | export const load = () => { 10 | return loadScript('http://localhost:4300/main.js', 'extapp', 'AppModule'); 11 | } 12 | export const app2State = { 13 | path: 'ext', 14 | 15 | /** Replace <%path-to-server-host%> with a server the will host the external application js**/ 16 | loadChildren: load 17 | }; 18 | 19 | export const APP_STATES = [ 20 | app1State, 21 | app2State 22 | ]; 23 | 24 | 25 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/app/app.common.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core' 2 | import {ExtComponent} from './ext.component' 3 | import {WelcomeComponent} from './welcome.component' 4 | import {ReactiveFormsModule} from "@angular/forms"; 5 | import {RouterModule} from "@angular/router"; 6 | import {CommonModule} from "@angular/common"; 7 | 8 | @NgModule({ 9 | imports: [CommonModule, ReactiveFormsModule, RouterModule], 10 | declarations: [ExtComponent, WelcomeComponent], 11 | bootstrap: [], 12 | entryComponents: [], 13 | providers: [], 14 | exports: [ExtComponent, WelcomeComponent] 15 | }) 16 | 17 | export class AppCommonModule {} 18 | -------------------------------------------------------------------------------- /example/shell-app/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {BrowserModule} from '@angular/platform-browser'; 3 | import {AppComponent} from './app.component'; 4 | import {SelectComponent} from './select.component'; 5 | import {UIRouterModule} from '@uirouter/angular'; 6 | import {APP_STATES} from './app.states'; 7 | import {App1Component} from './app1.component'; 8 | import {RouterModule} from '@angular/router' 9 | 10 | @NgModule({ 11 | imports: [BrowserModule, RouterModule.forRoot(APP_STATES)], 12 | declarations: [AppComponent, SelectComponent, App1Component], 13 | bootstrap: [AppComponent] 14 | }) 15 | export class AppModule { 16 | } -------------------------------------------------------------------------------- /example/ext-app-1/app/ext.prod.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {ExtComponent} from './ext.component'; 4 | import {WelcomeComponent} from './welcome.component'; 5 | import {RouterModule} from '@angular/router' 6 | 7 | 8 | @NgModule({ 9 | imports: [CommonModule, RouterModule.forChild( [ 10 | { 11 | path: '', 12 | component: ExtComponent 13 | }, 14 | { 15 | path: 'welcome', 16 | component: WelcomeComponent 17 | }])], 18 | exports: [RouterModule], 19 | declarations: [ExtComponent, WelcomeComponent], 20 | entryComponents: [] 21 | }) 22 | export class ExtModule { 23 | } 24 | -------------------------------------------------------------------------------- /example/ext-app-1/app/ext.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core' 2 | import {UIRouterModule} from '@uirouter/angular' 3 | import {BrowserModule} from '@angular/platform-browser' 4 | import {ExtComponent} from './ext.component' 5 | import {WelcomeComponent} from './welcome.component' 6 | import {RouterModule} from '@angular/router' 7 | 8 | @NgModule({ 9 | imports: [BrowserModule, RouterModule.forRoot([ 10 | { 11 | path: 'welcome', 12 | component: WelcomeComponent 13 | } 14 | 15 | ])], 16 | declarations: [ExtComponent, WelcomeComponent], 17 | bootstrap: [ExtComponent], 18 | providers: [], 19 | entryComponents: [] 20 | }) 21 | export class ExtModule { 22 | } -------------------------------------------------------------------------------- /example-cli/ext-app1/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | /node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | yarn-error.log 34 | testem.log 35 | /typings 36 | 37 | # System Files 38 | .DS_Store 39 | Thumbs.db 40 | -------------------------------------------------------------------------------- /example-cli/shell-app/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | /node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | yarn-error.log 34 | testem.log 35 | /typings 36 | 37 | # System Files 38 | .DS_Store 39 | Thumbs.db 40 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {BrowserModule} from '@angular/platform-browser'; 3 | import {AppComponent} from './app.component'; 4 | import {SelectComponent} from './select.component'; 5 | import {APP_STATES} from './app.states'; 6 | import {App1Component} from './app1.component'; 7 | import {RouterModule} from '@angular/router'; 8 | import {ReactiveFormsModule} from "@angular/forms"; 9 | 10 | @NgModule({ 11 | imports: [BrowserModule, ReactiveFormsModule, RouterModule.forRoot(APP_STATES)], 12 | declarations: [AppComponent, SelectComponent, App1Component], 13 | providers: [], 14 | bootstrap: [AppComponent] 15 | }) 16 | export class AppModule { 17 | } 18 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * In development mode, to ignore zone related error stack frames such as 11 | * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can 12 | * import the following file, but please comment it out in production mode 13 | * because it will have performance impact when throw error 14 | */ 15 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 16 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * In development mode, to ignore zone related error stack frames such as 11 | * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can 12 | * import the following file, but please comment it out in production mode 13 | * because it will have performance impact when throw error 14 | */ 15 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 16 | -------------------------------------------------------------------------------- /example/ext-app-1/app/ext.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, ViewEncapsulation} from '@angular/core' 2 | 3 | @Component({ 4 | selector: 'ext-comp', 5 | encapsulation: ViewEncapsulation.Native, 6 | styles: [` 7 | :host { 8 | display: block; 9 | border: 5px solid red; 10 | min-height: 90vh; 11 | background: red; 12 | } 13 | 14 | .btn { 15 | background: purple; 16 | color: white; 17 | text-align: center; 18 | height: 30px; 19 | } 20 | `], 21 | template: ` 22 |
23 | 24 | 25 |
26 | ` 27 | }) 28 | export class ExtComponent { 29 | } -------------------------------------------------------------------------------- /example-cli/ext-app1/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/app/ext.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, ViewEncapsulation} from '@angular/core' 2 | 3 | @Component({ 4 | selector: 'ext-comp', 5 | encapsulation: ViewEncapsulation.Native, 6 | styles: [` 7 | :host { 8 | display: block; 9 | border: 5px solid red; 10 | min-height: 90vh; 11 | background: red; 12 | } 13 | 14 | .btn { 15 | background: purple; 16 | color: white; 17 | text-align: center; 18 | height: 30px; 19 | } 20 | `], 21 | template: ` 22 |
23 | 24 | 25 |
26 | ` 27 | }) 28 | export class ExtComponent { 29 | } 30 | -------------------------------------------------------------------------------- /example-cli/ext-app1/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './src/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: require('path').join(__dirname, './tsconfig.e2e.json') 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; -------------------------------------------------------------------------------- /example-cli/shell-app/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './src/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: require('path').join(__dirname, './tsconfig.e2e.json') 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; -------------------------------------------------------------------------------- /example/ext-app-1/webpack.prod.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const {Externals} = require('share-loader'); 4 | 5 | module.exports = { 6 | entry: { 7 | 'ext1': './app/ext.prod.module.ts' 8 | }, 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.ts?$/, 13 | use: ['ts-loader', 'angular2-template-loader'] 14 | }] 15 | }, 16 | externals: [ 17 | Externals({ 18 | namespace: 'container-app', 19 | modules: [/@angular/, /@uirouter\/angular/] 20 | }) 21 | ], 22 | resolve: { 23 | extensions: ['.ts', '.tsx', '.js', '.pug', '.less'], 24 | modules: ['node_modules', 'app'] 25 | }, 26 | output: { 27 | filename: '[name].js', 28 | path: path.resolve('./dist'), 29 | chunkFilename: '[name].bundle.js', 30 | library: 'extapp', 31 | libraryTarget: 'umd' 32 | }, 33 | devServer: { 34 | historyApiFallback: { 35 | index: 'dist/index.html' 36 | } 37 | }, 38 | plugins: [ 39 | new HtmlWebpackPlugin(), 40 | ] 41 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "share-loader", 3 | "version": "0.7.0", 4 | "author": "MFrankel", 5 | "description": "share loader module for webpack", 6 | "license": "MIT", 7 | "main": "index.js", 8 | "scripts": { 9 | "bootstrap": "cd example/ext-app-1 && npm install && cd ../shell-app && npm install && cd ../../example-cli/ext-app1 && npm install && cd ../shell-app && npm install", 10 | "audit": "cd example/ext-app-1 && npm audit fix && cd ../shell-app && npm audit fix && cd ../../example-cli/ext-app1 && npm audit fix && cd ../shell-app && npm audit fix" 11 | }, 12 | "dependencies": {}, 13 | "devDependencies": {}, 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/MrFrankel/share-loader.git" 17 | }, 18 | "bugs": { 19 | "url": "https://github.com/MrFrankel/share-loader/issues" 20 | }, 21 | "homepage": "https://github.com/MrFrankel/share-loader", 22 | "peerDependencies": { 23 | "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0" 24 | }, 25 | "engines": { 26 | "node": ">= 4.3 < 5.0.0 || >= 5.10" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../coverage'), 20 | reports: ['html', 'lcovonly'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false 30 | }); 31 | }; -------------------------------------------------------------------------------- /example-cli/shell-app/src/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../coverage'), 20 | reports: ['html', 'lcovonly'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false 30 | }); 31 | }; -------------------------------------------------------------------------------- /example/ext-app-1/webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | 5 | module.exports = { 6 | entry: { 7 | 'vendor': './app/vendor.ts', 8 | 'app': './app/main.ts' 9 | }, 10 | module: { 11 | rules: [ 12 | { 13 | test: /\.ts?$/, 14 | use: ['ts-loader', 'angular2-template-loader'] 15 | }] 16 | }, 17 | externals: [], 18 | resolve: { 19 | extensions: ['.ts', '.tsx', '.js', '.pug', '.less'], 20 | modules: ['node_modules', 'app'] 21 | }, 22 | output: { 23 | filename: '[name].js', 24 | path: path.resolve('./dist'), 25 | chunkFilename: '[name].bundle.js', 26 | }, 27 | 28 | plugins: [ 29 | new HtmlWebpackPlugin({ 30 | template: './app/index.html' 31 | }), 32 | new webpack.ContextReplacementPlugin( 33 | // The (\\|\/) piece accounts for path separators in *nix and Windows 34 | /angular(\\|\/)core(\\|\/)@angular/, 35 | path.resolve(__dirname, './app}'), 36 | {} // a map of your routes 37 | ), 38 | ] 39 | }; -------------------------------------------------------------------------------- /example-cli/ext-app1/extra-webpack.prod.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const {Externals} = require('share-loader'); 3 | var LastCallWebpackPlugin = require('last-call-webpack-plugin'); 4 | module.exports = { 5 | output: { 6 | filename: '[name].js', 7 | path: path.resolve('./dist'), 8 | chunkFilename: '[name].js', 9 | library: 'ext', 10 | libraryTarget: 'umd' 11 | }, 12 | externals: [ 13 | Externals({ 14 | namespace: 'container-app', 15 | modules: [/@angular/], 16 | exclude: [/router.ngfactory/] 17 | }) 18 | ], 19 | optimization: { 20 | runtimeChunk: false, 21 | }, 22 | plugins: [ 23 | new LastCallWebpackPlugin({ 24 | assetProcessors: [ 25 | { 26 | regExp: /main.js$/, 27 | phase: 'compilation.optimize-chunk-assets', 28 | processor: (assetName, asset) => { 29 | 30 | return Promise.resolve(asset.source().replace('var AppModuleNgFactory', `window.extapp = {};\nvar AppModuleNgFactory = window.extapp.AppModule`)) 31 | } 32 | } 33 | ], 34 | canPrint: true 35 | }) 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | describe('AppComponent', () => { 4 | beforeEach(async(() => { 5 | TestBed.configureTestingModule({ 6 | declarations: [ 7 | AppComponent 8 | ], 9 | }).compileComponents(); 10 | })); 11 | it('should create the app', async(() => { 12 | const fixture = TestBed.createComponent(AppComponent); 13 | const app = fixture.debugElement.componentInstance; 14 | expect(app).toBeTruthy(); 15 | })); 16 | it(`should have as title 'app'`, async(() => { 17 | const fixture = TestBed.createComponent(AppComponent); 18 | const app = fixture.debugElement.componentInstance; 19 | expect(app.title).toEqual('app'); 20 | })); 21 | it('should render title in a h1 tag', async(() => { 22 | const fixture = TestBed.createComponent(AppComponent); 23 | fixture.detectChanges(); 24 | const compiled = fixture.debugElement.nativeElement; 25 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to shell-app!'); 26 | })); 27 | }); 28 | -------------------------------------------------------------------------------- /example-cli/ext-app1/README.md: -------------------------------------------------------------------------------- 1 | # ExtApp1 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.0.8. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 28 | -------------------------------------------------------------------------------- /example-cli/shell-app/README.md: -------------------------------------------------------------------------------- 1 | # ShellApp 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.0.8. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 28 | -------------------------------------------------------------------------------- /example/shell-app/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | 4 | module.exports = { 5 | entry: { 6 | 'vendor': './app/vendor.ts', 7 | 'app': './app/main.ts' 8 | 9 | }, 10 | module: { 11 | rules: [ 12 | { 13 | test: /\.ts?$/, 14 | use: ['ts-loader', 'angular2-template-loader'] 15 | }, 16 | { 17 | test: /\.js?$/, 18 | use: [{ 19 | loader: 'share-loader', 20 | options:{ 21 | modules: [/@angular/, /@uirouter\/angular/], 22 | namespace: 'container-app' 23 | } 24 | }] 25 | } 26 | ] 27 | }, 28 | resolve: { 29 | extensions: ['.ts', '.tsx', '.js', '.html', '.css'], 30 | modules: ['node_modules', 'app'], 31 | mainFields: ["browser", "module", "main"] 32 | }, 33 | devServer: { 34 | historyApiFallback: true 35 | }, 36 | output: { 37 | filename: '[name].js', 38 | path: path.resolve('./dist'), 39 | chunkFilename: '[name].bundle.js' 40 | 41 | }, 42 | 43 | plugins: [ 44 | new HtmlWebpackPlugin({ 45 | template: './app/index.html' 46 | }) 47 | ] 48 | }; -------------------------------------------------------------------------------- /example/shell-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular2-starter-basic", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build:dev": "webpack --progress", 8 | "serve:dev": "webpack-dev-server --progress" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@types/jasmine": "^2.8.6", 15 | "@types/node": "^9.4.1", 16 | "angular2-template-loader": "^0.6.2", 17 | "html-webpack-plugin": "^3.2.0", 18 | "share-loader": "0.2.2", 19 | "ts-loader": "^5.3.3", 20 | "typescript": "^2.7.1", 21 | "webpack": "^4.20.2", 22 | "webpack-cli": "^3.2.3", 23 | "webpack-dev-server": "^3.1.14" 24 | }, 25 | "dependencies": { 26 | "@angular/common": "^7.2.6", 27 | "@angular/compiler": "^7.2.6", 28 | "@angular/core": "^7.2.6", 29 | "@angular/forms": "^5.2.3", 30 | "@angular/http": "^7.2.6", 31 | "@angular/platform-browser": "^7.2.6", 32 | "@angular/platform-browser-dynamic": "^7.2.6", 33 | "@angular/router": "^5.2.4", 34 | "@uirouter/angular": "^1.0.0", 35 | "core-js": "^2.5.3", 36 | "jquery": "^3.4.0", 37 | "rxjs": "^6.4.0", 38 | "rxjs-compat": "^6.4.0", 39 | "zone.js": "^0.8.29" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | /example 61 | /coverage 62 | /dist 63 | /local 64 | /reports 65 | /node_modules 66 | .DS_Store 67 | Thumbs.db 68 | .idea 69 | .iml 70 | .vscode 71 | *.sublime-project 72 | *.sublime-workspace -------------------------------------------------------------------------------- /example/shell-app/app/sLoader.ts: -------------------------------------------------------------------------------- 1 | const _scriptCache = new Map(); 2 | 3 | /** 4 | * Load an external script. 5 | * 6 | * @param {string} url Absolute URL of script to load 7 | * @param {string=} name Name of global variable that the script is expected to define 8 | * @return {Promise} 9 | */ 10 | export function loadScript(url, name, module) { 11 | let promise; 12 | debugger; 13 | if(_scriptCache.has(url)) { 14 | // TODO: normalize URL 15 | promise = _scriptCache.get(url); 16 | } else { 17 | promise = new Promise((resolve,reject) => { 18 | let script = document.createElement('script'); 19 | script.onerror = event => reject(new Error(`Failed to load '${url}'`)); 20 | script.onload = resolve; 21 | script.async = true; 22 | script.src = url; 23 | 24 | if(document.currentScript) { 25 | document.currentScript.parentNode.insertBefore(script, document.currentScript); 26 | } else { 27 | (document.head || document.getElementsByTagName('head')[0]).appendChild(script); 28 | } 29 | }); 30 | 31 | _scriptCache.set(url, promise); 32 | } 33 | 34 | return promise.then(() => { 35 | if(global[name][module]) { 36 | return window[name][module]; 37 | } else { 38 | throw new Error(`"${name}" was not created by "${url}"`); 39 | } 40 | }); 41 | } -------------------------------------------------------------------------------- /example-cli/shell-app/src/app/sLoader.ts: -------------------------------------------------------------------------------- 1 | const _scriptCache = new Map(); 2 | 3 | /** 4 | * Load an external script. 5 | * 6 | * @param {string} url Absolute URL of script to load 7 | * @param {string=} name Name of global variable that the script is expected to define 8 | * @return {Promise} 9 | */ 10 | export function loadScript(url, name, module) { 11 | let promise; 12 | debugger; 13 | if(_scriptCache.has(url)) { 14 | // TODO: normalize URL 15 | promise = _scriptCache.get(url); 16 | } else { 17 | promise = new Promise((resolve,reject) => { 18 | let script = document.createElement('script'); 19 | script.onerror = event => reject(new Error(`Failed to load '${url}'`)); 20 | script.onload = resolve; 21 | script.async = true; 22 | script.src = url; 23 | 24 | if(document.currentScript) { 25 | document.currentScript.parentNode.insertBefore(script, document.currentScript); 26 | } else { 27 | (document.head || document.getElementsByTagName('head')[0]).appendChild(script); 28 | } 29 | }); 30 | 31 | _scriptCache.set(url, promise); 32 | } 33 | 34 | return promise.then(() => { 35 | if(window[name][module]) { 36 | return window[name][module]; 37 | } else { 38 | throw new Error(`"${name}" was not created by "${url}"`); 39 | } 40 | }); 41 | } 42 | -------------------------------------------------------------------------------- /example/ext-app-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular2-starter-basic", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build:prod": "webpack --config webpack.prod.config.js --progress", 8 | "build:dev": "webpack --config webpack.dev.config.js --progress", 9 | "serve:dev": "webpack-dev-server --config webpack.dev.config.js --progress" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@types/jasmine": "^2.8.6", 16 | "@types/node": "^9.4.1", 17 | "angular2-template-loader": "^0.6.2", 18 | "concurrently": "^3.5.1", 19 | "html-webpack-plugin": "^3.2.0", 20 | "lite-server": "^2.3.0", 21 | "share-loader": "^0.3.0", 22 | "ts-loader": "^5.3.3", 23 | "typescript": "^2.7.1", 24 | "webpack": "^4.20.2", 25 | "webpack-cli": "^3.2.3", 26 | "webpack-dev-server": "^3.1.14" 27 | }, 28 | "dependencies": { 29 | "@angular/common": "^7.2.6", 30 | "@angular/compiler": "^7.2.6", 31 | "@angular/core": "^7.2.6", 32 | "@angular/forms": "^5.2.3", 33 | "@angular/http": "^7.2.6", 34 | "@angular/platform-browser": "^7.2.6", 35 | "@angular/platform-browser-dynamic": "^7.2.6", 36 | "@angular/router": "^5.2.3", 37 | "@angular/upgrade": "^5.2.3", 38 | "@uirouter/angular": "^1.0.0", 39 | "core-js": "^2.5.3", 40 | "rxjs": "^6.4.0", 41 | "rxjs-compat": "^6.4.0", 42 | "zone.js": "^0.8.29" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /example-cli/shell-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shell-app", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "start:prod": "ng serve --prod", 8 | "build": "ng build", 9 | "build: prod": "ng build --prod", 10 | "test": "ng test", 11 | "lint": "ng lint", 12 | "e2e": "ng e2e" 13 | }, 14 | "private": true, 15 | "dependencies": { 16 | "@angular/animations": "^7.2.7", 17 | "@angular/common": "^7.2.7", 18 | "@angular/core": "^7.2.7", 19 | "@angular/forms": "^7.2.7", 20 | "@angular/http": "^7.2.7", 21 | "@angular/platform-browser": "^7.2.7", 22 | "@angular/platform-browser-dynamic": "^7.2.7", 23 | "@angular/router": "^7.2.7", 24 | "core-js": "^2.6.5", 25 | "rxjs": "^6.4.0", 26 | "zone.js": "^0.8.26" 27 | }, 28 | "devDependencies": { 29 | "@angular-builders/custom-webpack": "^7.4.1", 30 | "@angular-builders/dev-server": "^7.3.1", 31 | "@angular-devkit/build-angular": "^0.13.9", 32 | "@angular/cli": "^7.3.4", 33 | "@angular/compiler": "^7.2.7", 34 | "@angular/compiler-cli": "^7.2.7", 35 | "@angular/language-service": "^7.2.7", 36 | "@types/jasmine": "~3.3.9", 37 | "@types/jasminewd2": "~2.0.3", 38 | "@types/node": "~11.10.4", 39 | "codelyzer": "~4.5.0", 40 | "jasmine-core": "~3.3.0", 41 | "jasmine-spec-reporter": "~4.2.1", 42 | "karma": "~4.0.1", 43 | "karma-chrome-launcher": "~2.2.0", 44 | "karma-coverage-istanbul-reporter": "~2.0.0", 45 | "karma-jasmine": "~2.0.1", 46 | "karma-jasmine-html-reporter": "^1.4.0", 47 | "mime": "^2.4.0", 48 | "protractor": "~5.4.2", 49 | "share-loader": "^0.6.2", 50 | "ts-node": "~8.0.2", 51 | "tslint": "~5.13.1", 52 | "typescript": "^3.1.1" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /example-cli/ext-app1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ext-app1", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "start:ext": "ng run ext-app1:serve-ext", 8 | "start:ext:prod": "ng run ext-app1:serve-ext-prod", 9 | "build": "ng build", 10 | "build:ext": "ng run ext-app1:build-ext", 11 | "build:ext:prod": "ng run ext-app1:build-ext-prod --configuration=production", 12 | "test": "ng test", 13 | "lint": "ng lint", 14 | "e2e": "ng e2e" 15 | }, 16 | "private": true, 17 | "dependencies": { 18 | "@angular/animations": "^7.2.7", 19 | "@angular/common": "^7.2.7", 20 | "@angular/compiler": "^7.2.7", 21 | "@angular/core": "^7.2.7", 22 | "@angular/forms": "^7.2.7", 23 | "@angular/http": "^7.2.7", 24 | "@angular/platform-browser": "^7.2.7", 25 | "@angular/platform-browser-dynamic": "^7.2.7", 26 | "@angular/router": "^7.2.7", 27 | "core-js": "^2.6.5", 28 | "rxjs": "^6.4.0", 29 | "zone.js": "^0.8.26" 30 | }, 31 | "devDependencies": { 32 | "@angular-builders/custom-webpack": "^7.4.1", 33 | "@angular-builders/dev-server": "^7.3.1", 34 | "@angular-devkit/build-angular": "^0.13.9", 35 | "@angular/cli": "~7.3.4", 36 | "@angular/compiler-cli": "^7.2.7", 37 | "@angular/language-service": "^7.2.7", 38 | "@types/jasmine": "~3.3.9", 39 | "@types/jasminewd2": "~2.0.3", 40 | "@types/node": "~11.10.4", 41 | "codelyzer": "~4.5.0", 42 | "jasmine-core": "~3.3.0", 43 | "jasmine-spec-reporter": "~4.2.1", 44 | "karma": "~4.0.1", 45 | "karma-chrome-launcher": "~2.2.0", 46 | "karma-coverage-istanbul-reporter": "~2.0.0", 47 | "karma-jasmine": "~2.0.1", 48 | "karma-jasmine-html-reporter": "^1.4.0", 49 | "last-call-webpack-plugin": "^3.0.0", 50 | "protractor": "~5.4.2", 51 | "replace-in-file-webpack-plugin": "^1.0.6", 52 | "share-loader": "^0.6.2", 53 | "ts-node": "~8.0.2", 54 | "tslint": "~5.13.1", 55 | "typescript": "^3.1.1", 56 | "webpack-plugin-replace": "^1.2.0" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![npm](https://img.shields.io/npm/v/share-loader.svg?style=flat-square)](https://www.npmjs.com/package/share-loader) 2 | [![npm](https://img.shields.io/npm/dm/share-loader.svg?style=flat-square)](https://www.npmjs.com/package/share-loader) 3 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/MrFrankel/share-loader/blob/master/LICENSE) 4 | 5 |
6 | 7 | 8 | 10 | 11 |

Share Loader

12 |

The share loader allows you to share modules between webpack builds via a global namespace

13 |

14 | 15 |

Install

16 | 17 | ```bash 18 | npm i share-loader --save-dev 19 | ``` 20 | Or 21 | ```bash 22 | yarn add share-loader --save-dev 23 | ``` 24 |

Usage

25 | 26 | webpack config of exposing app 27 | ```js 28 | module: { 29 | rules: [{ 30 | test: /\.js?$/, 31 | use: [{ 32 | loader: 'share-loader', 33 | options: { 34 | modules: [/@angular/, /@uirouter\/angular/], 35 | exclude: [/@angular\/material/], 36 | namespace: 'some-name-space' 37 | } 38 | }] 39 | }] 40 | } 41 | ``` 42 | 43 | 44 | webpack config of consumer apps 45 | 46 | ```js 47 | const {Externals} = require('./share-loader'); 48 | 49 | externals: [ 50 | Externals({ 51 | namespace: 'some-name-space', 52 | modules: [/@angular/, /@uirouter\/angular/] 53 | }) 54 | ], 55 | output: { 56 | library: 'some-name-space', 57 | libraryTarget: 'umd' 58 | } 59 | 60 | 61 | Example 62 | 63 | 1. In the root folder, run npm bootstrap 64 | 2. Run npm run build:prod in the ext-app-1 root 65 | 3. Host the ext1.js file from ext-app-1 project in some localhost server 66 | 4. Change the <%path-to-server-host%> in the shell project app.state.ts 67 | 5. Run npm run serve:dev in the shell project root 68 | 69 | 70 | 71 | Example-cli 72 | 1. In the root folder, run npm bootstrap 73 | 2. In "shell app" folder run npm run start:prod 74 | 3. In the "ext-app1" folder run npm run start:ext:prod 75 | 4. For AOT run npm serve --prod in "shell-app" and npm run serve:ext:prod in "ext-app1" 76 | 5. You can also run ext-app1 in standalone mode with ng serve 77 | ``` -------------------------------------------------------------------------------- /example-cli/ext-app1/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "deprecation": { 15 | "severity": "warn" 16 | }, 17 | "eofline": true, 18 | "forin": true, 19 | "import-blacklist": [ 20 | true, 21 | "rxjs/Rx" 22 | ], 23 | "import-spacing": true, 24 | "indent": [ 25 | true, 26 | "spaces" 27 | ], 28 | "interface-over-type-literal": true, 29 | "label-position": true, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-arg": true, 47 | "no-bitwise": true, 48 | "no-console": [ 49 | true, 50 | "debug", 51 | "info", 52 | "time", 53 | "timeEnd", 54 | "trace" 55 | ], 56 | "no-construct": true, 57 | "no-debugger": true, 58 | "no-duplicate-super": true, 59 | "no-empty": false, 60 | "no-empty-interface": true, 61 | "no-eval": true, 62 | "no-inferrable-types": [ 63 | true, 64 | "ignore-params" 65 | ], 66 | "no-misused-new": true, 67 | "no-non-null-assertion": true, 68 | "no-shadowed-variable": true, 69 | "no-string-literal": false, 70 | "no-string-throw": true, 71 | "no-switch-case-fall-through": true, 72 | "no-trailing-whitespace": true, 73 | "no-unnecessary-initializer": true, 74 | "no-unused-expression": true, 75 | "no-use-before-declare": true, 76 | "no-var-keyword": true, 77 | "object-literal-sort-keys": false, 78 | "one-line": [ 79 | true, 80 | "check-open-brace", 81 | "check-catch", 82 | "check-else", 83 | "check-whitespace" 84 | ], 85 | "prefer-const": true, 86 | "quotemark": [ 87 | true, 88 | "single" 89 | ], 90 | "radix": true, 91 | "semicolon": [ 92 | true, 93 | "always" 94 | ], 95 | "triple-equals": [ 96 | true, 97 | "allow-null-check" 98 | ], 99 | "typedef-whitespace": [ 100 | true, 101 | { 102 | "call-signature": "nospace", 103 | "index-signature": "nospace", 104 | "parameter": "nospace", 105 | "property-declaration": "nospace", 106 | "variable-declaration": "nospace" 107 | } 108 | ], 109 | "unified-signatures": true, 110 | "variable-name": false, 111 | "whitespace": [ 112 | true, 113 | "check-branch", 114 | "check-decl", 115 | "check-operator", 116 | "check-separator", 117 | "check-type" 118 | ], 119 | "no-output-on-prefix": true, 120 | "use-input-property-decorator": true, 121 | "use-output-property-decorator": true, 122 | "use-host-property-decorator": true, 123 | "no-input-rename": true, 124 | "no-output-rename": true, 125 | "use-life-cycle-interface": true, 126 | "use-pipe-transform-interface": true, 127 | "component-class-suffix": true, 128 | "directive-class-suffix": true 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /example-cli/shell-app/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "deprecation": { 15 | "severity": "warn" 16 | }, 17 | "eofline": true, 18 | "forin": true, 19 | "import-blacklist": [ 20 | true, 21 | "rxjs/Rx" 22 | ], 23 | "import-spacing": true, 24 | "indent": [ 25 | true, 26 | "spaces" 27 | ], 28 | "interface-over-type-literal": true, 29 | "label-position": true, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-arg": true, 47 | "no-bitwise": true, 48 | "no-console": [ 49 | true, 50 | "debug", 51 | "info", 52 | "time", 53 | "timeEnd", 54 | "trace" 55 | ], 56 | "no-construct": true, 57 | "no-debugger": true, 58 | "no-duplicate-super": true, 59 | "no-empty": false, 60 | "no-empty-interface": true, 61 | "no-eval": true, 62 | "no-inferrable-types": [ 63 | true, 64 | "ignore-params" 65 | ], 66 | "no-misused-new": true, 67 | "no-non-null-assertion": true, 68 | "no-shadowed-variable": true, 69 | "no-string-literal": false, 70 | "no-string-throw": true, 71 | "no-switch-case-fall-through": true, 72 | "no-trailing-whitespace": true, 73 | "no-unnecessary-initializer": true, 74 | "no-unused-expression": true, 75 | "no-use-before-declare": true, 76 | "no-var-keyword": true, 77 | "object-literal-sort-keys": false, 78 | "one-line": [ 79 | true, 80 | "check-open-brace", 81 | "check-catch", 82 | "check-else", 83 | "check-whitespace" 84 | ], 85 | "prefer-const": true, 86 | "quotemark": [ 87 | true, 88 | "single" 89 | ], 90 | "radix": true, 91 | "semicolon": [ 92 | true, 93 | "always" 94 | ], 95 | "triple-equals": [ 96 | true, 97 | "allow-null-check" 98 | ], 99 | "typedef-whitespace": [ 100 | true, 101 | { 102 | "call-signature": "nospace", 103 | "index-signature": "nospace", 104 | "parameter": "nospace", 105 | "property-declaration": "nospace", 106 | "variable-declaration": "nospace" 107 | } 108 | ], 109 | "unified-signatures": true, 110 | "variable-name": false, 111 | "whitespace": [ 112 | true, 113 | "check-branch", 114 | "check-decl", 115 | "check-operator", 116 | "check-separator", 117 | "check-type" 118 | ], 119 | "no-output-on-prefix": true, 120 | "use-input-property-decorator": true, 121 | "use-output-property-decorator": true, 122 | "use-host-property-decorator": true, 123 | "no-input-rename": true, 124 | "no-output-rename": true, 125 | "use-life-cycle-interface": true, 126 | "use-pipe-transform-interface": true, 127 | "component-class-suffix": true, 128 | "directive-class-suffix": true 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /example-cli/ext-app1/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/weak-map'; 35 | // import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 38 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 39 | 40 | /** IE10 and IE11 requires the following for the Reflect API. */ 41 | // import 'core-js/es6/reflect'; 42 | 43 | 44 | /** Evergreen browsers require these. **/ 45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. 46 | import 'core-js/es7/reflect'; 47 | 48 | 49 | /** 50 | * Web Animations `@angular/platform-browser/animations` 51 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 52 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 53 | **/ 54 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 55 | 56 | /** 57 | * By default, zone.js will patch all possible macroTask and DomEvents 58 | * user can disable parts of macroTask/DomEvents patch by setting following flags 59 | */ 60 | 61 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 62 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 63 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 64 | 65 | /* 66 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 67 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 68 | */ 69 | // (window as any).__Zone_enable_cross_context_check = true; 70 | 71 | /*************************************************************************************************** 72 | * Zone JS is required by default for Angular itself. 73 | */ 74 | import 'zone.js/dist/zone'; // Included with Angular CLI. 75 | 76 | 77 | 78 | /*************************************************************************************************** 79 | * APPLICATION IMPORTS 80 | */ 81 | -------------------------------------------------------------------------------- /example-cli/shell-app/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/weak-map'; 35 | // import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 38 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 39 | 40 | /** IE10 and IE11 requires the following for the Reflect API. */ 41 | // import 'core-js/es6/reflect'; 42 | 43 | 44 | /** Evergreen browsers require these. **/ 45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. 46 | import 'core-js/es7/reflect'; 47 | 48 | 49 | /** 50 | * Web Animations `@angular/platform-browser/animations` 51 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 52 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 53 | **/ 54 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 55 | 56 | /** 57 | * By default, zone.js will patch all possible macroTask and DomEvents 58 | * user can disable parts of macroTask/DomEvents patch by setting following flags 59 | */ 60 | 61 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 62 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 63 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 64 | 65 | /* 66 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 67 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 68 | */ 69 | // (window as any).__Zone_enable_cross_context_check = true; 70 | 71 | /*************************************************************************************************** 72 | * Zone JS is required by default for Angular itself. 73 | */ 74 | import 'zone.js/dist/zone'; // Included with Angular CLI. 75 | 76 | 77 | 78 | /*************************************************************************************************** 79 | * APPLICATION IMPORTS 80 | */ 81 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License http://www.opensource.org/licenses/mit-license.php 3 | Author Maor Frankel 4 | */ 5 | 6 | var path = require('path'); 7 | 8 | function accesorString(value) { 9 | const childProperties = value.split("."); 10 | const length = childProperties.length; 11 | let propertyString = "window"; 12 | let result = ""; 13 | 14 | for (let i = 0; i < length; i++) { 15 | if (i > 0) 16 | result += "if(!" + propertyString + ") " + propertyString + " = {};\n"; 17 | propertyString += "[" + JSON.stringify(childProperties[i]) + "]"; 18 | } 19 | 20 | result += "module.exports = " + propertyString; 21 | return result; 22 | } 23 | 24 | function propertyString(value) { 25 | const childProperties = value.split("."); 26 | const length = childProperties.length; 27 | let propertyString = "window"; 28 | 29 | for (let i = 0; i < length; i++) { 30 | propertyString += "[" + JSON.stringify(childProperties[i]) + "]"; 31 | } 32 | 33 | return propertyString; 34 | } 35 | 36 | module.exports = function (input) { 37 | return input; 38 | }; 39 | 40 | module.exports.pitch = function (remainingRequest) { 41 | // Change the request from an /abolute/path.js to a relative ./path.js 42 | // This prevents [chunkhash] values from changing when running webpack 43 | // builds in different directories. 44 | // this.loadModule('@angular/core', (a,b,c,d) =>{debugger;}); 45 | if (this.query.exclude.some(mdl => this._module.rawRequest.match(new RegExp(mdl)))){ 46 | return; 47 | } 48 | if (this.query.modules && this.query.modules.length 49 | && this.query.modules 50 | .every(mdl => !this._module.rawRequest.match(new RegExp(mdl)))) { 51 | return; 52 | } 53 | const newRequestPath = remainingRequest.replace( 54 | this.resourcePath, 55 | '.' + path.sep + path.relative(this.context, this.resourcePath) 56 | ); 57 | 58 | this.cacheable && this.cacheable(); 59 | if (!this.query || !this.query.namespace || !this.query.modules) throw new Error("query parameter is missing"); 60 | // Determine how to resolve the global object 61 | let request = this._module.rawRequest.split('!'); 62 | 63 | let globalVar; 64 | if (this._module.userRequest.includes('/node_modules/')) { 65 | request = request[request.length - 1].replace(/^@/i, '').replace(/\//g, '.'); 66 | globalVar = `${this.query.namespace.replace(/^\?/i, '')}.${request}`; 67 | } else { //Use modules from parent app 68 | request = request[request.length - 1].replace(/\.\.\//g, '').replace(/\.\//g, '').replace(/\//g, '.'); 69 | globalVar = `${this.query.namespace}.${request}`; 70 | } 71 | 72 | this._module.userRequest = this._module.userRequest + '-shared'; 73 | return accesorString(globalVar) + " = " + 74 | "Object.assign(" + propertyString(globalVar) + " || {}, require(" + JSON.stringify("-!" + newRequestPath) + "));"; 75 | }; 76 | 77 | module.exports.Externals = function (options) { 78 | return function (context, request, callback) { 79 | if (options.modules.every(mdl => !request.match(new RegExp(mdl)))){ 80 | return callback(); 81 | } 82 | if (options.exclude && options.exclude.some(mdl => request.match(new RegExp(mdl)))){ 83 | return callback(); 84 | } 85 | let newRequest = request.split('!'); 86 | newRequest = newRequest[newRequest.length - 1].replace(/^[./@]/i, '').split('/'); 87 | return callback(null, { 88 | root: [options.namespace].concat(newRequest), 89 | commonjs: request, 90 | commonjs2: request, 91 | amd: request 92 | }); 93 | 94 | } 95 | }; -------------------------------------------------------------------------------- /example-cli/shell-app/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "shell-app": { 7 | "root": "", 8 | "sourceRoot": "src", 9 | "projectType": "application", 10 | "prefix": "app", 11 | "schematics": {}, 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-builders/custom-webpack:browser", 15 | "options": { 16 | "customWebpackConfig": { 17 | "path": "./extra-webpack.config.js" 18 | }, 19 | "outputPath": "dist/shell-app", 20 | "index": "src/index.html", 21 | "main": "src/main.ts", 22 | "polyfills": "src/polyfills.ts", 23 | "tsConfig": "src/tsconfig.app.json", 24 | "assets": [ 25 | "src/favicon.ico", 26 | "src/assets" 27 | ], 28 | "styles": [ 29 | "src/styles.css" 30 | ], 31 | "scripts": [] 32 | }, 33 | "configurations": { 34 | "production": { 35 | "fileReplacements": [ 36 | { 37 | "replace": "src/environments/environment.ts", 38 | "with": "src/environments/environment.prod.ts" 39 | } 40 | ], 41 | "optimization": true, 42 | "outputHashing": "all", 43 | "sourceMap": false, 44 | "extractCss": true, 45 | "namedChunks": false, 46 | "aot": true, 47 | "extractLicenses": true, 48 | "vendorChunk": false, 49 | "buildOptimizer": true 50 | } 51 | } 52 | }, 53 | "serve": { 54 | "builder": "@angular-builders/dev-server:generic", 55 | "options": { 56 | "browserTarget": "shell-app:build" 57 | }, 58 | "configurations": { 59 | "production": { 60 | "browserTarget": "shell-app:build:production" 61 | } 62 | } 63 | }, 64 | "extract-i18n": { 65 | "builder": "@angular-devkit/build-angular:extract-i18n", 66 | "options": { 67 | "browserTarget": "shell-app:build" 68 | } 69 | }, 70 | "test": { 71 | "builder": "@angular-devkit/build-angular:karma", 72 | "options": { 73 | "main": "src/test.ts", 74 | "polyfills": "src/polyfills.ts", 75 | "tsConfig": "src/tsconfig.spec.json", 76 | "karmaConfig": "src/karma.conf.js", 77 | "styles": [ 78 | "src/styles.css" 79 | ], 80 | "scripts": [], 81 | "assets": [ 82 | "src/favicon.ico", 83 | "src/assets" 84 | ] 85 | } 86 | }, 87 | "lint": { 88 | "builder": "@angular-devkit/build-angular:tslint", 89 | "options": { 90 | "tsConfig": [ 91 | "src/tsconfig.app.json", 92 | "src/tsconfig.spec.json" 93 | ], 94 | "exclude": [ 95 | "**/node_modules/**" 96 | ] 97 | } 98 | } 99 | } 100 | }, 101 | "shell-app-e2e": { 102 | "root": "e2e/", 103 | "projectType": "application", 104 | "architect": { 105 | "e2e": { 106 | "builder": "@angular-devkit/build-angular:protractor", 107 | "options": { 108 | "protractorConfig": "e2e/protractor.conf.js", 109 | "devServerTarget": "shell-app:serve" 110 | }, 111 | "configurations": { 112 | "production": { 113 | "devServerTarget": "shell-app:serve:production" 114 | } 115 | } 116 | }, 117 | "lint": { 118 | "builder": "@angular-devkit/build-angular:tslint", 119 | "options": { 120 | "tsConfig": "e2e/tsconfig.e2e.json", 121 | "exclude": [ 122 | "**/node_modules/**" 123 | ] 124 | } 125 | } 126 | } 127 | } 128 | }, 129 | "defaultProject": "shell-app" 130 | } -------------------------------------------------------------------------------- /example-cli/ext-app1/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "ext-app1": { 7 | "root": "", 8 | "sourceRoot": "src", 9 | "projectType": "application", 10 | "prefix": "", 11 | "schematics": {}, 12 | "architect": { 13 | "build-ext": { 14 | "builder": "@angular-builders/custom-webpack:browser", 15 | "options": { 16 | "customWebpackConfig": { 17 | "path": "./extra-webpack.config.js", 18 | "mergeStrategies": { "entry": "replace","output": "replace", "externals": "replace" } 19 | }, 20 | "outputPath": "dist", 21 | "index": "src/index.html", 22 | "main": "src/app/app.external.module.ts", 23 | "tsConfig": "src/tsconfig.app.json", 24 | "assets": [ 25 | "src/favicon.ico", 26 | "src/assets" 27 | ], 28 | "styles": [ 29 | "src/styles.css" 30 | ], 31 | "scripts": [], 32 | "optimization": false, 33 | "outputHashing": "none", 34 | "sourceMap": false, 35 | "extractCss": false, 36 | "namedChunks": false, 37 | "aot": false, 38 | "extractLicenses": false, 39 | "vendorChunk": false, 40 | "buildOptimizer": false 41 | } 42 | }, 43 | "build-ext-prod": { 44 | "builder": "@angular-builders/custom-webpack:browser", 45 | "options": { 46 | "customWebpackConfig": { 47 | "path": "./extra-webpack.prod.config.js", 48 | "mergeStrategies": { "plugins": "prepend","output": "replace", "externals": "replace" } 49 | }, 50 | "outputPath": "dist", 51 | "index": "src/index.html", 52 | "main": "src/main.prod.ts", 53 | "tsConfig": "src/tsconfig.app.json", 54 | "assets": [ 55 | "src/favicon.ico", 56 | "src/assets" 57 | ], 58 | "styles": [ 59 | "src/styles.css" 60 | ], 61 | "scripts": [], 62 | "optimization": true, 63 | "outputHashing": "none", 64 | "sourceMap": false, 65 | "extractCss": false, 66 | "namedChunks": false, 67 | "aot": true, 68 | "extractLicenses": false, 69 | "vendorChunk": false, 70 | "buildOptimizer": true 71 | } 72 | }, 73 | "build": { 74 | "builder": "@angular-devkit/build-angular:browser", 75 | "options": { 76 | "outputPath": "dist/ext-app1", 77 | "index": "src/index.html", 78 | "main": "src/main.ts", 79 | "polyfills": "src/polyfills.ts", 80 | "tsConfig": "src/tsconfig.app.json", 81 | "assets": [ 82 | "src/favicon.ico", 83 | "src/assets" 84 | ], 85 | "styles": [ 86 | "src/styles.css" 87 | ], 88 | "scripts": [] 89 | }, 90 | "configurations": { 91 | "production": { 92 | "fileReplacements": [ 93 | { 94 | "replace": "src/environments/environment.ts", 95 | "with": "src/environments/environment.prod.ts" 96 | } 97 | ], 98 | "optimization": true, 99 | "outputHashing": "all", 100 | "sourceMap": false, 101 | "extractCss": true, 102 | "namedChunks": false, 103 | "aot": true, 104 | "extractLicenses": true, 105 | "vendorChunk": false, 106 | "buildOptimizer": true 107 | } 108 | } 109 | }, 110 | "serve": { 111 | "builder": "@angular-builders/dev-server:generic", 112 | "options": { 113 | "port": 4300, 114 | "browserTarget": "ext-app1:build" 115 | } 116 | }, 117 | "serve-ext": { 118 | "builder": "@angular-builders/dev-server:generic", 119 | "options": { 120 | "port": 4300, 121 | "browserTarget": "ext-app1:build-ext" 122 | } 123 | }, 124 | "serve-ext-prod": { 125 | "builder": "@angular-builders/dev-server:generic", 126 | "options": { 127 | "port": 4300, 128 | "browserTarget": "ext-app1:build-ext-prod" 129 | } 130 | }, 131 | "extract-i18n": { 132 | "builder": "@angular-devkit/build-angular:extract-i18n", 133 | "options": { 134 | "browserTarget": "ext-app1:build" 135 | } 136 | }, 137 | "test": { 138 | "builder": "@angular-devkit/build-angular:karma", 139 | "options": { 140 | "main": "src/test.ts", 141 | "polyfills": "src/polyfills.ts", 142 | "tsConfig": "src/tsconfig.spec.json", 143 | "karmaConfig": "src/karma.conf.js", 144 | "styles": [ 145 | "src/styles.css" 146 | ], 147 | "scripts": [], 148 | "assets": [ 149 | "src/favicon.ico", 150 | "src/assets" 151 | ] 152 | } 153 | }, 154 | "lint": { 155 | "builder": "@angular-devkit/build-angular:tslint", 156 | "options": { 157 | "tsConfig": [ 158 | "src/tsconfig.app.json", 159 | "src/tsconfig.spec.json" 160 | ], 161 | "exclude": [ 162 | "**/node_modules/**" 163 | ] 164 | } 165 | } 166 | } 167 | }, 168 | "ext-app1-e2e": { 169 | "root": "e2e/", 170 | "projectType": "application", 171 | "architect": { 172 | "e2e": { 173 | "builder": "@angular-devkit/build-angular:protractor", 174 | "options": { 175 | "protractorConfig": "e2e/protractor.conf.js", 176 | "devServerTarget": "ext-app1:serve" 177 | }, 178 | "configurations": { 179 | "production": { 180 | "devServerTarget": "ext-app1:serve:production" 181 | } 182 | } 183 | }, 184 | "lint": { 185 | "builder": "@angular-devkit/build-angular:tslint", 186 | "options": { 187 | "tsConfig": "e2e/tsconfig.e2e.json", 188 | "exclude": [ 189 | "**/node_modules/**" 190 | ] 191 | } 192 | } 193 | } 194 | } 195 | }, 196 | "defaultProject": "ext-app1" 197 | } 198 | --------------------------------------------------------------------------------