historyApiFallback doesn't work in Webpack dev server - javascript

I use Webpack dev server and browserHistory in React Router to manipulate with urls by HTML5 History API. historyapifallback-option does not work in my webpack config file. After refreshing http://localhost:8080/users or http://localhost:8080/products I got 404.
webpack.config.js
var webpack = require('webpack');
var merge = require('webpack-merge');
const TARGET = process.env.npm_lifecycle_event;
var common = {
cache: true,
debug: true,
entry: './src/script/index.jsx',
resolve: {
extensions: ['', '.js', '.jsx']
},
output: {
sourceMapFilename: '[file].map'
},
module: {
loaders: [
{
test: /\.js[x]?$/,
loader: 'babel-loader',
exclude: /(node_modules)/
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
]
};
if(TARGET === 'dev' || !TARGET) {
module.exports = merge(common,{
devtool: 'eval-source-map',
devServer: {
historyApiFallback: true
},
output: {
filename: 'index.js',
publicPath: 'http://localhost:8090/assets/'
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('dev')
})
]
});
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<title>Test</title>
</head>
<body>
<div id="content">
<!-- this is where the root react component will get rendered -->
</div>
<script src="http://localhost:8090/webpack-dev-server.js"></script>
<script type="text/javascript" src="http://localhost:8090/assets/index.js"></script>
</body>
</html>
index.jsx
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {Router, Route, useRouterHistory, browserHistory, Link} from 'react-router';
class Home extends Component{
constructor(props) {
super(props);
}
render() {
return <div>
I am home component
<Link to="/users" activeClassName="active">Users</Link>
<Link to="/products" activeClassName="active">Products</Link>
</div>;
}
}
class Users extends Component{
constructor(props) {
super(props);
}
render() {
return <div> I am Users component </div>;
}
}
class Products extends Component{
constructor(props) {
super(props);
}
render() {
return <div> I am Products component </div>;
}
}
ReactDOM.render(
<Router history={browserHistory} onUpdate={() => window.scrollTo(0, 0)}>
<Route path="/" component={Home}/>
<Route path="/users" component={Users} type="users"/>
<Route path="/products" component={Products} type="products"/>
</Router>
, document.getElementById('content'));
package.json
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.jsx",
"scripts": {
"start": "npm run serve | npm run dev",
"serve": "./node_modules/.bin/http-server -p 8080",
"dev": "webpack-dev-server -d --progress --colors --port 8090 --history-api-fallback"
},
"author": "",
"license": "MIT",
"dependencies": {
"events": "^1.1.0",
"jquery": "^2.2.3",
"path": "^0.12.7",
"react": "^15.0.2",
"react-dom": "^15.0.2",
"react-mixin": "^3.0.5",
"react-router": "^2.4.0"
},
"devDependencies": {
"babel": "^6.5.2",
"babel-core": "^6.8.0",
"babel-loader": "^6.2.4",
"babel-polyfill": "^6.8.0",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"babel-register": "^6.8.0",
"http-server": "^0.9.0",
"webpack": "^1.13.0",
"webpack-dev-server": "^1.14.1",
"webpack-merge": "^0.12.0"
}
}
I tried to change devServer in my config, but it didn't help:
devServer: {
historyApiFallback: {
index: 'index.html',
}
},
devServer: {
historyApiFallback: {
index: 'index.js',
}
},
devServer: {
historyApiFallback: {
index: 'http://localhost:8090/assets',
}
},
devServer: {
historyApiFallback: {
index: 'http://localhost:8090/assets/',
}
},
devServer: {
historyApiFallback: {
index: 'http://localhost:8090/assets/index.html',
}
},
devServer: {
historyApiFallback: {
index: 'http://localhost:8090/assets/index.js',
}
},
devServer: {
historyApiFallback: {
index: 'http://localhost:8090/assets/index.js',
}
},
output: {
filename: 'index.js',
publicPath: 'http://localhost:8090/assets/'
},

I meet the same question today.
let config in webpack.config.js: output.publicPath be equal to devServer.historyApiFallback.index and point out html file route。my webpack-dev-server version is 1.10.1 and work well. http://webpack.github.io/docs/webpack-dev-server.html#the-historyapifallback-option doesn't work, you must point out html file route.
for example
module.exports = {
entry: "./src/app/index.js",
output: {
path: path.resolve(__dirname, 'build'),
publicPath: 'build',
filename: 'bundle-main.js'
},
devServer: {
historyApiFallback:{
index:'build/index.html'
},
},
};
historyApiFallback.index indicate that when url path not match a true file,webpack-dev-server use the file config in historyApiFallback.index to show in browser rather than 404 page. then all things about your route change let your js using react-router do it.

