Unable to get a simple hello world working!
server.js
var webpack = require('webpack')
var WebpackDevServer = require('webpack-dev-server')
var config = require('./webpack.config')
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
inline: true,
historyApiFallback: true
}).listen(3000, '0.0.0.0', function (err, result) {
if (err) {
console.log(err)
}
console.log('Listening at 0.0.0.0:3000')
})
webpack.config.js
var path = require("path")
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')
module.exports = {
context: __dirname,
entry: [
'./assets/js/index', // entry point of our app. assets/js/index.js should require other js modules and dependencies it needs
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
],
output: {
path: path.resolve('./assets/bundles/'),
filename: "[name]-[hash].js",
publicPath: 'http://localhost:3000/assets/bundles/', // Tell django to use this URL to load packages and not use STATIC_URL + bundle_name
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(), // don't reload if there is an error
new BundleTracker({filename: './webpack-stats.json'}),
],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['react-hot-loader/webpack', 'babel-loader?presets[]=react'],
}, // to transform JSX into JS
],
},
resolve: {
modules: ['node_modules', 'bower_components'],
extensions: ['.js', '.jsx']
},
}
index.html
{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Example</title>
</head>
<body>
<div id="react-app"></div>
{% render_bundle 'main' %}
</body>
</html>
index.js
var React = require('react')
var ReactDOM = require('react-dom')
var App = require('./app')
var Hello = React.createClass ({
render: function() {
return (
<h1>
Hello, World!
</h1>
)
}
})
ReactDOM.render(<Hello />, document.gectElementById('react-app'))
I have integrated React with Django, trying to setup hot-reload. However the error doesn't seem to be with any of django or react. Probably I'm missing something with webpack-dev-server.
Related
I'm hoping someone will be able to help.
I'm trying to use single-spa-angularjs to pull in a legacy AngularJS application into a React app. So the React app is the host. In the same React app, I'm also using Module Federation to pull in a separate React microfrontend.
So to sum it up, I have three apps:
React app - host and container
AngularJS app - legacy app using
AngularJS version 1.4.8
React microfrontend
All three apps are completely separate and hosted separately.
I was able to pull in the React microfrontend using Module Federation with no issues. The problem that I'm facing is pulling the AngularJS app into the host React app (app 1).
I'm getting a lot of errors in the console but I think this is the most relevant one:
xxx.js:701 Uncaught Error: application 'AngularJS' died in status LOADING_SOURCE_CODE: Module parse failed: Unexpected token (1:1)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <!DOCTYPE html>
| <html lang="en" ng-app="MyAngularJSApp" ng-controller="MyAngularJSCtrl">
| <head>
at eval (index.html:1:7)
at ./index.html (node_modules_angularjs-bootstrap-datetimepicker_node_modules_moment_locale_sync_recursive_-no-1f57b2.app.bundle.js:27:1)
at __webpack_require__ (remoteEntry.js:44:42)
at eval (app.entry.js:21:69)
at ./app/app.entry.js (node_modules_angularjs-bootstrap-datetimepicker_node_modules_moment_locale_sync_recursive_-no-1f57b2.app.bundle.js:113:1)
at __webpack_require__ (remoteEntry.js:44:42)
at eval (container_entry:3:298)
at u.m.<computed> (bundle.js:2:262091)
at u (bundle.js:2:259451)
This is my current set up:
AngularJS App:
We're using webpack so we have a webpack.config.js file and the most important part is:
module.exports = function (env = {}) {
const isProd = !!env.prod;
const buildpath = env.buildpath ? env.buildpath : isProd ? 'dist' : 'build';
return {
entry: path.resolve(__dirname, 'app/app.entry.js'),
output: {
path: path.resolve(__dirname, buildpath),
filename: 'js/app.bundle.js',
clean: true,
},
plugins: [
new webpack.container.ModuleFederationPlugin({
name: 'MyAngularJSApp',
filename: 'remoteEntry.js',
remotes: {},
exposes: {
'./App': path.resolve(__dirname, 'app/app.entry.js'),
},
}),
new HtmlWebpackPlugin({
inject: 'body',
template: path.resolve(__dirname, 'index.html'),
filename: path.resolve(buildpath, 'index.html'),
})
],
module: {
......
},
resolve: {
......
},
optimization: {
......
},
};
};
In app/app.entry.js I've added the following:
import singleSpaAngularJS from 'single-spa-angularjs';
import angular from 'angular';
import app from '../index.html'
const domElementGetter = () => document.getElementById('AngularJSApp');
const ngLifecycles = singleSpaAngularJS({
angular: angular,
domElementGetter,
mainAngularModule: 'AngularJSApp',
template: app,
});
export const bootstrap = ngLifecycles.bootstrap;
export const mount = ngLifecycles.mount;
export const unmount = ngLifecycles.unmount;
In the host/consuming React application:
webpack.config.js:
const path = require('path');
const webpack = require('webpack')
const { ModuleFederationPlugin } = webpack.container;
const HtmlWebpackPlugin = require("html-webpack-plugin");
const dependencies = require('./package.json').dependencies;
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
entry: './src/index.tsx',
mode: 'production',
performance: {
hints: false,
maxEntrypointSize: 512000,
maxAssetSize: 512000
},
module: {
rules: [
{
test: /\.(jsx|js)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
exclude: /\.lazy\.html$/,
use: [
{
loader: 'html-loader',
options: {
minimize: true,
},
},
],
},
// Use Babel to transpile TypeScript and TypeScript / React files to ES5
{
test: /\.(tsx|ts)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new ModuleFederationPlugin({
name: 'container',
remotes: {
reactMFE: 'reactMFE#http://localhost:3000/remoteEntry.js',
AngularJSApp: 'AngularJSApp#http://localhost:3004/remoteEntry.js',
},
shared: {
react: {
singleton: true,
eager: true,
requiredVersion: dependencies.react,
},
'react-dom': {
singleton: true,
eager: true,
requiredVersion: dependencies['react-dom'],
}
},
}),
new webpack.DefinePlugin({ // <-- key to reducing React's size
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
// new BundleAnalyzerPlugin(),
new HtmlWebpackPlugin({
template: './public/index.html',
}),
],
};
I've registered the Angular app in the entry point /src/index.tsx. The same file also imports 'bootstrap' to resolve the eager consumption error when using module federation:
/src/index.tsx:
import("./bootstrap")
import {registerApplication} from 'single-spa'
registerApplication(
'AngularJSApp',
//#ts-ignore
() => import('AngularJSApp/App'),
location => location.pathname.startsWith('/')
)
/src/bootstrap.tsx:
import React from 'react';
import ReactDOM from 'react-dom/client';
import { App } from './App'
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
I've made changes to load in the scripts for the imported apps in public/index.html:
<html>
<head>
<script src="http://localhost:3000/remoteEntry.js"></script>
<script src="http://localhost:3004/remoteEntry.js"></script>
</head>
<body>
<div>Container App</div>
<div id="root"></div>
{/* I've put these two lines as a last ditch attempt - not sure which one of them should be working*/}
<div id="AngularJSApp"></div>
<div id="single-spa-application:AngularJSApp"></div>
</body>
</html>
Can someone advise on how I can get this working, it would be much appreciated.
Thank you
I have this problem where my react production build shows a blank page when served with simple node server. I have tried to tackle this problem different ways but cant find a solution to this. Any suggestions how to fix this problem would be much appreciated.
I am using BrowserRouter as the routing option on client side.
Here is my webpack.common.js code for the production build:
const path = require("path");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const outputPath = path.join(__dirname, "dist");
const port = process.env.PORT || 8000;
module.exports = {
context: __dirname,
entry: {
main: ["#babel/polyfill", "./src/App.js"]
},
output: {
path: path.join(__dirname, "dist"),
filename: "bundle.js"
},
resolve: {
modules: ["node_modules", "./src"],
extensions: [".js", ".jsx"]
},
module: {
rules: [
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
use: "css-loader!sass-loader"
})
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: "css-loader"
})
},
{
test: /\.(js|jsx)$/,
loader: "babel-loader",
exclude: /node_modules/
},
{
test: /\.(jpg|jpeg|png|gif|mp3|svg)$/,
loaders: ["file-loader"]
},
{
test: /\.html$/,
use: [
{
loader: "html-loader"
}
]
}
]
},
plugins: [
new ExtractTextPlugin("bundle.css"),
new HtmlWebpackPlugin({
baseUrl: process.env.NODE_ENV == 'development' ? '/' : '/',
filename: "index.html",
template: path.join(__dirname, "./public/index.html")
})
],
devServer: {
port,
historyApiFallback: true,
publicPath: "/"
}
};
Here is the entry for the compiler to run the production build:
const webpack = require('webpack');
const merge = require('webpack-merge');
const webpackCommonConfig = require('./webpack.config.common');
module.exports = merge(webpackCommonConfig, {
plugins: [
new webpack.EnvironmentPlugin({ NODE_ENV: 'production' }),
],
devtool: "source-map",
devServer: {
compress: true,
},
});
Here is the code for node server serving the application:
const express = require('express')
const path = require('path')
const port = process.env.PORT || 8000
const fs = require('fs');
const app = express()
app.get(['/bundle.css', '/bundle.css.map'], (req, res) => {
res.writeHead(200, {'Content-Type': 'text/css'});
fs.createReadStream(path.resolve(__dirname, `../dist/${req.url}`)).pipe(res);
})
app.get(['/bundle.js', '/bundle.js.map'], (req, res) => {
res.writeHead(200, {'Content-Type': 'text/javascript'});
fs.createReadStream(path.resolve(__dirname, `../dist/${req.url}`)).pipe(res);
})
app.get('*', function (request, response){
response.sendFile(path.resolve(__dirname, '../dist', 'index.html'))
})
app.listen(port)
console.log("server started on port " + port)
Here is the index.html that is compiled to dist folder:
<!DOCTYPE html>
<html lang="en" style="height:100%">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.gif">
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<title>Zoi</title>
<link href="bundle.css" rel="stylesheet"></head>
<body style="height:100%">
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<script type="text/javascript" src="bundle.js"></script></body>
</html>
in my react app i'm using webpack 4,before implementing split chunk everything is working fine but after splitChunks it generating vendor.js file and it showing on html file also but page is blank.
my webpack file
const webpack = require('webpack');
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash');
const CompressionPlugin = require('compression-webpack-plugin');
const VENDOR_LIBS =[
'antd','axios','moment','rc-time-picker','react',
'react-dom','react-ga','react-google-maps','react-loadable',
'react-redux','react-router','react-router-dom','recompose','redux','redux-thunk'
];
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
entry:{
vendor: VENDOR_LIBS,
main: './src/app.js',
},
output: {
path: path.join(__dirname, 'public'),
filename: '[name].chunkhash.bundle.js',
chunkFilename: '[name].chunkhash.bundle.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.s?css$/,
use: ['style-loader', MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
},{
test: /\.(gif|svg|jpg|png|ttf|eot|woff(2)?)(\?[a-z0-9=&.]+)?$/,
loader: "file-loader",
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'style.[contenthash].css',
}),
new HtmlWebpackPlugin({
inject: false,
hash: true,
template: './src/index.html',
filename: 'index.html'
}),
new WebpackMd5Hash(),
new CompressionPlugin({
algorithm: 'gzip',
test : /\.js$|\.css$|\.eot?.+$|\.ttf?.+$|\.woff?.+$|\.svg?.+$/,
threshold: 10240,
minRatio: 0.8
}),
],
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'initial',
name: 'vendor',
test: 'vendor',
enforce: true
},
}
},
runtimeChunk: true,
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true
}),
new OptimizeCSSAssetsPlugin({})
],
},
};
and in my /src/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500">
<link rel="stylesheet" href="<%=htmlWebpackPlugin.files.chunks.main.css %>">
<title>Book Ambulance - Stanplus</title>
</head>
<body>
<div id="app">
</div>
<script src="<%= htmlWebpackPlugin.files.chunks.main.entry %>"></script>
<script src="<%= htmlWebpackPlugin.files.chunks.vendor.entry %>"></script>
</body>
</html>
you can that those files are loading in browser but page is blank
i have to questions
a) why my app not showing nothing even not any error(may be something in output,splitChunks or in html page).
b) after doing UglifyJsPlugin,CompressionPlugin and dynamically adding routes and import libs/files but also my vendor.js file size is 580 KB,except all these techniques how can i reduce the size of my vendor.js file
I am currently trying to learn ng2.
I have followed the tutorial here : https://angular.io/docs/ts/latest/guide/webpack.html
And have found creating a dist of my build, upon attempting to run it, both locally and on Github Pages, I am receiving a 404 error on my bundle files.
I have followed the tutorial line for line and it does not appear to be working.
Can anyone help?
My webpack build is as follows :
webpack.common.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');
module.exports = {
entry: {
'polyfills': './src/polyfills.ts',
'vendor': './src/vendor.ts',
'app': './src/main.ts'
},
resolve: {
extensions: ['', '.js', '.ts']
},
module: {
loaders: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular2-template-loader']
},
{
test: /\.html$/,
loader: 'html'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file?name=assets/[name].[hash].[ext]'
},
{
test: /\.css$/,
exclude: helpers.root('src', 'app'),
loader: ExtractTextPlugin.extract('style', 'css?sourceMap')
},
{
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw'
}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
};
webpack.prod.js
var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
module.exports = webpackMerge(commonConfig, {
devtool: 'source-map',
output: {
path: helpers.root('dist'),
publicPath: '/',
filename: '[name].[hash].js',
chunkFilename: '[id].[hash].chunk.js'
},
htmlLoader: {
minimize: false // workaround for ng2
},
plugins: [
new webpack.NoErrorsPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
mangle: {
keep_fnames: true
}
}),
new ExtractTextPlugin('[name].[hash].css'),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(ENV)
}
})
]
});
Index.html
<!DOCTYPE html>
<html>
<head>
<base href=/>
<title>Angular With Webpack</title>
<meta charset=UTF-8>
<meta name=viewport content="width=device-width,initial-scale=1">
<link href="/app.f053dbe7ce9dd32c3e43.css" rel="stylesheet">
</head>
<body>
<my-app>Loading...</my-app>
<script type="text/javascript" src="/polyfills.f053dbe7ce9dd32c3e43.js"></script>
<script type="text/javascript" src="/vendor.f053dbe7ce9dd32c3e43.js"></script>
<script type="text/javascript" src="/app.f053dbe7ce9dd32c3e43.js"></script>
</body>
</html>
I had the same problem! Do you have karma.conf.js in config dir? Your project structure should be like :
Just started redux, get stuck on a weird situation, webpack shows no error, but in the html, the component did not get rendered. The file structure:
dist
bundle.js
node_modules
src
index.js
.babelrc
index.html
package.json
server.js
webpack.config.js
index.html
<html>
<head>
<title>jie blog</title>
<meta charset="utf-8">
</head>
<body>
<div id="root"></div>
</body>
<script src="dist/bundle.js">
</script>
</html>
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { Router, Route, Redirect, browserHistory } from 'react-router'
import { syncHistoryWithStore } from 'react-router-redux'
class App extends React.Component{
render(){
return(
<div>
hello world
</div>
)
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
)
server.js
var http = require('http')
var express = require('express')
var httpProxy = require('http-proxy')
var fs = require('fs')
var babelrc = fs.readFileSync('./.babelrc')
var config = JSON.parse(babelrc)
require('babel-core/register')(config)
var proxy = httpProxy.createProxyServer({})
var app = express()
app.use(require('morgan')('short'))
// webpack
var webpack = require('webpack')
var config = require('./webpack.config')
var compiler = webpack(config)
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
publicPath: config.output.publicPath
}))
app.use(require('webpack-hot-middleware')(compiler))
app.all(/^\/api\/(.*)/, function api(req, res){
proxy.web(req, res, {
target: 'http://localhost:5000'
})
})
app.get(/.*/, function root(req, res){
res.sendFile(__dirname + '/index.html')
})
const server = http.createServer(app)
server.listen(process.env.PORT || 3000, function(){
const address = server.address()
console.log('listening on %j', address)
})
webpack.config.js
const webpack = require('webpack')
const path = require('path')
module.exports = {
devtool: 'source-map',
entry: [
'webpack-hot-middleware/client',
path.resolve(__dirname, 'src/index.js')
],
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
resolve: {
extensions: ['', '.jsx', '.js', '.json', '.scss']
},
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
}
}
output html
<body>
<div id="root"></div>
<script src="dist/bundle.js">
</script>
</body>
It looks it's not an issue with ReactDOM but instead a configuration problem.
In server.js
...
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
publicPath: config.output.publicPath // <--- /static/
}))
...
publicPath specifies the public URL address of your bundle.js when referenced in a browser. So /static/bundle.js as you set in your webpack.config.js. Ok fine !
So Index.html need to request for /static/bundle.js. and NOT dist/bundle.js
...
<script src="static/bundle.js"></script>
...
Check output.publicPath configurations for webpack for more informations
As index.html requested for your bundle at /dist and webpack-dev-middleware handle requests at /static, an index.html file was returned instead of a your bundle.js
app.get(/.*/, function root(req, res){
res.sendFile(__dirname + '/index.html')
})
It's why you got Uncaught SyntaxError: Unexpected token < bundler.js:1.
The problem is that Babel is transpiling only .jsx files:
test: /\.jsx?$/,
while your file with JSX has a .js extension (index.js)