Skip to content

Instantly share code, notes, and snippets.

@HoverBaum
Last active May 31, 2016 01:44
Show Gist options
  • Save HoverBaum/7f212b720799b23e19212ff0339741b7 to your computer and use it in GitHub Desktop.
Save HoverBaum/7f212b720799b23e19212ff0339741b7 to your computer and use it in GitHub Desktop.
Thinking about a coding standard for iceproject.

I.C.E. Project

This document strives to provide coding guidelines and standard to use in the iceproject.

At the same time it serves as the "must read" introduction for people new to the project.

General Filestructure

.
├── build
├── docs
├── gulpfile.js
├── package.json
└── src
    ├── css
    ├── js
    └── manifest.json

Workflow

During development we work on the files in the src folder. From here we then use a taskrunner to create a build version in the build folder. This is the folder you should drag into Chrome for local testing. And also the folder that will later be compressed into a ZIP archive for the store.

JavaScript

We will organize our JavaScript into modules. You can think of a module as a feature or a reusable component.

Module pattern

Our JavaScript will be organized using ES6 import and export.

This functionality is new in ES6 you can read more about it here. At present this requires the use of a compiler. Because browsers don't yet support this features. We use Babel to compile our ES6 based code to ES5 code that can be used in current browsers.

Using this approach a module and export one or multiple objects or functions for other parts of our extension to use.

Folder structure

.
└── js
	├── pageName.js
	├── otherPage.js
	└── modules
		└── moduleName.js

To keep organized we will have a single JavaScript file for each page we alter in our js folder. This in turn will have a module folder which will contain modules.

Modules are like building block, they implement and expose a functionality in a way so that others can use it without having to worry about how it is implement. In programming this is called encaplusation.

Documentation

We will use JSDoc to document our code.

JSDoc uses @tags to annotate you code inside of comments starting with /**. You can for example tell is that a function has a @param a parameter. Each function we create should have a JSDoc comment. Some conventions:

  • Variables you use in you module can be documented using a // comment.
  • // comments should have an empty line above them.
  • @tagss should be followed by {type} name - Description where a type and description is required

//TODO how to document ES6 modules

Using Documentation

We do two things with our documentation comments:

  1. Use them as reference during coding directly in the code
  2. Generate a HTML documentation

Since an HTML documentation is way better for reading we generate one from our comments. This however is it's own topic.

Background vs. Injected

Chrome extensions can have two types of JavaScript files. Ones that run in the Background and ones that get injected into pages. For each page on imgur we want to interact with we will create a single .js file.

//TODO more infos here liks what background and injected can do and not what we use background for.

CSS Naming conventions

Both classes and ids should start lower case. To distinguish classes and ids they should further:

  • classes should be named using "-" separated words. Like "ice-tag"
  • id should be name using camelCase. Like "iceTag"

At this point we opt to not use a preprocessor like Stylus to keep the project simpler and easier to get into.

Dist folder

The structure of this folder will look like this:

.
├── background.js
├── img
├── manifest.json
└── pageName.js
  • background.js - the file to be run as a background script
  • img/ - folder for images
  • manifest.json - the manifest file
  • pageName.js - script to be run as imgut.com/pageName

As you can see from the file structure we will create scripts for every page, such as 'favorites'. Those scripts will be build using a taskrunner and ensure to only include the needed modules.

Taskrunner

A taskrunner runs tasks for you. They do all the things we don't want to do manually. In this case minify files, create a single .js files from modular files and also create a .zip file for the store. We are using Gulp.

Inside the gulpfile.js tasks are defined. You can run a task using gulp task. Note that Gulp should be installed globally npm install -g gulp.

Setup

Due to the above described structure you needs a few things before you can start coding.

First you need node just install the latest version. To use node you will have to use the commandline. Since we are also using git you might as well get gitbash for windows. Just visit that link and install git, it comes with gitbash. Gitbash enables you to use some unix commands, super awesome as we can then provide things to put into your console that work on Linux and Windows.

Then some editor, really up to you. If you want a suggestion go for Atom.

Getting the project to work

Now open your commandline and clone the repo. After that you will have to install some npm dependencies. NPM ist a package manager that comes with Node.

git clone https://github.com/kyrofox/iceproject.git
cd iceproject
npm install

To get started with gulp (inside the project folder).

npm install -g gulp
gulp

Now you are all setup.
Consider making a fork of the repository and cloning that instead to make contributions via pull requests.

@kyrofox
Copy link

kyrofox commented May 27, 2016

This is awesome, thanks! If we end up using execute method vs. manifest method, here's a rough example of the revized module pattern:

var datModule = (function() {
    var publicString = "jeff";
    var privateString = "nojeff";

    function privateFunc(stuff) {
        console.log(stuff)
    }

    function publicFunc(moreStuff) {
        moreStuff.whatever = "asdasd";
        console.log("ok");
    }

    // important init code
    console.log("yo whassup");
    console.log(privateString + publicString);
    privateFunc(publicString);

    return {
        "publicFunc": publicFunc,
        "publicString": publicString
    }

)();

The difference would be that instead of returning an init that can be called, it would be initializing on execute.

@HoverBaum
Copy link
Author

Upon further consideration I think we might go best using ES6 modules instead. As we have a build chain anyways. We could compile ES6. That way we can be expressive about what modules what page depends on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment