mirror of
https://github.com/mgerb/react-starter
synced 2026-01-09 00:22:49 +00:00
upgrade to webpack 4 - complete overhaul
This commit is contained in:
2
.babelrc
2
.babelrc
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"presets": ["env", "react", "stage-0"]
|
||||
"presets": ["env", "react"]
|
||||
}
|
||||
|
||||
21
README.md
21
README.md
@@ -1,17 +1,22 @@
|
||||
# Starter project for React
|
||||
A simplified starter project for react/typescript.
|
||||
|
||||
- [Typescript](https://www.typescriptlang.org/)
|
||||
- [React 16](https://reactjs.org/)
|
||||
- [React Router 4](https://reacttraining.com/react-router/)
|
||||
- [Webpack 3](https://webpack.js.org/)
|
||||
- [Yarn](https://yarnpkg.com/lang/en/docs/install/)
|
||||
- [Webpack 4](https://webpack.js.org/)
|
||||
- [open-color](https://yeun.github.io/open-color/)
|
||||
|
||||
## Commands
|
||||
- yarn install
|
||||
- yarn start
|
||||
- npm install
|
||||
- npm start
|
||||
|
||||
http://localhost:8080
|
||||
|
||||
## Note
|
||||
There is currently a bug with yarn not updating package.json when upgrading packages.
|
||||
[See more here](https://github.com/yarnpkg/yarn/issues/2042#issuecomment-269601927).
|
||||
I added the `update-latest` script in package.json for a temporary fix.
|
||||
### TODO:
|
||||
Fix extract-text-webpack-plugin. Currently getting an error due to the webpack 4 upgrade.
|
||||
Everything still seems fine though.
|
||||
|
||||
```
|
||||
Entrypoint undefined = extract-text-webpack-plugin-output-filename
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import Wrapper from './Wrapper';
|
||||
import { Routes } from './routes';
|
||||
|
||||
ReactDOM.render(<Wrapper />, document.getElementById('app'));
|
||||
ReactDOM.render(<Routes />, document.getElementById('app'));
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
@import '../../scss/variables';
|
||||
|
||||
.Navbar__nav {
|
||||
height: 40px;
|
||||
border-bottom: 1px solid $light1;
|
||||
display: flex;
|
||||
background-color: $gray--lighter;
|
||||
}
|
||||
|
||||
.Navbar__header {
|
||||
display: flex;
|
||||
height: 50px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
background-color: $background;
|
||||
}
|
||||
|
||||
.Navbar__item {
|
||||
color: $fontPrimary;
|
||||
text-decoration: none;
|
||||
width: 100px;
|
||||
transition: all 0.1s linear;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
|
||||
&:hover {
|
||||
color: $fontSecondary;
|
||||
border-bottom: 2px solid $blue;
|
||||
}
|
||||
|
||||
& + .Navbar__item {
|
||||
border-left: 1px solid $gray;
|
||||
}
|
||||
}
|
||||
|
||||
.Navbar__item--active {
|
||||
color: $fontSecondary;
|
||||
border-bottom: 2px solid $blue;
|
||||
}
|
||||
1
app/components/index.ts
Normal file
1
app/components/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './nav-bar/nav-bar';
|
||||
38
app/components/nav-bar/nav-bar.scss
Normal file
38
app/components/nav-bar/nav-bar.scss
Normal file
@@ -0,0 +1,38 @@
|
||||
@import '~open-color/open-color.scss';
|
||||
|
||||
.nav-bar__nav {
|
||||
height: 40px;
|
||||
border-bottom: 1px solid $oc-gray-2;
|
||||
display: flex;
|
||||
background-color: $oc-gray-7;
|
||||
}
|
||||
|
||||
.nav-bar__header {
|
||||
color: $oc-gray-2;
|
||||
display: flex;
|
||||
height: 50px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
background-color: $oc-gray-8;
|
||||
}
|
||||
|
||||
.nav-bar__item {
|
||||
color: $oc-gray-2;
|
||||
text-decoration: none;
|
||||
width: 100px;
|
||||
transition: all 0.1s linear;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
|
||||
&:hover {
|
||||
color: $oc-gray-3;
|
||||
border-bottom: 2px solid $oc-indigo-5;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-bar__item--active {
|
||||
color: $oc-gray-3;
|
||||
border-bottom: 2px solid $oc-indigo-5;
|
||||
}
|
||||
@@ -1,21 +1,21 @@
|
||||
import React from 'react';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
|
||||
import './Navbar.scss';
|
||||
import './nav-bar.scss';
|
||||
|
||||
interface Props {}
|
||||
|
||||
interface State {}
|
||||
|
||||
export default class Navbar extends React.Component<Props, State> {
|
||||
export class NavBar extends React.Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<div className="Navbar">
|
||||
<div className="Navbar__header">
|
||||
<div>
|
||||
<div className="nav-bar__header">
|
||||
<span>React Starter</span>
|
||||
<a href="https://github.com/mgerb/react-webpack2-seed">
|
||||
GitHub
|
||||
@@ -23,20 +23,20 @@ export default class Navbar extends React.Component<Props, State> {
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="Navbar__nav">
|
||||
<div className="nav-bar__nav">
|
||||
<NavLink
|
||||
to="/"
|
||||
className="Navbar__item"
|
||||
className="nav-bar__item"
|
||||
exact
|
||||
activeClassName="Navbar__item--active"
|
||||
activeClassName="nav-bar__item--active"
|
||||
>
|
||||
Home
|
||||
</NavLink>
|
||||
<NavLink
|
||||
to="/new"
|
||||
className="Navbar__item"
|
||||
className="nav-bar__item"
|
||||
exact
|
||||
activeClassName="Navbar__item--active"
|
||||
activeClassName="nav-bar__item--active"
|
||||
>
|
||||
New
|
||||
</NavLink>
|
||||
@@ -1,3 +1,3 @@
|
||||
.Home {
|
||||
.home {
|
||||
padding: 10px;
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
import React from 'react';
|
||||
import { RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
import './Home.scss';
|
||||
import './home.scss';
|
||||
|
||||
interface Props extends RouteComponentProps<any> {}
|
||||
|
||||
interface State {}
|
||||
|
||||
export default class Home extends React.Component<Props, State> {
|
||||
export class Home extends React.Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div className="Home">test 123</div>;
|
||||
public render(): JSX.Element {
|
||||
return <div className="Home">test 123456</div>;
|
||||
}
|
||||
}
|
||||
2
app/pages/index.ts
Normal file
2
app/pages/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './home/home';
|
||||
export * from './not-found/not-found';
|
||||
@@ -1,4 +1,4 @@
|
||||
.NotFound {
|
||||
.not-found {
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
padding-top: 200px;
|
||||
@@ -1,18 +1,18 @@
|
||||
import React from 'react';
|
||||
import { RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
import './NotFound.scss';
|
||||
import './not-found.scss';
|
||||
|
||||
interface Props extends RouteComponentProps<any> {}
|
||||
|
||||
interface State {}
|
||||
|
||||
export default class NotFound extends React.Component<Props, State> {
|
||||
export class NotFound extends React.Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
public render(): any {
|
||||
return <div className="NotFound">404 Not Found</div>;
|
||||
public render(): JSX.Element {
|
||||
return <div className="not-found">404 Not Found</div>;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
import React from 'react';
|
||||
import { BrowserRouter, Route, Switch } from 'react-router-dom';
|
||||
|
||||
import Navbar from './components/Navbar/Navbar';
|
||||
import Home from './pages/Home/Home';
|
||||
import NotFound from './pages/NotFound/NotFound';
|
||||
import { NavBar } from './components';
|
||||
import { Home, NotFound } from './pages';
|
||||
|
||||
// styling
|
||||
import './scss/index.scss';
|
||||
@@ -12,16 +11,16 @@ interface Props {}
|
||||
|
||||
interface State {}
|
||||
|
||||
export default class Wrapper extends React.Component<Props, State> {
|
||||
export class Routes extends React.Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<div>
|
||||
<Navbar />
|
||||
<NavBar />
|
||||
<Switch>
|
||||
<Route exact path="/" component={Home} />
|
||||
<Route component={NotFound} />
|
||||
@@ -1,4 +1,5 @@
|
||||
@import '~font-awesome/css/font-awesome.css';
|
||||
@import '~normalize.css/normalize.css';
|
||||
@import './variables.scss';
|
||||
@import '~open-color/open-color.scss';
|
||||
@import './style.scss';
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ html {
|
||||
}
|
||||
|
||||
body {
|
||||
color: $fontPrimary;
|
||||
background-color: $white;
|
||||
color: $oc-gray-8;
|
||||
background-color: $oc-gray-0;
|
||||
}
|
||||
|
||||
.fa {
|
||||
@@ -14,10 +14,10 @@ body {
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: $fontPrimary;
|
||||
color: $oc-indigo-5;
|
||||
transition: all 0.1s linear;
|
||||
|
||||
&:hover {
|
||||
color: $blue;
|
||||
color: $oc-indigo-4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
$dark-blue: #1d2938;
|
||||
$gray: #293341;
|
||||
$gray--lighter: #3A4553;
|
||||
$blue: #258de5;
|
||||
$blue--lighter: saturate(lighten($blue, 10%), 100%);
|
||||
$green: #39ce83;
|
||||
$red: #e95779;
|
||||
$white: #fff;
|
||||
$light1: #e9eef2;
|
||||
|
||||
$background: $dark-blue;
|
||||
$foreground: #53718a;
|
||||
|
||||
$fontPrimary: lighten($gray, 50%);
|
||||
$fontSecondary: lighten($gray, 60%);
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
<head>
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100" rel="stylesheet">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
11010
package-lock.json
generated
Normal file
11010
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
48
package.json
48
package.json
@@ -6,44 +6,40 @@
|
||||
"build": "webpack -p --progress --colors",
|
||||
"dev": "webpack --progress --colors --watch",
|
||||
"c9": "webpack-dev-server --host 0.0.0.0 --port 8080 --inline --history-api-fallback",
|
||||
"lint": "tslint --project .",
|
||||
"start": "webpack-dev-server --inline --history-api-fallback",
|
||||
"update-latest": "rm -rf node_modules && rm yarn.lock && ncu --upgrade --upgradeAll && yarn install"
|
||||
},
|
||||
"author": "Mitchell Gerber",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/react": "^16.0.34",
|
||||
"@types/react-dom": "^16.0.3",
|
||||
"@types/react-router-dom": "^4.2.3",
|
||||
"autoprefixer": "^7.2.4",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-loader": "^7.1.2",
|
||||
"babel-plugin-add-module-exports": "^0.2.1",
|
||||
"@types/react": "^16.0.40",
|
||||
"@types/react-dom": "^16.0.4",
|
||||
"@types/react-router-dom": "^4.2.5",
|
||||
"babel-loader": "^7.1.4",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-preset-stage-0": "^6.24.1",
|
||||
"clean-webpack-plugin": "^0.1.17",
|
||||
"css-loader": "^0.28.7",
|
||||
"extract-text-webpack-plugin": "3.0.2",
|
||||
"file-loader": "^1.1.6",
|
||||
"clean-webpack-plugin": "^0.1.19",
|
||||
"css-loader": "^0.28.11",
|
||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||
"file-loader": "^1.1.11",
|
||||
"font-awesome": "^4.7.0",
|
||||
"html-webpack-plugin": "^2.30.1",
|
||||
"html-webpack-plugin": "^3.0.7",
|
||||
"node-sass": "^4.7.2",
|
||||
"normalize.css": "^7.0.0",
|
||||
"postcss-loader": "^2.0.9",
|
||||
"prettier": "^1.9.2",
|
||||
"normalize.css": "^8.0.0",
|
||||
"open-color": "^1.6.3",
|
||||
"postcss-loader": "^2.1.2",
|
||||
"react": "^16.2.0",
|
||||
"react-dom": "^16.2.0",
|
||||
"react-router-dom": "^4.2.2",
|
||||
"resolve-url-loader": "^2.2.1",
|
||||
"sass-loader": "^6.0.6",
|
||||
"style-loader": "^0.19.1",
|
||||
"ts-loader": "^3.2.0",
|
||||
"tslint": "^5.8.0",
|
||||
"tslint-config-airbnb": "^5.4.2",
|
||||
"typescript": "^2.6.2",
|
||||
"url-loader": "^0.6.2",
|
||||
"webpack": "3.10.0",
|
||||
"webpack-dev-server": "2.9.7"
|
||||
"sass-loader": "^6.0.7",
|
||||
"style-loader": "^0.20.3",
|
||||
"ts-loader": "^4.1.0",
|
||||
"tslint": "^5.9.1",
|
||||
"tslint-config-airbnb": "^5.8.0",
|
||||
"typescript": "^2.7.2",
|
||||
"webpack": "^4.1.1",
|
||||
"webpack-cli": "^2.0.12",
|
||||
"webpack-dev-server": "^3.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"extends": "tslint-config-airbnb",
|
||||
"rules": {
|
||||
"import-name": false
|
||||
"import-name": false,
|
||||
"ter-arrow-parens": [true, "as-needed"],
|
||||
"align": [true, "parameters", "statements"],
|
||||
"typedef": [true, "call-signature", "parameter", "member-variable-declaration"],
|
||||
"member-access": [true]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ const webpack = require('webpack');
|
||||
module.exports = {
|
||||
entry: {
|
||||
app: './app/app.tsx',
|
||||
vendor: ['react', 'react-dom'],
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
@@ -47,12 +46,18 @@ module.exports = {
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'static/[name].[hash].[ext]',
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
optimization: {
|
||||
occurrenceOrder: true,
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
new CleanWebpackPlugin(['dist'], {
|
||||
verbose: true,
|
||||
@@ -60,16 +65,12 @@ module.exports = {
|
||||
new ExtractTextPlugin({
|
||||
filename: '[name].[hash].css',
|
||||
disable: false,
|
||||
allChunks: true
|
||||
allChunks: true,
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
filename: 'index.html',
|
||||
template: './index.html',
|
||||
}),
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: ['vendor', 'manifest'],
|
||||
minChunks: 'Infinity',
|
||||
}),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user