My JavaScript Journey: Basic ES6 Browser Skeleton

In my last blog entry, I explained how to create a very basic ES6 CLI project. In this one, I will follow most of the same steps to create an ES6 browser project, instead. I’m not going to go into the same level of detail with respect to creating the project and checking in code in this article—see the first one if you have questions about those basics.

Add the App

After creating your project, add index.js to /src:

"use strict"

var sayHello = function () {
    return "Hello";
};

document.getElementById('msgBtn').addEventListener('click', function () {
    var message = sayHello();
    document.getElementById("message").innerHTML = message;
});

Create a new folder, /css, and add styles.css:

body {
    font-family: 'Arial';
    font-size: 16px;
    padding: 0;
    margin: 0;
}

header {
    background-color: #336666;
    padding: 14px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
}

h1, h2, h3 {
    font-weight: 200;
}

header > h1 {
    font-weight: 200;
    font-size: 18px;
    margin: 0;
    color: #FFFFFF;
}

h2 {
    font-size: 22px;
    margin: 20px 0 0 0;
}

h3 {
    margin: 10px 0 28px 0;
}

h3 > span {
    color: #0288D1;
}

label {
    display: inline-block;
    width: 80px;
    text-align: right;
    margin-right: 4px;
}

.content {
    padding: 20px;
}

.bar {
    display: inline-block;
    border: none;
    height: 8px;
}

.stretch {
    width: 100%;
    padding-left:0;
    padding-right:0;
}

.flex {
    display: -webkit-flex;
    display: flex;
}

.left {
    text-align: left;
}

.form > div {
    margin: 6px 0;
}

button {
    text-transform: none;
    -webkit-appearance: none;
    cursor: pointer;
    padding: 12px 18px;
    border-radius: 10px;
    background: #F1F1F1;
    font-size: 16px;
    border: solid 2px #ddd;
    color: #444;
}

button:hover {
    background: #F6F6F6;
    border: solid 2px #ccc;
}

button:active {
    background: #FCFCFC;
    border: solid 2px #ddd;
}

button:focus {
    outline:0;
}

In the project folder, add index.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
										<link href="css/styles.css" rel="stylesheet" type="text/css">
</head>
<body>
<header>
<h1>JavaScript ES6 Browser Skeleton</h1>
</header>
<div class="content">
<div class="form">
<div>
 <label htmlFor="msgBtn"></label>
 <button id="msgBtn">Get Message</button></div>
</div>
<h2>Message: <span id="message"></span></h2>
</div>
<script src="src/index.js"></script>
</body>
</html>

To see it work, open index.html in a browser (my example uses Chrome) and click the Get Message button: Screen Shot 2017-04-03 at 09.37.37 Checkin the code.

Add ES6 import/export Code

In /src, add hello.js:

const hello = 'Hello';
export default hello;

Modify index.js to import this module, then use it to get the text “hello.”

import hello from './hello.js';

var sayHello = function () {
    return hello;
};

document.getElementById('msgBtn').addEventListener('click', function () {
    var message = sayHello();
    document.getElementById("message").innerHTML = message;
});

If you run the code, you will get an error in the console (to open the console in Chrome, on a Mac, click ⌥⌘i). Output: Uncaught SyntaxError: Unexpected token import Screen Shot 2017-04-03 at 09.48.28 Do the next steps to fix it.

Add webpack

See https://www.npmjs.com/package/webpack/ webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser.

npm install webpack --save-dev

Modify index.html to run from webpack bundle: Replace:

<script src="src/index.js"></script>

with:

<script src="dist/bundle.js"></script>

To create the bundle, in the project folder, run:

./node_modules/.bin/webpack app/index.js dist/bundle.js

Output:

Hash: d65b6915dcad093cc77c
Version: webpack 2.3.3
Time: 109ms
    Asset     Size  Chunks             Chunk Names
