The UnFramework for Single Page Web Applications
By the author of Single Page Web Applications, JavaScript end-to-end, a Dr. Dobb's Best Book of 2014.
Like other Single Page Web App (SPA) frameworks, hi_score
provides an
enormous head-start in creating professional, release-ready applications. Yet
it is profoundly different from most of them in almost every other way.
The hi_score
framework helps developers create, understand, and constantly
improve the core technologies used by their SPAs instead of locking them
into a large and non-portable ecosystem. It uses a zero-transpile
development environment while still providing a rich set of capabilities
such as life-cycle management, type safety, run-time CSS, and state
management. It consumes far fewer resources and is productive with just a
text editor, a terminal, and a browser. Easy problems are easy to solve, and
hard problems are possible.
A framework should serve you, not the other way around. You should be free to move your web app to other environments without complex migration away from non-portable dead-end pseudo-languages. You shouldn't be forced to rewrite / refactor / debug all your apps every time your framework releases a new version.
If your framework is making your life more complex, if your teams can't
communicate because they are using competing Towers of
Babel, perhaps its time to use hi_score
so they can all
speak the same languages your apps actually use.
Version 1.7.12 enhancements:
- (x)
js/xhi/01_util
Add return map option to method_makeTmpltStr_
. This reports the keys actually used in a given operation through the map reference that is passed. If no map reference is passed, this function operates exactly as before.
On Mac, Ubuntu Linux, or WSL please follow these steps.
- Ensure prerequisites are met
- Enter the following commands into the terminal one at a time
git clone [email protected]:mmikowski/hi_score.git
cd hi_score
bin/xhi build,dev_start
# Press 'enter' when prompted to review TODOs
# Now open in a browser (adjust as needed)
google-chrome http://localhost:8080/build/latest/dist/app-tb02.html
These steps create a release-ready distribution in around 5 seconds on modern
hardware. In that time, hi_score
resolves all build
dependencies, coordinates with NPM to download and
install hundreds of packages, patches and deploys libraries, and runs
thousands of quality checks. Subsequent builds take less than half the time
thanks to cached environment dependencies.
You should now see the Typebomb 2 web app in a browser and may use the developer tools to inspect the CSS, the DOM, and the JavaScript. Notice how everything is production-ready including compressed CSS class names (yes, we were doing this five years before Facebook). Please compare it with the online version to ensure it is working correctly.
-
Manage the full life cycle
-
Integrate with NPM using
package.json
-
Never miss a lifecycle step with dependency resolution
-
Avoid the complexity and magic of the Tower of Babel
-
Develop rapidly in with only a browser, terminal, and text editor
-
Create in-line HTML documents from markdown (
bin/make-doc
) -
Build multiple related applications in a single project
-
Learn from a non-trivial
Typebomb 2
app -
Debug instantly using browser tools in a zero-compile development environment
-
Get Detailed help with
bin/xhi help -v
-
Use best practice reference Style, VDG, Library, Architecture using
bin/xhi design
. -
Enjoy type-safety without the complexities of TypeScript or Flow
-
Use a layered MVC arch with designed for testing
-
Leverage the extensively used and tested xhi library to guide the design of every layer of our app.
- Extensive, highly tested utilities in
js/xhi/01_util
- AJAX and socket methods in
js/xhi/02_data
- State and logic management in
js/xhi/03_model
- Feature modules as shown in
js/xhi/06_lb.js
- Double-buffered dynamic CSS with PowerCSS and
js/xhi/06_css
- Shell design in
js/xhi/07_shell
- Extensive, highly tested utilities in
-
Auto-installed a commit-hook (
bin/xhi install
) -
Deploy and patch all vendor assets (
bin/xhi setup
) -
Run all regression tests in a drop directory (
bin/xhi dev_test
) -
Serve content with
http-server
(bin/xhi dev_start
) -
Upgrade libraries only on request (
bin/xhi dev_upgrade
) -
Run suite of static tests (ESLint, whitespace, strict, TODOs) (
bin/xhi dev_lint
) -
Report code coverage with Istanbul (
bin/xhi dev_cover
) -
Run all tests prior to commit (
bin/xhi dev_commit
) -
Build for distribution with a single command (
bin/xhi build
)
The bin/xhi
tool automates good practice for almost every conceivable stage of the SPA life cycle. Configuration for every stage is found in the NPM package.json
file. This tool provides all NPM lifecycle scripts such as npm test
.
The lifecycle stages supported by bin/xhi
are shown below. Those marked placeholder
are those we plan to address in future releases. Use the command bin/xhi help all
to see the entire list as shown below.
$ bin/xhi help all
xhi> START Stage 00 help
xhi> 00 help : Help on 'xhi' tool, use -v for verbose
xhi> 01 install : Download and install npm modules
xhi> 02 setup : Patch and distribute vendor npm assets
xhi> 03 design : Show architecture, style, and VDG docs
xhi> 04 dev_pull : Download and merge SCMS assets (git pull)
xhi> 05 dev_upgrade : Upgrade packages to latest
xhi> 06 dev_start : Start local HTTP server
xhi> 07 dev_test : Run regression tests
xhi> 08 dev_lint : Lint changed code
xhi> 09 dev_cover : Create coverage report
xhi> 10 dev_commit : Commit changes with git
xhi> 11 build : Build a distribution
xhi> 12 publish : Upload to publishers
xhi> 13 dev_restart : Cycle local HTTP server
xhi> 14 dev_stop : Stop local HTTP server
xhi> 15 deploy : Upload distribution # placeholder
xhi> 16 prod_start : Start production server(s) # placeholder
xhi> 17 prod_restart: Cycle production server(s) # placeholder
xhi> 18 prod_stop : Stop production server(s) # placeholder
xhi> 19 fetch_info : Fetch feedback # placeholder
xhi> 20 uninstall : Remove xhi # placeholder
xhi> END Stage 00 help
Use bin/xhi design
to see the Architecture Guide, Style Guide, or Visual Design Guide (VDG). Detailed help on a stage or range of stages is shown with the -v
flag shown below.
$ bin/xhi help dev_lint -v
xhi> START Stage 00 help
xhi> 08 dev_lint:
xhi> Check lint quality of changed JS code.
xhi> Files in 'vendor|node_modules' directories are ignored.
xhi> Four tests are performed on each file:
xhi> 1. Check for tab characters or trailing space
xhi> 2. Ensure 'use strict'; is employed
xhi> 3. Run 'eslint' on each file (config in package.json)
xhi> 4. List TODO items for developer to review and approve
xhi> Any failed step causes this stage to report failure.
xhi>
xhi> This stage does not "short-circuit" so any and all issues are
xhi> shown for each run.
xhi>
xhi> NPM SCRIPTS : none.
xhi> SUCCESS CRITERIA : All tests complete without error
xhi> END Stage 00 help
Run a range of lifecycle steps as shown below.
# Get list of stages
$ xhi help all
# Run desired stage-range
$ xhi dev_cover,build
The bin/xhi
tool takes a <stage-range>
argument. Stages that are provided out-of-order are sorted before running. A number of examples are shown below.
# Run a single stage
$ xhi install
# Run all stages between 'install' and 'dev_commit' inclusive
$ xhi install-dev_commit
# Run individual stages explicitly
$ xhi update,dev_cover
# Run a range using stage numbers
$ xhi 0-5
# Get help on ranges
$ xhi help install -v
$ xhi help install-dev_commit
$ xhi help update,dev_cover
$ xhi help 0-5
The bin/xhi
tool will often run more than the number of stages requested. That's because many stages have dependencies as discussed in the next section.
The bin/xhi <stage-range>
command will always run the smallest safe number of steps to complete the target to minimize time and resources required. For example, consider the stages that are run when we enter bin/xhi build,dev_start
for the first time as shown below.
- 01 install Download all vendor assets
- 02 setup Copy, rename, and patch vendor files. Install commit hook.
- 06 dev_start Configure and start an HTTP server
- 07 dev_test Ran all unit test suites found in
test.d
- 08 dev_lint Ran all lint tests (whitespace, TODO, eslint, strict)
- 09 dev_cover Calculated and report coverage
- 11 build Minimized, obfuscated, and SuperPacked three apps
- 11 build Created a unique dist folder for each app with meta-data and build reports
After this initial run, many of these steps will not be repeated. The install and setup stages, for example, will not be needed again unless the installation changes. The code quality checks like linting will only be needed if code files change. These dependencies are resolved by bin/xhi
as discussed below.
Goal dependencies are stages that are always run before before a target stage. For example, if we run bin/xhi dev_commit
the dev_lint
, and dev_test
stages will always be run first to ensure the code quality is acceptable. If either requirement fails, bin/xhi
exits immediately (with an exit code of 1) and the target stage is not attempted. Goal dependencies are defined in package.json.xhi_commandTable
. Don't change these without careful consideration and testing.
Environment dependencies must be successfully completed in the development environment before the target stage. For example, if we run bin/xhi dev_commit
but have not run bin/xhi install
, the install
stage will be run before the dev_commit
stage. The success or failure of each stage is saved in the state file (run/xhi_state.json
) and the next stage is run. If the install
stage succeeds it will not be included in future steps for dev_commit
as it will have been completed in the prior run. Environment dependencies are defined in package.json.xhi_commandTable
. Don't change these without careful consideration and testing.
Previously completed environment dependencies may be invalidated. For example, if bin/xhi install
or bin/xhi upgrade
fail, the tool will mark the install
stage as failed and the stage will be attempted again in the next invocation that requires this stage as a dependencies.
Explicitly requested stages will always run regardless of their last success status. For example, bin/xhi dev_lint
may or may not run the install
stage, but bin/xhi install,dev_lint
will always run the install
stage because it is explicitly listed. bin/xhi help-dev_lint
will also run install
since it is explicitly within the range provided (help-dev_lint
). Reset the status by removing the stage_status_map
from the run/xhi_state.json
file.
If all the stages of a range are successfully run an exit status of 0
is returned. If any stage fails processing stops and an exit status of 1
is provided. In Bash, the return status is available in the $?
environment variable. If we apply minor adjustments to disable terminal interaction, bin/xhi
should be capable of integration to other tool chains.
We create a new application by adding files as shown below.
hi_score/
│
├── app-<name>.html <= Development test page
│
├── css
│  └── app-<name>/ <= CSS if needed (but consider PowerCSS)
│  └── <name>.css
├── img
│  └── app-<name>/ <= App-specific image files
│  └── <name>.<descr>.svg
└── js
  └── app-<name>/ <= Libraries (discussed below).
  └── <name>.00_root.js
