Commit 3305cea9 authored by Jaden's avatar Jaden

init and basic skeleton progress

parents
{
"plugins": [
"syntax-object-rest-spread",
"transform-object-rest-spread",
"transform-class-properties",
"syntax-dynamic-import"
],
"presets": [
"react",
[
"env",
{
"modules": false,
"debug": true,
"targets": {
"browsers": [
"last 1 Firefox versions",
"last 1 Chrome versions"
]
}
}
]
],
"env": {
"development": {
"plugins": [
"react-hot-loader/babel"
]
},
"test": {
"presets": [
"react",
[
"env",
{
"modules": true,
"debug": true,
"targets": {
"browsers": [
"last 1 Firefox versions",
"last 1 Chrome versions"
]
}
}
]
]
}
},
"ignore": [
"node_modules"
]
}
module.exports = {
env: {
'browser': true,
'worker': true,
},
parserOptions: {
'parser': 'babel-eslint',
'ecmaVersion': 8,
'sourceType': 'module',
'modules': true,
'ecmaFeatures': {
'jsx': true,
'impliedStrict': true,
'experimentalObjectRestSpread': true,
},
},
extends: [
'plugin:react/recommended',
'plugin:flowtype/recommended',
],
plugins: [
// lints for browser support (APIs and such)
// uses browserslist tech
'compat',
// react
'react',
// flow type annotations
'flowtype',
],
rules: {
// tabs not spaces
'indent': [
'error',
'tab',
// indent for switch statements
{
'SwitchCase': 1,
'MemberExpression': 0
}
],
// we want tabs
'no-tabs': 0,
// only unix endings
'linebreak-style': ['error', 'unix'],
// single quotes & double quotes are the same,
// but encourage single quotes cuz its one less
// button press
'quotes': ['error', 'single', { 'allowTemplateLiterals': true }],
// always use semi-colons at end of statements
'semi': ['error', 'always'],
// errors from compat are real errors
'compat/compat': 2,
// always have spaces in template strings curly braces
'template-curly-spacing': ['error', 'always'],
}
};
[ignore]
<PROJECT_ROOT>/node_modules/
[include]
<PROJECT_ROOT>/node_modules/react-dom/
<PROJECT_ROOT>/node_modules/react-router-dom/
<PROJECT_ROOT>/node_modules/reactstrap/
[libs]
<PROJECT_ROOT>/flow-typed
[lints]
[options]
# Created by https://www.gitignore.io/api/node
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# End of https://www.gitignore.io/api/node
# built files
dist/
# docs cache/build
styleguide/
flow-typed/
{
"plugins": {
"postcss-smart-import": {},
"postcss-cssnext": {}
}
}
{
"ecmaVersion": 6,
"libs": [
"browser",
"ecma5",
"ecma6"
],
"plugins": {
"jsx": {},
"modules": {},
"es_modules": {},
"webpack": {
"configPath": "./webpack.config.js"
}
},
"loadEagerly": [
"./src/**/*.js",
"./src/**/*.jsx"
]
}
# `beat.editor` Developer Guide
## Additional System Requirements
#### Testing
- Up-to-date Chrome browser for Chrome headless testing support (doesn't work on Chromium yet)
- Up-to-date Firefox browser for Firefox headless testing support
#### Editor Support
- Make sure to pick up JS & JSX syntax highlighting for your editor!
- The provided `.tern-project` file is configuration for Tern.js, a JS code analysis tool (autocompletion, etc.).
- Linting via ESLint should be configured to use the local installation (from `node_modules/`) - *not* a global installation. This lets ESLint properly find all the plugins on a per-project basis.
- Linting CSS via Stylelint should be configured similarly to ESLint. Since this linter is relatively new, your linting engine/editor probably won't pick it up automatically.
#### Development
- You'll probably want the [React devtools](https://github.com/facebook/react-devtools) and [Redux devtools](https://github.com/zalmoxisus/redux-devtools-extension) browser plugins to sanely debug and inspect React/Redux code.
- You might need to enable/configure sourcemaps in your browser manually.
- You'll probably want Webpack's dev server (`npm start` or `npm run start:ui`) running in a separate terminal window/tab, as Webpack will automatically rebuild/update your project when files change. However, changes to the webpack config or other configuration files may not be watched. In general, anything under `src/` should be hot-reloaded, while anything else may not be. If there's issues with the app when running the dev server that you don't expect or don't make sense (especially if the issue came up after a hot reload), try refreshing the page - sometimes the hot reloader doesn't properly handle complex changes (such as state management or async functionality).
- When adding dependencies - especially if you import them directly - run the `flow-install` npm script to try to find type definitions for the library. Do the same whenever you update dependencies too.
## NPM Scripts Explanations
| Script | Target | Purpose |
| :----: | :----: | :------ |
| `start` | `src/main.jsx` | Your actual project |
| `prebuild` | `dist/` | Clears `dist/` of old files |
| `build` | `src/main.js` | Builds the whole app for production into `dist/` |
| `test` | `karma.conf.js` | Runs tests in `test/` via Karma |
| `lint` | | Checks your JS, JSX, and CSS files for any errors |
| `lint:fix` | | Fixes any easier linting issues in your JS & JSX files |
| `flow` | `.flowconfig` | Checks your project's flow type annotations (static analysis) |
| `flow-install` | `flow-typed/` | Tries to install type definitions for the project's dependencies from `flow-typed`, and stubs out any dependencies without definition files |
| `prepush` | | Fires on Git's `pre-push` hook, running the `test` & `lint` scripts to make sure everything is passing locally |
## Technology Breakdown
### Runtime Dependencies
| Package | Purpose | Simple Explanation |
| :------ | :------ | :---------- |
| bootstrap | CSS source for `reactstrap` | Provides Bootstrap's styling to the `reactstrap` dependency |
| react | UI library | JS framework for defining the user interface & overall UX |
| react-dom | DOM compat for React | Lets React run in the browser |
| react-popper | React adaptor for `popper.js` | Dependency of `reactstrap` |
| react-redux | React integration for Redux | |
| react-router-dom | Routing for React | Gives us React-like APIs for managing navigation in Single Page Apps (SPAs) |
| react-transition-group | Helpers for writing transitions across React lifecycles | Dependency of `reactstrap` |
| reactstrap | Native React implementation of Bootstrap 4 | |
| redux | State Management library | Gives us a clear way to manage state across the entire app |
### Development Dependencies
| Package | Purpose | Simple Explanation |
| :------ | :------ | :----------------- |
| babel-core | Compiler | Core of Babel, an ecosystem for compiling JS code (e.g. transforming new features to older features to support old browsers) |
| babel-eslint | Compiler support for linter | Lets ESLint parse advanced features that aren't built into ESLint's default parser |
| babel-loader | Compiler support for Webpack | Lets Webpack pass JS files through Babel when building |
| babel-plugin-istanbul | Babel support for Istanbul | Lets Babel track which code is being ran as it's being compiled |
| babel-plugin-syntax-dynamic-import | Babel support for the dynamic import syntax | Lets Babel parse `import` statements in arbitrary places |
| babel-plugin-syntax-object-rest-spread | Babel support for the object spread syntax | Lets Babel parse using spread syntax (`...`) for objects as well as arrays |
| babel-plugin-transform-object-rest-spread | Babel support for transforming object spread | Lets Babel transform the object spread syntax into something compatible with older JS engines |
| babel-preset-env | Babel support for dynamic targeting via browserslist syntax | Lets Babel dynamically change what code it changes based on your configuration |
| babel-preset-react | Babel support for JSX, Flow types, and other react things | Lets Babel understand & process idiomatic React code |
| chai | Assertion library | Provides tools for `assert`ing things in tests |
| chai-enzyme | Chai support for enzyme functionality | |
| cross-env | Cross-environment variable support | Transforms environment variable definitions written in Linux format to the current platform |
| css-loader | Webpack CSS loader | Lets Webpack parse references to CSS files |
| enzyme | React test utilities | Adds helpers for testing React code, especially Components |
| eslint | JS Linter | Statically analyzes JS code according to your configuration |
| eslint-plugin-compat | ESLint support for browserslist | Lets ESLint check if the JS APIs you use are supported by the browsers set in your configuration |
| eslint-plugin-flowtype | ESLint support for flow | Lets ESLint check flow type annotations (across files too!) |
| eslint-plugin-import | ESLint support for dynamic `import`s | Lets ESLint parse `import`s anywhere in JS code |
| eslint-plugin-react | ESLint support for React | Lets ESLint parse & lint React code & JSX |
| flow-bin | Flow type annotation linting/checking support | Adds support for Flow type annotations in your code (opt-in static typing for JS!) |
| flow-typed | Tool to use type defs from `flow-typed` | Lets you download & use high-quality community-written flow type definitions for libraries |
| html-webpack-harddisk-plugin | Lets HtmlWebpackPlugin always write to disk | |
| html-webpack-plugin | Generates `index.html` files with all chunks included | |
| husky | Calls npm scripts on git hooks | |
| karma | Test runner | Runs tests on a certain environment according to configuration and reports on results |
| karma-chrome-launcher | Karma support for Chrome browser | Lets Karma run tests in the Chrome browser, if installed |
| karma-coverage | Karma support for coverage instrumentation | Lets karma read output from Istanbul |
| karma-firefox-launcher | Karma support for Firefox browser | Lets Karma run tests in the Firefox browser, if installed |
| karma-mocha | Karma support for mocha | Lets Karma understand tests written in the Mocha testing framework |
| karma-mocha-reporter | Karma support for mocha reporters | Lets Karma use mocha reporters |
| karma-sourcemap-loader | Karma support for sourcemaps | Errors during testing are shown on the actual line they came from, not the line in the compiled files |
| karma-webpack | Karma support for webpack | Lets Karma run test files through webpack before running tests |
| mocha | Unit Test Framework | Lets us run unit tests |
| postcss | CSS compiler | Like Babel, but for CSS |
| postcss-cli | CLI for PostCSS | Lets us run PostCSS in the commandline not just in JS |
| postcss-cssnext | PostCSS support for latest CSS features | Lets us use new CSS features that may not be available in all browsers |
| postcss-loader | Webpack support for PostCSS | Lets Webpack run CSS through PostCSS |
| postcss-smart-import | Smarter importing logic for CSS | |
| rimraf | Small helper for emptying a directory | |
| sinon | Spies, stubs, mocks for JS testing | Lets you test callbacks, stub libraries with "fake" functions, mock server data |
| style-loader | Supports embedding styles in JS code | |
| stylelint | CSS Linter | Like ESLint, but checks our CSS code instead of JS |
| stylelint-config-standard | Stylelint standard config | Gives sane default for Stylelint |
| svg-inline-loader | Webpack support for SVG files | Makes Webpack resolve `import <file>.svg` statements with the actually string from the SVG file |
| webpack | Build system | Processes & bundles your source files and dependencies together |
| webpack-dev-server | Serves a webpack project on a port & rebuilds when necessary | |
| webpack-visualizer-plugin | Visualizer for webpack chunks | Provides a webpage for inspecting the contents of the generated webpack chunks |
| worker-loader | Webpack support for shared/service workers | Lets you use JS files that will be executed in a worker |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="root"></div>
</body>
</html>
// we can just use the exact same webpack config by requiring it
// however, remember to delete the original entry since we don't
// need it during tests
let webpackConfig = require('./webpack.config.js');
delete webpackConfig.entry;
// karma.conf.js
module.exports = function (config) {
config.set({
browsers: [
'ChromeHeadless',
'FirefoxHeadless'
],
customLaunchers: {
FirefoxHeadless: {
base: 'Firefox',
flags: ['-headless']
}
},
frameworks: ['mocha'],
// this is the entry file for all our tests.
files: [
'src/**/*.test.jsx'
],
// we will pass the entry file to webpack for bundling.
preprocessors: {
'*.*': [ 'webpack', 'sourcemap' ],
},
reporters: [
'mocha',
'coverage'
],
// optionally, configure the reporter
coverageReporter: {
type : 'text',
//dir : 'coverage/'
},
// use the webpack config
webpack: webpackConfig,
// avoid walls of useless text
webpackMiddleware: {
stats: 'errors-only'
},
singleRun: true,
});
};
This diff is collapsed.
{
"name": "react-setup",
"version": "0.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "cross-env NODE_ENV=debug webpack-dev-server --hot",
"prebuild": "rimraf dist",
"build": "cross-env NODE_ENV=production webpack",
"test": "cross-env BABEL_ENV=test NODE_ENV=test karma start",
"lint": "eslint --ext .js,.jsx src && eslint test && stylelint 'src/**/*.jsx, src/**/*.css, src/**/*.html' && npm run flow",
"lint:fix": "eslint --ext .js,.jsx src --fix && eslint test --fix",
"flow": "flow",
"flow-install": "flow-typed install",
"prepush": "npm test && npm run lint"
},
"author": "",
"license": "MIT",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-eslint": "^8.0.1",
"babel-loader": "^7.1.2",
"babel-plugin-istanbul": "^4.1.5",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-syntax-object-rest-spread": "^6.13.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
"chai": "^4.1.2",
"chai-enzyme": "^0.8.0",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"enzyme": "^3.1.0",
"eslint": "^4.8.0",
"eslint-plugin-compat": "^1.0.4",
"eslint-plugin-flowtype": "^2.37.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-react": "^7.4.0",
"flow-bin": "^0.56.0",
"flow-typed": "^2.1.5",
"html-webpack-harddisk-plugin": "^0.1.0",
"html-webpack-plugin": "^2.30.1",
"husky": "^0.14.3",
"karma": "^1.7.1",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage": "^1.1.1",
"karma-firefox-launcher": "^1.0.1",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.4",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^2.0.4",
"mocha": "^3.5.3",
"postcss": "^6.0.12",
"postcss-cli": "^4.1.1",
"postcss-cssnext": "^3.0.2",
"postcss-loader": "^2.0.6",
"postcss-smart-import": "^0.7.5",
"react-hot-loader": "^3.0.0-beta.7",
"redux-devtools": "^3.4.0",
"rimraf": "^2.6.2",
"sinon": "^4.0.1",
"style-loader": "^0.18.2",
"stylelint": "^8.1.1",
"stylelint-config-standard": "^17.0.0",
"svg-inline-loader": "^0.8.0",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.1",
"webpack-visualizer-plugin": "^0.1.11",
"worker-loader": "^1.0.0"
},
"dependencies": {
"bootstrap": "^4.0.0-beta",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-popper": "^0.7.3",
"react-redux": "^5.0.6",
"react-router-dom": "^4.2.2",
"react-transition-group": "^2.2.1",
"reactstrap": "^5.0.0-alpha.3",
"redux": "^3.7.2"
}
}
// @flow
import React from 'react';
import { Component } from 'react';
import MainNav from './MainNav.jsx';
import MainContent from './MainContent.jsx';
type Props = {
};
type State = {
};
export default class App extends Component<Props, State> {
render() {
return (
<div>
<MainNav />
<MainContent />
</div>
);
}
};
import React from 'react';
import {mount, render, shallow} from 'enzyme';
class Fixture extends React.Component {
render () {
return (
<div>
<input id='checked' defaultChecked />
<input id='not' defaultChecked={false} />
</div>
);
}
}
const wrapper = mount(<Fixture />); // mount/render/shallow when applicable
expect(wrapper.find('#checked')).to.be.checked();
expect(wrapper.find('#not')).to.not.be.checked();
// @flow
import React, { Component } from 'react';
import {
Container,
Row,
Col,
Button,
} from 'reactstrap';
type Props = {
dataList: {
name: string
}[],
};
type State = {
};
export default class EntityHome extends Component<Props, State> {
state = {
}
render() {
return (
<Container>
{ this.props.dataList.map((d, i) => <Row key={i}><Col>{ d.name }</Col></Row>) }
</Container>
);
}
}
// @flow
import React, { Component } from 'react';
import {
Container,
Row,
Col,
Button,
} from 'reactstrap';
import {
HashRouter as Router,
Route,
Link
} from 'react-router-dom';
import EntityHome from './EntityHome.jsx';
type Props = {
};
const MainContent = (props: Props) => (
<Router>
<EntityHome dataList={[{name: 'hi'}]} />
</Router>
);
export default MainContent;
// @flow
import React, { Component } from 'react';
import {
Collapse,
Navbar,
NavbarToggler,
NavbarBrand,
Nav,
NavItem,
NavLink,
NavDropdown,
DropdownItem,
DropdownToggle,
DropdownMenu,
Button,
Modal, ModalHeader, ModalBody, ModalFooter,
} from 'reactstrap';
import {
HashRouter as Router,
Route,
Link
} from 'react-router-dom';
import Settings from './Settings.jsx';
type Props = {
};
type State = {
settingsOpen: boolean,
};
const entities: string[] = [
'databases',
'libraries',
'dataformats',
'algorithms',
'toolchains',
'experiments',
];
export default class MainNav extends Component<Props, State> {
state = {
settingsOpen: false,
}
toggle = () => {
this.setState({
settingsOpen: !this.state.settingsOpen
});
}
render() {
return (
<div>
<Router>
<Navbar color="faded" light expand>
<NavbarBrand href="/">beat.editor</NavbarBrand>
<Nav className="mr-auto" navbar>
{
entities
.map((e, i) =>
<NavItem key={i}>
<NavLink tag={Link} to={`/${ e }`}>{ e }</NavLink>
</NavItem>
)
}
</Nav>
<Nav className="ml-auto" navbar>
<NavItem>
<NavLink onClick={this.toggle}>Settings</NavLink>
<Settings isOpen={this.state.settingsOpen} toggle={this.toggle} />
</NavItem>
<NavItem>
<NavLink href="https://gitlab.idiap.ch/jdiefenbaugh/beat.editor">Github</NavLink>
</NavItem>
</Nav>
</Navbar>
</Router>
</div>
);
}
}
/* eslint react/no-multi-comp: 0, react/prop-types: 0 */
import React from 'react';
import { Tooltip } from 'reactstrap';
export default class Example extends React.Component {
constructor(props) {
super(props);
this.toggle = this.toggle.bind(this);
this.state = {
tooltipOpen: false
};
}
toggle() {
this.setState({
tooltipOpen: !this.state.tooltipOpen
});
}
render() {
return (
<div>
<p>Somewhere in here is a <a href="#" id="TooltipExample">tooltip</a>.</p>
<Tooltip placement="right" isOpen={this.state.tooltipOpen} target="TooltipExample" toggle={this.toggle}>
Hello world!
</Tooltip>
</div>
);
}
}
import React from 'react';
import {
HashRouter as Router,
Route,
Link
} from 'react-router-dom';
const Home = () => (
<div>
<h2>Home</h2>
</div>
);
const About = () => (
<div>
<h2>About</h2>
</div>
);
const Topic = ({ match }) => (
<div>