UniteJS — One CLI To Rule Them All
One CLI to rule them all, well maybe not quite yet, but that is the aim…
In these days of enormous web development investment in brain power, time and money there is a constant need for developers to deliver tangibles. While this is good for competition and moving technology forward it leaves scant amount of time for developers to invest in learning or adopting newer technologies or techniques.
A constant churn of frameworks, tools and libraries all vying to be flavour of the month also leaves developers thinking should I switch or will it take me down an infinite rabbit hole.
You may say this is the nature of web development and you may well be right, but wouldn’t it be nice to have an hour here or there to see if you might be missing out on the next best thing in web development.
Some of the newer application frameworks (Angular, Aurelia, Preact, React, Vue etc) have CLIs which allow you to create a boilerplate application with almost no user interaction. These generated applications are ready to build and run using the development stack that the framework developers deem the best combination for use with their technology. While this is great to get you up and running quickly each CLI generates its own unique stack, the technologies within it may or may not be familiar to you. As a developer you might already have favourite tools when it comes to other parts of your workflow (testing, styling etc) but you don’t want to spend any time working out how to incorporate them in to the generated app if it is even possible.
Most of the CLIs use some sort of bundling technology (Webpack, Browserify, SystemJS) to produce a bundled version of your app out of the box. These bundlers also provide hooks to do tasks such as transpilation of your code, linting, styling and more. While these facilities are fantastic, it can make the development process quite brittle if you want to change part of your workflow. Also, if there is not a plugin for your favourite tool you are faced with writing a plugin yourself or abandoning your preferred way of doing a specific task. Bundlers for the most part support hot module reloading so when you are testing the whole bundle doesn’t have to be updated when something small changes, but there is still a lot of overhead in doing so.
The combination of the CLI and bundlers can make debugging your application problematic. If part of the build workflow fails, do you have enough information to find out which step failed and where to even look to fix it. The same is true of bundling, you code is taken one step beyond transpilation, so is the problem your code, the transpiled code or the bundling process. In both scenarios if the problem turns out to be a problem with the CLI/bundler do you really want to be digging around in their source code or waiting for them to fix an issue that you raise.
The Best Tool For The Job
Some might say that the CLI/bundling opaqueness is not a problem and given enough time all the issues will be resolved, I look forward to that day. Until then I believe in directly using the best tool for the job and not calling them through another layer, this is the approach of UniteJS.
UniteJS is a CLI just like many of the others and has comparable features. The main difference is that is that it supports multiple application frameworks along with a multitude of options for other parts of the development stack.
Another huge difference is that during the development process UniteJS maintains your code in its base module form (AMD, CommonJS, SystemJS) making it quicker and easier to fault find. It is only when you create a bundled build that tools like Webpack, Browserify come in to play, all your code, styling, views will be in a form that can be bundled directly by the bundling tools so they are utilised to do the one job that they should be brilliant at.
- Application Framework — Angular, Aurelia, PlainApp (no framework), React
- Module Type — AMD, CommonJS, SystemJS
- Bundler — Browserify, RequireJS, SystemJS, Webpack
- Linter — ESLint, TSLint
- Unit Test Runner — Jest, Karma
- Unit Test Framework — Jasmine, Mocha
- Unit Test Engine — Chrome Headless, JSDom, PhantomJS
- E2E Test Runner — Protractor, WebdriverIO
- E2E Test Framework — Jasmine, Mocha
- CSS Pre-Processor — CSS, Less, Sass, Stylus
- CSS Post-Processor — None, PostCSS
- Task Runner — Gulp
- Package Manager — Npm, Yarn
- Packaging — Web App, Electron
UniteJS currently creates a build workflow based on Gulp which means that once UniteJS generates your initial boilerplate you might never need to use UniteJS again, there is no UniteJS code as part of the build process just one configuration file. Every application framework is provided with the same set of workflow tasks build, unit, e2e etc so once you have learned the tasks once you can change any option under the sun and the tasks you run are exactly the same.
UniteJS also has some built in profiles which should match the tool stack generated by the default CLIs for each application framework.
Before you begin you must install the unitejs-cli as a global package so:
npm install -g unitejs-cli or yarn global add unitejs-cli
Create an Angular app using TypeScript:
unite configure --packageName=my-app --title="My App" --profile=AngularTypeScript --outputDirectory=./my-app
or maybe switch to using less for syling:
unite configure --packageName=my-app --title="My App" --profile=AngularTypeScript --cssPre=Less --outputDirectory=./my-app
once generated you are not limited to your original choice, you can switch for example to use Sass in an already existing setup:
unite configure --cssPre=Sass --outputDirectory=./my-app
How about supplying all the options:
unite configure --packageName=my-app --title="My App" --license=MIT --appFramework=Aurelia --moduleType=SystemJS --bundler=SystemJSBuilder --sourceLanguage=TypeScript --linter=TSLint --unitTestRunner=Karma --unitTestFramework=Jasmine --unitTestEngine=ChromeHeadless --e2eTestRunner=Protractor --e2eTestFramework=Jasmine --cssPre=Sass --cssPost=PostCss --packageManager=Npm --outputDirectory=./my-app
and then changing your mind to use MochaChai:
unite configure --unitTestFramework=MochaChai --outputDirectory=./my-app
You can generate your own configurations using the online generator at http://unitejs.com/#/generator which has some validation built in to allow you to only choose valid option combinations.
In addition to just configuring the development stack UniteJS like the other CLIs can also generate components for your application:
- Angular: class, component, directive, enum, guard, interface, module, pipe, service
- Aurelia: attribute, binding-behavior, class, component, element, enum, interface, pipeline-step, value-converter
- PlainApp: class, enum, interface
- class, component, enum, interface
The generated code will be tailored to your configured options providing code, view, styling and tests where at all possible. The name will be manipulated to the correct case camel, snake, pascal, human to use in the generated items, it is best to supply the original in human readable form. The generated items will use the recommended naming convention and output location for each application framework.
unite generate --name="Super Spinner" --type=component
unite generate --name="The Thing " --type=class --subFolder=./myClasses/
UniteJS also support adding 3rd party libraries with a minimum of fuss and integrating them into your application, no need to worry about script includes, module loader configuration etc. Libraries often have different ways of loading and needs assets bundling, hopefully we have catered for the different varieties available but expect this to grow over time.
unite clientPackage --operation=add --packageName=moment
unite clientPackage --operation=add --packageName=font-awesome --assets=css/**/*;fonts/**/*
We also support profiles for some common libraries, expect this list to grow as well.
unite clientPackage --operation=add --profile=font-awesome
When your app is ready to deploy it is nice to be able to create a production release with just the essential components, this is where platform come in. Based on your current setup you can produce a web or Electron packaged build.
First add the platform to your configuration
unite platform --operation=add --platformName=Electron
Then you will have access to some additional build tasks which will provider you a completely standalone version of your application without all the detritus of the development process.
To reduce the other tasks you need to perform when generating your app we also have built in favicon generation for the different platforms, just provide a couple of SVGs and your accent colour, run the theme-build task and all the required image formats are generated using our own native image generator (that includes generating Apple icons on Windows, and Windows Icons on a Mac).
At UniteJS we will endeavour to assimilate all that we can (we already have a lot on the road map) and always open to suggestions.
We have no axe to grind with any specific framework or tool, if something new gains traction and enough adoption we will integrate it. All that being said UniteJS is open source and very modular so adding a new framework/tool is very easy (and in the process of getting easier).
So what are you waiting for, isn’t it worth a few minutes of your time to explore UniteJS, given the time, money and anguish it might save you in the long run!
Martyn Janes @martynjanes
Senior Developer UniteJS
For more information, documentation and the online CLI generator visit the web site at http://unitejs.com
Gitter Chat: https://gitter.im/unitejs/discuss