The $100k piece of paper

Like many people, I too have been pondering the purpose of college. It took me forever to complete, I have mortgage like loan terms setup where I will be paying if off for the next 25 years, and I cannot remember the last time anyone asked me about my education background. Part of me is thankful that I was able to attend and finish school, but a another part of me is upset about the burden I now have for what sometimes seems useless. I now have three children and I have been thinking about what they will do and how can I best support them in choosing their futures. I am exploring all of this to help me reason with our state of education. I would like to share my findings with you. This is my opinion and it is ok to respectfully disagree, but I think we all can agree that upper level education needs reform in some way or another.

Let's just start by addressing the claims that in three months in a bootcamp can better prepare you for a career than four years at a college. It is not a fair question and that claim should be disregarded completely and neither route is a guarantee of a successful career. All bootcamp and computer science degrees are not created equally. Any poor program will leave you ill prepared for any career. Completion of either program does not validate a student proficiency. A diploma does not come with a GPA on it and I am not sure if you can really fail out of a code school.

Code Schools

Overview

Code schools are focused topic education establishments that survey the current needs of technology companies and train people to fill those roles. They from a practical place using a hands on approach to train people. Students learn from industry professionals, technology forums, and the completion of projects. Instructors are not required to have a degree. Code schools take about three months to complete and can cost people up to $20,000. Graduates expect to quickly get a job making a ton of money and be great at it.

Assessment

The time and cost model is quite attractive but lets look a little deeper. Have you ever thought about the expenses saved not being in college but working? If you were hired after your bootcamp making just $60,000 a year, that's almost a quarter of a million in income that you would take in instead of being in a 4 year degree. You kind of have to appreciate what that is as so many people come out of college crippled with debt.

The curriculum does not come out of super pricey text books. It comes directly from professional developers. Content is directly relevant to the tech ecosystem. Code schools focus on what they say you need to know instead of general knowledge. You will not learn life science, economics, literature, or non tech history. You will learn the latest in industry standards and best practices. You will learn the tools used to be a master of your craft. You will go through career preparation and work on interviews. You will probably have accumulated over 500 hours coding and a solid portfolio.

You will not learn much about data structures, algorithms, or low level operations of a computer. You most likely will not learn about foundational concepts in technology. You probably will not talk about memory allocation, packets, artificial intelligence, data mining, robotics, or computer vision. I doubt you will go into networking or computer hardware.

Right now many employers do not see a bootcamp certificate as equal to a degree. This means that you may not have interviews lined up once you graduate like you may think.

There are a few things to be aware of when taking a bootcamp. Do you know whether or not the teacher is qualified? They may be a great developer but a horrible teacher. They may be a great teacher but a terrible developer. You can say the same about a college, but at a university there are some sort of guidelines. That being said, I feel some of those regulations can keep the best teachers out of play. Also think about what the school is teaching. They could just be teaching the latest trend and that trend will fade out. When that happens, will you be in trouble because you were too specialized?

Universities

Overview

Universities are broad topic education establishments that teach a lot of theory. The course content is regulated by the schools accreditation. They teach from a philosophical place focusing on lectures. Students learn from professors, reading text books, and writing papers. Instructors have many degrees. Universities take a minimum of four years and can cost well over $100,000 to complete. Again, graduates expect to quickly get a job making a ton of money and be great at it.

Assessment

College takes time and it is expensive. It is getting more expensive every year. A lot of the time and cost goes into the broad spectrum of classes that are required for degrees. A computer science major will need to take classes in non computer science fields. This can be seen as good and bad. Not every one knows what they want to be when they start college, so it is good to expose these young adults to all sorts of options. Also you may find that you are interested in topics that you would not expect. But is this worth the cost? That will be a personal answer.

A lot of the degree specific courses will be super heavy in theory, taught from a lecture hall, and reinforced through text books. The knowledge presented will be well rounded. The concepts are solid and have proven themselves over time. They teach a great foundation of knowledge and they will grow your ability to think critically.

There will not be as much project work and the projects you do will most likely not be as industry relative as a code school. The general take away I have from my reading is that university CS students do not write enough code, they do not have a strong portfolio, and are not prepared for a real job. Some companies claim that it takes longer than desired to get them to a productive place on a team.

Another troubling piece of info is the score cards the department of education has released on different programs. Here is the Computer Science one. Graduation rates look low, salaries look low, and graduation costs are high. It's not exactly the sales pitch that draws the masses.

I am not saying all colleges and all students are like this, but colleges place a lot of focus on the college life. Join some greek thing, go to football games, and have some kidney failure. You will not get that same experience in a code school and for some the social growth thats happens in college is super important.

Other Opinions

I read an article from Triplebyte; they did a study on candidates that they have been placing. They found that bootcamp grads as a group tend to be better than college grads at web programming, writing clean and modular code, but worse at algorithms and understanding how computers work. Bootcamp grads match or beat college grads on practical skills but lose on deep knowledge. Bootcamp grads do better on web questions involving web servers, databases and load balancers. College grads do better on low-level design questions involving bit/bytes, threading, and memory allocation.

I also watched an interview that CourseReport did with the Director of Education at a successful code school. He has his PHD and taught inside universities for 10 years but left the system because wasn't designed to successfully train his students. Computer Science students do not write nearly enough code in universities, to be successful.

My Story

Disclaimer: if you think college is the greatest thing out there and you just can't wait for you kids to be an alpha omega whateva just like you, skip this section :)

Ok, so I really tried to be impartial with my findings and I apologize if my world view is slightly jaded. I hope you can appreciate my effort to report something I don't fully support. I went to college; I have a 4 year degree. My $100,000 dollar piece of paper is in a box in the garage. I should get it framed or burn it.

