contact Me

Use the form on the right to contact me.

You are welcome, to contact me regarding the topics of this page, my open source projects, or my work. Please use the contact form and leave a valid email address for me to respond to.

Thank you.

Egidestr. 9
44892 Bochum
Germany

How I seed a new JavaScript Project

/brain/dump

Random thoughts, bright ideas and interesting experiments. In short the ramblings of a fulltime nerd.

 

How I seed a new JavaScript Project

Jakob Westhoff

I often need to start a new JavaScript project quickly. There are a lot of different reasons to start a new project:

  • Playing around with a new library or technology.
  • Develop a new utility library to be used in other projects.
  • Setup a new project for developing a customers project.

Of course there are further possible reasons, but I think you get the picture. In each of those cases starting from scratch isn't desirable. I want a certain basic structure, which is kind of similar for all my latest projects. Let's take a look at the needed components: Static Code Analysis, Testing, Dependency Management, Packaging and Minifying. Of course being easily extensible with custom or library specific tasks is important as well. To solve all of those different Tasks I currently tend to utilize the following tools/libraries:

  • Static Code Analysis: Currently only linting with jshint
  • Testing: Unit-Tests with karma-runner and PhantomJS and/or other Browsers
  • Dependency Management: npm and bower
  • Packaging: During development require.js inside the browser. For production r.js in combination with almond.js
  • Minifying: Usually done by uglifyjs
  • The build system combining all the tasks is currently grunt. (Mainly because there are plugins for mostly anything available)

Creating a generic Seed

Compiling and setting up a running environment of all those tools running in cooperation isn't hard, but always takes quite some time. As I did it for the nth time last month I decided to create a basic seed project for myself, to be reused every time I need such an environment. As I thought some other people might have a use for this as well, I put the whole seed up on github.

Shortly after pushing the seed I had the first use case for it. I wanted to develop something with Facebooks React. React is a little bit special regarding it's build process, as it utilizes JSX to allow for neat HTML-inline syntax during development, while still creating fast pure JavaScript code for production. Therefore I needed to adapt the seed to properly handle this in conjunction with requirejs and all the other parts of my toolset. Therefore I branched the seed (framework/react) and integrated all the necessary changes. Using branches for those special adaptions allows to easily backport new features into the main branch, as well as importing future additions of the main seed into the framework seeds.

You might think, why didn't he use Yeoman and its generators for all of this. The answer is simple: Yeoman is quite close to what I want, but doesn't provide the exact combination of tools I utilize out of the box. Writing a special generator for my needs wouldn't have been a problem, but I simply didn't see any real reason for it, as a git repository works quite well for me :).

Utilizing the Seed

Even though I don't want to replicate the documentation of all the different tools used, let's take a look at what my basic workflow of using the seed is:

  1. git clone the seed to a directory intended to be used for the new project.
  2. Optionally checkout a specific project branch
  3. Delete the .git folder inside the newly created seed
  4. Adapt package.json as well as bower.json to your needs. Especially name and description ;)
  5. Install basic dependencies using npm and bower: npm install && npm install bower.
  6. Create basic symlinks of all needed libraries for access during development: grunt symlink:www

After those initialization steps you might put up all your JavaScript source under the src directory using AMDs module syntax. The require.js configuration for arbitrary thirdparty libraries is stored at src/require.conf.js.

Opening up www/index_dev.html will dynamically load all the dependencies and execute them. After changing base dependencies or installing further assets you may need to call grunt symlink:www again to update the symlinks inside the www directory to be available for dynamic loading. However this should not be required most of the times, as the basic directories are linked, not their content specifically.

To create minified and combined versions a simple call to grunt build will create a production ready result inside the dist directory. It will include everything needed to run your library/application.

To specifically run separate steps of the build either call grunt tasks to show all available tasks, or take a look at the Gruntfile.js. Most of the basic tasks are defined as watch tasks as well. For example if you want to automatically build a new production version of the software everytime a relevant file changed just call grunt watch:build.

If you have any comments, questions or maybe additions to the seed I am always happy to accept pull requests. :)