Because HTML, CSS, and JS continue becoming more awesome, we don’t always need a framework these days. But not using a framework shouldn’t mean that other things (not related to design/dev) become more complicated. Arjan is a simple node js tool kit that helps you take your static (html/css/js) projects to production with the minimum overhead, lowest cost, and best performance. Arjan features an easy to use CLI (made to resemble git) with intuitive commands for each tool in the kit. Because it is NOT a framework, Arjan basically has No barriers to entry.
Load is an acronym for localize, optimize, audit, deploy. Four things that we repeatedly do to our static site projects. Since these four things aren’t related to the design or the development process of the website, they may fall outside of the expertise of a regular design firm causing a higher overhead.
Arjan uses several popular node js modules and builds some functionalities on top/besides them to help you LOAD effectively, with 0 overhead. Its CLI is fast and easy to use/integrate into your current process.
With all the APIs and new features that have been and continue being added to the web, including the support for ES6 syntax it seems that vanilla js will always continue becoming more usable and powerful. So in the end, if this is what the browser is using, and its super powerful, unless we have a very specific reason, why should we be using something else that compiles into something else that then compiles into the vanilla js that the browser understands??!
the purpose of the load workflow is to allow to continue doing what your doing (i.e. using HTML5, CSS3 and VanillaJS) and help you take your projects to production with the minimum amount of overhead. Avoid learning any new frameworks. Avoid having to constantly download and maintain many things at once. Avoid having to pay for a service to do all these things for you.
you only have to do this once (when you install arjan for the first time).
-
Install the arjan cli globally
npm i -g arjan-cli -
If you already have a local AWS profile that you intend to use with arjan you can disregard steps 3 - 5.
-
Run
arjan init <IAM_USER_NAME> <AWS_REGION> -g. This will pop open a browser window with the AWS console; Finish creating the IAM user and hold on to the keys. -
Update/create the local AWS profile on your machine by adding the profile and keys in the format shown bellow. The AWS profiles are stored in
~/.aws/credentialson mac/linux or inC:\Users\USER_NAME\.aws\credentialson windows.[profilename] aws_access_key_id = <YOUR_ACCESS_KEY_ID> aws_secret_access_key = <YOUR_SECRET_ACCESS_KEY>
before being able to use arjan in a particular project you must:
- go into the desired project's root directory
cd project_pathand runarjan init <AWS_PROFILE> <AWS_REGION>(without the -g flag)
now you can run any of the LOAD commands (All of the commands are always meant to be run from the root of your project). for more info check out the CLI’s README or run arjan --help. For more information on each of the commands check out their respective sections in the docs or run arjan COMMAND --``help
when you run the init command (without the -g flag) it creates some directories and files inside your project. after that, each of the commands will also generate some directories/files. Bellow is a depiction of how a simple project that only consists of an index.html file would look after its undergone the LOAD commands (localize, optimize, audit, deploy). In the example the file was translated into Spanish.
|--index.html
|--es/
| |--index.html
|--dep_pack/
| |--index.html
| |--es/
| | |--index.html
|--arjan_config/
| |--optimize_config.json
| |--audit_config.json
| |--changesets/
| |--locales/
| | |--en/
| | | |--index.json
| | |--es/
| | | |--index.json
| |--exports/
| | |--csv/
- dep_pack is a directory that contains your optimized deployment package.
- go to this section for more information on available output formats of localization
- everything else is inside the arjan_config directory
- optimize_config/audit_config contain the default configurations for the optimize/audit commands. when flags arent supplied, the settings defined in these config files are used.
- changesets contain a json object with the changset name and the template body for that changset as well as any existingResources.
- locales contains all of your json locales stored according to their language and filename. localenames are equivalent to the path of the file transformed in the following way
filePath.substr(0, filePath.lastIndexOf(".")).replace(/\//g, '_') - exports/csv contain the locales that have been converted into CSV
Arjan Localize is node module for automatically localizing and translating html sites. It features a powerful CLI command that allows you to localize multiple pages into multiple languages with a single command. It has a modular API and since it can export content into popular formats like JSON and CSV, it may also work as a very basic content management solution for html sites.
Localization consists of adapting a product to a particular locality or region. Even though machine translation services like google translate and amazon translate have gotten impressively good, there are still several scenarios were manual intervention is needed. If you are expanding your digital product/service into a new region its important to get everything perfect. Complex grammar rules and slang often cause errors in the translation making some manual intervention or at least revision necessary. Also a project that has been correctly localized will have way better SEO. Additionally, text content might not be the only thing that you want to localize; you might also need to use different images/videos and hyperlinks in your different versions.
A common practice is to create JSON files called locales that contain the text content of site/app. Then instead of using words in your file, you use variables that read from the locale object. This way content modification doesn't have to be made directly in the code. In general, this makes your internationalized project easier to maintain.
Arjan uses the id attributes already present in your html as the keys in the locale. The parser in Arjan Localize gets all the existing IDs of html elements with text content, and saves them in the locale. If the element didn't have an ID Arjan automatically creates an ID for the object with the following format: The first 12 characters of the text, replacing spaces with underscores and adding the translation index at the end.
Arjan Localize also helps you to automatically translate your JSON locales and files in up to 54 different languages. It uses AWS’s neural machine translation system which is used in amazon.com.
There’s three ways in which you can use Arjan Localize. The three are listed bellow with their pros and cons.
-
Arjan CLI
- pros:
- translate multiple pages
- bi-directional translation updates
- cons: No GUI. basic terminal usage knowledge
- pros:
-
The Arjan Localization GUI
- Pros:
- GUI
- No AWS account needed.
- cons:
- only translate a single page at a time
- cannot update translations
- Pros:
-
Programmatic usage
- Pros: integrate into other programs and workflows
- Cons: requires setup for each project
Arjan translate has a GUI at arjan.tools/translate. The GUI is a form with a drop zone made with super easy forms which features a node.js lambda function as its backend. The GUI is pretty limited as you cant update your translations but its good for a one time job especially if you don't like using the terminal.
- go into your sites directory
cd SITE_NAME - run
arjan init SITE_NAMERefer to the provider setup section if you haven't used any of the cloud translation APIs. - Run the translate command
arjan translate SITE_NAME [FILENAME]
the translate command generates 2 or 3 things
- locale JSON files for the input and output languages
- translated html file/s with the output language code (es.html or es/about.html)
- CSV file with translations (optional)
Once you have translated your doc you can improve all of your translations by working directly on your neatly organized JSON locale files and running the translate command with the —update flag (-u).
Arjan translations is bi-directional meaning that you can also work on the output HTML files and then run the translate command with the —backwards (-b) flag to update your JSON files.
You can also generate a single CSV file with all the translations for your site by running the translate command with the —export flag (-e). if you use both the —export and —backwards flags you can update the CSV with site data. if you provide the filename arg only translations for that file will be included in the CSV.
-
install the arjan-localize module
npm i arjan-localize -
for using the automatic translations feature refer to the provider setup section const arjanTranslate = require('arjan-translate')
//REGION is the AWS region of your IAM role ex. 'use-east-1' //PROFILE is the name of your desired AWS IAM profile ex. 'deafult'
arjanTranslate.Build('REGION', 'PROFILE', function(err, data){ if(err) console.log(err) else { //FROM is the language code of your origin file ex. 'en' //TO is the language code of your destination file ex. 'es' arjanTranslate.TranslateSite('FROM', 'TO'); } })
Translate locale considers that you can have 3 different routing formats for a multilingual HTML site. Let's take the following file for example: blog/posts/post1.html
- none: You haven't structured your site to be multilingual.
- file: You are using the language code as the name of the file. for example
blog/posts/article1/``en``.html - dir: You are using the language code as the name of the parent directory. i.e.
en``/blog/posts/article1.html
- In case 1, a directory named with the language code of your output language and the same file structure (excluding ignored directories and non-html files) will be created in the root of your project.
- In case 2, translated files will be saved with the name of the output language i.e.
blog/posts/article1/es.html - In Case 3, alike case 1, a directory with the name of the output language will be created in the root.
The example compares Arjan with i18n; Lets suppose our input is an en.html file with the following content:
<section>
<h1 id="title1">Arjan is super cool</h1>
</section>
After running the translate command we would get the following output:
- locales/en.json →
{ "title1":"Arjan is super cool" } - en.html
- Arjan→
<h1 id="title1"> Arjan is super cool </h1> - I18n →
<h1 id="title1"> {{arjan.t('title1)}} </h1>
- Arjan→
Let's suppose that our input string didn't have an id attribute:
- locales/en.json →
{ "arjan_is_sup1":"Arjan is super cool" } - en.html
- Arjan →
<h1 id="arjan_is_sup1"> Arjan is super cool </h1> - en.html →
<h1> {{arjan.t('arjan_is_sup1')}} </h1>
- Arjan →
Notice that an id with the first 12 characters of the string is created. Caps are lower-cased and spaces are replaced with underscores. A number with the index of the translations is inserted at the end (in case there’s another string that starts with the same 12 chars)
HTML5 option (Coming Soon) If you are using html5 elements in your page (nav, header, section, footer) you can add the html5 option in the translate command. This will generate objects with ids of html5 elements (nav, header, section, footer) and will insert translations as children of the object they belong to. suppose were still using the example above without ids:
-
translations/en.json →
{ "section1":{"arjan_is_sup":"Arjan is super cool" }} -
en.html
- Arjan ->
- I18n →
You can use the HTML translate tag to tell Arjan if you don't want to translate a particular element by setting translate="no" in your element
| Language | Language Code |
|---|---|
| Afrikaans | af |
| Albanian | sq |
| Amharic | am |
| Arabic | ar |
| Azerbaijani | az |
| Bengali | bn |
| Bosnian | bs |
| Bulgarian | bg |
| Chinese (Simplified) | zh |
| Chinese (Traditional) | zh-TW |
| Croatian | hr |
| Czech | cs |
| Danish | da |
| Dari | fa-AF |
| Dutch | nl |
| English | en |
| Estonian | et |
| Finnish | fi |
| French | fr |
| French (Canada) | fr-CA |
| Georgian | ka |
| German | de |
| Greek | el |
| Hausa | ha |
| Hebrew | he |
| Hindi | hi |
| Hungarian | hu |
| Indonesian | id |
| Italian | it |
| Japanese | ja |
| Korean | ko |
| Latvian | lv |
| Malay | ms |
| Norwegian | no |
| Persian | fa |
| Pashto | ps |
| Polish | pl |
| Portuguese | pt |
| Romanian | ro |
| Russian | ru |
| Serbian | sr |
| Slovak | sk |
| Slovenian | sl |
| Somali | so |
| Spanish | es |
| Spanish (Mexico) | es-MX |
| Swahili | sw |
| Swedish | sv |
| Tagalog | tl |
| Tamil | ta |
| Thai | th |
| Turkish | tr |
| Ukrainian | uk |
| Urdu | ur |
| Vietnamese | vi |
Arjan Optimize helps you optimize all of your static assets with a single command. It takes into account several of the modern web dev directives and uses some of the most popular node modules for minification/compression of assets with a couple of neat features of its own.
Most CDN’s like Cloudfront, allow you to compress file off the fly using GZIP. So why should you minify? Essentially minification and compression are two different techniques that can be used to reduce file size. One technique doesnt override the the other and for optimal result you should use both. If you want to learn more about minification/gzip compression and their differences, CSS Tricks’s Chris Coyier gives a great exaplanation in this article.
- easy installation
- compresses images to jpg/png/tiff/webp
- minifies svg
- converts images from any format to webp
- automatically replaces img tags in HTML
Arjan optimize scans your current directory recursively and for each file with a different module depending on the files MIME type. Arjan Optimize uses:
| Input | Module used | Output | options | reason used |
|---|---|---|---|---|
| html | html-minifier | html | options | best compression |
| css | csso | css | options | best overall size+speed+compression |
| js | terser | js | Parse, Compress, Mangle | support for ES6, best speed & compression |
| svg | svgo | svg | options | most widely used open source option |
| jpeg | sharp | jpeg | options | fastest option |
| png | sharp | png | options | fastest option |
| webp | sharp | webp | options | fastest option |
| gif | sharp | png | options | fastest option |
| tiff | sharp | tiff | options | fastest option |
The webp option in Arjan Optimize does 2 things:
- converts all your images to webp using sharp and saves them (without overwritting images in original format)
- In the HTML files, it replaces each img tag with a picture tag that holds both its original compressed version and its webp version.
Because webp is a relatively new format, it is not supported by all browsers. The picture tag is a solution that allows unsupported browsers to fall back to the original version of the image. This article goes more in depth on webp and the picture tag.
suppose we have the following image tag:
<img src="img/arjan-logo.png" class="img-fluid">
this will be replaced by:
<picture>
<source type="image/webp" srcset="img/arjan-logo.png">
<source type="image/png" srcset="img/arjan-logo.png">
<img src="img/arjan-logo.png" class="img-fluid">
</picture>
USAGE
$ arjan optimize [FILENAME]
ARGUMENTS
FILENAME name of the file i.e. index.html
OPTIONS
-c, --css minifiy css using cssnano
-h, --html compress html using html-minifier
-i, --images compress images and if possible maintain the format, otherwise its converted to png.
-j, --js minify js using uglify js
-w, --webp saves a webp version of each image, then replaces each image instance in the html files with a picture tag.
Arjan audit is a simple node module that helps automate the auditing process of static sites during the dev process using Google’s Lighthouse 6.
Often times when building a site, the page speed test is one of the last things we do. Sometimes theres a surprise and the score is not that good. To avoid these surprises you can use Arjan Audit in your dev process or even integrate it into your tests.
Arjan audit uses express to serve your site and google chrome-launcher to make a headless launch of google chrome and retrieve the audits from lighthouse 6. Arjan then parses the results returned by lighthouse and returns an organized subset of the results. When used from the CLI, Arjan returns a console report that adds colors and recomendations based on your threshold value.
the threshold value is a number from 0 to 1 that represents your personal threshold for what you consider a decent enough site. the default is .8 (a B) 10 points above from this score is great, anything bellow isn't acceptable. this threshold value will filter out recommendations and add colors to your scores in the report.
- install the arjan CLI globally.
npm i -g arjan-cli - inside your project directory, initialize arjan
arjan init - run an audit
arjan audit
const Audit = require('arjan-audit')
Audit('./', 'index.html', 8080, .7)
.then(data=> console.log(data))
.catch(err=>console.log(err))
the audit report is a subset of data from the JSON response of lighthouse 6. For more information on the parameters of lighthouse 6 see this [link](http://for more information on audit properties: https://github.com/GoogleChrome/lighthouse/blob/master/docs/understanding-results.md#audit-properties)
{
"lh5_score":float,
"lh6_score":float,
"main_metrics":{
"metric":{
"title":"string",
"score":float,
"description":"string"
}
},
"improvements":{
"improvement":{
"title":"title",
"score":float,
"description":"description",
"details":{}
}
}
}
| Audit | Weight |
|---|---|
| First Contentful Paint | 20% |
| Speed Index | 27% |
| First Meaningful Paint | 7% |
| Time to Interactive | 33% |
| First CPU Idle | 13% |
Google recently recalculated the score of what they consdier a healthy fast site. The new LCP metric was introduced and the score weights and metrics were changed. For more information check out Google’s Web Vitals
| Audit | Weight |
|---|---|
| First Contentful Paint | 15% |
| Speed Index | 15% |
| Largest Contentful Paint | 25% |
| Time to Interactive | 15% |
| Total Blocking Time | 25% |
| Cumulative Layout Shift | 5% |
- first-contentful-paint
- speed-index
- largest-contentful-paint
- total-blocking-time
- interactive
- cumulative-layout-shift
- first-meaningful-paint
- first-cpu-idle
- notification-on-start
- largest-contentful-paint-element
- critical-request-chains :
- layout-shift-elements:
- robots-txt
- canonical
- color-contrast
- label
- redirects
- content-width
- image-aspect-ratio
- image-size-responsive
- deprecations
- mainthread-work-breakdown
- bootup-time
- uses-rel-preload
- uses-rel-preconnect
- font-display
- aria-allowed-attr
- aria-hidden-body
- aria-hidden-focus
- aria-valid-attr-value
- aria-valid-attr
- button-name
- bypass
- document-title
- duplicate-id-active
- duplicate-id-aria
- frame-title
- heading-order
- html-has-lang
- html-lang-valid
- image-alt
- link-name
- list
- listitem
- meta-viewport
- video-caption
- video-description
- uses-long-cache-ttl
- total-byte-weight
- offscreen-images
- render-blocking-resources
- unminified-css
- unminified-javascript
- unused-css-rules
- unused-javascript
- uses-webp-images
- uses-optimized-images
- uses-text-compression
- uses-responsive-images
- efficient-animated-content
- appcache-manifest
- doctype
- charset
- dom-size
- external-anchors-use-rel-noopener
- no-document-write
- no-vulnerable-libraries
- js-libraries
- password-inputs-can-be-pasted-into
- uses-passive-event-listeners
- meta-description
- http-status-code
- font-size
- link-text
- is-crawlable
- tap-targets
- hreflang
- plugins
Arjan deploy is a tool that helps you deploy static websites to the AWS cloud using Cloudformation. The tool is modular and can be used with the Arjan CLI, or programmatically in your own node.js project. Arjan Deploy gives you several different options to deploy your static sites in AWS and it also helps you import existing AWS projects, or individual resources into your websites project.
Arjan deploy also helps you import existing sites into your CloudFromation stack. For example, suppose you had previously created a public bucket and a hosted zone for yourdomain.com. Now you decide you want to add a CDN with HTTPS to your site. When you run the updateStack command, Arjan will automatically find these resources and import them into your Cloudformation template which will also contain the certificate and the Cloudfront distribution. In general, it’s better practice to use Cloudformation template when you have a project that requires various pieces of infrastructure that depend or interact with one another. It just makes your project easier to keep track of and maintain.
It turns out things get a bit trickier than expected when throwing in a CDN with HTTPS into the equation. As of now, to host a static site with HTTPS in AWS it requires more than one template and/or the use of multiple operations in the SDK.
Generally static sites in the cloud consist of an object storage solution (i.e. S3), a DNS (from your domain name provider or your cloud provider) a CDN or cache distribution network, and optionally may contain a digital certificate. Arjan Gives you options to add the following resources to your stack depending on your needs.
root: an s3 bucket for the root domain dns: Adds a Route53 Hosted zone to your stack. cdn: Adds an AWS Cloudfront distribution to your sites stack. More about Cloudfront. https: creates a digital certificate for your domain with AWS ACM. If you have a route53 DNS it will automatically verify your certificate. Else you must manually verify your certificate with your DNS provider. www: a reroute bucket for www
- go to your project's directory
cd your_project - run
arjan init PROFILE REGION - If you want your site to be online while still in development you can run
arjan deploy DOMAIN create - Then to update your stack to production you can run
arjan deploy DOMAIN update prodthis will add a route53 DNS, a cloudfront distribution and a verified SSL ceritifcate to your stack. - alternatively you can just run
arjan deploy DOMAIN create prodfrom the start.
In order to deploy a production site you must have already purchased a domain from a domain name registrar and you should have their respective interface open in order to create DNS records or transfer nameservers. there are several popular options out there; we like to use namecheap because as the name suggests it, its cheap, and it also has great service.
For an easier development workflow we have defined some setups that include dev, test and prod (production). You can customize these by additionally providing flags. dev → test → prod
- Dev: S3 root bucket with a public policy
- Test: S3 root bucket, www reroute bucket and a route53 hosted zone.
- Prod: CDN w/ Route53 DNS (https): Deploys s3 bucket, route53 DNS, a cloudfront distribution and creates TLS certificates in AWS ACM.
Custom Setup Examples
- CDN w/ Route53 DNS (http): Deploys s3 bucket, route53 DNS, and a cloudfront distribution.
- CDN w/ external DNS (http): Deploys s3 bucket and a Cloudfront distribution. You must create a CNAME record (and reroute record) in your external DNS.
- CDN w/ external DNS (https): Deploys s3 bucket and a Cloudfront distribution and creates certificates in ACM. You must create a CNAME record (and optionally a reroute record) in your external DNS.
Amazon Route 53 provides highly available and scalable Domain Name System (DNS), domain name registration, and health-checking web services. It is designed to give developers and businesses an extremely reliable and cost effective way to route end users to Internet applications by translating names like example.com into the numeric IP addresses, such as 192.0.2.1, that computers use to connect to each other.
AWS Route53 has a
- Route 53 offers powerful routing policies to allow for efficient DNS requests.
- You can combine your DNS with health-checking services to route traffic to healthy endpoints or to independently monitor and/or alarm on endpoints.
- Route 53 effectively connects user requests to infrastructure running in AWS – such as Amazon EC2 instances, Elastic Load Balancing load balancers, or Amazon S3 buckets
- can also be used to route users to infrastructure outside of AWS.
You can only use an external DNS if you include the CDN option and exclude the route53 option. If you are using an external DNS a CNAME record pointing to the root will invalidate all other records pointing to the root; so if you have other records pointing to your root, for example mail exchange (MX) records to send/receive email with your custom domain you will have to perform some additional steps.
Instead of pointing the CNAME record to the root, you can point to the CNAME to the www subdomain. Then you can create a reroute or FWD record in your DNS provider console to reroute all http requests coming in to the root to the www. You can check out the following links to learn how to reroute requests in major DNS providers
- Namecheap
- Godaddy
- Marcaria
- Google domains
Feel like arjan is missing features? we do too! Since arjan isnt really a framework you can create or use any kind of node module as a plugin. To create a new command for your plugin you can run oclif command COMMAND_NAME. For more info on extending the cli commands checkout oclif's docs.
If you want your command to be added to arjans next version create a feature request in the cli's repo
sh-session
$ npm install -g arjan-cli
$ arjan COMMAND
running command...
$ arjan (-v|--version|version)
arjan-cli/0.1.0 linux-x64 node-v12.13.1
$ arjan --help [COMMAND]
USAGE
$ arjan COMMAND
...
arjan auditarjan deploy SITE ACTION [SETUP]arjan help [COMMAND]arjan init [REGION] [PROFILE]arjan localize LANGUAGE [FILES]arjan optimize [FILENAME]arjan upload
Describe the command here
USAGE
$ arjan audit
OPTIONS
-d, --dir=dir Directory path to serve. default is root (relative to the path in which you run the
command)
-f, --file=file Path of the page you want to audit. default is index.html
-p, --port=port Port used for the test server. Default is 8080.
-t, --threshold=threshold Integer value from 0 to 1 that represents what you consider to be an acceptable lighthouse
score for your site. Its very similar to what you would consider an acceptable school test
grade.
DESCRIPTION
...
Extra documentation goes here
See code: src/commands/audit.js
Describe the command here
USAGE
$ arjan deploy SITE ACTION [SETUP]
ARGUMENTS
SITE name of the site i.e. yoursite.com
ACTION (create|update|import|delete|upload) choose an action to perform. you can create, update, import your stack or
upload files to your bucket.
SETUP (dev|test|prod|custom) [default: dev] setup for the site - dev, test, production or custom
OPTIONS
-c, --cdn creates a CloudFront distribution for your site.
-e, --error=error [default: error.html] name of the error document
-h, --https creates and validates a TLS certificate for your site. If you arent using a route53 DNS you must
create a CNAME record manually in your DNS.
-i, --index=index [default: index.html] name of the index document. default is index.html
-r, --route53 creates a Hosted Zone in route 53. Have your current DNS provider page open and ready to add a
custom DNS.
-u, --upload=upload name of a specific file you want to upload to your site. all uploads all of the files
-w, --www creates a www s3 bucket that reroutes requests to the index.
DESCRIPTION
...
Extra documentation goes here
See code: src/commands/deploy.js
display help for arjan
USAGE
$ arjan help [COMMAND]
ARGUMENTS
COMMAND command to show help for
OPTIONS
--all see all commands in CLI
See code: @oclif/plugin-help
Describe the command here
USAGE
$ arjan init [REGION] [PROFILE]
ARGUMENTS
REGION [default: us-east-1] AWS Region
PROFILE [default: default] AWS Profile
OPTIONS
-a, --audit builds required files/dirs for arjan audit
-d, --deploy builds required files/dirs for arjan deploy
-l, --localize builds required files/dirs for arjan localize
-o, --optimize builds required files/dirs for arjan optimize
DESCRIPTION
...
Extra documentation goes here
See code: src/commands/init.js
Describe the command here
USAGE
$ arjan localize LANGUAGE [FILES]
ARGUMENTS
LANGUAGE origin language of the file/s.
FILES name of the file you want to translate -only html files accepted. Use all to translate all of your html
files (default).
OPTIONS
-b, --backwards Update JSON locale accoridng to changes made in the HTML file. Must be used together with
the update flag.
-c, --create Create locale/s for your site. When used with translate flags, it generates a translated
version of the locale and the HTML.
-e, --export Creates a CSV file for your JSON locale.
-i, --import Update JSON locale from changes made in the CSV file
-t, --translate=translate desired translation language. You may apply this flag multiple times to translate into
multiple languages.
-u, --update Update HTML file accoridng to changes made in the JSON locale.
DESCRIPTION
...
Extra documentation goes here
See code: src/commands/localize.js
Describe the command here
USAGE
$ arjan optimize [FILENAME]
ARGUMENTS
FILENAME name of the file i.e. index.html
OPTIONS
-c, --css minifiy css using cssnano
-h, --html compress html using html-minifier
-i, --images compress images and if possible maintain the format. otherwise its converted to png.
-j, --js minify js using uglify js
-w, --webp saves a webp version of each image, then replaces each image instance in the html files with a picture
tag.
DESCRIPTION
...
Extra documentation goes here
See code: src/commands/optimize.js
Describe the command here
USAGE
$ arjan upload
OPTIONS
-n, --name=name name to print
DESCRIPTION
...
Extra documentation goes here
See code: src/commands/upload.js
createDir(dir)
- Description: Writes a directory only if it didnt previously exist.
- params:(dir)
- dir: string: name of the directory to build.
- returns: Promise(resolve, reject)
- resolve: boolean: true
- reject: error
createFile(file, contents)
- Description: Writes a file only if the file didn't previously exist.
- params:(file, contents)
- filePath: string: path of the file
- contents: string: contents of the file as a string.
- returns: Promise(resolve, reject)
- resolve: string: contents of the file
- reject: error
initBuild(region, profile)
- Description: builds some required directories and files in your project.
- params:(region, profile)
- region: string: desired AWS region
- profile: string: local AWS profile
- returns: Promise(resolve, reject)
- resolve: string: ‘built’
- reject: error
CreateLocale(html)
- Description: Parses the HTML of the input file; then for all elements that contain text it adds an ID. Then it generates or re-writes a JSON file that contains ids and the text values.
- Params: (html)
- html: string: HTML content to parse.
- returns: Promise(resolve, reject)
- resolve: ({locale:locale, html:html})
- locale: string: JSON string with the locale.
- html: string: Modified HTML containing the necessary ID’s
- reject: error
- resolve: ({locale:locale, html:html})
TranslateLocale(input, language, translation)
- Description: Translates each value using amazon translate then generates or re-writes a JSON file that contains ids and translated values.
- params: (input, language, translation)
- input: string: Locale to parse
- language: string: Approporiate lanugage code for the input locale’s language.
- translation: string: Appropriate lanugage code for the desired output language
- returns: Promise(resolve, reject)
- resolve: translation: string
- reject: error
TranslateHtml(html, json)
- description: Replace text content in an HTML document according to the values in the provided JSON locale.
- params:(html, json)
- html: string: html string to parse.
- json: string: JSON string containing text values for the html (in the translated language).
- returns: Promise(resolve, reject)
- resolve: string: The translated html file
- reject: error
jsonToCsv(lang, obj)
- description: converts a JSON locale into a CSV.
- params:(lang, obj)
- lang: string: Approproate language code for the language of the file.
- obj: string: Properly formatted JSON locale as a string.
- returns: Promise(resolve, reject)
- resolve: csv: string: a string with the output CSV
- reject: error
csvToJson(lang, csv)
- description: reads a CSV file and converts it to JSON
- params: (lang, csv)
- lang: string: Approproate language code for the language of the file
- csv: string: a string formatted in CSV.
- returns: Promise(resolve, reject)
- resolve: string: a string with the JSON object.
- reject: error
copyFile(filename, output)
- Description: Copy a file into another directory.
- params: (filename, output)
- filename: string: Path of the file
- outputDir: string: the output directory in which you want to save the file
- returns: Promise(resolve, reject)
- resolve: string: path of the file
- reject: error
scanFolder(currentDirPath, outputDir, ignorePaths, callback)
- description: Recursively scans folder and creates arrays that contain the filepaths for each MIME type.
- params: (currentDirPath, outputDir, ignorePaths, callback)
- currentDirPath: string: Path of the current directory contents: string
- outputDir: string: output directory in which to copy the file to.
- ignorePaths: Object: a json object that contains filepaths to ignore as values and true|false as values.
- callback: (filePath, stat)
compressImages(filePath, output, imageArr, svgoConfig)
- description: Compresses an image according to its MIME type. Uses Sharp to compress most image formats and uses SVGO to minimize svgs.
- params:(filePath, output, imageArr, svgoConfig)
- filePath: string: Path of the image
- output: string: desired directory in which to save the compressed image
- imageArr: array: contains paths of images being compressed
- svgoConfig: Object: object with the options for svgo.
- returns: Promise(resolve, reject)
- resolve: int: size of image in bytes
- reject: error
compressWebp(filePath, outputDir)
- description: Converts an image into webp using sharp.
- params: (filePath, outputDir)
- filePath: string: Path of the image
- outputDir: string: desired output directory in which to save the compressed image.
- returns: Promise(resolve, reject)
- resolve: int: size of image in bytes
- reject: error
replaceWebp(imgPath, html)
- description: Parses your html document and replaces all img tags referencing the imagePath with a picture tag that contains the webp and regular/compressed versions of the image.
- params: (imgPath, html)
- imgPath: string: path of the image
- html: string: html string in which you want to find and replace the image.
- return: Promise(resolve, reject)
- resolve: int: size of image in bytes
- reject: error
runAudit(dir, index, port, threshold)
- description: starts a simple local static server with express, runs a lighthouse audit using lighthouse 6. Then it returns a JSON object with lighthouse scores + audit report details and exits the local server.
- params: (dir, index, port, threshold)
- dir: string: desired direcotry to serve e.g. dep_pack index: string: path of the file you want to audit; typically index.html.
- port: int: desired port number to use in the audit.
- threshold: float: number between 0 and 1. something bellow the threshold is considered a bad score. e.g. if you are a B student your threshold would be .8
- returns: Promise(resolve, reject)
- resolve: string: formatted
- reject: error
generateTemplate(domainName, index, error, www, cdn, route53, https)
- description: Generates a JSON cloudFormation template for your stack.
- params: (domainName, index, error, www, cdn, route53, https)
- domainName: string: domain name of your site i.e. yoursite.com
- index: string: Index document for your site i.e. index.html
- error: string: error document for your site i.e. error.html
- www: boolean: option to add re route bucket from www to root
- cdn: boolean: option to add a Cloudfront distribuition to your stack
- route53: boolean: option to add a Domain Name System DNS
- https: boolean: option to add a digital certificate
- returns: Promise(resolve, error)
- resolve({"template":template, "existingResources": ResourcesToImport})
- template: string: stringified JSON cloudformation template
- existingResources: Array: An array containing existing AWS resources that are included in the template.
- reject: error
- resolve({"template":template, "existingResources": ResourcesToImport})
deployStack(domainName, template, existingResources, importAction)
- description: Creates a cloudformation changeset and executes it.
- params: (domainName, template, existingResources, importAction)
- domainName: string: Domain name of your site i.e. yoursite.com
- template: string: stringified JSON cloudformation template
- existingResources: Array: An array containing existing AWS resources that you want to import into your stack (resourcesToImport).
- importAction: boolean: true|false. True if you want to execute an import. false if you want to execute a create|update.
- returns: Promise(resolve, error)
- resolve({stackName:stackName, changeSetName:changeSet.name, action:changeSet.action})
- name: string: Name of the cloudformation stack
- changeSet: string: Name of the changeset
- action: string: action to execute in cloudformation. options include: create|update|delete.
- reject: error
- resolve({stackName:stackName, changeSetName:changeSet.name, action:changeSet.action})
createChangeSet(stackName, template, existingResources, importAction)
- description: Creates a changeset in AWS cloudformation.
- params: (stackName, template, existingResources, importAction)
- stackName: string: Name of the cloudformation stack
- template: string: stringified JSON cloudformation template
- existingResources: Array: An array containing existing AWS resources that you want to import into your stack (resourcesToImport).
- importAction: boolean: true|false: true if you want to execute an import. false if you want to execute a create|update.
- returns: Promise(resolve, reject)
- resolve({changeSetName:changeSetName, action:action})
- name: string: Name of the changeset
- action: string: action to execute in cloudformation. options include: create|update|delete.
- reject: error
- resolve({changeSetName:changeSetName, action:action})
requestCertificate(domainName)
- description: requests an ACM certificate.
- params: (domainName)
- domainName: string: domain of your site i.e. yoursite.com
- returns: Promise(resolve, reject)
- resolve: string: ARN of the ACM certficate
- reject: error
describeCertificate
- description: gets the CNAME records required to verifiy the ACM certificate.
- params: (certificateArn)
- certificateArn: string: ARN (amazon resource number) for the ACM certificate.
- returns: Promise(resolve, reject)
- resolve: ({"cName": cName, "cValue": cValue})
- cName: string: name of the CNAME record
- cValue: string: value of the CNAME record
- reject: error
- resolve: ({"cName": cName, "cValue": cValue})
validateCertificate
- description: validates an ACM certificate by creating the required records in route53.
- params: (cName, cValue, stackName)
- cName: string: name of the CNAME record
- cValue: string: value of the CNAME record
- stackName: string: name of the CloudFormation stack
- returns: Promise(resolve, reject)
- resolve: string: “record for certificate created”
- reject: error
createCertificate
- description: requests and validate an ACM certificate
- params: (domainName, stackName, route53)
- domainName: string
- stackName: string
- route53: boolean
- returns: Promise(resolve, reject)
- resolve: arn: string
- reject: error
importCertificate(domain, template, existingResources, https, route53, certArn)
- description: import an ACM certificate into your stack.
- params: (domain, template, existingResources, https, route53, certArn)
- domain: string: domain of your site i.e. yoursite.com
- template: string
- existingResources: string
- https: string
- route53: string
- certArn: string
- returns: Promise(resolve, reject)
- resolve: string: existingResources
- reject: error
stackExists(stackName)
- description: check if a given cloudFormation stack exists. if the stack doesnt exist, the promise resolves with a null value.
- params: (stackName)
- stackName: string: name of the stack
- returns: Promise(resolve, reject)
- resolve: string: id of the cloudformation stack or null
- reject: error
bucketExists(domainName)
- description: check if a given bucket exists.
- params: (domainName)
- domainName: string: domain of your site i.e. yoursite.com
- returns: Promise(resolve, reject)
- resolve: boolean: true|false
- reject: error
distributionExists
- description: check if a cloudFormation distribution exists for a given domain. if it doesnt exist, the promise resolves a null.
- params: (domainName)
- domainName: string: domain of your site i.e. yoursite.com
- returns: Promise(resolve, reject)
- resolve: obj: {"id":cloudfront_dist_id, "domainName":domain}
- reject: error
certificateExists(domainName)
- description: check if an ACM certificate exists for a given domain.
- params: (domainName)
- domainName: string: your sites domain i.e. yoursite.com
- returns: Promise(resolve, reject)
- resolve: string: ARN of the ACM certificate
- reject: error
hostedZoneExists(domainName)
- description: check if a hosted zone exists for a given domain.
- params: (domainName)
- domainName: string: domain of your site i.e. yoursite.com
- returns: Promise(resolve, reject)
- resolve: string: Id of the hosted zone
- reject: error
newHostedZone(stackName)
- description: returns the 4 nameservers for the hostedzone associated to a given stack.
- params: (stackName)
- stackName: string: name of the cloudformation stack.
- returns: Promise(resolve, reject)
- resolve: array: string: nameservers
- reject: error
DeleteSite(stackName)
- description: deletes a cloudformation stack
- params: (stackName)
- stackName: string
- returns: Promise(resolve, reject)
- resolve: string: stackName + ' cloudFormation Stack is being deleted.’
- reject: error
deleteCertificate(domain)
- description: deletes ACM certificates and existing route53 records for a given certificate.
- params: (domain)
- domain: string: domain of the site
- returns: Promise(resolve, reject)
- resolve: string: stackName + ' cloudFormation Stack is being deleted.’
- reject: error