I was constantly struggling in my college because they were not teaching what I knew I needed to know. They are a school that takes pride in their technology training. When I had a question, they would open the teacher edition book and give me the answer. I would regularly post questions on forums and get real answers from members of the web community. The classes I needed and wanted to take were not offered when I needed them so I had to take something else that would count towards graduation. The program is flawed, the best teacher I had was a professional that came in to teach a class. Every time I send out a monthly payment for my student loan I am reminded of how college failed me.

After college I went to a bootcamp of sort run by a company. This was way before bootcamps were even a thing. What I learned in 6 weeks was above and beyond anything I ever learned in school (although college business law was amazing).

I do not think colleges are evil. I actually think they do have a place in our society just not our dev community. The code school needs to step up and teach computer science and the college needs to bow out... Ok, rant complete.

Take aways

Both routes will create success and failure. Both routes will have flaws and amazing components. It's not a one answer fits all kind of question. Each person needs to evaluate what is important to them and pick the path that will get them there.

People who will succeed will work hard, commit to the process, put the time in, inside and outside of the class, and do what it takes to succeed. This is true for both code schools and colleges.

Setting up your dev environment and intro to developer concepts

Browser

There are many options out there for a browser. The majority of people out there just use the browser that came on their computer because they don't know any better. But now that you are getting into development you do. All browser are not created equal. If you are writing and testing code you should use either

  • Google Chrome
  • Mozilla Firefox
  • Chrome Canary. Google Chrome Canary has the newest of the new Chrome features. Be forewarned: it's designed for developers and early adopters, and can sometimes break down completely.

So the reason you would use one of these is because or their debugging tools; meaning you have the ability to peer into the web page in a super efficient way to either see how it is working or why its broken.

Remember it is important to regularly view the code you write in multiple browsers. Different browsers will show your content in different ways. It will even prevent you from using the same HTML, CSS, and JavaScript features. The advanced browsers are known as evergreen browsers. They will self update with out a major press release or marketing version. Anyone who has ever worked in the web still gets shivers when they hear the name IE6.

For this course you will be developing in Google Chrome. We will not be addressing supporting non evergreen browsers.

Setup Chrome

  1. Download Google Chrome
  2. Install it with all the default settings
  3. Open Chrome
  4. Install plugin Web developer
  5. Install plugin Wappalzyer
  6. Install plugin Clear Cache

Chrome Dev tools

There are entire courses out there strictly teaching people how to use the chrome dev tools. Opend the dev tools by right clicking on a web page and selecting Inspect. We will only really be using two of these resources: Elements, Console, and maybe Device Mode.

That's it for now, but don't worry you will get a lot of time with this.

Choosing an editor

A text editor is not the same as a word processor. A word processor allows you to independently apply styles to text like italics, bold, underline, size, and font. Word processors were designed to create content to be read by people. It like looking at a website. You see the result of the formatting to make content easier to read.

A text editor is specific for writing code. It can apply formatting based on file extension; you cannot just randomly make a word large or big or red. You can write upper and lower case letters, numbers, and symbols. The default font is always set to a monospaced font (each character is the same width). This really helps visually align your code.

A text editor is not the same as and IDE (integrated development environment). An IDE is more of a toolbox while a text editor is more of a tool. IDE can really help with testing and compiling code but that comes at a price. A lot of times you will have to buy an IDE and they have the potential to use a lot of your system resources and they can run on the slower side. Some languages require an IDE. These languages are monolithic and rarely have the coolest tech available.

A text editor is usually a pretty fast application. When I said its more of a tool than a tool box you have to know that its a super tool thanks to the extensibility of the tool. You can install all sorts of plugins that will give your editor more power.

Editors are very personal, and each persons editor of choice is always the best. If you have one, I will not try to change your mind. But know that if you use the one I use (bc its the best) I will be able to help you write code in a very efficient way.

Some Editors

  • Atom.io
  • Sublime Text
  • Visual Code
  • Notepad++
  • VIM
  • Emacs

I use atom.io because its pretty. It is the first editor I used where i did not want to immediately change the colors. But truly atom is one of the more extensible editors out there. It was also built using html, css, and javascript. You can inspect this by opening the Developer Tools: View > Toggle Developer Tools menu, or by using the cmd-alt-i or ctrl-alt-i.

Setup Atom.io

  1. Download Atom
  2. Install Atom with all the default options
    1. Windows note: You may need to rename the downloaded file to have a .exe extension
  3. Open Atom

Configure Atom

Atom has a ton of configurations that can be installed. We are going to install a few that will help us get started.

Snippets | Keymap MAC | Keymap WIN | Config

Mac

  1. Open the Atom menu and select Preferences
  2. Click Open Config Folder
  3. Replace the content in each file with the appropriate content from above
  4. Close the config window

Windows

  1. Open the File menu and select Settings
  2. Click Open Config Folder
  3. Replace the content in each file with the appropriate content from above
  4. Close the config window

Code Quality Tools

Atom allows its functionality to be extended the the installation of Packages. Packages can be used for many things, but our main use for them now is to aid in the writing of clean and syntactically correct code.

  1. We need to open our Atom Settings again (you just did that).
  2. Click Packages
    • These are the packages that are already installed in our editor
    • Each one of them has settings that you can go into but for the core packages is usually good to leave them alone
  3. Click + Install and lets install these packages
    • editorconfig
    • linter
    • linter-standard-js
    • linter-htmlhint
    • linter-stylelint

OS Tweaks

We do a lot of things with files that normal users don't need to see. A lot of files on your computers are hidden to prevent people from breaking stuff. Its required that we see these files. It is also super important that we show file extensions too.

Mac

  1. Open your terminal
  2. defaults write com.apple.finder AppleShowAllFiles TRUE
  3. Open Finder and Finder Preferences
  4. Click the Advanced tab
  5. Check Show all filename extensions

