I'm sure you don't want to go through this whole guide every time you start a new JavaScript project, so I've summarized everything to get you going quickly in as few steps as possible in this chapter.
If even this is too much for you, there is actually a starter-project included in this repository, under the
Code
folder, callednewProject
. You could use that as a starter template for your projects. Just copy it and rename thenewProject
folder to your project name, cd into that folder and run:$ npm init
I am going to assume that you have Node.js (and npm) installed. If not, please do so now.
$ mkdir -p <Your-Project-Name>/src/lib && mkdir <Your-Project-Name>/dist \
&& mkdir <Your-Project-Name>/test
$ cd <Your-Project-Name>
$ npm init --yes
$ npm install browser-sync babel-cli babel-preset-es2015 \
webpack babel-loader eslint eslint-loader lodash tape \
html-webpack-plugin faucet babel-register --save-dev
Create a .babelrc
file with the folowing content:
{
"presets": [
[
"es2015"
]
]
}
Run:
$ ./node_modules/.bin/eslint --init
$ (
export PKG=eslint-config-airbnb;
npm info "$PKG@latest" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs npm install --save-dev "$PKG@latest"
)
Then edit .eslintrc.js
:
module.exports = {
'extends': 'airbnb-base',
'plugins': [
'import'
],
'rules': {
'semi': [2, 'never']
},
'env': {
'browser': true
}
}
Create a webpack.config.js
file with the folowing content:
var webpack = require('webpack')
var path = require('path')
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/app.js',
vendor: 'lodash'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
new webpack.optimize.CommonsChunkPlugin({
name: ['vendor', 'manifest'],
minChunks: function (module) {
// this assumes your vendor imports exist in the node_modules directory
return module.context && module.context.indexOf('node_modules') !== -1;
}
})
],
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader'
}, {
loader: 'eslint-loader',
options: { fix: true }
}
]
}
]
}
}
Create a webpack.prod.config.js
file with the folowing content:
var webpack = require('webpack')
var path = require('path')
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/app.js',
vendor: 'lodash'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
new webpack.optimize.CommonsChunkPlugin({
name: ['vendor', 'manifest'],
minChunks: function (module) {
// this assumes your vendor imports exist in the node_modules directory
return module.context && module.context.indexOf('node_modules') !== -1;
}
})
],
devtool: 'cheap-module-source-map',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader'
}, {
loader: 'eslint-loader',
options: { fix: true }
}
]
}
]
}
}
Add the following to you package.json
file in the scripts
section:
"scripts": {
"prebuild": "rm -rf ./dist",
"build": "webpack --progress --colors",
"watch": "webpack --progress --colors --watch",
"test": "tape --require babel-register test/**/*.js | faucet",
"preprod": "rm -rf ./dist",
"prod": "npm test && webpack --config webpack.prod.config.js -p"
}
Create an index.html
file in the root folder, add the following content:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="app"><div>
<script src="/dist/manifest.js"></script>
<script src="/dist/vendor.js"></script>
<script src="/dist/app.js"></script>
</body>
</html>
Create a sayHello.js
file in the src/lib
folder and add the following content:
import _ from 'lodash'
const sayHello = (name = 'Mark') => `Hello ${_.trim(name).charAt(0).toUpperCase() + _.trim(name).slice(1).toLowerCase()}`
export default sayHello
Create an app.js
file in the src
folder, add the following content:
import sayHello from './lib/sayHello'
document.getElementById('app').innerHTML = `<h1>${ sayHello() }<h1>`
Create a sayHello.spec.js
file in the test
folder and add the following content:
import test from 'tape'
import sayHello from '../src/lib/sayHello'
test('sayHello without a parameter', (t) => {
const actual = sayHello()
const expected = 'Hello Mark'
t.equal(actual, expected, 'When passing no parameters to sayHello(), the resulting string equals "Hello Mark"')
t.end()
})
test('sayHello with a parameter', (t) => {
const actual = sayHello('Tony')
const expected = 'Hello Tony'
t.equal(actual, expected, 'When passing "Tony" to sayHello(), the resulting string equals "Hello Tony"')
t.end()
})
test('sayHello capitalizes the name', (t) => {
const actual = sayHello('jake')
const expected = 'Hello Jake'
t.equal(actual, expected, 'When passing "jake" to sayHello(), the resulting string equals "Hello Jake"')
t.end()
})
test('sayHello trims the name', (t) => {
const actual = sayHello(' Thao ')
const expected = 'Hello Thao'
t.equal(actual, expected, 'When passing " Thao " to sayHello(), the resulting string equals "Hello Thao"')
t.end()
})
$ npm test
$ npm run watch
$ browser-sync start --server --files "dist/*.js, index.html"