I tried to setup my own toolchain to build a React app. I'm using Webpack with Typescript React.
package.json
{
"name": "library2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"lint": "eslint '**/*.{tsx,js,ts}'",
"lint:fix": "eslint --fix '**/*.{tsx,js,ts}'",
"start": "webpack-dev-server --mode development"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"pg": "^8.3.0",
"prettier": "^2.0.5",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"typescript": "^3.9.5"
},
"devDependencies": {
"#babel/cli": "^7.10.4",
"#babel/core": "^7.10.4",
"#babel/plugin-proposal-class-properties": "^7.10.4",
"#babel/preset-env": "^7.10.4",
"#babel/preset-react": "^7.10.4",
"#types/node": "^14.0.20",
"#types/react": "^16.9.41",
"#types/react-dom": "^16.9.8",
"#typescript-eslint/eslint-plugin": "^3.1.0",
"#typescript-eslint/parser": "^3.1.0",
"babel-loader": "^8.1.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"css-loader": "^3.6.0",
"eslint": "^6.8.0",
"eslint-config-airbnb": "^18.1.0",
"eslint-plugin-import": "^2.21.1",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.20.0",
"eslint-plugin-react-hooks": "^2.5.1",
"style-loader": "^1.2.1",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
}
}
webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/App.tsx',
mode: 'development',
module: {
rules: [
{
test: /\.(|ts|tsx|js|jsx)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: [
'#babel/preset-env',
'#babel/preset-react',
],
plugins: [
'#babel/plugin-proposal-class-properties',
],
},
},
},
{ // rules for css
test: /\.(css|scss)$/,
use: ['style-loader', 'css-loader'],
},
],
},
resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'] },
output: {
path: path.resolve(__dirname, 'dist/'),
publicPath: '/dist/',
filename: 'bundle.js',
},
devServer: {
contentBase: path.join(__dirname, 'public/'),
port: 3000,
publicPath: 'http://localhost:3000/dist/',
hotOnly: true,
},
plugins: [new webpack.HotModuleReplacementPlugin()],
};
.babelrc
{
"presets": ["#babel/preset-env", "#babel/preset-react"],
"plugins": ["#babel/plugin-proposal-class-properties"]
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="main"></div>
<script src="../dist/bundle.js"></script>
</body>
</html>
App.tsx
import React from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
render(<Hello />, document.querySelector('#main'));
Hello.tsx
import React from 'react';
import './hello.scss';
export default class Hello extends React.Component {
vark: number;
test() {
this.vark = 1;
}
render() {
return (
<div className="hello">Hello!</div>
);
}
}
I get the following error when webpack builds (npm run start):
ERROR in ./src/Hello.tsx
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/JAAI/Desktop/Library2/src/Hello.tsx: Unexpected token (5:6)
3 |
4 | export default class Hello extends React.Component {
> 5 | vark: number;
| ^
6 |
7 | test() {
8 | this.vark = 1;
at Object._raise (/Users/JAAI/Desktop/Library2/node_modules/#babel/parser/lib/index.js:757:17)
at Object.raiseWithData (/Users/JAAI/Desktop/Library2/node_modules/#babel/parser/lib/index.js:750:17)
at Object.raise (/Users/JAAI/Desktop/Library2/node_modules/#babel/parser/lib/index.js:744:17)
at Object.unexpected (/Users/JAAI/Desktop/Library2/node_modules/#babel/parser/lib/index.js:8834:16)
at Object.parseClassMemberWithIsStatic (/Users/JAAI/Desktop/Library2/node_modules/#babel/parser/lib/index.js:12169:12)
at Object.parseClassMember (/Users/JAAI/Desktop/Library2/node_modules/#babel/parser/lib/index.js:12062:10)
at /Users/JAAI/Desktop/Library2/node_modules/#babel/parser/lib/index.js:12007:14
at Object.withTopicForbiddingContext (/Users/JAAI/Desktop/Library2/node_modules/#babel/parser/lib/index.js:11078:14)
at Object.parseClassBody (/Users/JAAI/Desktop/Library2/node_modules/#babel/parser/lib/index.js:11984:10)
at Object.parseClass (/Users/JAAI/Desktop/Library2/node_modules/#babel/parser/lib/index.js:11958:22)
# ./src/App.tsx 3:0-28 4:41-46
ℹ 「wdm」: Failed to compile.
At first I thought this was because the Webpack env and react presets didn't allow for class properties so I included the class properties plugin but the error persisted. Note that if I remove that line it builds successfully.
Related
I am using webpack 5 now and using HMR for hot module replacements. But It shows in console that hmr working but that is not updating in HTML file.
My webpack.config.js file is:
const path = require('path');
module.exports = {
entry: {
bundle: './src/index.js'
},
output: {
path: path.resolve( __dirname, 'assets' ),
filename: '[name].js'
},
mode: 'development',
module: {
rules: [
{
test: /\.(js)$/,
exclude: /node_modules/,
use: [ 'babel-loader']
},
{
test: /\.s[ac]ss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.less$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: "less-loader",
options: {
lessOptions: {
javascriptEnabled: true
}
}
}]
}
]
},
devServer : {
headers: {
'Access-Control-Allow-Origin': '*'
},
client: {
progress: true,
},
allowedHosts: 'all',
hot: true,
static: {
directory: path.join(__dirname, 'dist')
},
}
}
My package.json is
{
"name": "booking",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
"start": "webpack-dev-server --hot"
},
"author": "",
"license": "ISC",
"dependencies": {
"#ant-design/icons": "^4.7.0",
"#headlessui/react": "^1.4.1",
"#heroicons/react": "^1.0.4",
"#reduxjs/toolkit": "^1.6.1",
"#tailwindcss/forms": "^0.3.4",
"antd": "^4.16.13",
"axios": "^0.21.4",
"bootstrap-icons": "^1.5.0",
"date-fns": "^2.24.0",
"moment": "^2.29.1",
"react": "^17.0.2",
"react-bootstrap-icons": "^1.5.0",
"react-dom": "^17.0.2",
"react-multi-date-picker": "^3.1.7",
"react-nice-dates": "^3.1.0",
"react-redux": "^7.2.5",
"react-smooth-list": "^1.0.2",
"redux": "^4.1.1"
},
"devDependencies": {
"#babel/core": "^7.15.5",
"#babel/preset-env": "^7.15.6",
"#babel/preset-react": "^7.14.5",
"autoprefixer": "^10.3.4",
"babel-loader": "^8.2.2",
"babel-plugin-import": "^1.13.3",
"cross-env": "^7.0.3",
"css-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"less": "^4.1.2",
"less-loader": "^10.2.0",
"node-sass": "^6.0.1",
"postcss": "^8.3.6",
"sass": "^1.39.2",
"sass-loader": "^12.1.0",
"style-loader": "^3.2.1",
"tailwindcss": "^2.2.15",
"webpack": "^5.52.0",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.7.4"
}
}
My main problem is its compiling in the console but not updating in htm file actually..I have mentioned if (module.hot) module.hot.accept() in my ./src/index.js file, but its not working yet.Anything I need to do more to get this working!
My ./dist/index.html is:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="wp-booking-press-container"></div>
<script src="bundle.js"></script>
</body>
</html>
I am getting the following error
external_"react":1 Uncaught ReferenceError: react is not defined
at eval (external_"react":1)
at Object.react (bundle.js:120)
at __webpack_require__ (bundle.js:20)
at eval (client.js:2)
at Module../src/client.js (bundle.js:97)
at __webpack_require__ (bundle.js:20)
at bundle.js:84
at bundle.js:87
eval # external_"react":1
react # bundle.js:120
__webpack_require__ # bundle.js:20
eval # client.js:2
./src/client.js # bundle.js:97
__webpack_require__ # bundle.js:20
(anonymous) # bundle.js:84
(anonymous) # bundle.js:87
I have read many articles on here about how to solve, but nothing works.
My webpack.config.js is as follows :
const isDevelopment = process.env.NODE_ENV === 'development';
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const isomorphicRules = [
{
test: /\.(js?|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'#babel/preset-env',
'#babel/preset-react'
]
}
}
},
{
test: /\.s[ac]ss$/i,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true
}
},
{
loader: 'sass-loader',
options: {
// Prefer `dart-sass`
implementation: require('sass'),
sassOptions: {
indentWidth: 4,
includePaths: ['public'],
},
},
}
]
},
];
const client = {
entry: './src/client.js',
output: {
path: path.join(__dirname, './src/public/dist/'),
publicPath: '/dist',
filename: 'bundle.js'
},
module: {
rules: isomorphicRules,
},
externals: ["react", "react-dom"],
plugins: [
new HtmlWebpackPlugin({
template: '!!raw-loader!' + path.join(__dirname, './src/views/clientside.ejs'),
filename: 'clientside.ejs',
inject: 'body'
})
]
};
const server = {
entry: './src/server.js',
output: {
path: path.join(__dirname, './src/public/dist/'),
filename: 'server.js'
},
module: {
rules: isomorphicRules
},
target: 'node',
externals: [nodeExternals(), "react", "react-dom"],
plugins: [
new HtmlWebpackPlugin({
template: '!!raw-loader!' + path.join(__dirname, './src/views/serverside.ejs'),
filename: 'serverside.ejs' // this line decide the extension of output file.
})
]
};
module.exports = [
client,
server,
];
I am stumped as I have added react as an external.
For good measure here is my package.json
{
"name": "webtest",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.5.0",
"#testing-library/user-event": "^7.2.1",
"abstract-syntax-tree": "^2.9.3",
"bootstrap": "^4.5.1",
"compression": "^1.7.4",
"dotenv": "^8.2.0",
"ejs": "^3.1.3",
"express": "^4.17.1",
"fabric": "^4.1.0",
"form-data": "^3.0.0",
"formidable": "^1.2.2",
"govuk-frontend": "^3.8.1",
"highlight.js": "^10.1.2",
"moment": "^2.27.0",
"node-fetch": "^2.6.0",
"react": "^16.13.1",
"react-bootstrap": "^1.3.0",
"react-dom": "^16.13.1",
"react-dom-server": "0.0.5",
"react-html-parser": "^2.0.2",
"react-json-view": "^1.19.1",
"react-router-dom": "^5.2.0",
"react-script-tag": "^1.1.2",
"react-scripts": "^3.4.3"
},
"scripts": {
"webpack": "webpack --mode development --config webpack.config.js",
"dev": "set NODE_ENV=development && webpack --mode development --config webpack.config.js && nodemon --exec babel-node src/index.js"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"#babel/core": "^7.11.1",
"#babel/node": "^7.10.5",
"#babel/plugin-proposal-class-properties": "^7.10.4",
"#babel/polyfill": "^7.10.4",
"#babel/preset-env": "^7.11.0",
"#babel/preset-react": "^7.10.4",
"babel-loader": "^8.1.0",
"babel-plugin-css-modules-transform": "^1.6.2",
"cross-env": "^7.0.2",
"css-loader": "^4.2.2",
"dart-sass": "^1.25.0",
"ejs-webpack-loader": "^2.2.2",
"file-loader": "^6.0.0",
"html-loader": "^1.3.0",
"html-webpack-plugin": "^4.4.1",
"mini-css-extract-plugin": "^0.10.0",
"node-sass": "^4.14.1",
"nodemon": "^2.0.4",
"nodemon-webpack-plugin": "^4.3.2",
"raw-loader": "^4.0.1",
"sass": "^1.26.10",
"sass-loader": "^10.0.1",
"style-loader": "^1.2.1",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12",
"webpack-node-externals": "^1.7.2"
}
}
I am using the npm start dev script to launch.
The rendered html is as follows :
<!DOCTYPE html>
<html lang="en">
<head>
<title>JSON Forms Demo</title>
</head>
<body>
<div id="root">
</div>
<script src="/dist/bundle.js"></script></body>
</html>
So it is clear to me the problem is that react is not defined. My question is why not?
My client.js looks like
import React from 'react';
import ReactDOM from 'react-dom';
import ClientApp from './clientApp';
ReactDOM.render(<ClientApp />, document.getElementById('root'));
And clientApp is as follows :
import React, { Component } from 'react';
class ClientApp extends Component {
render() {
return (
<div>
<h1>Hello World from Client Side App</h1>
</div>
);
}
}
export default ClientApp;
Also my .babelrc file looks like
{
"presets": ["#babel/preset-env", "#babel/preset-react"]
}
So I feel like I've covered all the bases with what I've read on here and on the webpack website, but I clearly have missed something and would be most grateful if the panel could take a look.
Thanks to tmhao2005, yuRa and Freestyle09. It was driving me spare.
I removed the external directive from the webpack config and it works.
So I´m using reactstrap and i´ve already installed the dependencies Bootstrap and Reactstrap. I also pasted the CDN´s in the html file.
I think the problem may be with the webpack config, but I´m not sure.
I´m trying to render a button but it doesnt show up with its styles, only a basic html button.
So this is the what I have:
App.jsx:
import React from 'react'
import { Button } from 'reactstrap';
class App extends React.Component {
render() {
return (
<div>
<Button></Button>
</div>
)
}
}
export default App;
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './component/App';
//import 'bootstrap/dist/css/bootstrap.min.css';
ReactDOM.render(<App />, document.getElementById('root'));
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>myDesk</title>
</head>
<body>
<div id='root'></div>
<!-- Main version -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/reactstrap/6.0.1/reactstrap.min.js"></script>
<!-- All optional dependencies version -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/reactstrap/6.0.1/reactstrap.full.min.js"></script>
</body>
</html>
Webpack.config.js:
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
entry: './assets/src/index.js'
},
output: {
path: __dirname + './assets/src/index.html',
filename: 'bundle.js'
},
module: {
rules: [
{
use: 'babel-loader',
test: /\.(js|jsx)$/,
exclude: /node_modules/
},
{
use: ['style-loader', 'css-loader'],
test: /\.css$/
}
]
},
resolve: {
extensions: ['*', '.js', '.jsx']
},
plugins: [
new HtmlWebpackPlugin({
template: 'assets/src/index.html'
})
]
};
package.json:
{
"name": "example",
"private": true,
"version": "0.0.0",
"description": "a Sails application",
"keywords": [],
"dependencies": {
"#sailshq/connect-redis": "^3.2.1",
"#sailshq/lodash": "^3.10.3",
"#sailshq/socket.io-redis": "^5.2.0",
"bootstrap": "^4.3.1",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"reactstrap": "^8.0.1",
"sails": "^1.2.3",
"sails-hook-apianalytics": "^2.0.3",
"sails-hook-organics": "^0.16.0",
"sails-hook-orm": "^2.1.1",
"sails-hook-sockets": "^2.0.0",
"sails-mongo": "^1.0.1"
},
"devDependencies": {
"eslint": "5.16.0",
"#babel/cli": "^7.5.0",
"#babel/core": "^7.5.4",
"#babel/preset-env": "^7.5.4",
"#babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.6",
"babel-preset-react": "^6.24.1",
"babel-preset-react-hmre": "^1.1.1",
"grunt": "1.0.4",
"html-webpack-plugin": "^3.2.0",
"htmlhint": "0.11.0",
"lesshint": "6.3.6",
"npm-run-all": "^4.1.5",
"rimraf": "^2.6.3",
"sails-hook-grunt": "^4.0.0",
"webpack": "^4.35.3",
"webpack-cli": "^3.3.5",
"webpack-dev-server": "^3.7.2"
},
"scripts": {
"start": "NODE_ENV=production node app.js",
"start:server": "nodemon app.js",
"start:client": "webpack-dev-server --mode development --open",
"test": "npm run lint && npm run custom-tests && echo 'Done.'",
"lint": "./node_modules/eslint/bin/eslint.js . --max-warnings=0 --report-unused-disable-directives && echo '✔ Your .js files look good.'",
"custom-tests": "echo \"(No other custom tests yet.)\" && echo"
},
"main": "app.js",
"repository": {
"type": "git",
"url": "git://github.com/michalruzicka/example.git"
},
"author": "michalruzicka",
"license": "",
"engines": {
"node": "^10.15"
}
}
Please notice that I´ve commented the import bootsrap from the index.js becouse it leads to the following error:
ERROR in ./assets/src/index.js
Module not found: Error: Can't resolve 'style-loader'
I'm having some trouble getting my bundle file to load in my html. Each time it returns 404. I have checked, and the Bundle is building fine.
package.json:
{
"name": "MyApp",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"bundle": "webpack"
},
"repository": {
"type": "git",
"url": ""
},
"author": "",
"license": "ISC",
"bugs": {
"url": ""
},
"homepage": "",
"dependencies": {
"angular": "^1.5.8",
"angular-jwt": "^0.1.7",
"angular-resource": "^1.5.8",
"angular-ui-router": "^0.3.1",
"bcrypt": "^0.8.7",
"cookie-parser": "^1.4.3",
"cors": "^2.8.1",
"debug": "^2.2.0",
"express": "^4.14.0",
"gulp": "^3.9.1",
"json-loader": "^0.5.4",
"jsonwebtoken": "^7.1.9",
"main-bower-files": "^2.13.1",
"mongoose": "^4.6.3",
"morgan": "^1.7.0",
"node-schedule": "^1.2.0",
"nodemailer": "^2.6.4",
"request-promise": "^4.1.1",
"run-sequence": "^1.2.2",
"sass": "^0.5.0",
"satellizer": "^0.15.5"
},
"devDependencies": {
"babel": "^6.5.2",
"babel-angular": "0.0.5",
"babel-core": "^6.18.0",
"babel-loader": "^6.2.5",
"babel-preset-angular": "^6.0.15",
"babel-preset-es2015": "^6.18.0",
"chai": "^3.5.0",
"chai-http": "^3.0.0",
"gulp": "^3.9.1",
"gulp-clean-css": "^2.0.13",
"gulp-concat": "^2.6.0",
"gulp-filter": "^4.0.0",
"gulp-livereload": "^3.8.1",
"gulp-nodemon": "^2.2.1",
"gulp-notify": "^2.2.0",
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.5.4",
"gulp-sass": "^2.3.2",
"gulp-uglify": "^2.0.0",
"mocha": "^3.1.2",
"node-sass": "^3.10.1",
"sass-loader": "^4.0.2",
"webpack": "^1.13.2",
"webpack-node-externals": "^1.5.4"
}
}
.babelrc:
{
"presets": [
'es2015', 'angular', 'stage-0'
]
}
webpack.config.js:
var webpack = require('webpack');
var nodeExternals = require('webpack-node-externals');
module.exports = {
target: 'node',
externals: [nodeExternals()],
entry: './app.js',
output: {
path: __dirname + '/app',
filename: './bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: '/(node_modules)/',
loader: 'babel'
},
{
test: /\.scss$/,
loader: 'style-loader!css-loader!sass-loader'
}
]
}
}
index.html head:
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
<title>MyApp</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<link rel="stylesheet" href="./css/reset.css">
<link rel="stylesheet" href="./css/app.css">
<link href="https://fonts.googleapis.com/css?family=Raleway:400,600" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular-resource.min.js"></script>
<script src="//npmcdn.com/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="//cdn.jsdelivr.net/satellizer/0.13.1/satellizer.min.js"></script>
<script src="https://cdn.rawgit.com/auth0/angular-jwt/master/dist/angular-jwt.js"></script>
<script src="/js/app.js"></script>
<script src="bundle.js"></script>
Any help much appreciated.
Try changing output in the webpack config file:
var webpack = require('webpack');
var nodeExternals = require('webpack-node-externals');
var here = require('path-here'); // <- Add path-here
module.exports = {
target: 'node',
externals: [nodeExternals()],
entry: './app.js',
output: {
path: here('dist'), // <- changed to this
filename: 'bundle.js' // <- changed to this
},
module: {
loaders: [
{
test: /\.js$/,
exclude: '/(node_modules)/',
loader: 'babel'
},
{
test: /\.scss$/,
loader: 'style-loader!css-loader!sass-loader'
}
]
}
}
Let me know if this helps.
I have no problem whatsoever working on the dev env, hot reloading and everything works fine. Trying to make a production build its proving to be quite challenging, getting nothing but a blank page. There seems to be similar questions on here but I'm not using any html as an entry point. Thanks in advance.
package.json
{
"name": "dc",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack-dev-server -d --content-base public --inline --hot --host 0.0.0.0",
"prod": "webpack -p --progress --config prod.config.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"axios": "^0.9.1",
"babel-core": "^6.7.2",
"babel-loader": "^6.2.4",
"babel-polyfill": "^6.7.4",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"babel-preset-react-hmre": "^1.1.1",
"css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.8.5",
"history": "^2.0.1",
"isomorphic-fetch": "^2.2.1",
"node-sass": "^3.4.2",
"react": "^0.14.7",
"react-css-transition-replace": "^1.1.0",
"react-dom": "^0.14.7",
"react-hot-loader": "^1.3.0",
"react-redux": "^4.4.1",
"react-router": "^2.0.1",
"redux": "^3.3.1",
"redux-logger": "^2.6.1",
"redux-thunk": "^2.0.1",
"sass-loader": "^3.2.0",
"style-loader": "^0.13.1",
"webpack": "^1.12.14"
},
"dependencies": {
"axios": "^0.9.1",
"history": "^2.0.1",
"isomorphic-fetch": "^2.2.1",
"react": "^0.14.7",
"react-redux": "^4.4.1",
"react-router": "^2.0.1",
"redux": "^3.3.1"
}
}
production config
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry : ["./app/App.js"],
output : {
filename: "bundle.js",
publicPath: 'dist/',
path : path.resolve(__dirname, 'dist/')
},
devtool: 'source-map',
devServer: {
contentBase: 'dist/'
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"',
},
__DEVELOPMENT__: false,
}),
new webpack.optimize.OccurenceOrderPlugin(),
new ExtractTextPlugin("styles.css"),
new webpack.NoErrorsPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: true,
},
}),
],
module : {
loaders : [
{ test : /\.jsx?$/, loader : 'babel-loader',
query : {
presets : ['react', 'es2015', 'react-hmre']
}
},
{ test: /\.(jpg|png)$/, exclude: /node_modules/, loader: "file?name=images/[name].[ext]"},
{ test: /\.css$/, exclude: /node_modules/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") },
{ test: /\.scss$/, exclude: /node_modules/, loader: ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader") }
]
}
};
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>lol</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="app"></div>
<script src="bundle.js"></script>
</body>
</html>
I have been working with a bit different solution. What I have been doing is bundling the files through webpack then use a koa server to serve a static file and then have a npm start script which sets NODE_ENV to production. Take a look:
package.json:
{
"name": "react",
"version": "1.0.0",
"description": "some description",
"main": "index.js",
"scripts": {
"test": "test",
"start": "NODE_ENV=production webpack --progress && NODE_ENV=production node server.js",
"dev": "webpack-dev-server --progress --colors --watch",
"build": "webpack --progress --watch"
},
"author": "your_name",
"license": "ISC",
"dependencies":{
"babel-core": "^6.7.2",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"copy-webpack-plugin": "^1.1.1",
"css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^1.0.1",
"image-webpack-loader": "^1.6.3",
"json-loader": "^0.5.4",
"sass-loader": "^3.2.0",
"style-loader": "^0.13.0",
"koa": "2.0.0-alpha.3",
"koa-convert": "1.2.0",
"koa-static": "2.0.0",
"react": "^0.14.7",
"react-dom": "^0.14.7",
"webpack": "^1.12.14",
"webpack-dev-server": "^1.14.1"
}
}
server.js:
'use strict';
const port = process.env.PORT || 3000;
const Koa = require('koa');
const serve = require('koa-static');
const convert = require('koa-convert');
const app = new Koa();
const _use = app.use;
app.use = (x) => _use.call(app, convert(x));
app.use(serve('./build'));
const server = app.listen(port, function () {
let host = server.address().address;
let port = server.address().port;
console.log('listening at http://%s:%s', host, port);
});
and finaly webpack.config.js:
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
entry: './main.js',
output: { path: __dirname + "/build/", filename: 'bundle.js' },
module: {
loaders: [
{
test: /.js?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract("style", "css!sass?")
},
{
test: /\.json$/,
loader: "json"
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'file?hash=sha512&digest=hex&name=[hash].[ext]',
'image-webpack?bypassOnDebug&optimizationLevel=7&interlaced=false'
]
}
]
},
plugins: [
new ExtractTextPlugin("main.css"),
new CopyWebpackPlugin([
{
from: __dirname + '/index.html',
to: __dirname + '/index.html'
},
])
]
};
If you will run those with an index.html file and an main.js file rendering some react to it it will run on production :) I recently wrote an article about how exactly my solution looks like. Feel free to take a look: https://medium.com/#TheBannik/get-ready-to-deploy-a-react-js-app-8f62c8e08282#.9gcd329h6