Skip to content

Commit

Permalink
Using eslint, prettier, and pre-commit hooks (#30)
Browse files Browse the repository at this point in the history
* Using CSS.escape instead of manual (incomplete) escaping of selector

* Adding lint, prettier, and pre-commit hook

* Self review

* Fixing typo in build

* Reinstating terser
  • Loading branch information
joeldenning authored Jan 10, 2020
1 parent 7650ca4 commit 6faf1d6
Show file tree
Hide file tree
Showing 10 changed files with 2,425 additions and 1,616 deletions.
4 changes: 4 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": ["important-stuff", "plugin:prettier/recommended"],
"parser": "babel-eslint"
}
5 changes: 5 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.prettierignore
.gitignore
lib
LICENSE
yarn.lock
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
language: node_js
node_js:
- "node"
script: yarn test && yarn build
script: yarn test && yarn lint && yarn build
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# single-spa-vue

[![Build Status](https://travis-ci.org/CanopyTax/single-spa-vue.svg?branch=master)](https://travis-ci.org/CanopyTax/single-spa-vue)

Generic lifecycle hooks for Vue.js applications that are registered as [applications](https://github.com/CanopyTax/single-spa/blob/master/docs/applications.md#registered-applications) of [single-spa](https://github.com/CanopyTax/single-spa).
Expand Down
30 changes: 23 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@
"scripts": {
"prepublishOnly": "yarn build",
"build": "rimraf lib && rollup -c",
"test": "jest"
"test": "jest",
"prettier": "prettier --write './**'",
"lint": "eslint src"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged && concurrently -n yarn:test yarn:lint"
}
},
"repository": {
"type": "git",
Expand All @@ -33,15 +40,24 @@
},
"homepage": "https://github.com/blittle/single-spa-vuejs#readme",
"devDependencies": {
"@babel/core": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@babel/core": "^7.7.7",
"@babel/preset-env": "^7.7.7",
"@rollup/plugin-commonjs": "^11.0.1",
"@rollup/plugin-node-resolve": "^7.0.0",
"@types/jest": "^24.0.15",
"babel-jest": "^24.8.0",
"@types/jest": "^24.0.25",
"babel-eslint": "^10.0.3",
"babel-jest": "^25.0.0",
"concurrently": "^5.0.2",
"css.escape": "^1.5.1",
"jest": "^24.8.0",
"rimraf": "^2.6.3",
"eslint": "^6.8.0",
"eslint-config-important-stuff": "^1.1.0",
"eslint-config-prettier": "^6.9.0",
"eslint-plugin-prettier": "^3.1.2",
"husky": "^4.0.6",
"jest": "^24.9.0",
"prettier": "^1.19.1",
"pretty-quick": "^2.0.1",
"rimraf": "^3.0.0",
"rollup": "^1.29.0",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-terser": "^5.1.3"
Expand Down
20 changes: 10 additions & 10 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import babel from 'rollup-plugin-babel'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'
import babel from "rollup-plugin-babel";
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import { terser } from "rollup-plugin-terser";

export default {
input: './src/single-spa-vue.js',
input: "./src/single-spa-vue.js",
output: {
dir: 'lib',
name: 'singleSpaVue',
dir: "lib",
name: "singleSpaVue",
sourcemap: true,
format: 'umd'
format: "umd"
},
plugins: [
babel({
exclude: 'node_modules/**'
exclude: "node_modules/**"
}),
resolve(),
commonjs(),
terser()
]
}
};
122 changes: 60 additions & 62 deletions src/single-spa-vue.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import 'css.escape'
import "css.escape";

const defaultOpts = {
// required opts
Vue: null,
appOptions: null,
template: null,
}
template: null
};

export default function singleSpaVue(userOpts) {
if (typeof userOpts !== 'object') {
if (typeof userOpts !== "object") {
throw new Error(`single-spa-vue requires a configuration object`);
}

const opts = {
...defaultOpts,
...userOpts,
...userOpts
};

if (!opts.Vue) {
throw new Error('single-spa-vuejs must be passed opts.Vue');
throw new Error("single-spa-vuejs must be passed opts.Vue");
}

if (!opts.appOptions) {
throw new Error('single-spa-vuejs must be passed opts.appOptions');
throw new Error("single-spa-vuejs must be passed opts.appOptions");
}

// Just a shared object to store the mounted object state
Expand All @@ -32,90 +32,88 @@ export default function singleSpaVue(userOpts) {
bootstrap: bootstrap.bind(null, opts, mountedInstances),
mount: mount.bind(null, opts, mountedInstances),
unmount: unmount.bind(null, opts, mountedInstances),
update: update.bind(null, opts, mountedInstances),
update: update.bind(null, opts, mountedInstances)
};
}

function bootstrap(opts) {
if (opts.loadRootComponent) {
return opts.loadRootComponent().then(root => opts.rootComponent = root)
return opts.loadRootComponent().then(root => (opts.rootComponent = root));
} else {
return Promise.resolve();
}
}

function mount(opts, mountedInstances, props) {
return Promise
.resolve()
.then(() => {
const appOptions = {...opts.appOptions}
if (props.domElement && !appOptions.el) {
appOptions.el = props.domElement;
}
return Promise.resolve().then(() => {
const appOptions = { ...opts.appOptions };
if (props.domElement && !appOptions.el) {
appOptions.el = props.domElement;
}

if (!appOptions.el) {
const htmlId = `single-spa-application:${props.name}`
appOptions.el = `#${CSS.escape(htmlId)} .single-spa-container`
let domEl = document.getElementById(htmlId)
if (!domEl) {
domEl = document.createElement('div')
domEl.id = htmlId
document.body.appendChild(domEl)
}

// single-spa-vue@>=2 always REPLACES the `el` instead of appending to it.
// We want domEl to stick around and not be replaced. So we tell Vue to mount
// into a container div inside of the main domEl
if (!domEl.querySelector('.single-spa-container')) {
const singleSpaContainer = document.createElement('div')
singleSpaContainer.className = 'single-spa-container'
domEl.appendChild(singleSpaContainer)
}

mountedInstances.domEl = domEl
if (!appOptions.el) {
const htmlId = `single-spa-application:${props.name}`;
appOptions.el = `#${CSS.escape(htmlId)} .single-spa-container`;
let domEl = document.getElementById(htmlId);
if (!domEl) {
domEl = document.createElement("div");
domEl.id = htmlId;
document.body.appendChild(domEl);
}

if (!appOptions.render && !appOptions.template && opts.rootComponent) {
appOptions.render = (h) => h(opts.rootComponent)
// single-spa-vue@>=2 always REPLACES the `el` instead of appending to it.
// We want domEl to stick around and not be replaced. So we tell Vue to mount
// into a container div inside of the main domEl
if (!domEl.querySelector(".single-spa-container")) {
const singleSpaContainer = document.createElement("div");
singleSpaContainer.className = "single-spa-container";
domEl.appendChild(singleSpaContainer);
}

if (!appOptions.data) {
appOptions.data = {}
}
mountedInstances.domEl = domEl;
}

appOptions.data = {...appOptions.data, ...props}
if (!appOptions.render && !appOptions.template && opts.rootComponent) {
appOptions.render = h => h(opts.rootComponent);
}

mountedInstances.instance = new opts.Vue(appOptions);
if (mountedInstances.instance.bind) {
mountedInstances.instance = mountedInstances.instance.bind(mountedInstances.instance);
}
return mountedInstances.instance;
})
if (!appOptions.data) {
appOptions.data = {};
}

appOptions.data = { ...appOptions.data, ...props };

mountedInstances.instance = new opts.Vue(appOptions);
if (mountedInstances.instance.bind) {
mountedInstances.instance = mountedInstances.instance.bind(
mountedInstances.instance
);
}
return mountedInstances.instance;
});
}

function update(opts, mountedInstances, props) {
return Promise.resolve().then(() => {
const data = {
...(opts.appOptions.data || {}),
...props,
...props
};
for (let prop in data) {
mountedInstances.instance[prop] = data[prop];
}
})
});
}

function unmount(opts, mountedInstances) {
return Promise
.resolve()
.then(() => {
mountedInstances.instance.$destroy();
mountedInstances.instance.$el.innerHTML = '';
delete mountedInstances.instance;

if (mountedInstances.domEl) {
mountedInstances.domEl.innerHTML = ''
delete mountedInstances.domEl
}
})
return Promise.resolve().then(() => {
mountedInstances.instance.$destroy();
mountedInstances.instance.$el.innerHTML = "";
delete mountedInstances.instance;

if (mountedInstances.domEl) {
mountedInstances.domEl.innerHTML = "";
delete mountedInstances.domEl;
}
});
}
Loading

0 comments on commit 6faf1d6

Please sign in to comment.