bundle.js  3.31 kB       0  [emitted]  main
   [0] ./src/hello.js 45 bytes {0} [built]
   [1] ./src/index.js 251 bytes {0} [built]

webpack creates bundle.js in /dist. Compare this file to index.js to see how webpack replaces the ES6 instructions with ES5 compatible wrapper code.

Either refresh your browser window or open index.html from your project folder. The error will be gone.

Screen Shot 2017-04-03 at 09.37.37

Add .gitignore:

.DS_Store
dist
node_modules

Checkin the code.

Using webpack with node

To enable node to build the webpack bundle, in the project folder, add webpack.config.js. Notice: this code is written in ES5.

var path = require('path');
module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

This can be run from the project directory to create dist/bundle.js (delete the existing dist/bundle.js first so you can see the new one get built):

./node_modules/.bin/webpack --config webpack.config.js

The final piece is to add a build script to package.json:

{
  ...
  "scripts": {
    "build": "webpack"
  },
  ...
}

In the project directory, run:

npm run build

And, there you have it. The node script builds the webpack bundle, dist/bundle.js from which index.html gets the packaged html that it renders.

Checkin the code.

In Conclusion

Packaging a simple ES6 app with webpack transpiles the code into a bundle that can be run on any browser that supports ES5. You can find the code in my github repository, skeleton-browser-js.

Copyright ©2014-17 Ramona Ridgewell. All rights reserved.

Posted in #Education, Coding, JavaScript, Writing | Tagged , , , , , | 1 Comment

Tishta the Crystal Orb: Denalton

I’m also back to having fun writing the story.

My latest chapter, “Denalton,” in my novel, “Tishta the Crystal Orb,” is now complete. Five chapters to go on this edit. I’ll be looking for Beta Readers, so if you’re interested, give me a shout. Follow my progress on The Wolf Dream Books blog.

via Tishta the Crystal Orb: Denalton — thewolfdreambooks

Posted in AmWriting, AmWritingFantasy, Books, Fantasy, Horror, Novel, Writing | Tagged , , , , , , , , | Leave a comment

Who’s Giving supports First Place School in April

Our featured Children’s Campaign for April is Classroom Wishes at First Place School.

via Classroom Wishes at First Place School is our April Children’s Campaign — Who’s Giving

Posted in Uncategorized | Leave a comment

My JavaScript Journey: Basic ES6 CLI Skeleton

I’ve been writing in this space as a sometimes journalist/essayist. Recently, it occurred to me I should share what I’m learning about JavaScript. One of the difficulties, for me, has been finding complete examples of how to set things up. I’ve been setting up bare-bones implementations—skeletons, aka, boilerplates—of projects. I have not taken good notes and I have not added them to my public repository. I’m going to change that, starting today.

The first project is a basic ES6 JavaScript CLI skeleton. I’m making an assumption that readers are fairly new to setting up their own projects. I do expect git and nodejs to already be installed.

If you are starting a new Javascript project, you should create it using ES6 JavaScript. This will mean using a transpiler to create ES5 code for browsers that don’t support ES6. babel is the accepted method to do this.

Initialize git Project

Start by creating a project directory.

mkdir JavaScriptEs6CliSkeleton
cd JavaScriptEs6CliSkeleton

Then, initialize it.

git init

Output:
Initialized empty Git repository in /Users/user/src/Closet/JavaScriptEs6CliSkeleton/.git/

Initialize npm Package

npm init -y

The -y argument creates a default package.json without prompting.

Output:
Wrote to /Users/ramonaridgewell/src/Closet/JavaScriptEs6CliSkeleton/package.json:

