Skip to content

Instantly share code, notes, and snippets.

View joeldenning's full-sized avatar
🎯
Focusing

Joel Denning joeldenning

🎯
Focusing
View GitHub Profile

Creating a new single-spa subapp

  1. Create new repo in gitlab

  2. Clone it locally

  3. 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>
@joeldenning
joeldenning / single-spa-react-parcel-example.jsx
Last active June 21, 2022 14:20
single-spa-react parcel example
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!
@joeldenning
joeldenning / parcel-example.js
Created June 16, 2018 21:30
single-spa parcel basic example
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()
@joeldenning
joeldenning / gnarly-bug.js
Last active February 8, 2018 20:01
styled-components inside of render
/*
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!"
@joeldenning
joeldenning / custom-elements.directive.js
Created February 5, 2018 23:37
Angular custom elements support
/* 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);
}