diff --git a/.circleci/config.yml b/.circleci/config.yml index 8a6840494..905229f48 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,9 +8,6 @@ jobs: - run: name: install command: npm install - - run: - name: test - command: npm run test - run: name: rebuildSass command: npm rebuild node-sass @@ -20,8 +17,26 @@ jobs: - run: name: bundlesize command: npm run bundlesize + test: + docker: + - image: circleci/node:latest + steps: + - checkout + - run: + name: install + command: npm install + - run: + name: lint + command: npm run lint + - run: + name: jest + command: npm run jest -- --forceExit --detectOpenHandles --runInBand + - run: + name: typescript + command: npm run type workflows: version: 2 test_and_build: jobs: - build + - test diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index e69de29bb..000000000 diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index f4b75fed5..000000000 --- a/.eslintrc +++ /dev/null @@ -1,55 +0,0 @@ -{ - "extends": "airbnb", - "parser": "babel-eslint", - "rules": { - "comma-dangle": 0, - "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], - "import/no-extraneous-dependencies": 0, - "import/prefer-default-export": 1, - "import/extensions": 0, - "import/no-unresolved": 0, - "property": 0, - "no-mixed-operators": 0, - "strict": 0 - }, - "no-confusing-arrow": [2, { - "allowParens": true - }], - "ecmaFeatures": { - "classes": true, - "jsx": true - }, - "plugins": ["react", "jest"], - "settings": { - "import/resolver": "webpack" - }, - "parserOptions": { - "ecmaFeatures": { - "experimentalObjectRestSpread": true - } - }, - "globals": { - "__DEVELOPMENT__": true, - "__CLIENT__": true, - "__SERVER__": true, - "__DISABLE_SSR__": true, - "__DEVTOOLS__": true, - "socket": true, - "webpackIsomorphicTools": true, - "ga": true, - "Raven": true, - "mixpanel": true, - "expect": true, - "browser": true, - "import": true, - "FB": true, - "window": true, - "sinon": true, - "fetch": true - }, - "env": { - "mocha": true, - "amd": true, - "jest/globals": true - } -} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..d587009ee --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,11 @@ +const path = require('path'); + +const paths = [path.join(__dirname, './config/eslint/base.js')]; + +paths.push(path.join(__dirname, './config/eslint/typescript.js')); + +paths.push(path.join(__dirname, './config/eslint/prettier.js')); + +module.exports = { + extends: paths, +}; diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 4b545569f..2e6de0e8d 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,12 +1,13 @@ # Contributing -You want to help? You rock! Now, take a moment to be sure your contributions make sense to everyone else. +Thank you very much for your interest to help. We could use as much help as possible from our community. ## Reporting Issues Found a problem? Want a new feature? - See if your issue or idea has [already been reported]. +- File a new issue in Github. ## Submitting Pull Requests diff --git a/.gitignore b/.gitignore index 336279022..8d11bd280 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ selenium-debug.log webpack-stats.debug.json *.DS_Store .vscode -coverage/ \ No newline at end of file +coverage/ +.awcache diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index f41664027..000000000 --- a/.prettierrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "useTabs": false, - "printWidth": 80, - "tabWidth": 2, - "singleQuote": true, - "trailingComma": "es5", - "jsxBracketSameLine": false, - "parser": "babylon", - "noSemi": true, - "rcVerbose": true -} diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 000000000..36594731e --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,8 @@ +module.exports = { + useTabs: false, + printWidth: 80, + tabWidth: 2, + singleQuote: true, + trailingComma: 'es5', + jsxBracketSameLine: false, +}; diff --git a/.stylelintrc b/.stylelintrc deleted file mode 100644 index c96c3f3e9..000000000 --- a/.stylelintrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "rules": { - "unit-no-unknown": true, - "no-duplicate-selectors": true, - "block-no-empty": true - } -} diff --git a/.stylelintrc.js b/.stylelintrc.js new file mode 100644 index 000000000..24f4ba5b1 --- /dev/null +++ b/.stylelintrc.js @@ -0,0 +1,7 @@ +module.exports = { + rules: { + 'unit-no-unknown': true, + 'no-duplicate-selectors': true, + 'block-no-empty': true, + }, +}; diff --git a/README.md b/README.md index e83555ef2..d54857fe9 100644 --- a/README.md +++ b/README.md @@ -15,16 +15,16 @@ Read the [contributing] section before creating an issue. - Ensure you have [nodejs] installed - Get the source by running `git clone https://github.com/quran/quran.com-frontend/` or creating a [fork] - Run `npm install` to do first time installation of all dependencies -- Run `npm run dev` to start the dev server. Make sure you have pm2 installed globally! `npm install -g pm2` +- Run `npm run dev` to start the dev server. - Open `http://localhost:8000` in your browser to see the app. ## Staging To see the app with the latest changes, see the [staging] site. Production releases are made periodically when staging is stable and well tested. ## Backend -The API source is at https://github.com/quran/quran-api-rails +The API source is at https://github.com/quran/quran.com-api -DB is private, message @mmahalwy for access. +DB is private. Message on Slack to requrest access. The dev server uses the staging API by default. If you want to use a local API server, follow the instructions in the API repo and run the server locally then update the API_URL field in app.json to point to the local address. @@ -34,13 +34,6 @@ Create an issue with your email for us to add you to the Slack group ## Design We currently use InvisionApp. Again, contact me if you'd like access to it. -## Making sure main.js is small -Follow: https://www.npmjs.com/package/webpack-bundle-size-analyzer -``` -env NODE_ENV=development webpack --json > bundle-stats.json -subl bundle-stats.json #so that you can the output -analyze-bundle-size bundle-stats.json -``` [Reactjs]: https://facebook.github.io/react/docs/getting-started.html [Redux]: http://redux.js.org/ diff --git a/config/components/ClientConfig.tsx b/config/components/ClientConfig.tsx new file mode 100644 index 000000000..f716b549c --- /dev/null +++ b/config/components/ClientConfig.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import serialize from 'serialize-javascript'; +import filterWithRules from '../../shared/utils/objects/filterWithRules'; +import values from '../values'; + +// Filter the config down to the properties that are allowed to be included +// in the HTML response. +const clientConfig = filterWithRules( + // These are the rules used to filter the config. + values.clientConfigFilter, + // The config values to filter. + values +); + +const serializedClientConfig = serialize(clientConfig); + +type Props = { + nonce: string; +}; +/** + * A react component that generates a script tag that binds the allowed + * values to the window so that config values can be read within the + * browser. + * + * They get bound to window.__CLIENT_CONFIG__ + */ +const ClientConfig: React.SFC = ({ nonce }: Props) => ( +