Windows

  1. Open your Explorer
  2. Press the alt button to bring up your menu options
  3. Open the Tools menu and select Folder Options
  4. Click the View tab at the top
  5. Under the Advanced settings there is a option for Hidden files and folders, select Show hidden files, folders, and drives
  6. Uncheck Hide extensions for known file types
  7. Click the Apply to Folders button
  8. Click Ok

Using your Terminal or Command Line

When most people think of programming a picture of the terminal may pop in ther head. It has the potential to be an intimidating tool but as a developer you will discover that you will not be able to live with you, and you will also realize it's not difficult to use at all.

Open your console. This is going to be a hands on exercise

Mac

  1. Mac: cmd + space Terminal
  2. Get your current directory pwd
  3. Get the name of the logged in user whoami
  4. List the content in your current directory ls
  5. Change you directory to your Desktop cd Desktop
  6. Make a new directory called New mkdir New
  7. Navigate into that directory cd New
  8. Create a new file called README.md echo hello > test.txt
  9. Open this directory in Finder open .
  10. Go to the immediate parent directory cd ..
  11. Close the terminal exit

Windows

  1. Win: Start > Run Command Prompt
  2. Get your current directory cd
  3. Get the name of the logged in user whoami
  4. List the content in your current directory dir
  5. Change you directory to your Desktop cd Desktop
  6. Make a new directory called New mkdir New
  7. Navigate into that directory cd New
  8. Create a new file called README.md echo hello > test.txt
  9. Open this directory in Explorer explorer .
  10. Go to the immediate parent directory cd ..
  11. Delete the New directory rd New
  12. Close the terminal exit

Version Control

Version control is a technological solution for being human. How many of you have ever deleted or changed something that you regret? We all have. Programmers don't just write code, we have this nasty habit of changing code. Unfortunately, no programmer is perfect, and sometimes, mistakes are made. Version control gives us the ability to go back to an older version of a file. It also allows us to see the changes that have occurred to a file over time.

There are many version control systems out there. Often they are divided into two groups: centralized and distributed.

Centralized version control systems (CVCS) are based on the idea that there is a single central copy of your project somewhere (probably on a server), and programmers will commit their changes to this central copy. Examples: CVS, Subversion, and Perforce.

Distributed systems (DVCS) do not necessarily rely on a central server to store all the versions of a project's files. Instead, every developer a copy of a repository and has the full history of the project on their own hard drive. This copy (or clone) has all of the metadata of the original. Examples: Git, Mercurial, Bazaar or Darcs.

<! data-preserve-html-node="true"--image-->

Read More

Git

Git is a distributed system. Conceptually, most other systems store information as a list of file-based changes. You think of the information they keep as a set of files and the changes made to each file over time.

<! data-preserve-html-node="true"--image-->

Instead, Git thinks of its data more like a set of snapshots of a miniature filesystem.
<! data-preserve-html-node="true"--image-->

Most of the interaction you have with git will be on your own local computer. Git can operate completely independently of a network connection; it doesn’t need to go out to the server to get the history and display it for you. This is accomplished by having a local git repository/database. You work with it and when you are ready, you can sync up with a git repository on the internet.

There are 3 states of a file in git: committed, modified, and staged.

  • Committed: The data is safely stored in your local repo/database.
  • Modified: You have changed the file but have not committed it to your database yet.
  • Staged: You have marked a modified file in its current version to go into your next commit.

<! data-preserve-html-node="true"--image-->

The basic Git workflow goes something like this:

  1. You modify files in your working directory.
  2. You stage the files, adding snapshots of them to your staging area.
  3. You do a commit, which takes the files as they are in the staging area and stores that snapshot permanently to your Git directory.

GitHub

GitHub is a code hosting platform for git that promotes collaboration. It lets you and others work together on projects from anywhere. You can create projects for just about anything. I use GitHub to hold the code my projects, to let me contribute to the code on other projects, to keep track of my computers configuration files, and to even plan events.

You will use GH to keep track of every piece of code you write in this class. By the end of this session you will have put a ton of content into your own personal repository.

GitHub Setup

  1. Go to GitHub
  2. Sign up
  3. EXERCISE: Learning GitHub

GitHub Issues

Github uses a concept of issues. The purpose of issues is basically calling out something thats broken or needs to be done. Issues are not a part of git; they are purely a GH feature.

You now know enough to be dangerous, so be careful and stay tuned for more

BUILDING A SEED PROJECT WITH WEBPACK, REACTJS, AND ES6: PART 4 LIVE RELOAD

Completed Repo: Part 3

In this post we will be taking the code from our the last part and turn that into a development server.

Main Topics

Webpack | ES6 | ReactJS

Supporting Topics

NPM

Dev Environment

So a developer environment can be a personal thing. But I think most of us would agree that we want something that watches our project for changes then live updates our code. We do not want errors in the code to terminate the process. Let's start with installing our server package with npm.

seed-project $ npm install --save-dev webpack-dev-server

Next we are going to create a npm script in our package.json file for running our dev environment. Here is the current script after dev has been added.

"scripts": {
  "test": "standard ./**/*.js, ./**/*.jsx, *.js | standard-reporter --stylish",
  "build-dist": "rm -rf ./dist && webpack --config webpack.config.js --bail -p",
  "dist": "npm test && npm run build-dist",
  "dev": "webpack-dev-server"
}

Go ahead and run the script now in your terminal.

seed-project $ npm run dev

So when we run this our, terminal will get real busy. It is going to process all of our assets, build the entire site, and print everything to the screen. The bigger your project the longer it will take for the initial build to happen. I have some pretty large projects using this with close to a thousand modules being processed. That takes about 10 seconds to load. Now take a look at your projects folders. You may have a dist directory from previously running our build process. If you do, press ctrl + c in your terminal to stop the dev server, delete the dist directory rm -rf dist, then restart your server. Before now we were serving our built directory but with our new dev server we are serving the project from a build that exists in our computers memory. It is the same build but it never creates physical copies of file to serve. Go ahead an make a change to the heading text in app/components/main/Main.js. Watch you terminal when you save it. It will detect the change and rebuild that module. If you refresh the browser you will see the change. Problem is we still have to refresh our page and that just gets tedious after about 5 minutes.

