Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parcel fixes #171

Merged
merged 8 commits into from
Apr 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 19 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,32 @@ To test out the angular schematics locally, run the following commands:
```sh
# First, fork the single-spa-angular repo and clone it.
# Then run the following commands inside of the single-spa-angular directory.
npm install
npm run build
npm link
yarn install
yarn build

## Now link the built files
cd lib
yarn link

# Now navigate to a new directory where we'll create an angular application to test this with
cd ..
cd ../..

## Now create an angular app
ng new

## Now install single-spa-angular from local file instead of npm, including running the schematics
npm link single-spa-angular
## This project uses yarn, so it's easiest to use yarn in your example project, too
yarn install

yarn link single-spa-angular

## Run the schematics
ng g single-spa-angular:ng-add
# Relink single-spa-angular (yes, it's necessary)
npm link single-spa-angular

## Install dependencies
yarn add single-spa
yarn add file:../single-spa-angular/lib

## Now try things out!
ng build
ng serve
yarn build
yarn start
```
27 changes: 12 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,34 @@
"private": true,
"scripts": {
"prepublishOnly": "yarn build && yarn test",
"clean": "rimraf lib pacel",
"build": "run-s clean build:single-spa-angular build:webpack build:schematics",
"test": "yarn clean && yarn jest",
"lint": "eslint ./src/**/*.ts",
":copy-schematic-files": "cpx \"src/**/_files/**/**\" lib",
"parcel": "ngc -p tsconfig.parcel.json",
"clean": "rimraf lib",
"build": "yarn clean && yarn build:single-spa-angular && concurrently yarn:build:schematics yarn:build:webpack",
"test": "yarn clean && jest",
"lint": "eslint src --ext ts",
"// - SINGLE-SPA-ANGULAR": "Scripts for building single-spa-angular",
"build:single-spa-angular": "yarn ts-node tools/build",
"build:single-spa-angular": "ng-packagr -p src/package.json",
"// - WEBPACK": "Scripts for building Webpack config transformer",
"prebuild:webpack": "rimraf lib/lib",
"build:webpack": "tsc -p tsconfig.webpack.json",
"// - SCHEMATICS": "Scripts for building schematics and copying its files",
"prebuild:schematics": "rimraf lib/schematics",
"build:schematics": "tsc -p tsconfig.schematics.json && run-s copy:schematics:*",
"build:schematics": "tsc -p tsconfig.schematics.json && concurrently yarn:copy:schematics:*",
"copy:schematics:json": "cpx schematics/schematics.json lib/schematics",
"copy:schematics:schema": "cpx \"schematics/ng-add/schema*\" lib/schematics/ng-add",
"copy:schematics:files": "cpx \"schematics/ng-add/_files/**/**\" lib/schematics/ng-add/_files",
"format": "prettier './**/*' --write",
"// - INTEGRATION INSTALLS": "Install packages for integration apps",
"install:integration:shop": "yarn --cwd integration/shop install",
"install:integration:portal": "yarn --cwd integration/portal install",
"install:integration": "run-s install:integration:shop install:integration:portal",
"install:integration": "concurrently yarn:install:integration:shop yarn:install:integration:portal",
"// - INTEGRATION BUILDS": "Build apps that are required for E2E testing #requires yarn install:integration",
"build:integration:shop": "yarn --cwd integration/shop build:single-spa",
"build:integration:portal": "yarn --cwd integration/portal build:prod",
"build:integration": "run-s build:integration:shop build:integration:portal",
"build:integration": "concurrently yarn:build:integration:shop yarn:build:integration:portal",
"// - APPS": "Serve apps that are required for E2E testing #requires yarn build:integration",
"start:integration": "concurrently -n w: yarn:start:integration:*",
"start:integration:shop": "yarn serve integration/shop/dist -s -l 4200 --cors",
"start:integration:portal": "yarn serve integration/portal/dist -s -l 8080",
"start:integration:shop": "serve integration/shop/dist -s -l 4200 --cors",
"start:integration:portal": "serve integration/portal/dist -s -l 8080",
"// - E2E": "E2E testing",
"cy:open": "cypress open --config integrationFolder=cypress/integration",
"cy:run": "cypress run --config integrationFolder=cypress/integration",
Expand Down Expand Up @@ -95,20 +93,19 @@
"jest": "^24.5.0",
"lint-staged": "^10.1.3",
"ng-packagr": "^9.1.0",
"npm-run-all": "^4.1.5",
arturovt marked this conversation as resolved.
Show resolved Hide resolved
"prettier": "^2.0.4",
"rimraf": "^2.6.2",
"rxjs": "~6.5.5",
"serve": "^11.3.0",
"start-server-and-test": "^1.10.11",
"start-server-and-test": "^1.11.0",
"ts-jest": "^24.0.0",
"tsickle": "^0.38.1",
"tslib": "^1.11.1",
"typescript": "3.7.5",
"zone.js": "~0.10.3"
},
"dependencies": {
"single-spa": ">= 5.1.1"
"single-spa": ">= 4"
arturovt marked this conversation as resolved.
Show resolved Hide resolved
},
"prettier": {
"semi": true,
Expand Down
68 changes: 31 additions & 37 deletions src/src/parcel-lib/parcel.component.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,41 @@
import {
Component,
OnInit,
OnDestroy,
Input,
OnChanges,
ViewChild,
ElementRef,
} from '@angular/core';
import { Parcel, ParcelConfig } from 'single-spa';
import { Component, OnInit, OnDestroy, Input, OnChanges, ElementRef } from '@angular/core';
import { Parcel, ParcelConfig, AppProps } from 'single-spa';

@Component({
selector: 'parcel',
template: ` <div #parcelDiv></div> `,
template: '<div></div>',
})
export class ParcelComponent implements OnInit, OnDestroy, OnChanges {
@ViewChild('parcelDiv') parcelDiv: ElementRef;
@Input() config: ParcelConfig;
@Input() mountParcel: any;
@Input() onParcelMount: () => void;
@Input() config!: ParcelConfig;
@Input() mountParcel!: AppProps['mountParcel'];
@Input() onParcelMount: (() => void) | null = null;
@Input() wrapWith = 'div';
@Input() customProps: any;
@Input() appendTo: any;
@Input() handleError = err => console.error(err);
@Input() customProps: object = {};
@Input() appendTo: Node | null = null;
@Input() handleError = (error: Error) => console.error(error);

createdDomElement: any;
hasError: boolean;
unmounted: any;
nextThingToDo: Promise<any>;
parcel: Parcel;
createdDomElement: HTMLElement | null = null;
hasError = false;
unmounted = true;
nextThingToDo!: Promise<any>;
parcel!: Parcel;

constructor() {}
// eslint-disable-next-line @typescript-eslint/no-parameter-properties
constructor(private host: ElementRef<HTMLElement>) {}

ngOnInit() {
if (!this.config) {
throw new Error(
`single-spa-angular's Parcel component requires the 'config' prop to either be a parcel config or a loading function that returns a promise. See https://github.com/CanopyTax/single-spa-angular`,
`single-spa-angular's Parcel component requires the [config] binding to either be a parcel config or a loading function that returns a promise. See https://github.com/CanopyTax/single-spa-angular`,
);
}

this.addThingToDo('mount', () => {
const mountParcel = this.mountParcel;
if (!mountParcel) {
throw new Error(`
<parcel> was not passed a mountParcel prop.
If you are using <parcel> within a module that is not a single-spa application, you will need to import mountRootParcel from single-spa and pass it into <parcel> as a mountParcel prop
<parcel> was not passed a [mountParcel] binding.
If you are using <parcel> within a module that is not a single-spa application, you will need to import mountRootParcel from single-spa and pass it into <parcel> as a [mountParcel] binding
`);
}
let domElement: HTMLElement;
Expand All @@ -53,7 +45,9 @@ export class ParcelComponent implements OnInit, OnDestroy, OnChanges {
this.appendTo.appendChild(domElement);
} else {
this.createdDomElement = domElement = document.createElement(this.wrapWith);
this.parcelDiv.nativeElement.appendChild(domElement);
// Except of having `@ViewChild` we can simply get the first child element.
const parcelDiv = this.host.nativeElement.children[0];
parcelDiv.appendChild(domElement);
}

this.parcel = mountParcel(this.config, { domElement, ...this.customProps });
Expand Down Expand Up @@ -82,13 +76,13 @@ export class ParcelComponent implements OnInit, OnDestroy, OnChanges {
});

if (this.createdDomElement) {
this.createdDomElement.parentNode.removeChild(this.createdDomElement);
this.createdDomElement.parentNode!.removeChild(this.createdDomElement);
}

this.unmounted = true;
}

addThingToDo(action, thing) {
addThingToDo(action: string, thing: Function) {
if (this.hasError && action !== 'unmount') {
// In an error state, we don't do anything anymore except for unmounting
return;
Expand All @@ -103,24 +97,24 @@ export class ParcelComponent implements OnInit, OnDestroy, OnChanges {

return thing(...args);
})
.catch(err => {
.catch(error => {
this.nextThingToDo = Promise.resolve(); // reset so we don't .then() the bad promise again
this.hasError = true;

if (err && err.message) {
err.message = `During '${action}', parcel threw an error: ${err.message}`;
if (error && error.message) {
error.message = `During '${action}', parcel threw an error: ${error.message}`;
}

if (this.handleError) {
this.handleError(err);
if (typeof this.handleError === 'function') {
this.handleError(error);
} else {
setTimeout(() => {
throw err;
throw error;
});
}

// No more things to do should be done -- the parcel is in an error state
throw err;
throw error;
});
}
}
2 changes: 2 additions & 0 deletions src/src/public_api.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export { singleSpaAngular } from './single-spa-angular';
export { getSingleSpaExtraProviders } from './extra-providers';
export { ParcelModule } from './parcel-lib/index';
export { ParcelComponent } from './parcel-lib/parcel.component';
12 changes: 0 additions & 12 deletions tsconfig.parcel.json

This file was deleted.

49 changes: 8 additions & 41 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7435,11 +7435,6 @@ memory-fs@^0.5.0:
errno "^0.1.3"
readable-stream "^2.0.1"

memorystream@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2"
integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI=

meow@5.0.0, meow@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4"
Expand Down Expand Up @@ -8023,21 +8018,6 @@ npm-registry-fetch@^8.0.0:
minizlib "^2.0.0"
npm-package-arg "^8.0.0"

npm-run-all@^4.1.5:
version "4.1.5"
resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba"
integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==
dependencies:
ansi-styles "^3.2.1"
chalk "^2.4.1"
cross-spawn "^6.0.5"
memorystream "^0.3.1"
minimatch "^3.0.4"
pidtree "^0.3.0"
read-pkg "^3.0.0"
shell-quote "^1.6.1"
string.prototype.padend "^3.0.0"

npm-run-path@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
Expand Down Expand Up @@ -8594,11 +8574,6 @@ picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==

pidtree@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a"
integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==

pify@^2.0.0, pify@^2.2.0, pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
Expand Down Expand Up @@ -10142,10 +10117,10 @@ simple-swizzle@^0.2.2:
dependencies:
is-arrayish "^0.3.1"

"single-spa@>= 5.1.1":
version "5.3.1"
resolved "https://registry.yarnpkg.com/single-spa/-/single-spa-5.3.1.tgz#ca11d7070d4fd8148f97f59adfdb0135db619a1e"
integrity sha512-UgoLq0Dl3Up5tgR1F/CBbY76eVZKeg/rH3dFf/MoL6NT+jYkgvpujb1LRL1bnShInZGMBPSiz7NW7FgtC6SuUQ==
"single-spa@>= 4":
version "5.3.2"
resolved "https://registry.yarnpkg.com/single-spa/-/single-spa-5.3.2.tgz#dfc0b97145819a77e7c2777ddcc9fb8fe639c234"
integrity sha512-3FKoXRkWbluoHI9eZ05KecsJqfXHaSSYeh3+Z0WlSwzm8YCpZYIyr8RM4U+5sp+q69X9wrY7+wEmnarvaiyO4A==

sisteransi@^1.0.4:
version "1.0.5"
Expand Down Expand Up @@ -10451,10 +10426,10 @@ stack-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8"
integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==

start-server-and-test@^1.10.11:
version "1.10.11"
resolved "https://registry.yarnpkg.com/start-server-and-test/-/start-server-and-test-1.10.11.tgz#24290ee8a5ed15f4a34e9bb45a5d6ff93c93c83e"
integrity sha512-CZilaj293uQWdD4vgOxTOuzlCWxOyBm6bzmH1r6OGLG/q5zcBmGYevLfOimkg0kSn9jLHwYSXLuoKG/DDQJhww==
start-server-and-test@^1.11.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/start-server-and-test/-/start-server-and-test-1.11.0.tgz#1b1a83d062b0028ee6e296bb4e0231f2d8b2f4af"
integrity sha512-FhkJFYL/lvbd0tKWvbxWNWjtFtq3Zpa09QDjA8EUH88AsgNL4hkAAKYNmbac+fFM8/GIZoJ1Mj4mm3SMI0X1bA==
dependencies:
bluebird "3.7.2"
check-more-types "2.24.0"
Expand Down Expand Up @@ -10574,14 +10549,6 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.0"

string.prototype.padend@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.0.tgz#dc08f57a8010dc5c153550318f67e13adbb72ac3"
integrity sha512-3aIv8Ffdp8EZj8iLwREGpQaUZiPyrWrpzMBHvkiSW/bK/EGve9np07Vwy7IJ5waydpGXzQZu/F8Oze2/IWkBaA==
dependencies:
define-properties "^1.1.3"
es-abstract "^1.17.0-next.1"

string.prototype.trimend@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.0.tgz#ee497fd29768646d84be2c9b819e292439614373"
Expand Down