Better webpack config

This commit is contained in:
Lucas Verney 2016-07-25 23:22:44 +02:00
parent 767fd0f7d1
commit 136fb59ed5
17 changed files with 1606 additions and 481 deletions

View File

@ -3,6 +3,13 @@ module.exports = {
"browser": true,
"es6": true
},
"globals": {
"$": false,
"jQuery": false,
"process": false,
"module": true,
"require": false
},
"extends": "eslint:recommended",
"installedESLint": true,
"parserOptions": {

7
.stylelintrc Normal file
View File

@ -0,0 +1,7 @@
{
"extends": "stylelint-config-standard",
"rules": {
"indentation": 4,
},
"defaultSeverity": "error"
}

View File

@ -16,7 +16,8 @@ to the correct URL :)
The supported browsers should be:
* `IE >= 9` (previous versions of IE are no longer supported by Microsoft)
* Any recent version of any other browser.
* Any last three versions of major browsers (> 1% net share).
* No support provided for Opera Mini.
If you experience any issue, please report :)

12
TODO
View File

@ -4,13 +4,25 @@
8. Search
9. Discover
# CSS
* Sidebar responsiveness
* Songs on iPhone 5
* Set sidebar .active
* /artist/:id and /album/:id arts in responsive view
* Scroll horizontal sidebar
* Move CSS in modules
## Global UI
* What happens when JS is off?
=> https://www.allantatter.com/react-js-and-progressive-enhancement/
* Back button?
## Miscellaneous
* See TODOs in the code
* https://facebook.github.io/immutable-js/ ?
* Web workers?
* Accessibility and semantics
* Uncaught TypeError: this.props.tracks.forEach is not a function
=> Be more robust, after, getHostNode is null

View File