We need to go back to our package.json and add a flag to our dev script.

"dev": "webpack-dev-server --inline"

We need to make another change to our webpack config. We are going to add a property to our output for a public path.

output: {
  filename: 'bundle.js',
  path: path.join(__dirname, 'dist'),
  publicPath: 'http://localhost:8080/'
}

Restart your server and change the heading text again. The browser should refresh and render your change. The --inline flag tells webpack that we want the server to run with auto refresh using inline mode instead of iframe mode.

Technically we could stop here but let's make this even cooler. To be continued...

Building a seed project with Webpack, ReactJS, and ES6: Part 3 Adding loaders

Completed Repo: Part 3

Welcome back! Last time we set up a basic webpack config giving us the ability to bundle our repository into a single source of code truth giving us an easy point to deploy from. we also learned about npm and semantic versioning of packages. Lastly, we setup up some code standards for linting. The last two moved kind of slow; think it of the warm up before the show because we are about to really start moving.

In this post we will build out a lot of functionality in our webpack process. We will transpile ES6 code, incorporate assets, and compile styles. I will also introduce a paradigm in file structure you may not be familiar with. I really like it and won't judge you if you don't.

Main Topics

Webpack | ES6 | ReactJS

Supporting Topics

Babel | NPM | Linting ES6 | ReactJS | Semantic Versioning

Webpack Loaders

So a webpack loader allows you to preprocess files. You can do this requiring or importing components. For example, you can include a style sheet, an image, or other JS files. The process we are going to do here is going to be very similar for each loader we use. We will install it with npm then add it to our webpack.config.js file. For clarity in the code examples I am going to only show the code where we are working. I will refer to the places we will be working by their commented section.

// webpack.config.js 
var path = require('path')
var HtmlWebpackPlugin = require('html-webpack-plugin')
// Include Section

module.exports = {
  entry: './app/index.js',
  output: {
    filename: 'bundle.js',
    path: path.join(__dirname, 'dist')
  },
  module: {
    preLoaders: [],
    loaders: [
      // Loader Config Section
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Seed Project',
      filename: 'index.html',
      template: 'index.tmpl.html',
      inject: 'body',
      hash: true
    })
  ]
}

JS Loader

babel-loader

Let's start with our JavaScript loading as there is really not an app without the JS. We will be using babel to handle our JS loading. We use babel because we are using ES6 and need to transpile our code. Run the following command to install our loader and the loader dependencies. You probably noticed that this install command looks a little different than previous ones. With npm we can install multiple packages in one command. We are installing babel and its' two dependencies.

seed-project $ npm install babel-loader babel-core babel-preset-es2015 --save-dev

Take a look at your package.json file and notice all the additions to our project. Next we are going to add a loader configuration to our webpack.config.js. The loader configuration is an object that has properties test (regex test on a file name), exclude (a pipe delimited list of excluded directories), loader (the loader to apply to the file type), and an optional query.

{
  test: /\.(jsx|js)$/,
  exclude: /node_modules/,
  loader: 'babel-loader',
  query: {
    presets: ['es2015']
  }
}

Go ahead and open app/index.js and update it to use a const data type.

console.log('this is my app')
const blar = 'plop'

Run our build process npm run build-dist and then look at the output in dist/bundle.js. You should be able to find the following code var blar = 'plop'; This means our ES6 code was successfully transpiled. So real quick we are going to create a little more structure to our app for our upcoming examples. We are going to start our ReactJS app structure by creating a components directory (more on this later) and then adding a test component.

seed-project $ mkdir app/components
seed-project $ mkdir app/components/test
seed-project $ touch app/components/test/index.js

Change app/components/test/index.js to make a simple get/set ES6 object. Also export that object so we can use it in app/index.js. It should look like this:

export default {
  _wiz: 'bang',
  set wiz (val) {
    this._wiz = val
  },
  get wiz () {
    return this._wiz
  }
}

Then update app/index.js to import the test component:

import test from './components/test'
console.log('test', test)
const blar = 'plop'

Run the npm build process again and go ahead and serve the dist directory. Side note: for all my simple web server needs I use the serve module. Once installed its as easy as running $ serve in any directory to have it running at http://localhost:3000. So once its running, open your browser console and notice our test component being logged out.

To make our folder structure a little more flexible we are going to add a properties to our webpack config: context and resolve. Long story short, this allows us to use an import syntax that does not require absolute paths. So we can restructure stuff as needed with minimal damage. Just so everyone is on the same page I am going to show the entire config here:

var path = require('path')
var HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  context: path.join(__dirname, 'app'),
  entry: './index.js',
  output: {
    filename: 'bundle.js',
    path: path.join(__dirname, 'dist')
  },
  resolve: {
    root: [
      path.join(__dirname, 'app')
    ]
  },
  module: {
    preLoaders: [],
      loaders: [
        {
          test: /\.(jsx|js)$/,
          exclude: /node_modules/,
          loader: 'babel-loader',
          query: {
            presets: ['es2015']
          }
        }
      ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Seed Project',
      filename: 'index.html',
      template: 'index.tmpl.html',
      inject: 'body',
      hash: true
    })
  ]
}

I added the context property, changed our entry point to reflect the context, and added our resolve properties.

ReactJS and ES6

In order to see the loading of styles and other assets we really need some sort of basic react app. So we are going to do that now. All of these React components will be built in ES6 manner, so you will not see and React.createClass syntax. So first of all we need to add react as a dependency.

seed-project $ npm install react react-dom --save

