diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..e7bacab --- /dev/null +++ b/.babelrc @@ -0,0 +1,6 @@ +{ + "presets": [ + "react", + "es2015" + ] +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c74335e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,26 @@ +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +# Spaces in js, jsx, and json +[*.{coffee,js,jsx,json}] +indent_style = space +indent_size = 2 + +# Tabs in styles +[*.{less,css,scss}] +indent_style = space +indent_size = 2 + +# Spaces in HTML +[*.html] +indent_style = space +indent_size = 2 + +[.eslintrc] +indent_style = space +indent_size = 2 diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..c94e1ad --- /dev/null +++ b/.eslintrc @@ -0,0 +1,181 @@ +{ + "parser": "babel-eslint", + "env": { + "browser": true, + "node": true, + "jasmine": true + }, + "plugins": [ + "react" + ], + "ecmaFeatures": { + "arrowFunctions": true, + "blockBindings": true, + "classes": true, + "defaultParams": true, + "destructuring": true, + "forOf": true, + "generators": false, + "modules": true, + "objectLiteralComputedProperties": true, + "objectLiteralDuplicateProperties": false, + "objectLiteralShorthandMethods": true, + "objectLiteralShorthandProperties": true, + "spread": true, + "superInFunctions": true, + "templateStrings": true, + "jsx": true + }, + "rules": { + "strict": [2, "never"], + "no-var": 2, + + "no-shadow": 2, + "no-shadow-restricted-names": 2, + "no-unused-vars": [2, { + "vars": "local", + "args": "after-used" + }], + "no-use-before-define": 2, + + "comma-dangle": [2, "never"], + "no-cond-assign": [2, "always"], + "no-console": 1, + "no-debugger": 1, + "no-alert": 1, + "no-constant-condition": 1, + "no-dupe-keys": 2, + "no-duplicate-case": 2, + "no-empty": 2, + "no-ex-assign": 2, + "no-extra-boolean-cast": 0, + "no-extra-semi": 2, + "no-func-assign": 2, + "no-inner-declarations": 2, + "no-invalid-regexp": 2, + "no-irregular-whitespace": 2, + "no-obj-calls": 2, + "quote-props": [2, 'consistent-as-needed'], + "no-sparse-arrays": 2, + "no-unreachable": 2, + "use-isnan": 2, + /*"block-scoped-var": 2,*/ + + "consistent-return": 2, + "curly": [2, "multi-line"], + "default-case": 2, + "dot-notation": [2, { + "allowKeywords": true + }], + "eqeqeq": 2, + "guard-for-in": 2, + "no-caller": 2, + "no-else-return": 2, + "no-eq-null": 2, + "no-eval": 2, + "no-extend-native": 2, + "no-extra-bind": 2, + "no-fallthrough": 2, + "no-floating-decimal": 2, + "no-implied-eval": 2, + "no-lone-blocks": 2, + "no-loop-func": 2, + "no-multi-str": 2, + "no-native-reassign": 2, + "no-new": 2, + "no-new-func": 2, + "no-new-wrappers": 2, + "no-octal": 2, + "no-octal-escape": 2, + "no-param-reassign": 2, + "no-proto": 2, + "no-redeclare": 2, + "no-return-assign": 2, + "no-script-url": 2, + "no-self-compare": 2, + "no-sequences": 2, + "no-throw-literal": 2, + "no-with": 2, + "radix": 2, + "vars-on-top": 2, + "wrap-iife": [2, "any"], + "yoda": 2, + + "indent": [2, 2], + "brace-style": [2, + "1tbs", { + "allowSingleLine": true + }], + "quotes": [ + 2, "single", "avoid-escape" + ], + "camelcase": [2, { + "properties": "never" + }], + "comma-spacing": [2, { + "before": false, + "after": true + }], + "comma-style": [2, "last"], + "eol-last": 2, + "func-names": 0, + "key-spacing": [2, { + "beforeColon": false, + "afterColon": true + }], + "new-cap": [2, { + "newIsCap": true, + "capIsNewExceptions": [ + "List", + "Map", + "OrderedMap", + "Set", + "OrderedSet", + "Stack", + "Record", + "Seq", + "KeyedSeq", + "IndexedSeq", + "SetSeq", + "Iterable", + "KeyedIterable", + "IndexedIterable", + "SetIterable", + "Collection", + "KeyedCollection", + "IndexedCollection", + "SetCollection" + ] + }], + "no-multiple-empty-lines": [2, { + "max": 2 + }], + "no-nested-ternary": 1, + "no-new-object": 2, + "no-spaced-func": 2, + "no-trailing-spaces": 2, + "no-extra-parens": 0, + "no-underscore-dangle": 0, + "one-var": [2, "never"], + "padded-blocks": [2, "never"], + "semi": [2, "always"], + "semi-spacing": [2, { + "before": false, + "after": true + }], + "space-after-keywords": 2, + "space-before-blocks": 2, + "space-before-function-paren": [2, "never"], + "space-infix-ops": 2, + "space-return-throw-case": 2, + "spaced-comment": 2, + "react/jsx-uses-react": 1, + "react/no-danger": 1, + "react/no-did-mount-set-state": 1, + "react/no-did-update-set-state": 1, + "react/react-in-jsx-scope": 1, + "react/require-extension": 1, + "react/self-closing-comp": 1, + "react/sort-comp": 1 + } +} diff --git a/.gitignore b/.gitignore index 615a102..7e95031 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ -node_modules/ -build/ -npm-debug.log +node_modules +build +dist +tmp +npm-debug.log* .DS_Store diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000..31876ac --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,52 @@ +/*eslint-disable */ +require('babel-register'); +var path = require('path'); +var webpack = require('webpack'); +var webpackConfig = require(path.join(__dirname, 'webpack.config.babel')).default; +/*eslint-enable */ + +module.exports = function(config) { + config.set({ + browsers: ['PhantomJS'], + singleRun: false, + logLevel: config.LOG_ERROR, + plugins: [ + 'karma-phantomjs-launcher', + 'karma-phantomjs-shim', + 'karma-mocha', + 'karma-chai', + 'karma-webpack', + 'karma-sourcemap-loader', + 'karma-mocha-reporter' + ], + frameworks: [ + 'mocha', + 'chai', + 'phantomjs-shim' + ], + files: [ + path.join(__dirname, 'tests.bundle.js') + ], + preprocessors: { + 'tests.bundle.js': [ + 'webpack', + 'sourcemap' + ] + }, + webpack: { + devtool: 'eval', + resolve: webpackConfig.resolve, + module: webpackConfig.module, + plugins: [ + new webpack.IgnorePlugin(/ReactContext/) + ] + }, + webpackMiddleware: { + noInfo: true, + watchOptions: { + poll: true + } + }, + reporters: [ 'mocha' ] + }); +}; diff --git a/package.json b/package.json index 594ad36..feaea1a 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,14 @@ "description": "Starter sederhana untuk ReactJS, Webpack, dan Babel ES2015", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "webserver": "node src/server.js", - "build": "node_modules/.bin/webpack", - "dev": "node_modules/.bin/webpack-dev-server", - "deploy": "NODE_ENV=production webpack -p" + "prestart": "rimraf tmp", + "start": "webpack-dev-server --watch-poll", + "prebuild": "rimraf dist", + "build": "npm run prestart && webpack --config webpack.config.prod.babel.js -p", + "test": "npm run prestart && karma start karma.conf.js --single-run", + "tdd": "karma start karma.conf.js", + "precommit": "npm test", + "cleanup": "npm run prestart && npm run prebuild" }, "repository": { "type": "git", @@ -26,16 +29,38 @@ }, "homepage": "https://github.com/reactjs-id/react-webpack-simple-starter#readme", "dependencies": { - "babel-core": "^6.3.17", - "babel-loader": "^6.2.0", - "html-webpack-plugin": "^1.7.0", "react": "^0.14.3", - "react-dom": "^0.14.3", - "webpack": "^1.12.9" + "react-dom": "^0.14.3" }, "devDependencies": { + "babel-core": "^6.3.17", + "babel-loader": "^6.2.0", "babel-preset-es2015": "^6.3.13", "babel-preset-react": "^6.3.13", + "babel-register": "^6.3.13", + "chai": "^3.4.1", + "css-loader": "^0.23.0", + "extract-text-webpack-plugin": "^0.9.1", + "file-loader": "^0.8.5", + "html-webpack-plugin": "^1.7.0", + "husky": "^0.10.2", + "karma": "^0.13.15", + "karma-chai": "^0.1.0", + "karma-mocha": "^0.2.1", + "karma-mocha-reporter": "^1.1.3", + "karma-phantomjs-launcher": "^0.2.1", + "karma-phantomjs-shim": "^1.1.2", + "karma-sourcemap-loader": "^0.3.6", + "karma-webpack": "^1.7.0", + "mocha": "^2.3.4", + "phantomjs": "^1.9.19", + "react-addons-create-fragment": "^0.14.3", + "react-addons-test-utils": "^0.14.3", + "react-hot-loader": "^1.3.0", + "rimraf": "^2.4.4", + "skin-deep": "^0.13.0", + "style-loader": "^0.13.0", + "webpack": "^1.12.9", "webpack-dev-server": "^1.14.0" } } diff --git a/readme.md b/readme.md index 809f391..4e2c2f1 100644 --- a/readme.md +++ b/readme.md @@ -14,24 +14,60 @@ Starter ini sangat sederhana dan hanya mencakup library berikut : Clone repository ini. lalu jalankan - npm install +```sh +npm install +``` -Setelah itu silakan mulai modifikasi file `src/index.js`. +untuk membuat komponen baru, buat folder di `src/components` sesuai dengan nama component yang ingin dibuat. lihat contoh component `hello`. + +untuk bisa melihat hasilnya, modifikasi file `src/index.js` dengan meng-import komponen yang baru dibuat. Untuk memulai aplikasi dengan mode development (webpack-dev-server) jalankan perintah berikut - npm run dev +```sh +npm start +``` lalu buka `http://localhost:8080/` -Untuk build aplikasi yang menghasilkan static file jalankan perintah berikut +# Testing + +untuk melakukan testing, silakan buat file dengan ekstensi `.spec.js` didalam folder komponen yang baru dibuat. silakan lihat contoh yang ada pada komponen `Hello`. + +untuk melakukan **continuous testing**, jalankan perintah berikut + +```sh +npm run tdd +``` + +sedangkan untuk melakukan testing pada sistem CI (Continuous Integration) seperti wercker/travisCI, jalankan perintah berikut + +```sh +npm test +``` + +# Deployment + +Untuk build aplikasi untuk deployment, jalankan perintah berikut + +```sh +npm run build +``` + +hasil kompilasi aplikasi akan ada di folder `dist`. + +# Lain lain - npm run build +## Testing on Commit +setiap anda melakukan `git commit` pada projek ini, secara otomatis komputer akan menjalankan command `npm test`. untuk melewati langkah ini, cukup gunakan perintah `git commit --no-verify`. -Untuk deploy production jalankan perintah berikut +## Windows Development +apabila anda melakukan development menggunakan OS Windows dan virtualbox (seperti vagrant/laravel homestead), maka tambahkan `env` HOST=0.0.0.0 sebelum menjalankan command `npm start`. - npm run deploy +```sh +$ HOST=0.0.0.0 npm start +``` # Lisensi -MIT \ No newline at end of file +MIT diff --git a/src/components/hello/index.js b/src/components/hello/index.js new file mode 100644 index 0000000..55c0bf8 --- /dev/null +++ b/src/components/hello/index.js @@ -0,0 +1,14 @@ +import React, { Component } from 'react'; + +class Hello extends Component { + render() { + return ( +
Selamat belajar ReactJS
+Selamat belajar ReactJS
-