{
  "name": "JavaScriptEs6CliSkeleton",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Add the App

Add a folder, /src.
Add a file, /src/index.js:

function main() {
    var args = process.argv;
    if (args[2] && args[2] === '--v' ) {
        console.log('Es6CliSkeleton - version 1.0.0');
    } else {
        console.log('Hello');
    }
}
main();

In /src, run:

node index

Output:
Hello

Checkin Code

See http://gitref.org/basic/

From the project directory, run:

git st

Output:
On branch master
Initial commit
Untracked files:
(use "git add ..." to include in what will be committed)
package.json
src/
nothing added to commit but untracked files present (use "git add" to track)

From the project directory, run:

git add .
git st

Output:
On branch master
Initial commit
Changes to be committed:
  (use "git rm --cached ..." to unstage)
new file:   package.json
new file:   src/index.js

git commit -m "initial checkin"

Output:
[master (root-commit) 3b2adb4] initial checkin
2 files changed, 22 insertions(+)
create mode 100644 package.json
create mode 100644 src/index.js

To put the code into your GitHub repository, you need to push it.

git push origin master

If you go to your repo, you’ll see your checkin.

Add ES6 Code

For an example of how babel transpiles, add a new file, /src/hello.js.

const hello = 'Hello';
export default hello;

Modify index.js to import this module, then use it to get the text “hello.”

import hello from './hello';
function main() {
  let args = process.argv;
  if (args[2] && args[2] === '--v' ) {
    console.log('Es6CliSkeleton - version 1.0.0');
  } else {
    console.log(hello);
  }
}
main();

In /src, run:

node index

Output:
/Users/user/src/Closet/JavaScriptEs6CliSkeleton/src/index.js:1
(function (exports, require, module, __filename, __dirname) {
import hello from './hello';
^^^^^^
SyntaxError: Unexpected token import
at Object.exports.runInThisContext (vm.js:76:16)
at Module._compile (module.js:542:28)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:509:3

Do the next step to fix it.

Add babel Components

See https://babeljs.io/

Add babel basics

npm install babel-core --save-dev
npm install babel-preset-env --save-dev

If you wish, this can be done on a single line:

npm install babel-core babel-preset-env --save-dev

Add .babelrc

{
  "presets": [
    "env"
  ]
}

Add .babel-register

See https://babeljs.io/docs/usage/babel-register/

The require hook will bind itself to node’s require and automatically compile files on the fly.

npm install babel-register --save-dev

Add dev version of index.js, called _index.js. This is just my coding convention to differentiate between my working app and the one that will be distributed. Since index.js is written in ES6, it will not run without being transpiled. The act of requiring it from _index.js is what causes the transpiling to take place. Here is the code:

require("babel-register");
require("./index");

In /src, run:

node _index

Output:
Hello

If you run:

node index

Output (same as above):
SyntaxError: Unexpected token import

Note: Using npm install --save-dev (or --save), adds devDependencies (or dependencies) in package.json. At this point, it should look like this:

{
  "name": "JavaScriptEs6CliSkeleton",
  "version": "1.0.0",
  "description": "JavaScript ES6 CLI Skeleton",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-cli": "^6.24.0",
    "babel-core": "^6.24.0",
    "babel-preset-env": "^1.2.2",
    "babel-register": "^6.24.0"
  }
}

Add .gitignore

In the project directory, run:

git st

Output:
On branch master
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: package.json
modified: src/index.js
Untracked files:
(use "git add ..." to include in what will be committed)
.DS_Store
.babelrc
node_modules/
src/_index.js
src/hello.js

You don’t want to check in node_modules/ or .DS_Store (.DS_Store shows up as soon as you view the folder heirarchy in the Finder). Add .gitignore to the project directory to ignore these at checkin.

.DS_Store
/node_modules/

Checkin Code

To see current modifications, from the project directory, run:

git diff

Output:

diff --git a/package.json b/package.json
index cfc2e4f..f33febf 100644
--- a/package.json
+++ b/package.json
@@ -8,5 +8,10 @@
   },
   "keywords": [],
   "author": "",
-  "license": "ISC"
+  "license": "ISC",
+  "devDependencies": {
+    "babel-core": "^6.24.0",
+    "babel-preset-env": "^1.3.2",
+    "babel-register": "^6.24.0"
+  }
 }