This is where I will start showing some of the component paradigm I subscribe to. Each react component I create will have its' own directory. You can almost think of each of these component directories as its own little app. This means it should have all the files it needs to work. For this project we are going to make a main component with some test content. The app will include the main component and render it to the page.

seed-project $ mkdir app/components/Main && touch app/components/Main/index.js && touch app/components/Main/Main.js

We will be doing this a lot so I simplified our creation process to one task. This creates our main directory then puts two files in it. The index.js file is what will be imported into our app, while main.js will be our react class that handles the output of the component.

Open app/components/Main/Main.js and create a basic react class. Remember I am not teaching you React with this post so I will not be explaining all of the pieces of this class.

// app/components/Main/Main.js
import React, { Component, PropTypes } from 'react'

export default class Main extends Component {
  static get displayName () {
    return 'Main'
  }

  static get propTypes () {
    return {}
  }

  static get defaultProps () {
    return {}
  }

  constructor (props) {
    super(props)
  }

  render () {
    return (
      <h1>Main</h1>
    );
  }
}

This class can be used as a snippet for all of our react classes. Doing this will save you tons of time and ensure you are consistent with your structure. I actually put all of this into an atom.io snippet and get all this with four characters.

Now open app/components/Main/index.js and pull in all the files needed for this component. Right now its just one file.

// app/components/Main/index.js
import Main from './Main.js'
export default Main

I am going to add a couple more npm packages here: debug and babel-preset-react. We will use debug in app/index.js for debugging and babel-preset-react for transpiling JSX our content.

seed-project $ npm install --save-dev debug babel-preset-react

Open our webpack config and add another loader after the JS one.

{
  test: /\.jsx?$/,
  exclude: /node_modules/,
  loader: 'babel',
  query: {
    presets: ['es2015', 'react']
  }
}

Lastly open app/index.js and we are going to remove all existing code and put in some react.

// app/index.js
import debug from 'debug'
import React from 'react'
import { render } from 'react-dom'
import Main from 'components/Main'

const log = debug('application:bootstrap')

log('creating application node')
const applicationNode = document.createElement('div')
applicationNode.className = 'container'
applicationNode.id = 'application'

log('adding application node to body')
document.body.appendChild(applicationNode)

render(<Main />, applicationNode, () => {
  log('finished mounting application')
})

Time to test. Run the build process again to make sure you don't have and build errors. Once the build completes take a look in the browser and you should see a mostly blank page with one word on it, Main.

Loading Styles and Assets

We are going to start buy pulling in Bootstrap as a base for all styles.

seed-project $ npm install --save bootstrap

As Bootstrap is an application dependency, it will be imported on our primary JS file which is app/index.js. Insert the following line at line 1 of app/index.js

import 'bootstrap/dist/css/bootstrap.min.css'

If you were to run our build now you would notice a ton of CSS printed into our console as an error. We are loading the CSS but webpack is not able to handle it; we need to handle the loading of styles. This process is going to be the same for every loader we need: install and configure.

seed-project $ npm install --save-dev style-loader css-loader less-loader file-loader url-loader

Every loader does not always have its own configuration. The loaders are tied to file types. Some files will use multiple loaders and some loaders will be used for multiple files. Add each of these loaders and then I will explain them individually.

{
  test: /\.css$/,
  loader: 'style-loader!css-loader'
},
{
  test: /\.less$/,
  loader: 'style-loader!css-loader!less-loader'
},
{
  test: /\.(png|jpg|jpeg|gif|svg|mp4)$/,
  loader: 'url-loader?limit=100000'
},
{
  test: /\.(otf|ttf|eot|woff(2)?)(\?[a-z0-9]+)?$/,
  loader: 'file-loader'
}

style-loader

The style loader takes CSS and inserts it into the page, thus activating the styles.

css-loader

This does not actually load CSS like the style loader. It processes a CSS file and resolves import statements and url requests.

less-loader

Similar to the CSS loader, the LESS loader just processes the LESS files and passes them to the style loader.

file-loader

The file loader returns a public path to any of the associated file type resources.

url-loader

The url loader works like the file loader, but can return a data url if the file is smaller than a limit you set.

Adding component specify style

We are going to make a specific style for our main component.

seed-project $ touch app/components/Main/main.less

Open app/components/Main/main.less and add a style to the file. I just did a color of my h1 tag.

h1 {
  color: red;
}

Now open app/components/Main/index.js and import this style.

import './main.less'
import Main from './Main.js'
export default Main

Run our build again, refresh the page, and you will see the style on the page. Ok so here is why this is important; anyone who has ever dealt with large, I mean LARGE, styles for a project have been devoured by random styles. It can start great but become unmanageable instantly, especially if your team is not supportive of strict structure. This seems to be a possible solution so far.

Loading Images

This should be super easy as we already setup the file loader. I added an svg that you can pull from the repo but any old image will work for this. Take you new image and place it in app/components/Main. We are going to assume that this image is specific to this component and not used anywhere else. Open app/components/Main/Main.js so we can modify the render function a bit. We are going to require the image and set it to a const variable. Go ahead an log it out to your console. You will notice that imgSrc is not a path but actually a data url. Its actually the base 64 for that image.

render () {
  const imgSrc = require('./osx.svg')

  return (
    <div>
      <h1>Main</h1>
      <img src={imgSrc} />
    </div>
  )
}

Rebuild and you should see your image.

Loading Other JS Libraries (optional but kind of fun)

Lets pull in another library for fun. For this example I am going to add in GreenSock. GreenSock is ultra high-performance, professional-grade animation for the modern web. It's probably the best tool out there today if you have greater aspirations than jQuery.

seed-project $ npm install --save gsap

Open app/components/Main/Main.js. We need to include TweenMax from GreenSock then use it in an mouse click event.