The Typebomb 2
app uses PowerCSS instead of an external CSS file. In addition, there are no external images as it uses embedded SVGs. Our files therefore are as shown below.
hi_score/
│
├── app-tb02.html <= Development test page
│
└── js
  └── app-tb02/ <= Libraries (discussed below).
  ├── tb02.00_root.js
├── tb02.01_util.js
└── ...
hi_score
is build from the ground-up to support feature module architecture. Key tenants of this architecture and the xhi
library are shown below.
- All layers are order from most basic
00_root
to highest abstraction08_app
. - Each layer is created using a corresponding
xhi
library file. - Data flows from the lowest layer
00_root
to the highest08_app
. - All method calls are made from higher levels to lower. Calls from 02_data to 01_util or 03_model to 01_util are expected. Calls from a high layer like
07_shell
to a low layer like02_data
should be scrutinized because one probably be calling all intermediate layer to safe state. All method calls from a lower layer to a higher layer or across modules of the same level are not allowed. - Use event registration to communicate changes up the stack. For example, the
03_model
may communicate an online status by publishing event data. All registered feature modules may then update their display. - Create feature modules that contain their own isolated data and models when appropriate. This is pragmatic and recognizes the fractal nature of MVC.
The Typebomb 2
app has files for each layer as shown below.
Module layers
========================================
tb02.00_root.js | ^ \
tb02.01_util.js load | |
tb02.02_data.js order | |
tb02.02_01_data_mock.js | | |
tb02.03_model.js | call, |
tb02.04_utilb.js | init > xhi library
tb02.05_02_css_base.js events order |
tb02.05_03_css_lb.js | | |
tb02.05_css.js | | |
tb02.06_lb.js | | |
tb02.07_shell.js | | |
tb02.08_app.js v | /
All these modules claim a slice of the application name-space (tb02
) and use js/xhi
libraries in one of three ways:
- Create a configured instance and use as-is
- Create an instance and decorate
- Use the module to guide development
More specific notes about Typebomb 2
app are provide in README.app-tb02.md
. One can omit unused layers for a given app. However, for illustrative purposes, we have included all layers here. One can copy these to a new name-space to create a new app and edit from there. One can easily create a generator to automate these steps, but we show them in full for now.
cd ~/Github/hi_score;
export _ns='mine'
cp /template/app-tb02.html "app-${_ns}.html"
mkdir "js/app-${_ns}"
cd "js/app-${_ns}"
cp ../app-tb02/tb02.00_root.js "${_ns}.00_root.js"
cp ../app-tb02/tb02.01_util.js "${_ns}.01_util.js"
cp ../app-tb02/tb02.02_data.js "${_ns}.02_data.js"
cp ../app-tb02/tb02.02_01_data_mock.js "${_ns}.02_01_data_mock.js"
cp ../app-tb02/tb02.03_model.js "${_ns}.03_model.js"
cp ../app-tb02/tb02.04_utilb.js "${_ns}.04_utilb.js"
cp ../app-tb02/tb02.05_02_css_base.js "${_ns}.05_02_css_base.js"
cp ../app-tb02/tb02.05_03_css_lb.js "${_ns}.05_03_css_lb.js"
cp ../app-tb02/tb02.05_css.js "${_ns}.05_css.js"
cp ../app-tb02/tb02.06_lb.js "${_ns}.06_lb.js"
cp ../app-tb02/tb02.07_shell.js "${_ns}.07_shell.js"
cp ../app-tb02/tb02.08_app.js "${_ns}.08_app.js"
git add .
There is a lot less duplicate code here than it may appear. For example, any 01_util
layer is just a singleton instance of the js/xhi/01_util
utilities. And any model almost certainly inherits and reuses state values and methods from an instance of the js/xhi/03_model
.
We change all references from tb02
in these new files to our new name-space, ${_ns}
. We also create a new build manifest in package.json
using the xhi_11_BuildMatrix
configuration for tb02
as a guide. Once we confirm our new app builds as expected using bin/xhi build
(check the output in build/latest/dist/app-${_ns}.html
) we proceed to customize it as desired.
The bin/xhi setup
stage patches and deploys vendor assets using the xhi_02_SetupMatrix
configuration found in package.json
. This field is correlated with the with the devDependencies
map to ensure assets are properly label, patched, distributed, and ignored by Git.
Assets are copied to their destination directory with their version number appended to their names. The .gitignore
file instructs git
to ignore all these files as their development management is external to our project. Every time bin/xhi setup
is run the vendor directories are deleted and recreated.
Vendor executables are copied to the bin/vendor
directory.
Vendor font files are copied to the font/vendor
directory. These fonts are currently installed:
- Font Awesome: Icon fonts
- Open Sans: OSS Font face
Vendor images are be copied to the img/vendor
directory.
Client libraries are copied to the js/vendor
directory. This makes them available to the web server. The following libraries are installed:
- jQuery: DOM manipulation
- PowerCSS: JS-powered CSS
- jQuery Plugin: event.dragscroll: Inertia scroll
- jQuery Plugin: event.gevent: Global events
- jQuery Plugin: event.ue: Touch and desktop gestures
- jQuery Plugin: scrolli: Scroll indicators
- jQuery Plugin: urianchor: SPA routing
- SprintF: Sprintf library
- TaffyDB: Client data management
The jQuery
name-space is changed to xhiJQ
and the PowerCSS name-space is changed from pcss
to xhiCSS
. This avoids conflicts with other libraries. The naming may be updated by adjusting bin/rename-vendor-symbols
. When coding, please use these symbol (xhiJQ
and xhiCSS
) instead of their usual names (jQuery
and pcss
). Also, we do not expect the $
symbol to represent jQuery. Rely on local mapping if we want that behavior, e.g. (function ($) { ... }( xhiJQ ))
.
NodeJS libraries are not copied to a vendor
directory. We may change
this if we decide to create a server distribution. The following libraries are
installed:
- clusterjs: Server multiplexer
- express: Minimalist Sinatra HTTP server
- mongodb: Official mongodb node client
- mysql2: Faster mysql interface
- websocket: Websockets interface
Development libraries are used for testing a building code. They are not
copied to a vendor
directory. The following libraries are installed:
- coveralls: Code coverage reporting
- istanbul: Code coverage
- jsdom: DOM mock for testing
- eslint: Linting for commit hook
- nodeunit: Unit testing
- node-inspector: Debugging
- uglifycss: CSS minification
- uglifyjs: JS minification
Vendor CSS libraries are copied to the css/vendor
directory. The following
CSS files are installed:
- Font Awesome: Icon font CSS
The xhi_02_SetupMatrix.patch_matrix
directs patch application. This capability allows us to use great tools tweaked for our needs while maintaining the upstream source. For example, we patch uglify-js
to support object property name compression and shuffling by superpack
. We also patch font-awesome
CSS files to have the correct path for our environment. The bin/xhi setup
stage applies patches after vendor assets are copied to their directories. The configuration for patches are in package.json
in the xhiPatchMatrix
map. The patches are stored in the patch
directory. Patches can be created as follows:
cd js/vendor
cp jquery-3.5.1.js jquery-3.5.1.js.O
# Now change jquery-3.5.1.js as required
# And create the diff
cd ../..
diff -u js/vendor/jquery-3.5.1.js.O js/vendor/jquery-3.5.1.js
> patch/jquery-3.5.1.patch
Use bin/xhi build
or bin/xhi make
to build a distribution. The tool concatenates, compresses, and obfuscates and SuperPacks JavaScript and CSS. It copies only the required assets into the the distribution directory (build/<build_id>/dist
). The result loads faster, runs faster, and typically consumes roughly 1/50th the space of the development environment.
$ ## Show disk usage of all development files
$ cd hi_score && export PATH=`pwd`/bin:$PATH;
$ du -sh .
148M
$ ## Get disk usage of all distribution files
$ xhi build && cd build/latest && du -sh .
3.6M
The bin/xhi build
stage uses uses SuperPack to analyze symbols (variable names, object properties, and labels) and replace them with shortened and shuffled keys. The shortest keys are used for the most frequently found symbols. SuperPack reports the key-to-symbol mapping and the frequency of use which makes further optimizations by pruning code easier (see build/<build-number>/stage/<name>-sp.diag
for mapping and key use). Projects with many object properties can be compressed up to an additional 50% by SuperPack, and it hinders reverse-engineering of code.
The build process enhances security because only a tiny, curated, obfuscated portion of our code is published and sensitive data such as SCMS information, documentation, lookup-maps, and development assets are omitted. We can publish these assets elsewhere at our discretion. The distribution also reduces the dozens of HTTP calls to just a few. This too reduces load time as illustrated below.
Attribute | Original (%) | Minified (%) | SuperPack (%) |
---|---|---|---|
Size | 601,027 (100.0%) | 215,400 ( 35.8%) | 162,494 ( 27.1%) |
Gzipped | 151,716 ( 25.2%) | 62,895 ( 10.4%) | 57,275 ( 09.5%) |
HTTP reqs | 27 (100.0%) | 4 ( 15.4%) | 4 ( 15.4%) |
Local ms | 231 (100.0%) | 166 ( 71.2%) | 144 ( 62.3%) |
Deploy Size | 121 MB | 8 MB ( 6.6%) | 8 MB ( 6.5%) |
The load time measurements were made using a local HTTP server. Remote devices over slow networks would have a much larger delta in favor of SuperPack.
Name-spaces enable us to provide a suite of web apps that share a great deal of code but have instances and data cleanly isolated. Name-spacing across JS and CSS can help one trace behaviors to the controlling code faster and with greater accuracy. We open them in the browser (bin/xhi install && google-chrome ex*.html
) and use the developer tools to see this in practice.
When we view Example 1 (ex01.html
) we can open the browser development tools (press <shift>-<ctrl>-i
or <shift>-<cmd>-i
on a Mac), type ex01
into the JavaScript console and press <return>
to inspect that value. We see that this single variable that contains our entire application. When we enter ex02
we see that it is undefined
. When we visit the Example 2 (ex02.html
) instead we see that ex01
is undefined
and ex02
contains our app code using a similar process.
We also name-space our CSS classes to avoid collisions. When we inspect the HTML of the Example 1 app we see that nearly all classes start with an ex01-
prefix. When we inspect Example 2 tab we find the prefix is ex02-
. As with the JavaScript name-spacing, the prefixes are hierarchical. For example, the ex02-_lb_
class was generated for use by the ex02-_lb_
module. During the build process selectors are shortened along with property values as long as they use the property-name structure. For example, ex02-_shell_title_underscore_
will compress to something like ex02-jp
.
A good way to integrate the hi_score
repository is to use it as a git
upstream source. One may then create new application using the hi_score
infrastructure without missing upstream improvements or bug fixes.
First create a new empty repository on Github and copy the ssh
repository URL, which should look similar to [email protected]:<user>/<repo_name>
and then proceed as below:
# Create and use Github directory
mkdir -p ~/Github && cd ~/Github
# Set up variables - change these as needed
_app_name='paw'
_git_user='mmikowski'
_repo_name='myproject'
# Clone the empty repository
git clone "[email protected]:${_git_user}/${_repo_name}"
cd "${_repo_name}"
# Create master branch
touch "README.${_app_name}.md" # Add app specific docs here
git add .
git commit -m "First commit for ${_repo_name}"
git push
# Verify origin
git remote -v
# origin [email protected]:<user>/<repo_name>.git (fetch)
# origin [email protected]:<user>/<repo_name>.git (push)
# Add upstream repository
git remote add upstream [email protected]:mmikowski/hi_score.git
# Verify upstream
git remote -v
# origin [email protected]:<user>/<repo_name>.git (fetch)
# origin [email protected]:<user>/<repo_name>.git (push)
# upstream [email protected]:mmikowski/hi_score.git (fetch)
# upstream [email protected]:mmikowski/hi_score.git (push)
# Merge changes from upstream and push to origin
git fetch -a --prune upstream
git merge --allow-unrelated-histories upstream/master
git push
One can delete all the example apps (tb02
, ex01
, ex02
) from the project if they get in the way. However we recommend retaining at least tb02
for reference because it will continue to be refined along with the hi_score
project. One can refresh upstream at any time as shown below.
# Refresh view of branches
git fetch -a --prune
# Pull latest master or dev branch
git checkout master
git pull
# Create a new branch to test merge
git checkout -b upstream-check
# Refresh view of upstream and test merge
git fetch -a --prune upstream
git merge --no-commit upstream/master
We recommend running bin/xhi install,setup
after any such merge.
If we want to create a single page web application these days there is no shortage of help. Developers are lured into using a starter project which we will call a Tower of Babel. Typically these projects include a not-yet-abandoned SPA framework (maybe React, Vue, Angular, Aurelia or Ext.js) along with a static CSS compiler (like SASS or LESS or Stylus or SCSS), a run-time CSS manager (like BootStrap), a JavaScript compiler (typically Babel with JSX and Typescript and ES5.2), a build system (like Brunch or Webpack or Parcel) so on and ad-nauseum. This requires a sophisticated management server orchestrate the numerous cross-dependencies and transpiles. There are a few guarantees beside the system will be Magic.
Sorry Gandalf but we don't mean Magic in a good way. Sure, we'll be able to create that sample-TODO-application-designed-to-impress-the-CTO in record time because of the built-in-demo-on-rails. But once one moves away from the demo even a little bit, things tend to go south fast. The build path from source code to the rendered HTML + CSS + JavaScript (HCJ) is so complex that it's impossible for a human to trace. When it breaks - and it will - all that Magic becomes Evil Curses. That's because these Tower of Babel solutions have traded HTML + CSS + Javascript for a Mötley Crüe of transpiled languages that are often larger, more numerous, harder to learn, poorly documented, poorly integrated, and much easier to break. Problems that should be easy to solve - like adding an app to share resources - can be effectively impossible.
hi_score
is designed to avoid the Tower of Babel, automate processes around the HCJ, and help the developers continuously improve their skills and understanding on the core technologies of web apps. We hope you like it.
When using Ubuntu Linux 16.04+ or a derivative -- such a Linux Mint, Kubuntu, Xubuntu, Lubuntu, or similar -- ensure the following libraries are installed. Run the attached commands one at a time to ensure all prerequisites are met.
# Install required libraries
sudo apt install build-essential git \
libfile-slurp-perl liblist-moreutils-perl \
net-tools openssh-server pandoc pandoc-citeproc \
unzip zip;
# Install recommended libraries
sudo apt install apt-file htop kdiff3 \
mysql-client mysql-server \
meld ppa-purge sysstat vim-gtk vim-nox vim-syntax-gtk
# Install nodejs
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
sudo apt-get install -y nodejs
Return to Quick Start
Other Linux distributions should generally work as long as the same libraries can be installed as with Ubuntu. With Fedora 30, for example, the following should be pretty close.
yum install gcc gcc-c++ make openssl-devel
# Now make sure the perl libraries and node.js 10+ is installed
See this guide for NodeJS package installation on other Linux distros. Here is a more generic guide for Kubuntu and Ubuntu.
Return to the Quick Start
MacOS Catalina is reported to work with the following commands:
- Install NodeJS
# Install Pandoc
brew install pandoc
# Install cpanm
cpan App::cpanminus
# Install CPAN modules
cpanm Getopt::Simple File::Slurp
Another option is to use Parallels, VMFusion, or a Docker container to host Kubuntu 22.04 LTS or similar. VirtualBox also will work but does not integrate as well to MacOS. This ensures everything works as intended.
In theory, the Windows Subsystem for Linux running an Ubuntu distro should work as with the prerequisites listed above. However, we haven't tested it. One may also use the virutal appliance detailed above.
Return to the Quick Start
Our baseline compatibility is IE9+. Those supporting IE 8 have our sympathy.
The server component of hi_score is designed to run on industry-standard hardware, cloud instances like Amazon EC2, and containers. Our server platform is Ubuntu 24.04 LTS. Later version of Ubuntu and other distributions should work well.
We use the code style presented in Single Page Web Applications - JavaScript end-to-end (see reviews on Amazon) in the upcoming 2nd edition. The full code standard is found in the docs
directory.
We provide configs for JetBrain's IDE IntelliJ or Webstorm in the repository. Other IDEs will work fine, but you will need to manually adjust them to support the code style. One should only need to do this once per IDE and then it can be added to the repository. Contributions for VSCode, VIM, and other environments are welcome.
While hi_score
is opinionated, it is also modular and designed for change. For example, the bin/xhi
tool is easily extended by dropping a short module into the the lib/
directory. The architecture and code style docs used by bin/xhi
are easily edited in the docs/
directory. Developers are encouraged to add vendor libraries and patches as needed. Any improvements or suggestions are welcome through the issues tracker. Pull requests are appreciated!
2016 - 2019 Michael S. Mikowski (mike[dot]mikowski[at]gmail[dotcom])
MIT
- (x) Initial preparation
- (x) Library updates
- (x) Regression and integration testing
- (x) Rudimentary sample app
- (x) Add code coverage
- (x) Replace
getDeepMapVal
andsetDeepMapVal
with more powerful and testedgetStructData
andsetStructData
- (x) Updates to
xhi/01_util.js
- (x) Replace
jscoverage
with much more complete and recentistanbul
- (x) Add
cast
routines and detail their use - (x) Consolidate utilities to increase coverage
- (x) Update lite-box using
cast
methods
- (x) Add
jsdom
to expand testing to modules that use jQuery - (x) Continue regression test expansion
- (x) Rationalize libraries
- (x) Add lite-box regression tests
- (x) Remove vendor code from repo and auto-copy on install
- (x) Add native utils
makeThrottleFn
andmakeDebounceFn
- (x) Add links to revised code style guides
- (x) Replace
install
script withprep-libs
(v0.6.17+)
- (x) Move to constructor approach to easily create multiple concurrent name-spaced apps using the common xhi core
- (x) Update index page to illustrate
- (x) Make example app less trivial
- (x) Number code library level
- (x) Work on build system
- (x) Unify shell scripts nomenclature
- (x) Add constructor where only selected components are added
- (x) Add dependency levels for xhi libs
- (x) Add distribution build system
npm run buildify
- (x) Add utilities and tests
- (x) Initial feature complete
- (x) Add utils and tests
- (x) Rename
npm run prep-libs
tonpm run setup
- (x) Rename
npm run cover
tonpm run coverage
- (x) Rename
npm run covera
tonpm run publish-coverage
- (x) Rename
npm run buildify
tonpm run make
- (x) Syntax refinements
- (x) Update libs, add express
- (x) Add utils and tests
- (x) Convert bin/setup in JavaScript
- (x) Configure setup completely in package.json
- (x) Replace JSLint with ESLint for ES2015 support
- (x) Convert from
var
=>let
- (x) Implement
bin/xhi
tool development capabilities- (x) 00 xhi help
- (x) 01 install
- (x) 02 setup
- (x) 03 design
- (x) 04 dev_pull
- (x) 05 dev_upgrade
- (x) 06 dev_start
- (x) 07 dev_test
- (x) 08 dev_lint
- (x) 09 dev_cover
- (x) 10 dev_commit
- (x) 11 build
- (x) 12 publish
- (x) 13 dev_restart
- (x) 14 dev_stop
- (x) Tool enhancements
- (x)
bin/xhi setup
: Implement env dependencies andlib/xhi_state.json
- (x)
bin/xhi setup
: Auto-createlib/xhi_state.json
if required - (x)
bin/xhi build
: Create build directory likedist/\<build-number\>
- (x)
bin/xhi build
: Linkdist/latest
to latest build - (x)
bin/xhi build
: Do not auto-increment build until next commit - (x)
bin/xhi dev_cover
: Move todist/\<build-number\>
directories
- (x)
- (x) Update all NPM lifecycle scripts to use
bin/xhi
- (x)
"help" : "bin/xhi help"
- (x)
"make" : "bin/xhi make"
- (x)
"setup": "bin/xhi setup"
- (x)
"test" : "bin/xhi test"
- (x)
- (x) Move build manifest to
package.json
- (x) Implement build numbers and link last build to
latest
- (x) Move coverage reports into build directories
- (x) Store build and env state in
lib/xhi_state.json
- (x) Create and update virtualBox OVA for development (offline, was link _42)
- (x) Create and update Parallels VMX image (offline, was link _42)
- (x) Replace JSLint setting from per-file to config/jslint.conf
- (x) Expect browser env for js/xhi libraries
- (x) Fix
js/xhi/01_util.js::makeSeriesMap
across timezones - (x) Update code standard
- (x) Create AMI image for deployment
2017-10-10 through 2019-01-01
- (x) Add
Typebomb 2
example application - (x) Convert build system to JavaScript using
package.json
as manifest - (x) Enhance
js/xhi
libs and docs - (x) Expand and enhance utility functions (
xhi/01_util.js
) - (x) Expand doc for
bin/xhi help build
- (x) Fix
bin/xhi dev_cover
dependency resolution - (x) Fix
superpack
to be more reliable - (x) Fix font path errors with patch for font-awesome CSS
- (x) Revise code standards and images
- (x) Update AMI image for deployment and add screen shot
- (x) Update README with images
- (x) Add symbol renaming to avoid conflicts (jQuery => xhiJQ, pcss => xhiCSS)
- (x) Replace JSLint with ESLint and
package.json
for config
2019-01-01 through 2019-06-15
- (x) Add capabilities and documentation to
js/xhi/01_utils.js
- (x) Update all libs to latest
- (x) Revised templates per latest best practice
- (x) Include event pub-sub system in the
js/xhi/03_model.js
instance. This provides an integrated event log system for use in regression tests
2019-06-16 through 2019-07-25
- (x) Significantly updated documentation.
- (x) Move
lib/xhi_state.json
torun/xhi_state.json
- (x) Update quick reference, VDG, and code standard
- (x) Updated docs, no code changes
- (x) Added check for GIT when using
bin/xhi
. NPM installs are not yet supported.
2019-07-25 ongoing
- (x) Enhance utility capabilities
- (x) Replace makeDeepKeyList with more-useful makeDeepData
- (x) Make getStructData more reliable for named objects
- (x) Update test to match new capabilities
- (x) Improve default symbol contents
- (x) Fix ex01 and ex02 example apps to show again
- (x) Update docs to current practices
- (x) Update js code standard to recent developments
- (x) Fix js code standard to render correctly
- (x) Update dependent library (
bin/xhi dev_upgrade
)
- (x)
server/index.js
Replace http-server with express server Supports .env, directory listing - (x)
package.json
Add cloud storage libs, update libs to lastest - (x)
bin/make_doc
Improve techniques used in bash utility - (x)
doc/js-code-standard.adoc
Add section on value passing to - (x)
xhi/02_data.js
Remove no-auth hack from - (x)
xhi/03_model.js
Extend event publish capability - (x)
xhi/05_02_css_base.js
Remove unused code from CSS module - (x)
lib/xhi_06
,lib/xhi_13
Adjust to start and stopserver/index.js
- (x)
js/app-tb02/tb02.07_shell.js
Fix audio on chrome over http by appending audio elments to body. - (x)
js/xhi/01_util
and tests: replacemakePadNumStr
tomakePadStr
- (x) Eslint fixes in ~20 files for redundant global symbols
- (x)
doc/spa-manuscript-v2
Add wip for maniscript for Single Page Web Applications JavaScript End-to-end - Second Edition. - (x) Improve diagnostics when superpack install is missing libs
- (x) Improve correctness of makeThrottleFn and makeDebounceFn
- (x)
js/xhi/01_util
Add return map option to method_makeTmpltStr_
. This reports the keys actually used in a given operation through the map reference that is passed. If no map reference is passed, this function operates exactly as before.
- (i) Improve CLI presentation of
bin/xhi design
reference by searching and using platform viewers - (i) Add generator to create new apps cleanly and very quickly
- (i) Update tb02 libs to latest best practice (events)
- (i) Update virtual appliance
- (i) Add CSS => PowerCSS parser
- (o) Convert SuperPack Perl to JS and use
package.json
config - (o) Add UUID snippet from Git to build number, for example,
000025-1c002d
- (o) Test load times using remote server
- (o) Implement
bin/xhi deploy
- (o) Push to NPM using
bin/xhi publish