diff --git a/src/index.js b/src/index.js
index 25e17da..2d42343 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,9 +1,11 @@
+import hello from './hello';
+
 function main() {
     var args = process.argv;
     if (args[2] && args[2] === '--v' ) {
         console.log('Es6CliSkeleton - version 1.0.0');
     } else {
-        console.log('Hello');
+        console.log(hello);
     }
 }

From the project directory, run:

git add .
git commit -m "added Babel components"

Output:
[master 0502202] added Babel components
6 files changed, 21 insertions(+), 2 deletions(-)
create mode 100644 .babelrc
create mode 100644 .gitignore
create mode 100644 src/_index.js
create mode 100644 src/hello.js

Build ES5 Compatible App

Next, build with babel-cli, which will transpile the ES6 to ES5. This also creates a build that babel-register does not compile each time it is run.

Add babel-cli

npm install babel-cli --save-dev

Add a script to package.json to “build” using babel and to have “start” run index:

{
  "name": "JavaScriptEs6CliSkeleton",
  "version": "1.0.0",
  "description": "JavaScript ES6 CLI Skeleton",
  "main": "index.js",
  "scripts": {
    "build": "babel src -d dist",
    "start": "node dist/index",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-cli": "^6.24.0",
    "babel-core": "^6.24.0",
    "babel-preset-env": "^1.3.2",
    "babel-register": "^6.24.0"
  }
}

In the project directory, run:

npm run build

Output:
babel src -d dist
src/_index.js -> dist/_index.js
src/index.js -> dist/index.js
src/hello.js -> dist/hello.js

In the project directory, run:

npm start

Output:
node dist/index
Hello

Update .gitignore

/dist/

Checkin code

From the project directory, run:

git diff

Output:

diff --git a/.gitignore b/.gitignore
index cfca405..17a7dd4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 .DS_Store
 /node_modules/
