diff --git a/packages/xarc-app-dev/src/config/eslint/.eslintrc-base b/packages/xarc-app-dev/src/config/eslint/.eslintrc-base index 509fa97d6..b6b0d0b60 100644 --- a/packages/xarc-app-dev/src/config/eslint/.eslintrc-base +++ b/packages/xarc-app-dev/src/config/eslint/.eslintrc-base @@ -1,3 +1,5 @@ --- extends: - "./js/base.js" +rules: + "func-style": ["off"] diff --git a/packages/xarc-app-dev/src/config/eslint/.eslintrc-mocha-test b/packages/xarc-app-dev/src/config/eslint/.eslintrc-mocha-test index 871ed7588..98dc3ab6e 100644 --- a/packages/xarc-app-dev/src/config/eslint/.eslintrc-mocha-test +++ b/packages/xarc-app-dev/src/config/eslint/.eslintrc-mocha-test @@ -13,3 +13,4 @@ rules: "max-statements": "off" "max-nested-callbacks": "off" "no-multi-spaces": "off" + "func-style": ["off"] diff --git a/packages/xarc-app-dev/src/config/eslint/.eslintrc-mocha-test-es6 b/packages/xarc-app-dev/src/config/eslint/.eslintrc-mocha-test-es6 index e1abc9fcf..d152cb0d0 100644 --- a/packages/xarc-app-dev/src/config/eslint/.eslintrc-mocha-test-es6 +++ b/packages/xarc-app-dev/src/config/eslint/.eslintrc-mocha-test-es6 @@ -13,3 +13,4 @@ rules: "max-nested-callbacks": "off" "prefer-arrow-callback": "off" "no-multi-spaces": "off" + "func-style": ["off"] diff --git a/packages/xarc-app-dev/src/config/eslint/.eslintrc-react b/packages/xarc-app-dev/src/config/eslint/.eslintrc-react index 738f58fd5..bbf0ba5d9 100644 --- a/packages/xarc-app-dev/src/config/eslint/.eslintrc-react +++ b/packages/xarc-app-dev/src/config/eslint/.eslintrc-react @@ -1,14 +1,18 @@ --- extends: - "./js/es6-react.js" + - "plugin:react/recommended" globals: window: false document: false ReactElement: false -plugins: [ - "flowtype" -] +env: + mocha: true +plugins: + - flowtype + - react rules: + "maxlen": "off" "react/jsx-boolean-value": "off" "react/jsx-closing-bracket-location": "off" "react/no-string-refs": "off" @@ -20,3 +24,21 @@ rules: "flowtype/define-flow-type": "warn" "flowtype/use-flow-type": "warn" "flowtype/require-valid-file-annotation": "error" + "func-style": ["off"] + + "react/no-render-return-value": "warn" + "react/display-name": "warn" +"settings": + "react": + "createClass": "createReactClass" + "pragma": "React" + "fragment": "Fragment" + "version": "detect" + "flowVersion": "0.53" + "propWrapperFunctions": + - "forbidExtraProps" + - {"property": "freeze", "object": "Object"} + - {"property": "myFavoriteWrapper"} + "linkComponents": + - "Hyperlink" + - {"name": "Link", "linkAttribute": "to"} diff --git a/packages/xarc-app-dev/src/config/eslint/.eslintrc-react-demo b/packages/xarc-app-dev/src/config/eslint/.eslintrc-react-demo index d5f1969d2..b630b00f9 100644 --- a/packages/xarc-app-dev/src/config/eslint/.eslintrc-react-demo +++ b/packages/xarc-app-dev/src/config/eslint/.eslintrc-react-demo @@ -15,3 +15,4 @@ rules: "flowtype/define-flow-type": "warn" "flowtype/use-flow-type": "warn" "flowtype/require-valid-file-annotation": "error" + "func-style": ["off"] diff --git a/packages/xarc-app-dev/src/config/eslint/.eslintrc-react-test b/packages/xarc-app-dev/src/config/eslint/.eslintrc-react-test index da09e408c..c618b0ace 100644 --- a/packages/xarc-app-dev/src/config/eslint/.eslintrc-react-test +++ b/packages/xarc-app-dev/src/config/eslint/.eslintrc-react-test @@ -7,12 +7,14 @@ globals: expect: false sinon: false Element: false -plugins: [ - "flowtype" -] +env: + mocha: true +plugins: + - flowtype + - react rules: "no-unused-expressions": "off" # for `chai.expect` - "max-len": ["error", 100, 2, {ignorePattern: "^\\s*(?:it|describe)\\(.*"}] + "max-len": "off" "max-statements": "off" "max-nested-callbacks": "off" "react/jsx-wrap-multilines": "warn" @@ -21,3 +23,6 @@ rules: "flowtype/define-flow-type": "warn" "flowtype/use-flow-type": "warn" "flowtype/require-valid-file-annotation": "error" + "func-style": ["off"] + "react/no-render-return-value": "warn" + "react/display-name": "warn" diff --git a/packages/xarc-app-dev/src/lib/dev-tasks.ts b/packages/xarc-app-dev/src/lib/dev-tasks.ts index dbdbd189a..6577cc2be 100644 --- a/packages/xarc-app-dev/src/lib/dev-tasks.ts +++ b/packages/xarc-app-dev/src/lib/dev-tasks.ts @@ -228,10 +228,23 @@ export function loadXarcDevTasks(xrun, userOptions: XarcOptions = {}) { { custom: [], archetype: [] } ); + const ignorePattern = options.ignorePatterns + ? options.ignorePatterns.map(p => `--ignore-pattern ${p}`) + : ""; + + const version = require("eslint/package.json") + .version.split(".") + .map(x => parseInt(x)); + const noUnmatchError = + version[0] > 6 && version[1] > 8 ? ` --no-error-on-unmatched-pattern` : ""; + const commands = [ - grouped.custom.length > 0 && `~$eslint${ext} ${grouped.custom.join(" ")}`, + grouped.custom.length > 0 && + `~$eslint${ext}${noUnmatchError} ${grouped.custom.join(" ")} ${ignorePattern}`, grouped.archetype.length > 0 && - `~$eslint${ext} --no-eslintrc -c ${options.config} ${grouped.archetype.join(" ")}` + `~$eslint${ext}${noUnmatchError} --no-eslintrc -c ${ + options.config + } ${grouped.archetype.join(" ")} ${ignorePattern}` ]; return Promise.resolve(commands.filter(x => x)); @@ -1040,50 +1053,78 @@ You only need to run this if you are doing something not through the xarc tasks. } if (xarcOptions.options.eslint) { + const hasTest = Fs.existsSync("test"); + const hasTestServer = Fs.existsSync("test/server"); + // legacy src/client and src/server only setup? + let isLegacySrc = false; + try { + const files = Fs.readdirSync("src").filter(x => !x.startsWith(".")); + isLegacySrc = files.sort().join("") === "clientserver"; + } catch (err) { + // + } + + const lintTasks = [ + "lint-client", + hasTest && "lint-client-test", + "lint-server", + hasTestServer && "lint-server-test" + ].filter(x => x); + Object.assign(tasks, { - lint: xclap2.concurrent( - "lint-client", - "lint-client-test", - "lint-server", - "lint-server-test" - ), + lint: xclap2.concurrent(...lintTasks), + "lint-client": { - desc: "Run eslint on client code in directories client and templates", + desc: + "Run eslint on code in src/client and templates with react rules (ignore src/server)", task: () => lint({ - ext: ".js,.jsx", + ext: ".js,.jsx,.ts,.tsx", config: eslintConfig(".eslintrc-react"), - targets: [AppMode.src.client, "templates"] - }) - }, - "lint-client-test": { - desc: "Run eslint on client test code in directory test/client", - task: () => - lint({ - ext: ".js,.jsx", - config: eslintConfig(".eslintrc-react-test"), - targets: ["test/client", ...jestTestDirectories.map(dir => `${dir}/client`)] + targets: isLegacySrc + ? [AppMode.src.client, "templates"] + : [AppMode.src.dir, "templates"], + ignorePatterns: [AppMode.src.server] }) }, + "lint-server": { - desc: "Run eslint on server code in directory server", + desc: "Run eslint on server code in src/server with node.js rules", task: () => lint({ + ext: ".js,.jsx,.ts,.tsx", config: eslintConfig(".eslintrc-node"), targets: [AppMode.src.server] }) - }, - "lint-server-test": { - desc: "Run eslint on server test code in directories test/server and test/func", + } + }); + + if (hasTest) { + tasks["lint-client-test"] = { + desc: "Run eslint on code in test with react rules (ignore test/server)", + task: () => + lint({ + ext: ".js,.jsx,.ts,.tsx", + config: eslintConfig(".eslintrc-react-test"), + targets: ["test", ...jestTestDirectories.map(dir => `${dir}`)], + ignorePatterns: ["test/server"] + }) + }; + } + + if (hasTestServer) { + tasks["lint-server-test"] = { + desc: "Run eslint on code in in test/server with node.js rules", task: () => lint({ + ext: ".js,.jsx,.ts,.tsx", config: process.env.SERVER_ES6 ? eslintConfig(".eslintrc-mocha-test-es6") : eslintConfig(".eslintrc-mocha-test"), - targets: ["test/server", "test/func"] + targets: ["test/server"] }) - } - }); + }; + } } else { const lintDisabled = () => { logger.info(`eslint tasks are disabled because @xarc/opt-eslint is not installed. diff --git a/samples/stylus-sample/src/client/components/demo-buttons.jsx b/samples/stylus-sample/src/client/components/demo-buttons.jsx index 855a57db3..73e4eb848 100644 --- a/samples/stylus-sample/src/client/components/demo-buttons.jsx +++ b/samples/stylus-sample/src/client/components/demo-buttons.jsx @@ -4,13 +4,15 @@ import React from "react"; * Demostrates a simple pure functional component */ -export const DemoButtons = () => +export const DemoButtons = () => (
- To verify, use your browser's view source to see the original HTML of this page and see - this being part of the SSR content + To verify, use your browser's view source to see the original HTML of this page and + see this being part of the SSR content
You should see this fill up your browser screen to push content below the browser view @@ -70,7 +71,7 @@ export class AboveFold extends React.Component { {this.props.skip ? (
- This content block is wrapped inside the AboveTheFoldOnlyServerRender{" "} + This content block is wrapped inside the AboveTheFoldOnlyServerRender component, with the skip prop set to {`${this.props.skip}`}.
diff --git a/samples/universal-react-node/src/client/components/home.tsx b/samples/universal-react-node/src/client/components/home.tsx index 056387020..bfb371d18 100644 --- a/samples/universal-react-node/src/client/components/home.tsx +++ b/samples/universal-react-node/src/client/components/home.tsx @@ -4,7 +4,7 @@ import electrodeLogo from "../images/electrode.svg"; import Notifications from "react-notify-toast"; type HomeProps = { - data: string + data: string; }; /* eslint-disable max-len */ @@ -40,14 +40,14 @@ export class Home extends Component