commit 26668a7f685fdae17f8a95663b99b66ac260e8c2 parent 4e73555efe8ef312bdf2939869b7e06b934cabc7 Author: Konstantin Tarkus <hello@tarkus.me> Date: Sat, 19 Sep 2015 10:22:04 +0300 Update npm modules; use AirBnb ESLint settings Diffstat:
28 files changed, 128 insertions(+), 167 deletions(-)
diff --git a/.eslintrc b/.eslintrc @@ -1,54 +1,10 @@ { - "extends": "eslint:recommended", - "parser": "babel-eslint", - "plugins": [ - "react" - ], - "env": { - "browser": true, - "node": true, - "es6": true - }, + "extends": "airbnb", "globals": { - "__DEV__": true, - "__SERVER__": true - }, - "ecmaFeatures": { - "jsx": true + "__DEV__": true }, "rules": { - // Strict mode - "strict": [2, "never"], - - // Code style - "indent": [2, 2], - "quotes": [2, "single"], - - // React - "react/display-name": 0, - "react/jsx-boolean-value": 1, - "react/jsx-closing-bracket-location": 1, - "react/jsx-curly-spacing": 1, - "react/jsx-max-props-per-line": 0, - "react/jsx-indent-props": 0, - "react/jsx-no-duplicate-props": 1, - "react/jsx-no-undef": 1, - "react/jsx-quotes": 1, - "react/jsx-sort-prop-types": 0, - "react/jsx-sort-props": 0, - "react/jsx-uses-react": 1, - "react/jsx-uses-vars": 1, - "react/no-danger": 0, - "react/no-set-state": 1, - "react/no-did-mount-set-state": 1, - "react/no-did-update-set-state": 1, - "react/no-multi-comp": 1, - "react/no-unknown-property": 1, - "react/prop-types": 1, - "react/react-in-jsx-scope": 1, - "react/require-extension": 1, - "react/self-closing-comp": 1, - "react/sort-comp": 1, - "react/wrap-multilines": 1 + "react/jsx-quotes": 0, + "jsx-quotes": [2, "prefer-double"] } } diff --git a/package.json b/package.json @@ -25,41 +25,42 @@ "superagent": "1.4.0" }, "devDependencies": { - "autoprefixer": "^6.0.2", - "babel-eslint": "^4.1.2", + "autoprefixer": "^6.0.3", + "babel-eslint": "^4.1.3", "babel-loader": "^5.3.2", "browser-sync": "^2.9.3", "css-loader": "^0.18.0", "csscomb": "^3.1.8", "del": "^2.0.2", - "eslint": "^1.4.1", + "eslint": "^1.5.0", + "eslint-config-airbnb": "0.0.8", "eslint-loader": "^1.0.0", - "eslint-plugin-react": "^3.3.2", + "eslint-plugin-react": "^3.4.2", "gaze": "^0.5.1", "git-push": "^0.1.1", "glob": "^5.0.14", - "jest-cli": "^0.5.4", + "jest-cli": "^0.5.7", "mkdirp": "^0.5.1", "ncp": "^2.0.0", "postcss": "^5.0.5", - "postcss-cssnext": "^2.0.1", + "postcss-cssnext": "^2.1.0", "postcss-import": "^7.0.0", "postcss-loader": "^0.6.0", "postcss-nested": "^1.0.0", "psi": "^1.0.6", "react-hot-loader": "^1.3.0", "replace": "^0.3.0", - "run-sequence": "^1.1.2", - "style-loader": "^0.12.3", + "style-loader": "^0.12.4", "url-loader": "^0.5.6", - "webpack": "^1.12.1", + "webpack": "^1.12.2", "webpack-dev-middleware": "^1.2.0", - "webpack-hot-middleware": "^2.0.2" + "webpack-hot-middleware": "^2.1.0" }, "jest": { "rootDir": "./src", "scriptPreprocessor": "../preprocessor.js", "unmockedModulePathPatterns": [ + "fbjs", "react" ] }, diff --git a/src/api/content.js b/src/api/content.js @@ -20,7 +20,7 @@ const router = new Router(); router.get('/', async (req, res, next) => { try { - let path = req.query.path; + const path = req.query.path; if (!path || path === 'undefined') { res.status(400).send({error: `The 'path' query parameter cannot be empty.`}); diff --git a/src/app.js b/src/app.js @@ -7,24 +7,24 @@ import Router from './routes'; import Location from './core/Location'; import { addEventListener, removeEventListener } from './utils/DOMUtils'; -let appContainer = document.getElementById('app'); let cssContainer = document.getElementById('css'); -let context = { +const appContainer = document.getElementById('app'); +const context = { onSetTitle: value => document.title = value, onSetMeta: (name, content) => { // Remove and create a new <meta /> tag in order to make it work // with bookmarks in Safari - let elements = document.getElementsByTagName('meta'); + const elements = document.getElementsByTagName('meta'); [].slice.call(elements).forEach((element) => { if (element.getAttribute('name') === name) { element.parentNode.removeChild(element); } }); - let meta = document.createElement('meta'); + const meta = document.createElement('meta'); meta.setAttribute('name', name); meta.setAttribute('content', content); document.getElementsByTagName('head')[0].appendChild(meta); - } + }, }; function render(state) { @@ -60,20 +60,25 @@ function run() { path: location.pathname, query: location.query, state: location.state, - context + context, }); render(currentState); }); // Save the page scroll position into the current location's state - var supportPageOffset = window.pageXOffset !== undefined; - var isCSS1Compat = ((document.compatMode || '') === 'CSS1Compat'); + const supportPageOffset = window.pageXOffset !== undefined; + const isCSS1Compat = ((document.compatMode || '') === 'CSS1Compat'); const setPageOffset = () => { currentLocation.state = currentLocation.state || Object.create(null); - currentLocation.state.scrollX = supportPageOffset ? window.pageXOffset : isCSS1Compat ? - document.documentElement.scrollLeft : document.body.scrollLeft; - currentLocation.state.scrollY = supportPageOffset ? window.pageYOffset : isCSS1Compat ? - document.documentElement.scrollTop : document.body.scrollTop; + if (supportPageOffset) { + currentLocation.state.scrollX = window.pageXOffset; + currentLocation.state.scrollY = window.pageYOffset; + } else { + currentLocation.state.scrollX = isCSS1Compat ? + document.documentElement.scrollLeft : document.body.scrollLeft; + currentLocation.state.scrollY = isCSS1Compat ? + document.documentElement.scrollTop : document.body.scrollTop; + } }; addEventListener(window, 'scroll', setPageOffset); diff --git a/src/components/App/App.js b/src/components/App/App.js @@ -14,7 +14,7 @@ class App extends Component { static propTypes = { children: PropTypes.element.isRequired, - error: PropTypes.object + error: PropTypes.object, }; render() { diff --git a/src/components/ContactPage/ContactPage.js b/src/components/ContactPage/ContactPage.js @@ -8,11 +8,11 @@ import withStyles from '../../decorators/withStyles'; class ContactPage extends Component { static contextTypes = { - onSetTitle: PropTypes.func.isRequired + onSetTitle: PropTypes.func.isRequired, }; render() { - let title = 'Contact Us'; + const title = 'Contact Us'; this.context.onSetTitle(title); return ( <div className="ContactPage"> diff --git a/src/components/ContentPage/ContentPage.js b/src/components/ContentPage/ContentPage.js @@ -10,11 +10,11 @@ class ContentPage extends Component { static propTypes = { path: PropTypes.string.isRequired, content: PropTypes.string.isRequired, - title: PropTypes.string + title: PropTypes.string, }; static contextTypes = { - onSetTitle: PropTypes.func.isRequired + onSetTitle: PropTypes.func.isRequired, }; render() { diff --git a/src/components/ErrorPage/ErrorPage.js b/src/components/ErrorPage/ErrorPage.js @@ -9,11 +9,11 @@ class ErrorPage extends Component { static contextTypes = { onSetTitle: PropTypes.func.isRequired, - onPageNotFound: PropTypes.func.isRequired + onPageNotFound: PropTypes.func.isRequired, }; render() { - let title = 'Error'; + const title = 'Error'; this.context.onSetTitle(title); return ( <div> diff --git a/src/components/Footer/Footer.js b/src/components/Footer/Footer.js @@ -13,13 +13,13 @@ class Footer extends Component { static propTypes = { viewport: PropTypes.shape({ width: PropTypes.number.isRequired, - height: PropTypes.number.isRequired - }).isRequired + height: PropTypes.number.isRequired, + }).isRequired, }; render() { // This is just an example how one can render CSS - let { width, height } = this.props.viewport; + const { width, height } = this.props.viewport; this.renderCss(`.Footer-viewport:after {content:' ${width}x${height}';}`); return ( diff --git a/src/components/Link/Link.js b/src/components/Link/Link.js @@ -17,12 +17,12 @@ class Link extends Component { to: PropTypes.string.isRequired, children: PropTypes.element.isRequired, state: PropTypes.object, - onClick: PropTypes.func + onClick: PropTypes.func, }; static handleClick = event => { - var allowTransition = true; - var clickResult; + let allowTransition = true; + let clickResult; if (this.props && this.props.onClick) { clickResult = this.props.onClick(event); diff --git a/src/components/LoginPage/LoginPage.js b/src/components/LoginPage/LoginPage.js @@ -8,11 +8,11 @@ import withStyles from '../../decorators/withStyles'; class LoginPage extends Component { static contextTypes = { - onSetTitle: PropTypes.func.isRequired + onSetTitle: PropTypes.func.isRequired, }; render() { - let title = 'Log In'; + const title = 'Log In'; this.context.onSetTitle(title); return ( <div className="LoginPage"> diff --git a/src/components/Navigation/Navigation.js b/src/components/Navigation/Navigation.js @@ -10,7 +10,7 @@ import Link from '../Link'; class Navigation extends Component { static propTypes = { - className: PropTypes.string + className: PropTypes.string, }; render() { diff --git a/src/components/NotFoundPage/NotFoundPage.js b/src/components/NotFoundPage/NotFoundPage.js @@ -9,11 +9,11 @@ class NotFoundPage extends Component { static contextTypes = { onSetTitle: PropTypes.func.isRequired, - onPageNotFound: PropTypes.func.isRequired + onPageNotFound: PropTypes.func.isRequired, }; render() { - let title = 'Page Not Found'; + const title = 'Page Not Found'; this.context.onSetTitle(title); this.context.onPageNotFound(); return ( diff --git a/src/components/RegisterPage/RegisterPage.js b/src/components/RegisterPage/RegisterPage.js @@ -8,11 +8,11 @@ import styles from './RegisterPage.css'; class RegisterPage extends Component { static contextTypes = { - onSetTitle: PropTypes.func.isRequired + onSetTitle: PropTypes.func.isRequired, }; render() { - let title = 'New User Registration'; + const title = 'New User Registration'; this.context.onSetTitle(title); return ( <div className="RegisterPage"> diff --git a/src/components/TextBox/TextBox.js b/src/components/TextBox/TextBox.js @@ -8,11 +8,11 @@ import styles from './TextBox.css'; class TextBox extends Component { static propTypes = { - maxLines: PropTypes.number + maxLines: PropTypes.number, }; static defaultProps = { - maxLines: 1 + maxLines: 1, }; render() { diff --git a/src/content/index.jade b/src/content/index.jade @@ -10,8 +10,6 @@ div.row dd A JavaScript library for building user interfaces, developed by Facebook dt <a href="http://facebook.github.io/flux/">Flux</a> dd Application architecture for building user interfaces - dt <a href="http://getbootstrap.com/">Bootstrap</a> - dd CSS framework for developing responsive, mobile first interfaces div.col-sm-4 h3 Development Tools dl diff --git a/src/core/HttpClient.js b/src/core/HttpClient.js @@ -1,13 +1,16 @@ /*! React Starter Kit | MIT License | http://www.reactstarterkit.com/ */ import request from 'superagent'; -import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment'; +import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment'; -const getUrl = path => path.startsWith('http') ? - path : ExecutionEnvironment.canUseDOM ? path : - process.env.WEBSITE_HOSTNAME ? - `http://${process.env.WEBSITE_HOSTNAME}${path}` : - `http://127.0.0.1:${global.server.get('port')}${path}`; +function getUrl(path) { + if (path.startsWith('http') || canUseDOM) { + return path; + } + return process.env.WEBSITE_HOSTNAME ? + `http://${process.env.WEBSITE_HOSTNAME}${path}` : + `http://127.0.0.1:${global.server.get('port')}${path}`; +} const HttpClient = { @@ -26,7 +29,7 @@ const HttpClient = { resolve(res.body); } }); - }) + }), }; diff --git a/src/decorators/withContext.js b/src/decorators/withContext.js @@ -11,29 +11,29 @@ function withContext(ComposedComponent) { onInsertCss: PropTypes.func, onSetTitle: PropTypes.func, onSetMeta: PropTypes.func, - onPageNotFound: PropTypes.func - }) + onPageNotFound: PropTypes.func, + }), }; static childContextTypes = { onInsertCss: PropTypes.func.isRequired, onSetTitle: PropTypes.func.isRequired, onSetMeta: PropTypes.func.isRequired, - onPageNotFound: PropTypes.func.isRequired + onPageNotFound: PropTypes.func.isRequired, }; getChildContext() { - let context = this.props.context; + const context = this.props.context; return { onInsertCss: context.onInsertCss || emptyFunction, onSetTitle: context.onSetTitle || emptyFunction, onSetMeta: context.onSetMeta || emptyFunction, - onPageNotFound: context.onPageNotFound || emptyFunction + onPageNotFound: context.onPageNotFound || emptyFunction, }; } render() { - let { context, ...other } = this.props; // eslint-disable-line no-unused-vars + const { context, ...other } = this.props; // eslint-disable-line no-unused-vars return <ComposedComponent {...other} />; } diff --git a/src/decorators/withStyles.js b/src/decorators/withStyles.js @@ -10,16 +10,17 @@ function withStyles(styles) { return (ComposedComponent) => class WithStyles extends Component { static contextTypes = { - onInsertCss: PropTypes.func + onInsertCss: PropTypes.func, }; constructor() { super(); this.refCount = 0; - ComposedComponent.prototype.renderCss = function (css) { + ComposedComponent.prototype.renderCss = function render(css) { let style; if (canUseDOM) { - if (this.styleId && (style = document.getElementById(this.styleId))) { + style = this.styleId && document.getElementById(this.styleId); + if (style) { if ('textContent' in style) { style.textContent = css; } else { @@ -60,7 +61,7 @@ function withStyles(styles) { if (this.styleId) { this.refCount--; if (this.refCount < 1) { - let style = document.getElementById(this.styleId); + const style = document.getElementById(this.styleId); if (style) { style.parentNode.removeChild(style); } diff --git a/src/decorators/withViewport.js b/src/decorators/withViewport.js @@ -22,7 +22,7 @@ function withViewport(ComposedComponent) { super(); this.state = { - viewport: canUseDOM ? {width: window.innerWidth, height: window.innerHeight} : viewport + viewport: canUseDOM ? {width: window.innerWidth, height: window.innerHeight} : viewport, }; } diff --git a/src/routes.js b/src/routes.js @@ -12,7 +12,6 @@ import NotFoundPage from './components/NotFoundPage'; import ErrorPage from './components/ErrorPage'; const router = new Router(on => { - on('*', async (state, next) => { const component = await next(); return component && <App context={state.context}>{component}</App>; @@ -33,7 +32,6 @@ const router = new Router(on => { <App context={state.context} error={error}><NotFoundPage /></App> : <App context={state.context} error={error}><ErrorPage /></App> ); - }); export default router; diff --git a/src/server.js b/src/server.js @@ -35,7 +35,7 @@ server.get('*', async (req, res, next) => { onInsertCss: value => css.push(value), onSetTitle: value => data.title = value, onSetMeta: (key, value) => data[key] = value, - onPageNotFound: () => statusCode = 404 + onPageNotFound: () => statusCode = 404, }; await Router.dispatch({ path: req.path, context }, (state, component) => { diff --git a/tools/config.js b/tools/config.js @@ -22,11 +22,11 @@ const AUTOPREFIXER_BROWSERS = [ 'Explorer >= 9', 'iOS >= 7', 'Opera >= 12', - 'Safari >= 7.1' + 'Safari >= 7.1', ]; const GLOBALS = { 'process.env.NODE_ENV': DEBUG ? '"development"' : '"production"', - '__DEV__': DEBUG + '__DEV__': DEBUG, }; // @@ -37,7 +37,7 @@ const GLOBALS = { const config = { output: { publicPath: '/', - sourcePrefix: ' ' + sourcePrefix: ' ', }, cache: DEBUG, @@ -52,15 +52,15 @@ const config = { chunks: VERBOSE, chunkModules: VERBOSE, cached: VERBOSE, - cachedAssets: VERBOSE + cachedAssets: VERBOSE, }, plugins: [ - new webpack.optimize.OccurenceOrderPlugin() + new webpack.optimize.OccurenceOrderPlugin(), ], resolve: { - extensions: ['', '.webpack.js', '.web.js', '.js', '.jsx'] + extensions: ['', '.webpack.js', '.web.js', '.js', '.jsx'], }, module: { @@ -68,33 +68,33 @@ const config = { test: /\.jsx?$/, include: [ path.resolve(__dirname, '../node_modules/react-routing/src'), - path.resolve(__dirname, '../src') + path.resolve(__dirname, '../src'), ], - loaders: [...(WATCH && ['react-hot']), 'babel-loader'] + loaders: [...(WATCH && ['react-hot']), 'babel-loader'], }, { test: /\.json$/, - loader: 'json-loader' + loader: 'json-loader', }, { test: /\.txt$/, - loader: 'raw-loader' + loader: 'raw-loader', }, { test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/, - loader: 'url-loader?limit=10000' + loader: 'url-loader?limit=10000', }, { test: /\.(eot|ttf|wav|mp3)$/, - loader: 'file-loader' - }] + loader: 'file-loader', + }], }, - postcss: function() { + postcss: function plugins() { return [ require('postcss-import')({ - onImport: files => files.forEach(this.addDependency) + onImport: files => files.forEach(this.addDependency), }), require('postcss-nested')(), - require('postcss-cssnext')({autoprefixer: AUTOPREFIXER_BROWSERS}) + require('postcss-cssnext')({autoprefixer: AUTOPREFIXER_BROWSERS}), ]; - } + }, }; // @@ -104,31 +104,31 @@ const config = { const appConfig = merge({}, config, { entry: [ ...(WATCH && ['webpack-hot-middleware/client']), - './src/app.js' + './src/app.js', ], output: { path: path.join(__dirname, '../build/public'), - filename: 'app.js' + filename: 'app.js', }, devtool: DEBUG ? 'source-map' : false, plugins: [ ...config.plugins, - new DefinePlugin(merge({}, GLOBALS, {'__SERVER__': false})), + new DefinePlugin(GLOBALS), ...(!DEBUG && [ new webpack.optimize.DedupePlugin(), new webpack.optimize.UglifyJsPlugin({compress: {warnings: VERBOSE}}), - new webpack.optimize.AggressiveMergingPlugin() + new webpack.optimize.AggressiveMergingPlugin(), ]), ...(WATCH && [ - new webpack.HotModuleReplacementPlugin() - ]) + new webpack.HotModuleReplacementPlugin(), + ]), ], module: { loaders: [...config.module.loaders, { test: /\.css$/, - loader: 'style-loader/useable!css-loader!postcss-loader' - }] - } + loader: 'style-loader/useable!css-loader!postcss-loader', + }], + }, }); // @@ -140,17 +140,17 @@ const serverConfig = merge({}, config, { output: { path: './build', filename: 'server.js', - libraryTarget: 'commonjs2' + libraryTarget: 'commonjs2', }, target: 'node', externals: [ - function (context, request, cb) { - var isExternal = + function filter(context, request, cb) { + const isExternal = request.match(/^[a-z][a-z\/\.\-0-9]*$/i) && !request.match(/^react-routing/) && !context.match(/[\\/]react-routing/); cb(null, Boolean(isExternal)); - } + }, ], node: { console: false, @@ -158,21 +158,21 @@ const serverConfig = merge({}, config, { process: false, Buffer: false, __filename: false, - __dirname: false + __dirname: false, }, devtool: DEBUG ? 'source-map' : 'cheap-module-source-map', plugins: [ ...config.plugins, - new DefinePlugin(merge({}, GLOBALS, {'__SERVER__': true})), + new DefinePlugin(GLOBALS), new BannerPlugin('require("source-map-support").install();', - { raw: true, entryOnly: false }) + { raw: true, entryOnly: false }), ], module: { loaders: [...config.module.loaders, { test: /\.css$/, - loader: 'css-loader!postcss-loader' - }] - } + loader: 'css-loader!postcss-loader', + }], + }, }); export default [appConfig, serverConfig]; diff --git a/tools/copy.js b/tools/copy.js @@ -28,7 +28,7 @@ export default async () => { // Website and email templates copy('src/templates', 'build/templates'), - copy('package.json', 'build/package.json') + copy('package.json', 'build/package.json'), ]); replace({ @@ -36,14 +36,14 @@ export default async () => { replacement: '"start": "node server.js"', paths: ['build/package.json'], recursive: false, - silent: false + silent: false, }); if (global.WATCH) { const watcher = await watch('src/content/**/*.*'); watcher.on('changed', async (file) => { - file = file.substr(path.join(__dirname, '../src/content/').length); - await copy(`src/content/${file}`, `build/content/${file}`); + const relPath = file.substr(path.join(__dirname, '../src/content/').length); + await copy(`src/content/${relPath}`, `build/content/${relPath}`); }); } }; diff --git a/tools/deploy.js b/tools/deploy.js @@ -20,19 +20,19 @@ export default () => new Promise((resolve, reject) => { remote = { name: 'production', url: 'https://example.scm.azurewebsites.net/example.git', - branch: 'master' + branch: 'master', }; } else if (process.argv.includes('staging')) { remote = { name: 'staging', url: 'https://example-staging.scm.azurewebsites.net/example.git', - branch: 'master' + branch: 'master', }; } else { remote = { name: 'test', url: 'https://example-test.scm.azurewebsites.net/example.git', - branch: 'master' + branch: 'master', }; } diff --git a/tools/lib/fs.js b/tools/lib/fs.js @@ -11,7 +11,7 @@ import fs from 'fs'; import mkdirp from 'mkdirp'; const writeFile = (file, contents) => new Promise((resolve, reject) => { - fs.writeFile(file, contents, 'utf8', err => err ? reject(err): resolve()); + fs.writeFile(file, contents, 'utf8', err => err ? reject(err) : resolve()); }); const makeDir = (name) => new Promise((resolve, reject) => { diff --git a/tools/serve.js b/tools/serve.js @@ -20,7 +20,7 @@ export default () => new Promise((resolve, reject) => { function start() { const server = cp.fork(path.join(__dirname, '../build/server.js'), { env: Object.assign({ NODE_ENV: 'development' }, process.env), - silent: false + silent: false, }); server.once('message', message => { diff --git a/tools/start.js b/tools/start.js @@ -21,7 +21,6 @@ const bundler = webpack(config); * synchronizing URLs, interactions and code changes across multiple devices. */ export default async () => { - await require('./build')(); await require('./serve')(); @@ -40,15 +39,15 @@ export default async () => { stats: config.stats, hot: true, - historyApiFallback: true + historyApiFallback: true, // for other settings see // http://webpack.github.io/docs/webpack-dev-middleware.html }), // bundler should be the same as above - webpackHotMiddleware(bundler) - ] + webpackHotMiddleware(bundler), + ], }, // no need to watch '*.js' here, webpack will take care of it for us, @@ -57,7 +56,7 @@ export default async () => { 'build/public/**/*.css', 'build/public/**/*.html', 'build/content/**/*.*', - 'build/templates/**/*.*' - ] + 'build/templates/**/*.*', + ], }); };