-
Create new repo in gitlab
-
Clone it locally
-
Create .babelrc in project root:
{
"presets": [
"@babel/preset-env",
| /* Util functions | |
| */ | |
| /* Use this function to check that the hash begins with a certain prefix | |
| */ | |
| export function hashPrefix(location, ...prefixes) { | |
| return prefixes.some(prefix => location.hash.indexOf(`#/${prefix}`) === 0); | |
| } | |
| /* App-specific implementations that determine if they are active or not. |
| import * as isActive from './child-app-active.functions.js'; | |
| import * as singleSpa from 'single-spa' | |
| // Main-content apps | |
| singleSpa.registerApplication('workflow-ui', () => SystemJS.import('workflow-ui!sofe'), isActive.workflowUI); | |
| singleSpa.registerApplication('end-user-forms-ui', () => SystemJS.import('end-user-forms-ui!sofe'), isActive.endUserFormsUI); | |
| singleSpa.registerApplication('sme-qa-ui', () => SystemJS.import('sme-qa-ui!sofe'), isActive.smeQAUI); | |
| singleSpa.registerApplication('letters-ui', () => SystemJS.import('letters-ui!sofe'), isActive.lettersUI); | |
| singleSpa.registerApplication('docs-ui', () => SystemJS.import('docs-ui!sofe'), isActive.docsUI); |
| // The things imported with ES6 are things we want to execute right up front. | |
| // The things required below are things we want to execute only when someone needs them. | |
| // Switching between the two impacts performance. In general, it's better to be lazy with | |
| // executing code, but there are some things we need to do right up front. | |
| import SystemJS from 'systemjs' | |
| if (window.sofeManifest) { | |
| SystemJS.config(sofeManifest) | |
| delete window.sofeManifest | |
| } |
| <!DOCTYPE html> | |
| <html lang="en" style="width: 100%; min-height: 100%;"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
| <meta name="description" content=""> | |
| <meta name="author" content="Your devoted Canopian engineering team"> | |
| <title> | |
| Canopy: Delightful Client Management | |
| </title> |
| import {Parcel} from 'single-spa-react/parcel' | |
| import parcelConfig from './other-file.js' | |
| import {mountRootParcel} from 'single-spa' | |
| function MyReactComponent(props) { | |
| // The parcelConfig could be implemented in Angular, Vue, or anything else, | |
| // but it works inside of a React component! | |
| return ( | |
| <div> | |
| Lets render a parcel with jsx! |
| const parcel = singleSpa.mountRootParcel(parcelConfig, parcelProps) | |
| // First wait for mounting to finish | |
| parcel.mountPromise.then(() => { | |
| // Then re-render the parcel | |
| const newProps = {foo: 'bar'} | |
| return parcel.update(newProps) | |
| }).then(() => { | |
| // Then unmount the parcel | |
| return parcel.unmount() |
| /* | |
| The goal of the following code is to render the text “Copied!” when you click on a div. | |
| After two seconds, you want to change the text to say “Something else.” | |
| However, there is a bug which makes “Something else” never render. The reason why is that | |
| React considers the StyledDiv to be a new type of element every time that Parent rerenders. | |
| And one of React's reconciliation heuristics is to unmount/remount whenever the top level | |
| returned child is a different type of element. So by the time the setTimeout happens, we are calling | |
| setState on an already unmounted component. A new Child component has been created, with the initial state saying | |
| "Copied!" |
| /* NOTE: that this code was written for https://github.com/CanopyTax and some parts might not be suitable for the generic use case. | |
| It assumes that string data can be passed as both a property or an html attribute, and it prefers properties over attributes for everything. | |
| USAGE: | |
| - <x-foo attr1="'string'" /> | |
| - <button is="my-button" /> | |
| - <x-foo attr2="objOnScope" /> | |
| */ | |
| import angular from 'angular'; | |
| import {forEach, kebabCase, includes} from 'lodash'; |
| // single-spa will import this file and call the exported lifecyle functions | |
| let user; | |
| export function bootstrap() { | |
| return fetch('/api/users/0') | |
| .then(response => response.json()) | |
| .then(json => user = json); | |
| } |