output: {
...
publicPath: "/"
},
Adding public path solved this for me

I had this problem and was only able to fix it using index: '/' with webpack 4.20.2
historyApiFallback: {
index: '/'
}

There is a very tricky thing going on here!
The 404 can be two totally different things below. You can open the Network tab of Chrome to see if it's the initial request that is 404, or the assets within.
If you are not afraid of terminal, you can also do curl -v http://localhost:8081/product to see the actual HTTP response code.
Case 1: 404 on the initial HTML page
This is the case that set-up with historyFallbackApi is not correct.
Usually just historyApiFallback: true should work in devServer configs of Webpack. (source) Yet, if you happen to have a custom output folder, you have to set the index property of historyApiFallback to the same path, as advised by the other answers on this question like jsdeveloper's or echzin's.
Case 2: 404 on the assets (e.g. bundle.js or vendor.js)
This one is quite interesting!
In this case you do actually get the initial HTML (i.e. if you add view-source: before your URL to become view-source:http://localhost:8081/admin, you see your HTML, and/or curl command shows the HTML), but the page doesn't work in the browser.
What historyApiFallback does, which might sound like a magic, is literally just setting req.url of the Express server to be the index.html file, for any incoming GET request within the domain. (The main two lines in the Source Code)
However, if the path to your assets is relative (e.g. in the view-source, you see <script src="vendor.js"></script>) AND the path that you are landing is not at the same path-depth as index (e.g. you are trying to load http://localhost:8081/admin/user/12/summary while the main server is at http://localhost:8081/admin), what happens is it cannot find the .js files for your JavaScript code. (in my case http://localhost:8081/admin/user/12/vendor.js)
Note that whatever router that deals with HTML5 History here (react router or vue router), knows how to initialize the internal path to document.location.href upon the initial load. But, it doesn't know where is the "root" to properly update the assets' path to it. (And maybe it's not even its job, in terms of responsibility.) As a result, the path to assets would be calculated based on the URL's path, not the index.html's path! So, for just src="vendor.js" with no absolute / prefix, it tries to find /admin/user/12/vendor.js instead of /vendor.js.
What you need to do here is to make sure the output path of your WebPack is an absolute path and starts with /, so regardless of the landing URL, it would always work. i.e. it's always <script src="/vendor.js"></script> in the HTML source.
To do so, you have to set output.publicPath to be an absolute path (with or without domain). You can verify this via the view-source: or curl technique above. :)

Ref.: https://webpack.js.org/configuration/dev-server/#devserver-historyapifallback
This works with any react-router
You have to add historyApiFallback: true
module.exports = {
cache: true,
entry: "./index.js",
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'public')
},
context: SRC,
devServer: {
contentBase: path.resolve(__dirname, 'public/assets'),
stats: 'errors-only',
open: true,
port: 8080,
compress: true,
historyApiFallback: true
},
...
}

If you're finding that some paths work but others don't, you may be falling foul of the "dot rule". Per the docs:
When using dots in your path (common with Angular), you may need to
use the disableDotRule:
webpack.config.js
module.exports = {
//...
devServer: {
historyApiFallback: {
disableDotRule: true,
},
},
};

For me this setting worked out:
module.exports = {
output: {
path: path.resolve(__dirname, 'build'),
publicPath: '/',
filename: 'bundle-main.js'
},
devServer: {
/* Telling the server to fallback to index.html if the route is not found at the backend server */
historyApiFallback: true,
}
};

In webpack.config.js just add these lines
devServer: {
open: true,
historyApiFallback: true,
allowedHosts: 'all',
hot: true
},
and add this -> // prefixes: ["http://your url:8081/"]
it's working perfectly.

Related

webpack-dev-server not hot reloading (webpack 5)