import React, { Component, PropTypes } from 'react'
import TweenMax from 'gsap/src/minified/TweenMax.min.js'

export default class Main extends Component {
  static get displayName () {
    return 'Main'
  }

  static get propTypes () {
    return {}
  }

  static get defaultProps () {
    return {}
  }

  constructor (props) {
    super(props)

    this.onClick = this.onClick.bind(this)
  }

  onClick (e) {
    const el = e.currentTarget

    TweenMax.from(el, 1, {
      css: { rotation: 360 },
      ease: window.Quad.easeInOut
    })
  }

  render () {
    const imgSrc = require('./osx.svg')

    return (
      <div>
        <h1>Main</h1>
        <img src={imgSrc} onClick={this.onClick} />
      </div>
    )
  }
}

Conclusion

You should now be able to completely build a project with ReactJS, ES6, and Webpack. Once you have it working, remember to pull the caret range versions from your package.json to prevent unexpected errors from reckless package updates.

What? You don't think that running a build process manually after every change is a sustainable way to write code... Me neither. The next post in this series will cover taking all of this and putting it into a live reloading, hot swappable, thing of pure awesomeness.

Building a seed project with Webpack, ReactJS, and ES6: Part 2 Setting up Webpack

Repo

Ok so hopefully you read or already knew the topics presented in the part 1 post of this series. We basically went over a super basic setup of folder structure for the seed project we will be creating.

For this post we will be picking up where we left off in part one; use this repo to align yourself. We are going to be installing Webpack and setting up a build process. Our build process will eventually transpile our ES6 code, processing images, applying styles, and including a an additional library. Right now it is just going to bundle some stuff together and use an html template to create static source code.

Main Topics

Webpack

Supporting Topics

NPM | Linting | Semantic Versioning

Webpack

Overview

Webpack is a module bundler that will create static assets. Basically we can create our project how ever we want then use Webpack to build a static site. This makes it easy to deploy but can be hard to debug.

Basic Install

Open your project in your IDE of choice and also open your project's root directory in your terminal. We are going to be using npm a lot in this post. You will have to have node/npm installed in order to do this. You can verify npm by running the following in your terminal:

$ npm -v

Hopefully you will see a version printed out. If not you may not have node installed. Follow these instructions for installation.

Ok so let's get this started. First we are going to install Webpack and we are going to use a flag telling it to save this as a project development dependency. It is a development dependency because it is not needed to run the application, but it is to work on it. You will also have to install webpack globally in order to use the command line tools.

seed-project $ npm install webpack --save-dev
seed-project $ npm install -g webpack

If you get an error trying to install globaly you may need to change some permissions. Some people would recommend using sudo for global installs but I would rather just give myself ownership of thise directories:

seed-project $ sudo chown -R yourUser ~/.npm
seed-project $ sudo chown -R yourUser /usr/local/lib/node_modules
seed-project $ sudo chown -R yourUser /usr/local

This creates an entry in package.json. Open that file and take a look. You will notice webpack listed as a key on an object. The value is the version of webpack we are using. It is using a caret range meaning it will allow changes that do not modify the left-most non-zero digit. Ideally this 3 part identification follows this pattern [major, minor, patch]. In a perfect world, this would be safe but it does assume the author of the package will only release breaking changes in a major version. That is rarely true so I advise against using caret ranges and using exact version installs. The easiest way to resolve this is to manually delete the caret from the package.json file.

It also copied the webpack code locally to this project and put it in the node_modules directory. Every installation we do with npm will by default place content in this directory. You may remember in the previous post we created a file to ignore content from our git repo. Our node modules are folders we do not want versioned. They already are so no need for us to do it too.

Setup Webpack Config

Next we need to create our configuration file that will instruct webpack what to do.

seed-project $ touch webpack.config.js

Open this file in your editor and add the following code.

// webpack.config.js
var path = require('path')

module.exports = {
  entry: './app/index.js',
  output: {
    filename: 'bundle.js',
    path: path.join(__dirname, 'dist')
  }
}

So lets explain this real quick. We are exporting a configuration object and right now we only have 2 properties in it: and entry point for webpack and an output for our bundled JavaScript file. We can run this right now but it will throw an error as we do not have this file app/index.js. Lets create a place holder file real quick from our terminal.

seed-project $ echo "console.log('this is my app')" >> ./app/index.js

Running Webpack

Ok, time to run webpack. We use the webpack command line interface (CLI) and give it a configuration file. By default webpack will look for webpack.config.js so technically we do not have to pass the file name of our configuration. I have never really liked defaults and prefer to be explicit; it's easier to understand for the next guy.

seed-project $ webpack --config webpack.config.js

Look at your project folder structure; you should now see dist/bundle.js. If you see this, go ahead and high five yourself because you did it right. But what are we going to do with a lone JavaScript file. We need to put this file in an html page and we need that html page in our dist directory. So we could very easily just make an index.html file there and have it load bundle.js. But your project should be smarter than that. The dist directory should be, and eventually will be, able to be completely purged from your project every build. This ensures you don't have any changes local on your computer that are not able to be recreated else where. How many times have you heard "But it works on my computer". This helps to resolve that kind of problem.

Creating an HTML template

For this next part we need another package installed, html-webpack-plugin. This plugin simplifies the creation of html files to serve our webpack bundles. So webpack has a concept of plugins. This allows us to use existing functionality or even write new stuff into our build processes.

seed-project $ npm install html-webpack-plugin --save-dev

We need to create a new file to serve as our template file.

seed-project $ touch index.tmpl.html

Open this file and add some basic html

<!-- index.tmp.html -->
<!DOCTYPE html>
<html>
  <head>
    <title>{%= o.htmlWebpackPlugin.options.title %}</title>
  </head>
  <body>
  </body>
</html>

