diff --git a/Gruntfile.js b/Gruntfile.js
index 9b5ab45..e2d7912 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,14 +1,5 @@
'use strict';
-var serveStatic = require('serve-static');
-
-var mountFolder = function (dir) {
- return serveStatic(require('path').resolve(dir));
-};
-
-var webpackDistConfig = require('./webpack.dist.config.js');
-var webpackDevConfig = require('./webpack.config.js');
-
module.exports = function (grunt) {
// Let *load-grunt-tasks* require everything
require('load-grunt-tasks')(grunt);
@@ -19,107 +10,24 @@ module.exports = function (grunt) {
grunt.initConfig({
'pkg': pkgConfig,
- 'webpack': {
- options: webpackDistConfig,
- dist: {
- cache: false
- }
- },
-
- 'webpack-dev-server': {
- options: {
- hot: true,
- port: 8000,
- webpack: webpackDevConfig,
- publicPath: '/assets/',
- contentBase: './<%= pkg.src %>/'
- },
-
- start: {
- keepAlive: true
- }
- },
-
- 'connect': {
- options: {
- port: 8000
- },
-
- dist: {
- options: {
- keepalive: true,
- middleware: function () {
- return [
- mountFolder(pkgConfig.dist)
- ];
- }
- }
- }
- },
-
'open': {
options: {
delay: 500
},
- dev: {
- path: 'http://localhost:<%= connect.options.port %>/webpack-dev-server/index.web.html'
- },
dist: {
- path: 'http://localhost:<%= connect.options.port %>/index.html'
- }
- },
-
- 'karma': {
- unit: {
- configFile: 'karma.conf.js'
- }
- },
-
- 'copy': {
- dist: {
- files: [
- {
- flatten: true,
- src: ['<%= pkg.src %>/index.web.html'],
- dest: '<%= pkg.dist %>/index.html'
- },
- {
- flatten: true,
- src: ['<%= pkg.src %>/favicon.ico'],
- dest: '<%= pkg.dist %>/favicon.ico'
- }
- ]
- }
- },
-
- 'clean': {
- dist: {
- files: [{
- dot: true,
- src: [
- '<%= pkg.dist %>'
- ]
- }]
- }
- },
-
- 'watch': {
- options: {
- livereload: true
- },
- build: {
- files: 'src/**/*.js',
- tasks: ['webpack']
+ path: 'http://localhost:8000/'
}
},
'exec': {
- launch_nw: '/Applications/nwjs.app/Contents/MacOS/nwjs .'
+ watch: pkgConfig.scripts.watch,
+ server: pkgConfig.scripts.server,
+ launch_nw: '/Applications/nwjs.app/Contents/MacOS/nwjs dist'
},
'concurrent': {
target: {
- tasks: ['watch', 'exec:launch_nw'],
+ tasks: ['exec:watch', 'exec:launch_nw'],
options: {
logConcurrentOutput: true
}
@@ -128,13 +36,9 @@ module.exports = function (grunt) {
});
grunt.registerTask('serve-web', function (target) {
- if (target === 'dist') {
- return grunt.task.run(['build', 'open:dist', 'connect:dist']);
- }
-
grunt.task.run([
- 'open:dev',
- 'webpack-dev-server'
+ 'open:dist',
+ 'exec:server'
]);
});
@@ -144,7 +48,5 @@ module.exports = function (grunt) {
]);
});
- grunt.registerTask('test', ['karma']);
- grunt.registerTask('build', ['clean', 'copy', 'webpack']);
grunt.registerTask('default', []);
};
diff --git a/README.md b/README.md
index 651b5a5..1e071bb 100644
--- a/README.md
+++ b/README.md
@@ -33,8 +33,8 @@ This project uses libraries and tools like:
- [NW](http://nwjs.io) to package the Desktop App
- [flux](https://facebook.github.io/flux) to organize the data flow management
- [css-loader](https://github.com/webpack/css-loader) to integrate the styles in the builds
-- [grunt](http://gruntjs.com) to create the builds
-- [webpack](https://webpack.github.io) to help during the development phase with hot reloading
+- [grunt](http://gruntjs.com) to launch NW.js or your web browser
+- [webpack](https://webpack.github.io) to create the builds and help during the development phase with hot reloading
## Basic philosophy
@@ -148,8 +148,8 @@ There isn't any addtional requirements since you already installed the deps with
### Quick start
-- `npm run build` to build the project (at least the first time)
-- `npm run serve-web` to preview in the browser at http://localhost:8000/index.web.html or http://localhost:8000/webpack-dev-server/index.web.html with webpack-dev-server and hot reload enabled
+- `npm run build` to build the project
+- `npm run serve-web` to preview in the browser at http://localhost:8000/ with webpack-dev-server and hot reload enabled
Congratulations! You've just successfully run the project as a Website App.
@@ -171,7 +171,7 @@ You can also setup an alias to call the binary.
### Quick start
-- `npm run build` to build the project (at least the first time)
+- `npm run build` to build the project
- `npm run serve-nw` to launch the desktop app and enable livereload
Congratulations! You've just successfully run the project as a Desktop App.
diff --git a/index.web.html b/index.html
similarity index 50%
rename from index.web.html
rename to index.html
index 84cbeee..609c401 100644
--- a/index.web.html
+++ b/index.html
@@ -1,8 +1,14 @@
-
+
- Calculator Web App
+ {%=o.htmlWebpackPlugin.options.title || 'Webpack App'%}
+ {% if (o.htmlWebpackPlugin.files.favicon) { %}
+
+ {% } %}
+ {% for (var css in o.htmlWebpackPlugin.files.css) { %}
+
+ {% } %}
@@ -16,6 +22,9 @@
-
+
+ {% for (var chunk in o.htmlWebpackPlugin.files.chunks) { %}
+
+ {% } %}
diff --git a/index.nw.html b/index.nw.html
deleted file mode 100644
index 4ec0975..0000000
--- a/index.nw.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- Calculator Desktop App
-
-
-
-
-
-
-
-
diff --git a/karma.conf.js b/karma.conf.js
index ae1d042..f868a67 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -1,6 +1,6 @@
'use strict';
-var path = require('path');
+var webpackConfig = require('./webpack.config.js');
module.exports = function (config) {
config.set({
@@ -19,27 +19,7 @@ module.exports = function (config) {
},
webpack: {
cache: true,
- module: {
- loaders: [{
- test: /\.gif/,
- loader: 'url-loader?limit=10000&mimetype=image/gif'
- }, {
- test: /\.jpg/,
- loader: 'url-loader?limit=10000&mimetype=image/jpg'
- }, {
- test: /\.png/,
- loader: 'url-loader?limit=10000&mimetype=image/png'
- }, {
- test: /\.js$/,
- loader: 'babel-loader'
- }, {
- test: /\.sass/,
- loader: 'style-loader!css-loader!sass-loader?outputStyle=expanded'
- }, {
- test: /\.css$/,
- loader: 'style-loader!css-loader'
- }]
- }
+ module: webpackConfig.module
},
webpackServer: {
stats: {
diff --git a/package.json b/package.json
index 5ecf63c..20a7ef1 100644
--- a/package.json
+++ b/package.json
@@ -16,15 +16,12 @@
"flux",
"babel"
],
- "src": "./",
- "test": "./test",
- "dist": "./dist",
- "mainInput": "main",
- "mainOutput": "main",
- "main": "index.nw.html",
"scripts": {
- "build": "grunt build",
+ "build": "npm run clean && `npm bin`/webpack --config webpack.dist.config.js",
+ "clean": "`npm bin`/rimraf dist",
"deploy": "gh-pages -d dist",
+ "karma": "`npm bin`/karma start",
+ "server": "`npm bin`/webpack-dev-server --config ./webpack.hot.config.js --content-base ./dist/ --port 8000 --inline --hot --progress",
"travis": "npm run build && npm run react-native:ios && npm run react-native:android && npm test",
"react-native:ios": "react-native bundle --root src --platform ios --minify",
"react-native:android": "react-native bundle --root src --platform android --minify",
@@ -32,14 +29,8 @@
"serve-web": "grunt serve-web",
"serve-web:dist": "grunt serve-web:dist",
"start": "node_modules/react-native/packager/packager.sh",
- "test": "jest"
- },
- "window": {
- "toolbar": true,
- "min_width": 300,
- "min_height": 475,
- "max_width": 800,
- "max_height": 600
+ "test": "`npm bin`/jest",
+ "watch": "`npm bin`/webpack --config webpack.config.js --watch"
},
"jest": {
"scriptPreprocessor": "/node_modules/babel-jest",
@@ -80,20 +71,15 @@
"css-loader": "^0.22.0",
"eslint": "^1.9.0",
"eslint-plugin-react": "^3.8.0",
+ "file-loader": "^0.8.4",
"gh-pages": "^0.5.0",
"grunt": "^0.4.5",
"grunt-concurrent": "^2.0.4",
- "grunt-contrib-clean": "^0.6.0",
- "grunt-contrib-connect": "^0.11.2",
- "grunt-contrib-copy": "^0.8.2",
- "grunt-contrib-watch": "^0.6.1",
"grunt-exec": "^0.4.6",
- "grunt-karma": "^0.12.1",
"grunt-open": "^0.2.3",
- "grunt-webpack": "^1.0.11",
+ "html-webpack-plugin": "^1.6.2",
+ "jasmine-core": "^2.3.4",
"jest-cli": "^0.7.1",
- "jshint": "^2.8.0",
- "jshint-loader": "^0.8.3",
"karma": "^0.13.15",
"karma-chrome-launcher": "^0.2.1",
"karma-firefox-launcher": "^0.1.6",
@@ -102,7 +88,10 @@
"karma-script-launcher": "^0.1.0",
"karma-webpack": "^1.7.0",
"load-grunt-tasks": "^3.3.0",
+ "node-sass": "^3.4.1",
+ "phantomjs": "^1.9.18",
"react-hot-loader": "^1.3.0",
+ "rimraf": "^2.4.3",
"sass-loader": "^3.1.1",
"style-loader": "^0.13.0",
"url-loader": "^0.5.6",
diff --git a/src/index.js b/src/index.js
index 05ca008..c116947 100644
--- a/src/index.js
+++ b/src/index.js
@@ -5,6 +5,9 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route } from 'react-router';
+require('file?name=package.json!./package.web.json');
+require('file?name=favicon.ico!../favicon.ico');
+
// CSS
require('normalize.css');
require('./styles/main.css');
diff --git a/src/package.web.json b/src/package.web.json
new file mode 100644
index 0000000..21ea46e
--- /dev/null
+++ b/src/package.web.json
@@ -0,0 +1,11 @@
+{
+ "name": "react-native-nw-react-calculator-nwjs",
+ "main": "index.html",
+ "window": {
+ "toolbar": true,
+ "min_width": 300,
+ "min_height": 475,
+ "max_width": 800,
+ "max_height": 600
+ }
+}
diff --git a/webpack.config.js b/webpack.config.js
index 8a20ea3..ac1cb3f 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,36 +1,41 @@
/*
- * Webpack development server configuration
+ * Webpack base configuration
*/
'use strict';
-var webpack = require('webpack');
+var path = require('path');
+var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
- output: {
- filename: 'main.js',
- publicPath: '/assets/'
- },
- cache: true,
- debug: true,
- devtool: false,
+ devtool: 'source-map',
+
entry: [
- 'webpack/hot/only-dev-server',
- './src/index.js'
+ './src/index.js'
],
+
+ output: {
+ filename: 'assets/main.js',
+ path: path.join(__dirname, 'dist')
+ },
+
stats: {
colors: true,
reasons: true
},
+
plugins: [
- new webpack.HotModuleReplacementPlugin(),
- new webpack.NoErrorsPlugin()
+ new HtmlWebpackPlugin({
+ title: 'Calculator App',
+ template: './index.html'
+ })
],
+
module: {
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
- loader: 'react-hot!babel-loader'
+ loader: 'babel-loader'
}, {
test: /\.sass/,
loader: 'style-loader!css-loader!sass-loader?outputStyle=expanded&indentedSyntax'
diff --git a/webpack.dist.config.js b/webpack.dist.config.js
index a65c7fe..4e02671 100644
--- a/webpack.dist.config.js
+++ b/webpack.dist.config.js
@@ -6,41 +6,17 @@
'use strict';
+require('babel/register');
var webpack = require('webpack');
+var baseConfig = require('./webpack.config.js');
-module.exports = {
- output: {
- publicPath: '/assets/',
- path: 'dist/assets/',
- filename: 'main.js'
- },
- debug: false,
+module.exports = Object.assign({}, baseConfig, {
devtool: false,
- entry: './src/index.js',
- stats: {
- colors: true,
- reasons: false
- },
- plugins: [
+
+ plugins: baseConfig.plugins.concat([
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.AggressiveMergingPlugin()
- ],
- module: {
- loaders: [{
- test: /\.js$/,
- exclude: /node_modules/,
- loader: 'babel-loader'
- }, {
- test: /\.css$/,
- loader: 'style-loader!css-loader'
- }, {
- test: /\.sass/,
- loader: 'style-loader!css-loader!sass-loader?outputStyle=expanded&indentedSyntax'
- }, {
- test: /\.(png|jpg)$/,
- loader: 'url-loader?limit=8192'
- }]
- }
-};
+ ])
+});
diff --git a/webpack.hot.config.js b/webpack.hot.config.js
new file mode 100644
index 0000000..cbf4e8a
--- /dev/null
+++ b/webpack.hot.config.js
@@ -0,0 +1,24 @@
+/*
+ * Webpack development server configuration
+ */
+
+'use strict';
+
+require('babel/register');
+var webpack = require('webpack');
+var baseConfig = require('./webpack.config.js');
+
+module.exports = Object.assign({}, baseConfig, {
+ debug: true,
+
+ entry: [
+ 'webpack/hot/only-dev-server'
+ ].concat(baseConfig.entry),
+
+ plugins: baseConfig.plugins.concat([
+ new webpack.HotModuleReplacementPlugin(),
+ new webpack.NoErrorsPlugin()
+ ])
+});
+
+module.exports.module.loaders[0].loader = 'react-hot!babel-loader';