I'm new to this webpack thing so I was looking through some Webpack 5 tutorials online and documentation but I don't know how to fix this issue
File Structure:
dist
node_modules
src
modules
js files
style
style.css
index.html
index.js
package.json
package-lock.json
webpack.config.js
Webpack Config:
const { appendFile } = require("fs");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: 'development',
entry: {
main: path.resolve(__dirname,'src/index.js'),
},
output: {
path:path.resolve(__dirname,'dist'),
filename: 'app.bundle.js',
hashFunction: 'xxhash64',
},
devtool: 'inline-source-map',
devServer: {
static: {
directory:path.resolve(__dirname,'dist'),
watch:true,
},
port: 8080,
open: true,
hot: true,
},
//loaders
module: {
rules: [
{test: /\.css$/, use:['style-loader','css-loader']}
]
},
//plugins
plugins: [new HtmlWebpackPlugin({
title: 'To Do List',
filename: 'index.html',
template: path.resolve(__dirname,"./src/index.html")
})]
}
When I run "npm run dev" my webpage opens with the HTML/CSS/JS but nothing changes (no recompiling happens) when I make a change to my code.
Also, another weird problem that occurs is that my import statements get deleted in the index.js file on save, not sure if thats related to this or just a VScode problem
You have a place to correct in your devServer.static.directory: it should be ./, not dist. Here is the set of devServer's settings, which worked out for me:
devServer: {
port: 8080,
hot: "only",
static: {
directory: path.join(__dirname, './'),
serveIndex: true,
},
},
I was struggling with HMR aswell and it is really disappointing to end up with almost nothing, except i got it working with this approach:
devServer: {
port: 8080,
hot: false,
liveReload: true,
watchFiles: ['dist/**/*'],
open: ['http://localhost:8080/html/index.html']
}
basically i switched to liveReload to achieve same result and it works now.
P.S. you don't need to use 'open' but my html is located in dist/html/index.html and i used a link to open window with that html

After building react app using webpack, browserRouter does not allow me to go directly to a route, but hashRouter does?

My issue
When I run npm run dev, the app loads up and all is good, I can go to my route defined as and be able to see the component. However when I do npm run buildDev and load up the app, it loads the "/" route fine, but when i manually go to "/login" it says "cannot get /login"
what works
if I were to click the "login" link as set up my "Link" it works fine, even after the build. Then I went into my index.js and changed my browserrouter to hashrouter and then ran buildDev again and npm start, and i was able to go to the login route if i did "/#/login"
What am I doing wrong here that browser router doesnt work?
My package.json scripts file is as below as well:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"client": "webpack-dev-server --mode development",
"server": "nodemon server-dev.js",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"buildDev": "rimraf build && webpack --mode development --config webpack.server.config.js && webpack --mode development --config webpack.dev.config.js",
"buildProd": "rimraf build && webpack --mode production --config webpack.server.config.js && webpack --mode production --config webpack.prod.config.js",
"start": "node ./build/server.bundle.js"
},
My webpack.dev.config.js file has the contents below:
module.exports = {
devtool: "cheap-module-source-map",
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "build"),
filename: "[name].bundle.js",
chunkFilename: "[name].bundle.js",
publicPath: "/"
},
mode: "development",
target: "web",
resolve: {
extensions: [".js", ".jsx"]
},
module: {
rules: [
{
test: /\.js$/,
loader: "babel-loader",
exclude: /node_modules/
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{ loader: "style-loader" },
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: true,
camelCase: "dashes",
localIdentName: "[name]_[local]_[hash:base64:5]"
}
},
{
loader: "postcss-loader",
options: {
ident: "postcss",
plugins: () => [
autoprefixer({
browsers: [">1%", "last 2 versions"]
})
]
}
}
]
},
{
test: /\.(png|jpe?g|gif)$/,
loader: "url-loader?limit=8000&name=images/[name].[ext]"
}
]
},
devServer: {
port: 3000,
open: true,
proxy: {
"/main": {
target:"http://localhost:8080"
}
},
historyApiFallback: true
},
plugins: [
new HtmlWebpackPlugin({
template: __dirname + "/src/index.html",
filename: "index.html",
inject: "body",
excludeChunks: ["server"]
})
],
optimization: {
minimizer: [new UglifyJsPlugin()]
}
};
My app.js looks like the below:
const AsyncPizza = React.lazy(() => import("./containers/Pizza"));
class App extends Component {
render() {
return (
<div>
<Link to="/login">login</Link>
<div>
<Suspense fallback={<div>loading...</div>}>
<Route path="/login" component={Authentication} />
<Route path="/" exact component={LandingPage} />
<Route path="/pizza" exact component={AsyncPizza} />
</Suspense>
</div>
</div>
);
}
}
EDIT
My server-dev.js is as follows:
app.use(express.static("build"));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
require("./routes")(app);
app.listen(8080, () => console.log("Listening on port 8080!"));
My webpack.server.config.js is as follows:
module.exports = (env, argv) => {
const SERVER_PATH =
argv.mode === "production" ? "./server-prod.js" : "./server-dev.js";
return {
entry: {
server: SERVER_PATH
},
output: {
path: path.join(__dirname, "build"),
filename: "[name].bundle.js",
chunkFilename: "[name].bundle.js",
publicPath: "/"
},
mode: argv.mode,
target: "node",
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false // and __filename return blank or /
},
externals: [nodeExternals()], // Need this to avoid error when working with Express
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
};
};
EDIT 2:
In my routes folder I have a index.js file which has the following contents:
module.exports=function(app){
app.use("/main",require("./main"))
}
Then in "main" folder I just have a "test" file which has the following route that is exported:
router.get(
"/test",
(req, res) =>
res.send("hello")
);
As per the previous person, you need to add this after your app.use routes part in your server-dev.js
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/index.html'));
})
this should fix it
You can try with this sample of code (In case you are using the server for serving only the react app):
app.get('*', (req,res) =>{
res.sendFile(path.join(__dirname+'/client/build/index.html'));
});
Where you can replace the link of the index.html file as per your file structure.