Now go back to webpack.config.js so we can use this plugin in our process.

  • Require this new package
  • Add a new property to our configuration called plugins. Plugins is an array.
  • Create a new instance of our plugin and pass in a configuration for it.

Here is the result:

// webpack.config.js
var path = require('path')
var HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './app/index.js',
  output: {
    filename: 'bundle.js',
    path: path.join(__dirname, 'dist')
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Seed Project',
      filename: 'index.html',
      template: 'index.tmpl.html',
      inject: 'body',
      hash: true
    })
  ]
}

Real quick I'll explain the configuration we are using for this plugin.

  • Title: Sets a property that we use in our template for the title tag.
  • Filename: The name of our file once it is created. This file will be placed in the output path that we created earlier.
  • Template: The template we are using to create the html file.
  • Inject: Determines where we place the script tag for bundle.js.
  • Hash: This gives us the option of adding a random query string to prevent the browser from using cached versions of a file.

There are way more configuration options available. Read about them.

Linting

I know by now some of you are judging me personally because of my JavaScript syntax. Yes, I know, I did not use semicolons but that was on purpose. To avoid bikeshedding in all of my blogs I plan to use a style that I cannot control nor manipulate. So I will be using StandardJS; you complain there if you feel the need to. Now let's get on with it. First install standard and a reporter.

seed-project $ npm install --save-dev standard standard-reporter

Now let's run the code linter. What we are going to do is run the standard code rules on all .js and .jsx files in the project, then take the output of that and run it through the the standard-reporter for better formatting and readability.

seed-project $ standard ./**/*.js, ./**/*.jsx, *.js | standard-reporter --stylish

This should pass and basically nothing will happen. You can test a failure by adding a semicolon after the path declaration on line 1 of webpack.config.js. Save the file and then run our last terminal command. You should see an error now. Go ahead and revert that change, save, and run again. Project is now listing and your code will be cleaner. Many IDEs have really useful plugins for StandardJS too.

NPM Script Sugar

Ok so now we have a lot of long terminal scripts that would be really hard to remember. I think it would be great if there was a better way to standardize all of this. There is. So npm is not just a module manager, you can actually create and run bash scripts with it. Go ahead and open your package.json file. We are going to create a npm script for testing our code and building our distribution directory. You should already have a scripts property in your json doc. Here is my file now:

{
  "name": "seed-project",
  "version": "1.0.0",
  "description": "A web seed project using webpack, react, and es6",
  "main": "./app/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "html-webpack-plugin": "1.7.0",
    "standard": "^5.4.1",
    "standard-reporter": "^1.0.5",
    "webpack": "1.12.9"
  }
}

I am going to add three scripts. The first one is called test and it will run our standard code listing task. The next one is called build-dist and it will delete the dist directory then run webpack to create a clean distribution folder. The last one is a compound task that basically runs tasks. It will run the test script and if it passes it will run the dist script. If test fails it will error out the report in the terminal.

{
  "name": "seed-project",
  "version": "1.0.0",
  "description": "A web seed project using webpack, react, and es6",
  "main": "./app/index.js",
  "scripts": {
    "test": "standard ./**/*.js, ./**/*.jsx, *.js | standard-reporter --stylish",
    "build-dist": "rm -rf ./dist && webpack --config webpack.config.js  --bail -p",
    "dist": "npm test && npm run build-dist"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "html-webpack-plugin": "1.7.0",
    "standard": "^5.4.1",
    "standard-reporter": "^1.0.5",
    "webpack": "1.12.9"
  }
}

To execute the dist script do the following:

seed-project $ npm run dist

Conclusion

Awesome! We covered a lot here but this just the tip of the iceberg with Webpack and ReactJS. Stay tuned; the next one will really put some pixels on the page.

Things to come in this series:

  • Installing webpack loaders to for ReactJS, ES6, images, fonts, and styles
  • Building a super tiny ReactJS example to show all the above installs working
  • Using webpack to create a development server with live reload
  • Building a bare bones react flux app structure
  • Maybe some sort of tests
  • Might be cool to get into some sort of app packaging... TBD

ProTip: How to sync your Atom.io preferences across multiple computers

So maybe this is just me, but I am always developing on multiple computers. I am not a fan of having to manually keep my dev environment consistent. My IDE is the most volatile and most used part of my development.

My current code tool of choice is atom.io and the behavior I want does exist as a feature. I would like to have multiple computers use the same atom preferences. So let's just make this happen on our own.

There are a few things that need to be done before you can sync you configurations. For this demo you need to have a Dropbox account (its free) and you need to have the app installed on you computer. The Dropbox app gives you access to the folder structure in your cloud drive. I am assuming that you did the default install and the Dropbox folder is located at the user root in your file system.

Also make sure you have atom installed. You can make your ideal IDE before or after this process.

Step 1: Create a master configuration in a shared location

You will only do this on one computer, the computer that has the atom configuration you want to share.

Exit from atom if it is running.

In the root of your user directory on you mac is a hidden folder called .atom. This holds all of you snippets, style preferences, and installed packages. We are going to move this to your Dropbox folder. Open your terminal app on your mac:

Verify that you have a .atom directory.

$ ls -a ~/

Move your .atom directory to your Dropbox folder.

$ mv ~/.atom ~/Dropbox

You should now have your .atom directory in your Dropbox folder instead of your root. Verify that it moved.

$ ls -a ~/Dropbox

You should no longer see it in your user directory.

$ ls -a ~/

Step 2: Link to the shared config

You will do this on every computer that you want to use the shared configuration.

Make sure atom is closed.

Create a symbolic link (aka symlink) on the computer with the same name as the folder to the Dropbox folder.

$ ln -s ~/Dropbox/.atom ~/.atom

You should now be able to verify the presence of the sym link in your root directory.

$ ls -a ~/

Relaunch atom and you should be working off the same config folder.

Additional computer step

There are a few extra steps when you need to add an additional computer.