@ -2,8 +2,6 @@ import React, { Component, PropTypes } from "react";
import { AlbumRow } from "./Album";
// TODO: Songs without associated album
export default class Artist extends Component {
render () {
var albumsRows = [];

View File

@ -2,9 +2,9 @@ import React, { Component, PropTypes } from "react";
export class LoginForm extends Component {
constructor (props) {
super(props)
super(props);
this.handleSubmit = this.handleSubmit.bind(this)
this.handleSubmit = this.handleSubmit.bind(this);
}
setError (formGroup, error) {
@ -30,11 +30,11 @@ export class LoginForm extends Component {
hasError |= this.setError(this.refs.endpointFormGroup, !endpoint);
if (!hasError) {
this.props.onSubmit(username, password, endpoint, rememberMe)
this.props.onSubmit(username, password, endpoint, rememberMe);
}
}
componentDidUpdate (prevProps) {
componentDidUpdate () {
if (this.props.error) {
$(this.refs.loginForm).shake(3, 10, 300);
this.setError(this.refs.usernameFormGroup, this.props.error);

1
app/dist/fix.ie9.js.map vendored Normal file

File diff suppressed because one or more lines are too long

8
app/dist/index.js vendored

File diff suppressed because one or more lines are too long

1
app/dist/index.js.map vendored Normal file

File diff suppressed because one or more lines are too long

1944
app/dist/style.css vendored

File diff suppressed because it is too large Load Diff

1
app/dist/style.css.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"style.css","sourceRoot":""}

View File

@ -15,51 +15,61 @@
color: white;
border-right: 1px solid #eee;
}
/* Sidebar elements */
.sidebar a {
color: white;
}
.sidebar h1 {
margin: 0;
margin-bottom: 20px;
}
.sidebar h1 img {
height: 46px;
}
.sidebar h1 a {
text-decoration: none;
}
/* Sidebar navigation */
.nav-sidebar {
margin-right: -21px; /* 20px padding + 1px border */
margin-bottom: 20px;
margin-left: -20px;
}
.nav-sidebar > li > a {
padding-right: 20px;
padding-left: 20px;
}
.nav-sidebar .nav-sidebar {
margin-bottom: 0; /* No margin bottom for nested nav-sidebar. */
}
.nav-sidebar > .active > a,
.nav-sidebar > .active > a:hover,
.nav-sidebar > .active > a:focus,
.nav>li>a:hover {
.nav > li > a:hover,
.nav > li > a:focus {
color: #fff;
background-color: #222;
}
.icon-navbar {
background-color: #555;
font-size: 1.25em;
}
.icon-navbar-nav {
display: inline-block;
float: none;
vertical-align: top;
text-align: center;
}
.icon-navbar-nav {
display: inline-block;
float: none;
vertical-align: top;
text-align: center;
}
/*
* Main content
@ -67,6 +77,7 @@
.main-panel {
padding: 20px;
}
@media (min-width: 768px) {
.main-panel {
padding-right: 40px;
@ -74,29 +85,30 @@
}
}
/*
* Filtering field
*/
div.filter {
margin-bottom: 34px;
}
.filter-legend {
text-align: right;
line-height: 34px;
}
@media (max-width: 767px) {
.filter-legend {
text-align: center;
}
}
@media (min-width: 767px) {
.filter .form-group {
width: 75%;
}
}
/*
* Placeholder dashboard ideas
*/
@ -104,22 +116,24 @@ div.filter {
margin-bottom: 30px;
text-align: center;
}
.placeholders h4 {
margin-bottom: 0;
}
.placeholder img:hover {
transform: scale(1.1);
cursor: pointer;
}
/**
* Pager
*/
.pagination-nav {
text-align: center;
}
.pagination>li>span {
.pagination > li > span {
cursor: pointer;
}
@ -129,6 +143,7 @@ div.filter {
.login h1 img {
height: 46px;
}
@media (max-width: 767px) {
.login .submit {
text-align: center;
@ -142,12 +157,11 @@ div.filter {
.art {
display: inline-block;
border-radius: 50%;
margin-bottom: .5em;
margin-bottom: 0.5em;
width: 75%;
height: auto;
}
.albumRow {
margin-top: 30px;
}

View File

@ -1,4 +1,4 @@
import React, { Component } from "react";
import { Component } from "react";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
@ -16,11 +16,8 @@ export class LogoutPage extends Component {
}
}
const mapStateToProps = (state) => ({
});
const mapDispatchToProps = (dispatch) => ({
actions: bindActionCreators(actionCreators, dispatch)
});
export default connect(mapStateToProps, mapDispatchToProps)(LogoutPage);
export default connect(null, mapDispatchToProps)(LogoutPage);

View File

@ -1,7 +1,5 @@
#!/bin/sh
# TODO: Rebuild only if needed
# Get against which ref to diff
if git rev-parse --verify HEAD >/dev/null 2>&1
then
@ -26,21 +24,6 @@ then
fi
# ESLint modified files
if [ -e "./node_modules/eslint/bin/eslint.js" ]
then
ESLINT="node ./node_modules/eslint/bin/eslint.js"
elif hash eslint
then
ESLINT="eslint"
else
exit "You should install ESLint."
fi
echo "Running ESLint on your code…"
$ESLINT $js_files
# Run webpack
if [ -e "./node_modules/webpack/bin/webpack.js" ]
then

View File

@ -35,15 +35,20 @@
"babel-loader": "^6.2.4",
"babel-preset-react": "^6.11.1",
"css-loader": "^0.23.1",
"doiuse": "^2.4.1",
"eslint": "^3.1.1",
"eslint-loader": "^1.4.1",
"eslint-plugin-react": "^5.2.2",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.9.0",
"postcss": "^5.1.0",
"postcss-loader": "^0.9.1",
"postcss-reporter": "^1.4.1",
"precss": "^1.4.0",
"redux-logger": "^2.6.1",
"style-loader": "^0.13.1",
"stylelint": "^7.0.3",
"stylelint-config-standard": "^11.0.0",
"url-loader": "^0.5.7",
"webpack": "^1.13.1"
}

View File

@ -2,8 +2,12 @@ var path = require("path");
var webpack = require("webpack");
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var postcssReporter = require("postcss-reporter");
var doiuse = require("doiuse");
var stylelint = require("stylelint");
var precss = require("precss");
var autoprefixer = require("autoprefixer");
var browsers = ["ie >= 9", "> 1%", "last 3 versions", "not op_mini all"];
module.exports = {
entry: {
@ -18,6 +22,13 @@ module.exports = {
},
module: {
preLoaders: [
{
test: /\.jsx?$/,
loader: "eslint-loader?{failOnError: true}",
exclude: /node_modules/
}
],
loaders: [
// Handle JS/JSX files
{
@ -26,10 +37,17 @@ module.exports = {
loaders: ["babel"],
include: __dirname
},
// Do not postcss vendor modules
{
test: /\.css$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader!postcss-loader")
},
{
test: /\.css$/,
exclude: /app/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
{
test: /\.less$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")
@ -66,9 +84,7 @@ module.exports = {
],
postcss: function () {
return [precss, autoprefixer({
browsers: ["last 3 versions"]
})];
return [doiuse({ browsers: browsers }), stylelint, precss, autoprefixer({ browsers: browsers }), postcssReporter({ throwError: true, clearMessages: true })];
},
resolve: {

View File

@ -3,7 +3,6 @@ var config = require("./webpack.config.base.js");
// Report first error as hard error
config.bail = true;
// Switch to debug mode
config.debug = false;
// Do not capture timing information for each module
config.profile = false;
@ -11,6 +10,7 @@ config.profile = false;
config.devtool = "#source-map";
config.plugins = config.plugins.concat([
new webpack.NoErrorsPlugin(),
new webpack.optimize.OccurenceOrderPlugin(true),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({