diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..86c445f
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,3 @@
+{
+ "presets": ["es2015", "react"]
+}
diff --git a/.eslintrc b/.eslintrc
index f392780..365c9a4 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,9 +1,9 @@
{
- "extends": "eslint-config-airbnb",
- "env": {
- "browser": true
- },
+ "extends": "airbnb",
+ parser: "babel-eslint",
"rules": {
+ "react/prop-types": [2],
+ "no-unused-vars": 0,
"react/no-multi-comp": 0,
"import/default": 0,
"import/no-duplicates": 0,
@@ -19,16 +19,16 @@
"react/jsx-filename-extension": 0,
"arrow-body-style": 0,
"react/jsx-space-before-closing": 0,
+ "no-undef": 0, # Should look into this one #
"eol-last": 0,
"max-len": ["error", 120],
"react/forbid-prop-types": 0,
"object-curly-spacing": 0
},
"plugins": [ "react" ],
- "settings": {
- "import/parser": "babel-eslint",
+ "settings": {
"import/resolve": {
"moduleDirectory": ["node_modules", "src"]
}
}
-}
\ No newline at end of file
+}
diff --git a/.gitignore b/.gitignore
index f430b96..fca988f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,8 @@
.idea
node_modules
npm-debug.log
+.webpack.config.js.swp
+.eslintcache
-# Dest assets folders
-public/css
-public/js
+# Build folder
+dist/
diff --git a/.stylelintrc b/.stylelintrc
index 6ef1afa..cfd499c 100644
--- a/.stylelintrc
+++ b/.stylelintrc
@@ -1,19 +1,7 @@
{
"rules": {
- "block-no-empty": null,
- "color-no-invalid-hex": true,
- "comment-empty-line-before": [ "always", {
- "ignore": ["stylelint-commands", "between-comments"],
- } ],
- "declaration-colon-space-after": "always",
- "indentation": ["tab", {
- "except": ["value"]
- }],
"max-empty-lines": 2,
- "rule-nested-empty-line-before": [ "always", {
- "except": ["first-nested"],
- "ignore": ["after-comment"],
- } ],
- "unit-whitelist": ["em", "rem", "%", "s"]
+ "max-line-length": 90,
+ "max-nesting-depth": 3,
}
}
diff --git a/.travis.yml b/.travis.yml
index cb71dab..d0151b3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,5 +10,4 @@ before_install:
npm install
npm --version
script:
- - npm run js-lint -s
- - npm run sass-lint -s
+ - npm run lint
diff --git a/Gulpfile.js b/Gulpfile.js
deleted file mode 100644
index 8fe57f5..0000000
--- a/Gulpfile.js
+++ /dev/null
@@ -1,106 +0,0 @@
-var gulp = require('gulp');
-var eslint = require('gulp-eslint');
-var uglify = require('gulp-uglify');
-var concat = require('gulp-concat');
-var cleanCSS = require('gulp-clean-css');
-var gulpStyleLint = require('gulp-stylelint');
-var browserSync = require('browser-sync').create();
-var sass = require('gulp-sass');
-var autoprefixer = require('gulp-autoprefixer');
-var notify = require('gulp-notify');
-var babelify = require('babelify');
-var browserify = require('browserify');
-var source = require('vinyl-source-stream');
-var buffer = require('vinyl-buffer');
-var sourcemaps = require('gulp-sourcemaps');
-
-
-// Static Server + watching scss/html files
-gulp.task('serve', ['sass', 'js'], function() {
- browserSync.init({
- server: './public'
- });
- gulp.watch('app/**/*.scss', ['sass']);
- gulp.watch('app/**/*.js', ['js']);
- gulp.watch('public/*.html').on('change', browserSync.reload);
-});
-
-// Run lint for sass
-gulp.task('stylelint', function lintCssTask() {
- return gulp.src('./app/main.scss')
- .pipe(gulpStyleLint({
- reporters: [
- {formatter: 'string', console: true}
- ]
- }));
-});
-
-// Run lint for js
-gulp.task('jslint', function() {
- return gulp.src(['app/**/*.js'])
- .pipe(eslint())
- .pipe(eslint.format());
-});
-
-// Min js files
-gulp.task('uglify', ['js'], function() {
- return gulp.src('./public/js/build.js')
- .pipe(uglify())
- .pipe(concat('build.js'))
- .pipe(gulp.dest('./public/js'))
-});
-
-// Min css files
-gulp.task('minify-css', ['sass'], function() {
- return gulp.src('./public/css/main.css')
- .pipe(cleanCSS())
- .pipe(concat('main.css'))
- .pipe(gulp.dest('./public/css'))
-});
-
-// Compile sass into CSS & auto-inject into browsers
-gulp.task('sass', ['stylelint'], function() {
- return gulp.src('./app/main.scss')
- .pipe(sass().on('error', sass.logError))
- .pipe(autoprefixer({
- browsers: ['last 2 versions'],
- cascade: false
- }))
- .pipe(sourcemaps.init({ loadMaps: true }))
- .pipe(sourcemaps.write('./'))
- .pipe(gulp.dest('./public/css'))
- .pipe(browserSync.stream())
- .pipe(notify({message: 'CSS created!', onLast: true}));
-});
-
-// Transpile ES6 js (React app) into JS & auto-inject into browsers
-gulp.task('js', ['jslint'], function() {
- var bundler = browserify('./app/app.js').transform("babelify", {presets: ["es2015", "react"]});
- return bundler.bundle()
- .on('error', function(err) { console.error(err); this.emit('end'); })
- .pipe(source('build.js'))
- .pipe(buffer())
- .pipe(sourcemaps.init({ loadMaps: true }))
- .pipe(sourcemaps.write('./'))
- .pipe(gulp.dest('./public/js/'))
- .pipe(browserSync.stream())
- .pipe(notify({message: 'JS bundle created!', onLast: true}));
-});
-
-// PRODUCTION
-gulp.task('set-prod-node-env', function() {
- return process.env.NODE_ENV = 'production';
-});
-
-gulp.task('production', ['uglify', 'minify-css', 'set-prod-node-env']);
-
-// Start server without build
-gulp.task('start', ['production'], function() {
- browserSync.init({
- server: './public'
- });
-});
-
-// Tasks
-gulp.task('default', ['serve']);
-
diff --git a/README.md b/README.md
index 5f29b35..49ddad5 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,9 @@ This base project allows you to have a basic React App folder structure followin
It contain some basic components that you can use. All the components are not (or minimally) stylized. The main objective
of this project is to have a basic structure, that is the reason we are not doing complex styles and/or adding many libs.
+Also, each component is a JSX file and a .scss file that is associated to the component. This means, all the
+components for this project should be modular, to make it easy its usage between different apps.
+
## Tools
Using these package, you will be able to start a new fresh React project with the basic folder and file structures.
@@ -17,17 +20,19 @@ web server in your machine that automatically updates the code and the styles wh
## Features
-* ES6 to JS Transpile
-* SASS to CSS
-* React Router
+* Webpack
+* ES6
+* SASS
+* React Router
* Auto watcher for JS and SCSS files
* Atomic design project structure
-* Launch server that updates itself every time we change a file with browsersync
+* Launch server with hot-reload using webpack
* JS Lint ( extending airbnb eslint styles )
* Styleint
## TODO List
* Tests
+* Upgrade to Webpack 2.^ once stable
## Requirements
* nodejs v5.*
@@ -45,11 +50,6 @@ Clone this repo (Be sure you delete the .git file, or move the files to your own
git clone -b master --single-branch --depth 1 git@github.com:Rulox/react-atomic-structure.git
```
-##### Install Gulp globally
-```bash
-npm install -g gulp
-```
-
##### Install npm dependencies
```bash
npm install
@@ -59,13 +59,12 @@ npm install
```bash
npm run start
```
-A browser window should open, if not, open it manually and go to http://localhost:3000/ (or any other URL+PORT that your terminal says). You can start working right now in the code, and all the changes will be visible in the browser just opened.
+A browser webpack server should be ready on http://localhost:8080/ (or any other URL+PORT that your terminal says). You can start working right now in the code, and all the changes will be visible in the browser just opened.
## Predefined components
But first, [What is Atomic Design?](http://bradfrost.com/blog/post/atomic-web-design/)
-These components are just an idea on how to develop your application following the Atomic Design. Feel free to upgrade/delete
-them in order to do your own app!
+These components are just an idea on how to develop your application following the Atomic Design. Feel free to upgrade/delete them in order to do your own app!
#### Atoms (stateless component)
* Anchor
@@ -94,9 +93,7 @@ them in order to do your own app!
To create a new component, just create a new folder in the atoms/molecules/organisms/templates folder with the
name of your component.
-Create now the React component in the js file. Also create your .scss file and remember to import it in the _style.scss
-of the parent folder (For example, if you're creating a new atom called Checkbox, you should have `atoms/Checkbox/_style.scss`. So in
-the main style file for atoms `atoms/_style.scss` just import your new scss file so it can be imported.
+Create now the React component in the jsx file. Also create your .scss file and remember to import it in the component jsx file using `require`.
## NPM Scripts
This project comes with the following scripts to help you.
@@ -105,33 +102,18 @@ This project comes with the following scripts to help you.
npm run start
```
1. Create CSS and JS bundles from Sass and JS.
-2. Launch a browsersync web server and open default browser.
+2. Launch a web server.
3. Launch watchers on JS/CSS files.
```bash
-npm run build-dev
-```
-1. Build CSS and JS from sources but does not start browsersync server.
-
-```bash
-npm run build-prod
+npm run build
```
-1. Build CSS and JS minified and ready for production but does not start browsersync server.
+1. Build CSS and JS files. With this command, the js will be minified, the bundle version will be used in the html.
```bash
-npm run start-server
-```
-1. Run the server serving the `/public` folder using browsersync.
-
-```bash
-npm run js-lint
+npm run lint
```
1. Launch JS Lint checker.
-```bash
-npm run sass-lint
-```
-1. Launch SASS Lint checker.
-
## Contributions
Feel free to create a pull request or create an issue to add features or fix bugs.
diff --git a/app/components/atoms/Base/_style.scss b/app/_style.scss
similarity index 67%
rename from app/components/atoms/Base/_style.scss
rename to app/_style.scss
index 6269caf..c600317 100644
--- a/app/components/atoms/Base/_style.scss
+++ b/app/_style.scss
@@ -1,4 +1,6 @@
+/* General Styles */
+
html, body, ul, li {
margin: 0;
padding: 0;
-}
+}
\ No newline at end of file
diff --git a/app/app.js b/app/app.js
deleted file mode 100644
index 8293034..0000000
--- a/app/app.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import { Router, Route, IndexRoute, browserHistory } from 'react-router';
-
-import Home from './components/templates/Home/Home';
-import Main from './components/templates/Main/Main';
-import About from './components/templates/About/About';
-
-const App = () => {
- return (
-
-
-
-
-
-
- );
-};
-
-ReactDOM.render(, document.getElementById('app'));
diff --git a/app/app.jsx b/app/app.jsx
new file mode 100644
index 0000000..5441918
--- /dev/null
+++ b/app/app.jsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import { Router, Route, IndexRoute, browserHistory } from 'react-router';
+
+// Components
+import Home from './components/templates/Home/Home';
+import Main from './components/templates/Main/Main';
+import About from './components/templates/About/About';
+
+require('./_style.scss');
+
+const App = () => (
+
+
+
+
+
+
+);
+
+if (typeof window !== 'undefined') {
+ ReactDOM.render(, document.getElementById('app'));
+}
diff --git a/app/components/atoms/Anchor/Anchor.js b/app/components/atoms/Anchor/Anchor.js
deleted file mode 100644
index c400935..0000000
--- a/app/components/atoms/Anchor/Anchor.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import React from 'react';
-
-const Anchor = (props) => {
- return (
- {props.text}
- );
-};
-
-Anchor.propTypes = {
- text: React.PropTypes.string.isRequired
-};
-
-export default Anchor;
diff --git a/app/components/atoms/Anchor/Anchor.jsx b/app/components/atoms/Anchor/Anchor.jsx
new file mode 100644
index 0000000..6f5d9d1
--- /dev/null
+++ b/app/components/atoms/Anchor/Anchor.jsx
@@ -0,0 +1,13 @@
+import React from 'react';
+
+require('./_style.scss');
+
+const Anchor = props => (
+ {props.text}
+);
+
+Anchor.propTypes = {
+ text: React.PropTypes.string.isRequired,
+};
+
+export default Anchor;
diff --git a/app/components/atoms/Button/Button.js b/app/components/atoms/Button/Button.js
deleted file mode 100644
index a03c062..0000000
--- a/app/components/atoms/Button/Button.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import React from 'react';
-
-const Button = (props) => {
- return (
-
- );
-};
-
-Button.propTypes = {
- children: React.PropTypes.string.isRequired
-};
-
-export default Button;
diff --git a/app/components/atoms/Button/Button.jsx b/app/components/atoms/Button/Button.jsx
new file mode 100644
index 0000000..34a9541
--- /dev/null
+++ b/app/components/atoms/Button/Button.jsx
@@ -0,0 +1,13 @@
+import React from 'react';
+
+require('./_style.scss');
+
+const Button = props => (
+
+);
+
+Button.propTypes = {
+ text: React.PropTypes.string.isRequired,
+};
+
+export default Button;
diff --git a/app/components/atoms/Image/Image.js b/app/components/atoms/Image/Image.js
deleted file mode 100644
index 555aa37..0000000
--- a/app/components/atoms/Image/Image.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import React from 'react';
-
-const Image = (props) => {
- return (
-
- );
-};
-
-Image.propTypes = {
- src: React.PropTypes.string.isRequired,
- alt: React.PropTypes.string
-};
-
-export default Image;
\ No newline at end of file
diff --git a/app/components/atoms/Image/Image.jsx b/app/components/atoms/Image/Image.jsx
new file mode 100644
index 0000000..be9c17b
--- /dev/null
+++ b/app/components/atoms/Image/Image.jsx
@@ -0,0 +1,14 @@
+import React from 'react';
+
+require('./_style.scss');
+
+const Image = props => (
+
+);
+
+Image.propTypes = {
+ src: React.PropTypes.string.isRequired,
+ alt: React.PropTypes.string,
+};
+
+export default Image;
diff --git a/app/components/atoms/Input/Input.js b/app/components/atoms/Input/Input.js
deleted file mode 100644
index a42035c..0000000
--- a/app/components/atoms/Input/Input.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from 'react';
-
-const Input = (props) => {
- return (
-
- );
-};
-
-Input.propTypes = {
- text: React.PropTypes.string,
- type: React.PropTypes.string,
- placeholder: React.PropTypes.string
-};
-
-export default Input;
\ No newline at end of file
diff --git a/app/components/atoms/Input/Input.jsx b/app/components/atoms/Input/Input.jsx
new file mode 100644
index 0000000..ce6c993
--- /dev/null
+++ b/app/components/atoms/Input/Input.jsx
@@ -0,0 +1,15 @@
+import React from 'react';
+
+require('./_style.scss');
+
+const Input = props => (
+
+);
+
+Input.propTypes = {
+ text: React.PropTypes.string,
+ type: React.PropTypes.string,
+ placeholder: React.PropTypes.string,
+};
+
+export default Input;
diff --git a/app/components/atoms/Label/Label.js b/app/components/atoms/Label/Label.js
deleted file mode 100644
index d71992b..0000000
--- a/app/components/atoms/Label/Label.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import React from 'react';
-
-const Label = (props) => {
- return (
- {props.text}
- );
-};
-
-Label.propTypes = {
- text: React.PropTypes.string.isRequired
-};
-
-export default Label;
\ No newline at end of file
diff --git a/app/components/atoms/Label/Label.jsx b/app/components/atoms/Label/Label.jsx
new file mode 100644
index 0000000..352769c
--- /dev/null
+++ b/app/components/atoms/Label/Label.jsx
@@ -0,0 +1,13 @@
+import React from 'react';
+
+require('./_style.scss');
+
+const Label = props => (
+ {props.text}
+);
+
+Label.propTypes = {
+ text: React.PropTypes.string.isRequired,
+};
+
+export default Label;
diff --git a/app/components/atoms/Paragraph/Paragraph.js b/app/components/atoms/Paragraph/Paragraph.js
deleted file mode 100644
index 08fec3b..0000000
--- a/app/components/atoms/Paragraph/Paragraph.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import React from 'react';
-
-const Paragraph = (props) => {
- return (
-