As you are using content that exists in the cloud, make sure that Dropbox has synced the .atom directory to this computer.

Start by deleting the .atom folder.

$ rm -rf ~/.atom

Now you can do step 2 and things should work.

Building a seed project with Webpack, ReactJS, and ES6: Part 1 Overview and Setup

Project Overview

I have always thought one of the most difficult and frustrating parts of development is just getting started. There are so many different packages, and repos, npm installs this, --save (should I make it dev), bowers, then I need a gulp of something, and the entire process is usually full of grunts. Needless to say, many of my initial concepts to change the world have been stifled by this brain surgery like process. Note: in no way am I really comparing what I am doing to brain surgery. I just want something that's basic, that makes sense, and that I can explain to you. I hate just using something because it works. So I will do my best in this blog series to explain the purpose of most of the dependencies. I will do my best to bring a little clarity to the clutter. I will explain a lot of stuff that many people take for granted. All apologies if I go too basic at times.

Goal for this blog series

  1. Teach you how to pull a seed together and understand why we did what we did.
  2. I will not teach you how to write react or the ins and outs of ES6 as there are a ton of great resources out there.
  3. Lastly, I want to have a seed project that I can clone and start coding in with minimal effort.

Main topics

EcmaScript 6

The majority of this project will be coded using the ES6 standard. Using ES6 comes at a cost though, it still needs to be transpiled. This means that the ES6 code will need to be processed and converted to an older version of JavaScript that works on all browsers.

Webpack

We will be using a lot of different code repositories to create the optimal developer environment. Webpack is going to be our go to tool for our development and for making a distribution package that we could host on a web server somewhere.

ReactJS

React is my new best friend, replacing angular. React is the front end framework that I will be implementing.

Supporting topics

Babel

This is the transpiler code we will use to convert our ES6 JavaScript to ES5 so it will work in browsers. Babel allows us to use the tech of tomorrow today.

Flux

This project will be setup using the flux architecture. You don't have to know this topic in order to go through this lesson. You don't even need to do the flux part... Now that I think about it, I don't either. I will do the flux stuff last so you can skip it. I will even let you know when to tune out if you are not interested in flux.

NPM

Npm is the default package manager for the JavaScript/NodeJS environment. In normal terms, npm allows people to create useful projects and then share them with the rest of the world. Npm can make your work load a lot easier, but it can also lead you down some crazy rabbit holes.

Code linting via eslint

Having code that is valid is super important. Having code that is performant is also super important. But having code that is maintainable and readable by the next guy is one of the most important tasks for a developer. Having code that can be validated is a part of this process; we will use eslint for that.

Git/Github

Github is a version control service that I will be using for this project. Each part of this post will have its own branch of code. The master branch for this repository will be the final project. If you need more information on using git please look here.

Setup

In this first part of the series we will be going over creating you project, setting up folders, and putting all of this stuff into version control. Feel free to skip this part if you want. But you could also read it and provide some feedback on my process. Who knows, maybe together we can do it better than I can alone.

What you will need:

  1. Some sort of text editor program, not a document editor (Word, Pages, etc). Editors are a very personal thing and you do not have to use what I use. Lately I have been using atom.io. Its free, customizable, and I like the themes. Plus their t-shirts are super soft (I wish I did not lose mine). I like soft clothes and nice colors, what can I say. Some other popular tools out there are Sublime Text, WebStorm, Emacs, Visual Studio, and Notepad++. Use what you want and do not think that yours is the best; it's all about preference.
  2. You will need to have node installed.
  3. I will be using git for version control; you do not have to. If you want to follow with the entire process, you will need something though.
  4. Also I will be doing some work in my terminal. I am using OS X El Capitan.

Create the project

Scaffolding

Open you terminal and navigate to where you would like to create your project. Create a new directory and call it seed-project. We will then make 2 more directories in seed-project: app and templates.

I am going to use my terminal for this:

$ mkdir seed-project
$ cd seed-project
seed-project $ mkdir app templates

Git

In order to use version control we will need to initialize seed-project as an empty git repository. This is kind of where you can do whatever you want with your version control. I will be making branches for each part of this blog. Here is what I did. I created a new public repo in my Github account. Git hub gives you the exact commands to use to initialize your repo and a nice little copy to clipboard button. I just copy the commands with their button and then paste it into my terminal.

Next I am going to create a file that git will use to know whether or not content from your project should be in version control. For example, we do not want all of our npm packages to be in version control. That would take up a lot of unnecessary space and kind of defeat the purpose of using npm. More on that later. For now we are just going to create a .gitignore file and add the node_modules directory to it. Don't worry, we will have that folder in the near future.

echo "node_modules" >> .gitignore

Npm

We now need to initialize npm so we can leverage all sorts of code repositories for our project. Running npm init from your terminal will start a series of prompts in the terminal to aid in creating a config file for your project. The is the package.json file. You do not have to do this with the npm init command. You can just create the json file by hand, but we will use the init command.

seed-project jordan$ npm init

The first prompt is the name of your project. Npm tries to offer sensible defaults when it can. To accept the default you can just press return. Accept the default name and version unless you want to change the semantic versioning to 0.1.0.

name: (seed-project)
version: (1.0.0)

Just accept the defaults for the rest of the prompts. We can always change them later. This process should have created the following package.json file:

{
  "name": "seed-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Be careful when manually working with the package.json file. A malformed json file will throw an error and prevent you from executing any npm commands.

Conclusion

I am stopping here because it just seems like a good spot conceptually. Right now I imagine some of you may feel like you just wasted some time. Others will hopefully have had some insights into the creation of a project. This is foundational to all projects and we are starting at the beginning to ensure this is a thorough and complete explanation of creating the seed project. Fortunately, this part of the project is super agnostic to tech and can be easily reproduced. In the future, you won't even think twice about doing this.