diff --git a/.eslintrc b/.eslintrc index 924a5bf..0c9970d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -31,6 +31,7 @@ "react/prop-types": 0, "react/jsx-filename-extension": 0, "comma-dangle": [2, "always-multiline"], + "arrow-parens": ["warn", "always"], "jsx-a11y/anchor-is-valid": [ "error", { "components": [ "Link" ], "specialLink": [ "to", "hrefLeft", "hrefRight" ], diff --git a/bin/commands.js b/bin/commands.js index baa7cee..07a5329 100644 --- a/bin/commands.js +++ b/bin/commands.js @@ -5,10 +5,6 @@ const colors = require('colors'); const host = config.get('host') || 'localhost'; const port = config.get('port') || '8080'; -console.log('using settings:'); -console.log('\thost:', host); -console.log('\tport:', port); - const option = process.argv[2]; switch (option) { @@ -16,10 +12,10 @@ switch (option) { shell.exec('cross-env eslint src/js/** server/** --format node_modules/eslint-friendly-formatter . --ext .js --ext .jsx --cache; exit 0'); break; case 'dev': - shell.exec(`cross-env HOST=${host} PORT=${port} webpack-dev-server --hot --progress --no-info --inline --colors --content-base ./docroot`); + shell.exec(`cross-env HOST=${host} PORT=${port} webpack-dev-server --config webpack.config.dev-server.babel.js --hot --progress --no-info --inline --colors --content-base ./docroot`); break; case 'build': - shell.exec(`cross-env rimraf docroot && webpack --progress --display-error-details`); + shell.exec(`cross-env rimraf docroot && webpack --config webpack.config.build.babel.js --progress --display-error-details`); break; default: // If the app type is invalid, stop execution of the file. diff --git a/bin/shouldBuild.js b/bin/shouldBuild.js deleted file mode 100644 index 36e12e2..0000000 --- a/bin/shouldBuild.js +++ /dev/null @@ -1,7 +0,0 @@ -// - Note: You can add in more environment if you want, our current setting -// is we only built and optimize `production` and `release`. - -const IS_PRODUCTION = process.env.NODE_ENV === 'production'; -const IS_RELEASE = process.env.NODE_ENV === 'release'; - -export const SHOULD_BUILD = IS_PRODUCTION || IS_RELEASE; \ No newline at end of file diff --git a/bin/start.js b/bin/start.js deleted file mode 100644 index 8a0e090..0000000 --- a/bin/start.js +++ /dev/null @@ -1,8 +0,0 @@ -import shell from 'shelljs'; -import { SHOULD_BUILD } from './shouldBuild'; - -// Is the app in production mode -const command = SHOULD_BUILD ? 'build' : 'dev'; - -// Run the appropriate npm command -shell.exec(`npm run ${command}`); diff --git a/config/default.json b/config/default.json index 400d26c..11a132b 100644 --- a/config/default.json +++ b/config/default.json @@ -2,6 +2,8 @@ "env": "default", "host": "localhost", "port": "8080", + "publicPath": "/", + "assetPath": "assets", "jsSourcePath": "src/js", "s3": { "s3Deploy": false, diff --git a/config/development.json b/config/development.json index b800f55..9d2c40f 100644 --- a/config/development.json +++ b/config/development.json @@ -2,6 +2,6 @@ "env": "development", "app": { "description": "you can overwrite the default config", - "hello": "Config is configurable" + "hello": "You are in local development mode" } } diff --git a/config/production.json b/config/production.json index 385f8e0..cfd422d 100644 --- a/config/production.json +++ b/config/production.json @@ -1,4 +1,4 @@ { "env": "production", - "publicPath": "./" + "publicPath": "/" } diff --git a/config/release.json b/config/stage.json similarity index 100% rename from config/release.json rename to config/stage.json diff --git a/package.json b/package.json index cb688a4..c96b421 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "dev": "cross-env NODE_ENV=development DASHBOARD_PORT=9901 webpack-dashboard -p 9901 -c red -t dashboard -- node bin/commands.js dev", "build": "cross-env NODE_ENV=production node bin/commands.js build", - "build:release": "cross-env NODE_ENV=release node bin/commands.js build", + "build:stage": "cross-env NODE_ENV=stage node bin/commands.js build", "clean": "rimraf docroot", "test": "jest --no-cache", "lint": "node bin/commands.js lint" diff --git a/webpack.config.babel.js b/webpack.config.babel.js deleted file mode 100644 index 479ef21..0000000 --- a/webpack.config.babel.js +++ /dev/null @@ -1,12 +0,0 @@ -import { SHOULD_BUILD } from './bin/shouldBuild'; -// Defining config variables -// ================================================================================ - -// If it's production or release, we use the production config, -// Otherwise, use the development config -// please looked at ./bin/shouldBuild.js -const webpackConfig = (SHOULD_BUILD) - ? require('./webpack.config.prod') - : require('./webpack.config.dev'); - -export default webpackConfig; diff --git a/webpack.config.prod.js b/webpack.config.build.babel.js similarity index 90% rename from webpack.config.prod.js rename to webpack.config.build.babel.js index bfa2cf0..dfc47c2 100644 --- a/webpack.config.prod.js +++ b/webpack.config.build.babel.js @@ -21,14 +21,14 @@ const APP_ENTRY_POINT = `${JS_SOURCE}/router`; const webpackProdOutput = { publicPath: PUBLIC_PATH, - filename: 'assets/[name]-[hash].js', - chunkFilename: "assets/[id].[hash].js", + filename: `${config.get('assetPath')}/[name]-[hash].js`, + chunkFilename: `${config.get('assetPath')}/[id].[hash].js`, }; // This section is for common chunk behavior // do we need to exclude css from this rule const optimizationMinChunks = config.get('optimization.cssExclusion') ? - function(module, count) { + (module, count) => { return module.resource && !(/\.css/).test(module.resource) && count >= config.get('optimization.commonMinCount'); @@ -42,7 +42,7 @@ const html = config.get('html'); // to deploy the generated html to production. // I don't mind you name your page as Retro // if you want to ... -const htmlPlugins = html.map((page) => +const htmlPlugins = html.map(page => new HtmlWebpackPlugin({ title: page.title, template: `src/assets/template/${page.template}`, @@ -53,8 +53,7 @@ const htmlPlugins = html.map((page) => collapseWhitespace: true, conservativeCollapse: true, } - }) -); + })); // ---------------------------------------------------------- // Extending Webpack Configuration @@ -66,7 +65,7 @@ webpackConfig.output = Object.assign(webpackConfig.output, webpackProdOutput); webpackConfig.module.rules = webpackConfig.module.rules.concat({ test: /\.css$/, use: ExtractTextPlugin.extract({ - fallback: "style-loader", + fallback: 'style-loader', use: [ { loader: 'css-loader', @@ -120,8 +119,8 @@ if (IS_S3_DEPLOY) { webpackConfig.plugins = webpackConfig.plugins.concat(s3Config); } -if(config.get('optimization.analyzeMode') === true) { - var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; +if (config.get('optimization.analyzeMode') === true) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; webpackConfig.plugins = webpackConfig.plugins.concat( new BundleAnalyzerPlugin({ @@ -152,7 +151,7 @@ webpackConfig.plugins.push( }), new webpack.optimize.CommonsChunkPlugin({ name: 'common', - filename: 'assets/common-[hash].js', + filename: `${config.get('assetPath')}/common-[hash].js`, minChunks: optimizationMinChunks, }), new SaveAssetsJson({ @@ -164,7 +163,7 @@ webpackConfig.plugins.push( }, }), new ExtractTextPlugin({ - filename: 'assets/[name]-[hash].css', + filename: `${config.get('assetPath')}/[name]-[hash].css`, disable: false, allChunks: true, }) diff --git a/webpack.config.common.js b/webpack.config.common.js index e6ac198..dd1b2e7 100644 --- a/webpack.config.common.js +++ b/webpack.config.common.js @@ -7,19 +7,10 @@ import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin'; import config from 'config'; import fs from 'fs'; -import { SHOULD_BUILD } from './bin/shouldBuild'; - // trace which loader is deprecated // feel free to remove that if you don't need this feature process.traceDeprecation = false; -// Please read the following link if -// you have no idea how to use this feature -// https://github.com/motdotla/dotenv -if(!SHOULD_BUILD) { - require('dotenv').config({silent: true}); -} - // Environment variable injection // ================================================================================ const version = JSON.parse(fs.readFileSync('package.json', 'utf8')).version; @@ -27,7 +18,8 @@ process.env.PACKAGE_VERSION = version; // Defining config variables // ================================================================================ -const BUILD_PATH = path.join(__dirname, 'docroot'); + +export const BUILD_PATH = path.join(__dirname, `docroot${config.get('publicPath')}`) const COMMON_LOADERS = [ { @@ -38,7 +30,7 @@ const COMMON_LOADERS = [ options: { hash: 'sha512', digest: 'hex', - name: 'assets/[hash].[ext]', + name: `${config.get('assetPath')}/[hash].[ext]`, } }, { @@ -83,6 +75,7 @@ const COMMON_LOADERS = [ options: { limit: 10000, mimetype: 'application/font-woff', + name: `${config.get('assetPath')}/[name].[ext]`, } } ], @@ -95,6 +88,7 @@ const COMMON_LOADERS = [ options: { limit: 10000, mimetype: 'application/font-woff', + name: `${config.get('assetPath')}/[name].[ext]`, } } ], @@ -107,6 +101,7 @@ const COMMON_LOADERS = [ options: { limit: 10000, mimetype: 'application/octet-stream', + name: `${config.get('assetPath')}/[name].[ext]`, } } ], @@ -119,6 +114,7 @@ const COMMON_LOADERS = [ options: { limit: 10000, mimetype: 'application/vnd.ms-fontobject', + name: `${config.get('assetPath')}/[name].[ext]`, } } ], @@ -131,7 +127,7 @@ export const JS_SOURCE = config.get('jsSourcePath'); export default { output: { - path: BUILD_PATH, + path: path.join(__dirname, 'docroot'), }, resolve: { extensions: ['.js', '.jsx', '.css'], diff --git a/webpack.config.dev.js b/webpack.config.dev-server.babel.js similarity index 71% rename from webpack.config.dev.js rename to webpack.config.dev-server.babel.js index e78d9c8..2bb4f28 100644 --- a/webpack.config.dev.js +++ b/webpack.config.dev-server.babel.js @@ -7,24 +7,32 @@ import postcssCssnext from 'postcss-cssnext'; import webpackConfig, { JS_SOURCE } from './webpack.config.common'; -const PUBLIC_PATH = `${config.get('host')}:${config.get('port')}`; +// Please read the following link if +// you have no idea how to use this feature +// https://github.com/motdotla/dotenv +require('dotenv').config({ silent: true }); + +const HOST = process.env.HOST || config.get('host') || '0.0.0.0' +const PORT = process.env.PORT || config.get('port') || '8080' const APP_ENTRY_POINT = `${JS_SOURCE}/router`; const webpackDevOutput = { - publicPath: `http://${PUBLIC_PATH}/`, - filename: 'assets/bundle.js', + publicPath: config.get('publicPath'), + filename: 'bundle.js', }; // Merges webpackDevOutput and webpackConfig.output webpackConfig.output = Object.assign(webpackConfig.output, webpackDevOutput); webpackConfig.devServer = { - port: config.get('port'), - clientLogLevel: "error", + host: HOST, + port: PORT, + disableHostCheck: true, + clientLogLevel: 'error', compress: true, noInfo: true, quiet: true, - stats: "errors-only", + stats: 'errors-only', }; // This is your testing container, we did @@ -39,8 +47,7 @@ const htmlPlugins = html.map((page) => template: `src/assets/template/${page.template}`, inject: 'body', filename: page.filename, - }) -); + })); webpackConfig.plugins.push( new DashboardPlugin({ @@ -64,23 +71,21 @@ webpackConfig.plugins.push( // We turn off browserSync by default // Turn that on if you want to include this use case -if(config.get('browserSync.active') === true) { +if (config.get('browserSync.active') === true) { const BrowserSyncPlugin = require('browser-sync-webpack-plugin'); - webpackConfig.plugins.push( - new BrowserSyncPlugin({ - host: 'localhost', - port: config.get('browserSync.port'), - proxy: `http://localhost:${process.env.PORT}/`, - - // Prevents BrowserSync from automatically opening up the app in your browser - open: false, - reloadDelay: 2500, - }, { - // Disable BrowserSync's browser reload/asset injections feature because - // Webpack Dev Server handles this for us already - reload: false, - }) - ); + webpackConfig.plugins.push(new BrowserSyncPlugin({ + host: 'localhost', + port: config.get('browserSync.port'), + proxy: `http://localhost:${process.env.PORT}/`, + + // Prevents BrowserSync from automatically opening up the app in your browser + open: false, + reloadDelay: 2500, + }, { + // Disable BrowserSync's browser reload/asset injections feature because + // Webpack Dev Server handles this for us already + reload: false, + })); } webpackConfig.module.rules = webpackConfig.module.rules.concat({ @@ -117,7 +122,7 @@ webpackConfig.devtool = 'cheap-module-eval-source-map'; webpackConfig.entry = [ 'babel-polyfill', - `webpack-dev-server/client?http://${PUBLIC_PATH}`, + `webpack-dev-server/client?http://${HOST}:${PORT}`, 'webpack/hot/only-dev-server', `./${APP_ENTRY_POINT}`, ];