I recently try to make a boilerplate for webpack2 + babel6 + gulp + react-hot-loader project. I started by forking react-hot-loader-minimal-boilerplate. Then I added a gulpfile to it as this branch.
If you read the code, you'll find I've only added the last 1 commit, which added the gulp package, gulp file and add the npm run gulp script. You 'd want to take a look at gulpfile.babel.js, which currently looks like this:
const gulp = require('gulp');
const webpack = require('webpack');
const cfg = require('./webpack.config');
const devServer = require('webpack-dev-server');
const path = require('path');
const util = require('gulp-util');
gulp.task('dev', () => {
cfg.plugins = [
new webpack.HotModuleReplacementPlugin(),
];
cfg.entry = {
'app': [
'babel-polyfill',
'react-hot-loader/patch',
'webpack-dev-server/client?http://localhost:8080',
'./src/index',
],
};
new devServer(webpack(cfg), {
//contentBase: path.join(__dirname, 'dist'),
hot: true,
historyApiFallback: true,
//publicPath: cfg.output.publicPath,
stats: {
colors: true,
},
}).listen(8080, 'localhost', function (err) {
if(err) throw new gutil.PluginError("webpack-dev-server", err);
util.log(`'${util.colors.cyan('dev:server')}' http://localhost:8080/webpack-dev-server/index.html`);
});
});
Supposedly, the command npm run dev and npm run gulp should have the same effect. But in reality, the gulp command is not working.
If I change my React code, the code in browser should update accordingly.
The console log for code update in npm run dev:
Instead, although the browser did get signal from webpack-dev-server for the update, the DOM is not updated along with the signal.
The console log for code update in npm run gulp:
Any suggestion on how to fix this boilerplate?
Related
Module not found: Error: Can't resolve 'process/browser' in '/Users/nigelng/oxpay-merchant-portal-fe/node_modules/xlsx'
Did you mean 'browser.js'?
I have installed xlsx 0.18.5 npm package to export xlsx files, I found out that's a webpack issue (https://github.com/SheetJS/sheetjs/issues/2527), but the solutions didn't work for me.
do anyone experience the same error?
The way I fixed this was by using the package #craco/craco so you can manually change the webpack config file without ejecting create-react-app (since that is permanent). Once craco is installed create a file in the root directory named craco.config.js and then copy and paste this configuration, should fix your problem:
const webpack = require("webpack");
module.exports = {
webpack: {
configure: {
module: {
rules: [
{
test: /\.m?js/,
resolve: {
fullySpecified: false
}
}
]
},
}
}
};
Make sure to change your start script to "craco start" and you should be off to the races.
Unable to resolve module #env from D:\react\weatho\weatho-app\App.js: #env could not be found within the project
10:import {REACT_APP_WEATHER_API_KEY} from "#env";
my env file looks like this:
REACT_APP_WEATHER_API_KEY=2607fb610e6f9fecd16c84408d0b42a2
and my Babel file looks like this:
module.exports = function(api) {
api.cache(true);
return {
plugin: ['babel-preset-expo','module:react-native-dotenv'],
}
}
and my env file is in root folder along with Appjson and few other files
You should add a plugin like this(.env file must be in the root directory)
module.exports = function (api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
plugins: [
[
"module:react-native-dotenv",
{
moduleName: "#env",
path: ".env",
},
],
],
};
};
And don't forget to restart the expo start and ios/android restart the app.
If you are still getting the same issue then it can be a cache issue.
You can easily clear the babel cache by running the following command :
rm -rf node_modules/.cache/babel-loader/*
or
yarn start --reset-cache
or
expo r -c
Your babel config has 'plugin' which should be 'plugins'
yarn start --reset-cache
npm start -- --reset-cache
expo start -c
I'm stuck in a trouble with my project. I am using gulp + webpack to compile the client side. During the developing stage, I want to use nodemon to watch the file changing in the server directory and I want to find a suitable mode to watch the client side part of the project and re-run the webpack task.
Here is my gulpfile
gulp.task('clean:tmp', (cb) => {
del([paths.tmp]).then(paths => {
plugins.util.log('[clean]', paths);
cb();
});
});
gulp.task('serve', ['clean:tmp'], () => {
const config = require('./webpack.dev.config');
config.entry.app = paths.entry;
return gulp.src(paths.entry)
.pipe(webpack(config))
.pipe(gulp.dest('.tmp'));
});
gulp.task('watch', ['serve'], () => {
return nodemon({
script: `${rootServer}/`,
watch: ['server/*'],
});
});
The problem is that if I run the gulp watch with webpack.config.watch = true, webpack breaks the gulp pipe logic.
I also check out this answer Watch webpack.config.js and re-run webpack command in response to a file change
but I cannot apply the solution.
Any suggestion?
Update current problem :
it seems that the webpack hot loader goes wrong,because when i run the following cmd:webpack,it can be built as usual.but when i run ""dev": "webpack-dev-server --color --hot --progress && node ./server.js"".webpack cannot generate built files for me .
my webpack.config is as follows:
module.exports = {
entry: getEntries(),
.....
function getEntries(){
var routeDir = path.join(SRC_DIR,"javascripts","routes");
var routeNames = routeDir?fs.readdirSync(routeDir):[];
var nameMaps = {};
routeNames.forEach(function(routeName){
var filename = routeName.match(/(.+)\.js$/)[1];
console.log("filename in entry ",filename);
if(filename){
var devEntryPath = [
'webpack-dev-server/client?http://127.0.0.1:3001', // WebpackDevServer host and port
'webpack/hot/only-dev-server',
path.join(routeDir,filename)
];
nameMaps[filename] = devEntryPath;
}
});
return nameMaps;
}
server.js
var server = new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: true
}).listen(3001,'localhost',function(err,result){
if(err) console.log(err);
console.log("webpack listening at port 3001");
});
var app = express();
app.get("/monitor/index",function(req,res){
res.sendFile(__dirname+"/src/views/"+"page1.html");
});
app.get("/monitor/category/*",function(req,res){
res.sendFile(__dirname+"/src/views/"+"page2.html");
});
app.use(express.static(__dirname))
.listen(9090, 'localhost', function (err, result) {
if (err) console.log(err);
console.log('Listening at localhost:9090');
});
finally,i found where the problem is,and know the relationship between webpack-dev-server and my express server.
when using hot-loader with webpack-dev-server:
step1:the webpack build the input file to the publicPath (which was designated in "output" of webpack.config.js).
step2,the node server will send html to the front,and search for the related assets(such as js,img etc),but where? we can change the script(related with html) path to the webpack-dev-server.(just generated by step1),so node-server will ask webpack-dev-server for help.
to sum up ,i modified 3 places:
publicPath of webpackDevServer
webpack output(publicPath),equal to above
script path in html.
that's all.and now,my project can run as expected.
I am using react-hot-loader and webpack. I also use webpack-dev-server together with an express backend.
This is my relevant webpack config for development:
var frontendConfig = config({
entry: [
'./src/client/app.js',
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/dev-server'
],
output: {
path: targetDir,
publicPath: PROD ? '/build/assets/' : 'http://localhost:3000/build/assets/' ,
filename: 'app.js'
},
module: {
loaders: [
{test: /\.js$/,
exclude: /node_modules/,
loaders: PROD ? [babelLoader] : ['react-hot', babelLoader] }
]
},
plugins: [
new webpack.HotModuleReplacementPlugin({ quiet: true })
]
});
with this config I start webpack and webpack-dev-server
gulp.task('frontend-watch', function() {
new WebpackDevServer(webpack(frontendConfig), {
publicPath: frontendConfig.output.publicPath,
hot: true,
stats: { colors: true }
}).listen(3000, 'localhost', function (err, result) {
if(err) {
console.log(err);
}
else {
console.log('webpack dev server listening at localhost:3000');
}
});
});
so webpack-dev-server is running at localhost:3000 and receives app.js from webpack watcher (which now is not anymore written to file system).
my express server serves as a backend/api and has the following config:
var express = require('express');
// proxy for react-hot-loader in dev mode
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({
changeOrigin: true,
ws: true
});
var isProduction = process.env.NODE_ENV === 'production';
// It is important to catch any errors from the proxy or the
// server will crash. An example of this is connecting to the
// server when webpack is bundling
proxy.on('error', function(e) {
console.log('Could not connect to proxy, please try again...');
});
module.exports = function (app) {
// We only want to run the workflow when not in production
if (!isProduction) {
console.log('setting up proxy for webpack-dev-server..');
// Any requests to localhost:4200/build is proxied
// to webpack-dev-server
app.all('assets/app.js', function (req, res) {
proxy.web(req, res, {
target: 'http://localhost:3000'
});
console.log('request proxied to webpack-dev!');
});
}
var server = require('http').createServer(app);
app.use(express.static(homeDirectory + '/build'));
app.use(express.static(homeDirectory + '/files'));
server.listen(4200);
};
That's all good so far, the proxying work for app.js and I see successfull hot update messages in the browser console:
Now, while it looks fine it does not work as I expected:
when I change a component's render() method it updates as supposed, but when I change a helper method (that is used in render()) then I don't get any hot update. is that normal?
Another thing that bugs me, if I work like this, and do a 'hard' browser reload at some point, all changes I made are reverted to the point where I started my webpack-dev-server - all the hot updates in between have not been persisted somehow. is that normal as well? I would expect that I loose my state but not any changes I made to the code in the meantime. That has probably something to with my app.js not being written to the file system.
For your question #2, that's not normal, I have a template repo that has HMR working available here and it works just fine https://github.com/briandipalma/wp-r-template
For question #1, usually render methods display or format data, not grab it from somewhere. But if you need to format data, use a function outside of the component
Parent component would call the following once you retrieve the price
<ChildComponent price={this.state.price}
ChildComponent's render function would use props (or better yet a parameter of the function). Remember: the whole point of React is composition and data flow
return (
<div>{this.props.price}</div>
);