Polymer 3 in other project (like ASP.NET MVC) - create reusable components (PolymerElements)

I am trying to create and reuse Polymer 3 components in ASP.NET MVC application. Right now I am not sure if I am approaching the issue correctly.
So first thing, I want to run everything from IIS express.
Right now I have this issue:
Uncaught TypeError: Failed to resolve module specifier "#polymer/polymer/polymer-element.js".
Relative references must start with "/", "./", or "../".
Here is my code:
Index.cshtml:
<head>
<script src="~/Scripts/PolymerApp/node_modules/#("#webcomponents")/webcomponentsjs/webco
mponents-loader.js"></script>
<script type="module" src="~/Scripts/PolymerApp/first-element.js">
</script>
</head>
<h2>Index</h2>
<div>
<first-element></first-element>
</div>
This is my first-element.js:
import {html, PolymerElement} from '#polymer/polymer/polymer-element.js';
class FirstElement extends PolymerElement {
static get template() {
return html`
<style>
:host {
display: block;
}
</style>
<h2>Hello [[prop1]]!</h2>
`;
}
static get properties() {
return {
prop1: {
type: String,
value: 'first-element',
},
};
}
}
window.customElements.define('first-element', FirstElement);
I created this through cmd: polymer init and then chose element template.
When I run this through polymer serve on polymer`s localhost it works, so i guess there is some build process going on.
Thanks in advance. I hope that i described everything.
I've attempted to do a string replacement in the polymer generated html file using webpack and a plug-in, but it doesn't seem to find the file. Maybe someone more knowledgeable in Webpack-fu can figure out the rest.
// webpack.config.js
var webpack = require('webpack');
const ReplaceInFileWebpackPlugin = require('replace-in-file-webpack-plugin');
"use strict";
module.exports = {
entry: {
main: '/'
},
output: {
filename: "./wwwroot/dist/[name].bundle.js",
publicPath: "/temp/"
},
devServer: {
contentBase: ".",
host: "localhost",
port: 9000
}, mode: "development",
plugins: [
new ReplaceInFileWebpackPlugin([{
dir: './path/to/polymer-built-app/build/default/',
test: /\.html$/,
rules: [{
search: '/#webcomponents/',
replace: '/#{\'#webcomponents\'}/'
}]
}])
]
};
**EDIT: 08/04/2018 **
I've figured this much out:
/// <binding BeforeBuild='Run - Development' />
// webpack.config.js
var webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackStringReplacePlugin = require('html-webpack-string-replace-plugin');
"use strict";
module.exports = {
entry: {
main: './'
},
output: {
publicPath: '/',
path: path.resolve(__dirname, 'wwwroot'),
filename: "./dist/[name].bundle.js"
},
devServer: {
contentBase: ".",
host: "localhost",
port: 9000
},
mode: "development",
plugins: [
new HtmlWebpackPlugin({
"template": "./path/to/index.html",
"filename": "../path/to/Views/Shared/_PolymerLayout.cshtml"
}),
new HtmlWebpackStringReplacePlugin({
'#webcomponents':
'#Html.Raw("#webcomponents")',
'%40webcomponents':
'#Html.Raw("#webcomponents")',
'%40polymer':
'#Html.Raw("#polymer")',
'/node_modules/':
'/path/to/node_modules/',
'./src/path/to/polymer-app',
'<!-- See google short url -->':
'<!-- See google short url -->\r\n<base href="/custom/base/ref">'
})
]
};
If the .js import path starts like this:
from '#polymer/...'
Polymer 3 has a command "polymer build" that automatically translates the path to a real location:
Before:
from '#polymer/polymer/polymer-element.js';
After:
from "./node_modules/#polymer/polymer/polymer-element.js";
You can type ./node_modules/ in front to skip using the polymer build command line tool.

Eslint errorring importing jsx without extension

I am trying, in es6, to import jsx files without requiring the .jsx extension:
import LoginErrorDialog from './LoginErrorDialogView';
Not:
import LoginErrorDialog from './LoginErrorDialogView.jsx';
While I have got webpack to import in this fashion successfully:
export default {
entry: './src/ui/js/app.js',
output: {
publicPath: '/',
filename: 'bundle.js'
},
resolve: {
extensions: ['.js', '.jsx'],
Eslint (esw webpack.config.* ./ --color --ext .js --ext .jsx) is still errorring.
Unable to resolve path to module './LoginView' import/no-unresolved
Any ideas?
I had the same issue here, and I fixed adding extra configuration in my .eslintrc.
In the extends property add:
"plugin:import/react"
In the settings property add:
"import/resolver": {
"node": {
"extensions": [".js",".jsx"]
}
}
Your .eslintrc will look like:
{
"extends": [
...
"plugin:import/react",
...
],
...
"settings": {
"import/resolver": {
"node": {
"extensions": [".js",".jsx"]
}
}
},
...
}
Add to rule section, below rule
"import/extensions": [0, { "js": "always" }]

ReactJS: Unexpected Token <

TL;DR: Why am I getting the error with my code? Previous question is different (online vs desktop) and it's answers don't work for me.
Complete code here
Based on code more or less originating here (I'm not quite to the end of the "lesson"
Question: Following this "intro to ReactJS". The walkthrough has Webpack/Babel setup. It runs with plain JS, but when I switch to JSX it chokes. This is similar to this question, but none of those answers seem to work. Main difference: Web Playground vs locally on my box?
The end of the video I'm working on leads to this code - although, I'm only 3/4 of the way through so parts aren't included yet. So, I've dialed it back into this fork with my edits (Sorry if I've butchered forking and pushing my changes...)
Notes: The BEFORE and AFTER is the only things I've changed. It works with javascript/jquery - but not with JSX. I found a couple typos, case errors (thisItem vs thisitem) and some items that shouldn't have been there (brackets removed).
I've changed "my" typed out version to more closely match "their" version (Hello instead of HelloWorld) and made other minor changes... same error.
The biggest remaining changes I see other than some spacing issues is versions - minor version bumps from the recorded class.
My Code:
.babelrc
{ "presets": [ "react" ] }
package.json
{
"name": "github-battle",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server",
"production": "webpack -p"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^0.14.7",
"react-dom": "^0.14.7"
},
"devDependencies": {
"babel-core": "^6.6.0",
"babel-loader": "^6.2.4",
"babel-preset-react": "^6.5.0",
"html-webpack-plugin": "^2.9.0",
"webpack": "^1.12.14",
"webpack-dev-server": "^1.14.1"
}
}
webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin')
var HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
template: __dirname + '/app/index.html',
filename: 'index.html',
inject: 'body'
})
module.exports = {
entry: [
'./app/index.js'
],
output: {
path: __dirname + '/dist',
filename: "index_bundle.js"
},
module: {
loaders:[
{ test: /\.js$/,include: __dirname + '/app',loader: "babel-loader" }
]
},
plugins: [HtmlWebpackPluginConfig]
}
app\index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Github Battle</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" >
</head>
<body>
<div id="app"></div>
</body>
</html>
app\index.js BEFORE
var app = document.getElementbyid('app')
app.innerHTML = 'Hello
app\index.js AFTER
var React = require('react');
var ReactDOM = require('react-dom');
var HelloWorld = React.createClass({
render: function () {
return <div> Hello World </div>
}
});
ReactDOM.render(
<HelloWorld />,
document.getElementById('app')
);
Result:
> B:\Users\Chris\react-js\React-Fundamentals>npm run production
> gh-battle#1.0.0 production B:\Users\Chris\react-js\React-Fundamentals
> webpack -p
Hash: 21e367e251c35209471c
Version: webpack 1.12.14
Time: 375ms
Asset Size Chunks Chunk Names
index_bundle.js 289 bytes 0 [emitted] main
index.html 305 bytes [emitted]
[0] multi main 28 bytes {0} [built] [1 error]
[1] ./app/index.js 0 bytes [built] [failed]
ERROR in ./app/index.js
Module parse failed: B:\Users\Chris\react-js\React-Fundamentals\app\index.js Line 6: Unexpected token <
You may need an appropriate loader to handle this file type.
| var Hello = React.createClass({
| render: function () {
| return <div> Hello ReactJS World! </div>
| }
| });
# multi main
Child html-webpack-plugin for "index.html":
+ 3 hidden modules
B:\Users\Chris\react-js\React-Fundamentals>
webpack.config.js #2: Same rror
var HtmlWebpackPlugin = require('html-webpack-plugin');
...
module.exports = {
...
module: {
loaders: [
{test: /\.js$/, include: __dirname + '/app', loader: "babel-loader"}
],
query: {
presets: ['react']
}
},
plugins: [HTMLWebpackPluginConfig]
};
You need to rename index.js to index.jsx.
silly question: have you tried removing the square brackets in the "entry" declaration?
module.exports = {
entry: './app/index.js',
output: {
path: __dirname + '/dist',
filename: "index_bundle.js"
},
module: {
loaders:[
{
test: /\.js$/,
include: __dirname + '/app',
loader: "babel-loader"
}
]
},
plugins: [HtmlWebpackPluginConfig]
}
From your second webpack config file, query should be inside the babel loader object.
module: {
loaders: [
{
test: /\.js$/,
include: __dirname + '/app',
loader: "babel-loader",
query: {
presets: ['react']
}
}
]
}
Don't forget to install the babel-preset-es2015 plugin if you plan on using es6.
Working Code here
After banging my head against the wall (which, honestly, helps beat the knowledge in - so it isn't all for naught)... I've made a couple minor changes and seem to be successful now:
changed .js to .jsx - I like the "explicit" acknowledgement that these aren't plain ole js. (not required I think, more style)
I've removed the babelrc file and moved query into webpack.config... seems to be easier to compartmentalize things in a single file. this actually isn't working for me... se'la'vie
The "solution" seems to be the __dirname + '/dir' changed into path.join(...) - with var path = require('path') actually included. I'll research (and ask a new question if I don't find one) how/why those two aren't equal, but I can only assume it has something to do with differing operating systems (Windows 10x64 for me).
EDIT:: Just some random poking, but include:__dirname + 'app', fails... as does '\app', '\app\', '/app', '/app/'... no clue why, but path.join(...) works.
Also worth noting, is that template: __dirname + '...', seems to work, but not the parts below it. Filename vs directory, so again not sure of the difference.
webpack.config.js
var path = require('path');
var HTMLWebpackPlugin = require('html-webpack-plugin');
var HTMLWebpackPluginConfig = new HTMLWebpackPlugin({
template: __dirname + '/app/index.html',
filename: 'index.html',
inject: 'body'
});
module.exports = {
entry: [
'./app/index.jsx'
],
output: {
path: path.join(__dirname, '/dist'),
filename: "index_bundle.js"
},
module: {
loaders: [{
test: /\.jsx?$/,
include: path.join(__dirname, '/app'),
loader: "babel-loader"},
]
},
plugins: [HTMLWebpackPluginConfig]
};
index.jsx
var React = require('react');
var ReactDOM = require('react-dom');
var HelloWorld = React.createClass({
render: function () {
return <div> Hello ReactJS World! </div>
}
});
ReactDOM.render(
<HelloWorld />,
document.getElementById('app')
);
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Github Battle</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body>
<div id="app"></div>
<script src="index_bundle.js"></script></body>
</html>

Categories