+/dist/
diff --git a/package.json b/package.json
index f33febf..8b7c9c2 100644
--- a/package.json
+++ b/package.json
@@ -4,12 +4,15 @@
   "description": "",
   "main": "index.js",
   "scripts": {
+    "build": "babel src -d dist",
+    "start": "node dist/index",
     "test": "echo \"Error: no test specified\" && exit 1"
   },
   "keywords": [],
   "author": "",
   "license": "ISC",
   "devDependencies": {
+    "babel-cli": "^6.24.0",
     "babel-core": "^6.24.0",
     "babel-preset-env": "^1.3.2",
     "babel-register": "^6.24.0"

From the project directory, run:

git add .
git commit -m "added Babel CLI"

Output:
[master cddf638] added Babel CLI
2 files changed, 4 insertions(+)

In Conclusion

And there you have it. An ES6 JavaScript skeleton ready for you to flesh out. You can find the code in my github repository, skeleton-cli-js.

Copyright ©2014-17 Ramona Ridgewell. All rights reserved.

Posted in #Education, Coding, Education, JavaScript, Programming, Software Development | Tagged , , , , | 1 Comment

Three Years on WordPress

I want to thank everyone who has visited my site and read my blogs. It sometimes surprises me how many people read them. There have been 38,430 views. I received a notification that it was my anniversary on WordPress. I started my blog three years ago. I wasn’t very good at it then, but I learn.

My most popular post, by far, is one of my very first, “‘Bones,’ Cancer and Real Life.” It has received 25,571 views. At the time I watched my first “Bones” episode—season 9, episode 13, “Big in the Philippines,” which was directed by David Boreanaz, who also plays a lead in the series—in January of 2014, I was just coming out of my grief over my husband’s death in September of 2012. I remember feeling like the sun had finally come out after more than a year in the rain. Even though I knew nothing about “Bones” or the characters, I was pulled deeply into the story. I gasped. I talked back to the characters (I’m weird, that way). I cried—a lot. I wrote the blog two months later, after I binged on the series and experienced it sequentially, with all the richness a decade of character development can bring to a story. I was moved in different ways.

Even though most of my blogs are related to celebrities and celebrity events—Echoes of Hope‘s annual celebrity hockey game being among them—I have also gotten fairly strong responses to some of my blogs about local history and events. For example, “Randy Lewis Talks about the Occupation of Fort Lawton” has received nearly 300 views. For this one, I drove up to Everett (half an hour north of Seattle) to interview Randy Lewis, Colville, one of the Elders at United Indians of All Tribes Foundation (UIATF). I like interviewing people and taking their photos. And, I like sharing it with others.

During the last year, I began writing about current events, many of which were about the violence in our society—”A Culture of Violence,” “Forty-nine New Names,” “How Many Gun Deaths Are Acceptable,” “Remember Them,” and “Dakota Access Pipeline Protest Turns Violent.” These stories felt too important not to write. I shared my deepest feelings, about my continuing grief and healing process over the loss of my husband, in a post, “Four Years Gone“—not the first time I’ve written about him; my concerns for America in “Thoughts on a Polarized America” and “The Beginning of the End for the EPA?;” things I find interesting, such as “My First Biography, or The Importance of Reading as a Child“—which is about my childhood hero, Harriet Tubman—and a few indie film blogs, like “Don’t Miss Jack Goes Home” and “‘Last Days of Summer’ Premieres at Rhode Island International Film Festival,” which involved two of my favorite actors, Thomas Dekker (who wrote and directed “Jack Goes Home”) and Michael Rosenbaum (who acted in “Last Days of Summer”). I even posted two of my own short stories, “The Boy with the Broken Zipper,” which is based on a real boy I met who was living on the streets, and “Once There Were Men,”which is dystopian SciFi.

I don’t publish nearly enough here, but that’s partly because I maintain two other blogs—one for my business, Who’s Giving, and another for my books, The Wolf Dream Books. I also maintain three Twitter accounts @RamonaRidgewell, @WhosGiving and @TheWolfDreams, as well as my personal Facebook account, and Facebook pages for my company (Who’s Giving) and my books (The Wolf Dream Books). It’s been a lot of work handling them all, but I’m actually managing two businesses, so I don’t how else to set it up.

The most amazing thing I’ve learned in the last three years is, once you start writing, there is no stopping it. It’s like an addiction I need to manage so it doesn’t interfere too much with the things I’m supposed to be doing. I’m not planning to stop any time soon.

Copyright ©2014-17 Ramona Ridgewell. All rights reserved.

Posted in #bones, #cancer, #heroes, AmWriting, AmWritingFantasy, Books, Childhood, Common Ground, Dakota Access Pipeline, David Boreanaz, Environment, EPA, Fantasy, Gun Violence, Harriet Tubman, Homeless Youth, Homelessness, Independent films, Indie Film, Michael Rosenbaum, Non-profits, Pancreatic Cancer, Polarized America, Police Accountability, Pulse, Pulse Murders, Science, Slavery, Television, Theater, Thomas Dekker, Uncategorized, Writing | Tagged , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Tishta the Crystal Org: Another Week, Another Chapter

This week was a good one. I finished another chapter.

via Tishta the Crystal Orb: Another Week, Another Chapter — thewolfdreambooks

Posted in Uncategorized | Leave a comment

Don’t Miss Two Hour Transport March 22

This is my favorite place to read my own work and listen to a host of others at open mic. It is followed by invited readers. Always a thoroughly enjoyable night.

Join us for two hours of science fiction and fantasy reading at Cafe Racer on Wednesday, March 22nd. Signups start at 7:00 pm Five minute readings from signup 7:30 – 8:30 pm Invited readers 8:45 – 9:45 pm Invited Reader Bios Anaea Lay lives in Seattle, Washington where she writers, cooks, plays board games, reads […]

via March 2017 Reading — twohourtransport

Posted in Uncategorized | 1 Comment