I created a reactjs app with webpack. Everything works fine on local. Just by using npm start. I want to deploy a simple package for prod with webpack -p command. it gave me a bundle.js I appended it, and it works fine too. but it is still looking for my local server running as part of hot reloading config. I changed hot:false, but its still looking for it.
here is my webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://csd.local.com:3000',
'webpack/hot/only-dev-server',
'./src/index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify('production')})
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel'],
include: path.join(__dirname, 'src')
},
{ test: /\.scss$/,
loaders: ["style", "css", "sass"],
include: path.join(__dirname, 'src')
}
]
}
};
And here is my 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: false,
historyApiFallback: true
}).listen(3000, 'localhost', function (err, result) {
if (err) {
return console.log(err);
}
console.log('Listening at http://csd.local.com:3000/');
});
All I want is, turn off hot reloading in prod.
That's because you're telling webpack to bundle HMRE's client-side scripts together with your app:
'webpack-dev-server/client?http://csd.local.com:3000',
'webpack/hot/only-dev-server',**strong text**
The solution would be to detect wether you're in "development" or "production" environment. To do so you can use "yargs" to parse your cli arguments (it's a webpack dependency so you don't even have to install it), and use the result to dynamically build your config.
var production = require('yargs').argv.p;
See a complete example at http://pastie.org/10895795
Related
I'm running this command to try & generate a production webpack build:
rimraf ./build/* && webpack -p --progress --config webpack.production.js
However, when I open up the build/index.html, it's failing to load a lot of files because the locations are off.
It fails to put the correct location for the bundle.js file. It loads it like this: /bundle.js. However the bundle.js file is actually in the same directory as the index.html file in the build folder so it should load it like this ./bundle.js
If I correct the bundle.js path, it's still putting an incorrect route for the assets:
What's interesting is that my app currently works with the webpack dev server when I run: webpack-dev-server --inline --progress --config webpack.dev.js.
Here is what my current webpack.production.js file looks like:
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'source-map',
devServer: {
historyApiFallback: true, // This will make the server understand "/some-link" routs instead of "/#/some-link"
},
entry: [
'./src/scripts' // This is where Webpack will be looking for the entry index.js file
],
output: {
path: path.join(__dirname, 'build'), // This is used to specify folder for producion bundle
filename: 'bundle.js', // Filename for production bundle
publicPath: '/'
},
resolve: {
modules: [
'node_modules',
'src',
path.resolve(__dirname, 'src/scripts'),
path.resolve(__dirname, 'node_modules')
], // Folders where Webpack is going to look for files to bundle together
extensions: ['.jsx', '.js'] // Extensions that Webpack is going to expect
},
module: {
// Loaders allow you to preprocess files as you require() or “load” them.
// Loaders are kind of like “tasks” in other build tools, and provide a powerful way to handle frontend build steps.
loaders: [
{
test: /\.jsx?$/, // Here we're going to use JS for react components but including JSX in case this extension is preferable
include: [
path.resolve(__dirname, "src"),
],
loader: ['react-hot-loader']
},
{
loader: "babel-loader",
// Skip any files outside of your project's `src` directory
include: [
path.resolve(__dirname, "src"),
],
// Only run `.js` and `.jsx` files through Babel
test: /\.jsx?$/,
// Options to configure babel with
query: {
plugins: ['transform-runtime'],
presets: ['es2015', 'stage-0', 'react'],
}
},
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(), // Webpack will let you know if there are any errors
// Declare global variables
new webpack.ProvidePlugin({
React: 'react',
ReactDOM: 'react-dom',
_: 'lodash'
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html',
hash: true
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
}),
]
}
And just in case, this is what my current webpack.dev.js file looks like:
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'cheap-module-source-map',
devServer: {
historyApiFallback: true, // This will make the server understand "/some-link" routs instead of "/#/some-link"
},
entry: [
'babel-polyfill',
'webpack-dev-server/client?http://127.0.0.1:8080/', // Specify the local server port
'webpack/hot/only-dev-server', // Enable hot reloading
'./src/scripts' // This is where Webpack will be looking for the entry index.js file
],
output: {
path: path.join(__dirname, 'build'), // This is used to specify folder for producion bundle
filename: 'bundle.js', // Filename for production bundle
publicPath: '/'
},
resolve: {
modules: [
'node_modules',
'src',
path.resolve(__dirname, 'src/scripts'),
path.resolve(__dirname, 'node_modules')
], // Folders where Webpack is going to look for files to bundle together
extensions: ['.jsx', '.js'] // Extensions that Webpack is going to expect
},
module: {
// Loaders allow you to preprocess files as you require() or “load” them.
// Loaders are kind of like “tasks” in other build tools, and provide a powerful way to handle frontend build steps.
loaders: [
{
test: /\.jsx?$/, // Here we're going to use JS for react components but including JSX in case this extension is preferable
include: [
path.resolve(__dirname, "src"),
],
loader: ['react-hot-loader']
},
{
loader: "babel-loader",
// Skip any files outside of your project's `src` directory
include: [
path.resolve(__dirname, "src"),
],
// Only run `.js` and `.jsx` files through Babel
test: /\.jsx?$/,
// Options to configure babel with
query: {
plugins: ['transform-runtime', 'transform-decorators-legacy'],
presets: ['es2015', 'stage-0', 'react'],
}
},
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(), // Hot reloading
new webpack.NoEmitOnErrorsPlugin(), // Webpack will let you know if there are any errors
// Declare global variables
new webpack.ProvidePlugin({
React: 'react',
ReactDOM: 'react-dom',
_: 'lodash'
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html',
hash: false
})
]
}
Any ideas what I'm doing wrong?
faced a similar issue. setting output.publicPath: "/" in webpack.dev.js and output.publicPath: "./" in webpack.prod.js, did the trick for me.
Got the same error when running npm run watch, local dev still worked, but after deploying to demo server the app crashed on wrong js-file url.
Cause:
Some changes in my webpack.mix.js started compiling a index.html file that was found by the browser, instead of the app.blade I was using.
Fixed the paths by setting: publicPath: './public/'
(Note that it's a relative path). Also, I removed the generated url by setting inject: false, in the HtmlWebpackPlugin({ section and used the asset('/...') logic.
I am using gulp& webpack to run my reactjs app. At the moment I have an issue that when I delete a file from my app it is still present in the browser chrome devtools. This is my webpack.config.js:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: "./app/app.js",
output: {
path: path.resolve(__dirname, "dist"),
publicPath: "/dist/",
filename: "myapp.js",
sourceMapFilename: "myapp.map"
},
devtool: '#source-map',
module: {
loaders: [{
loader: 'babel',
exclude: /node_modules/
}]
},
devServer: {
inline: true
}
}
Even when I delete the dist folder completely the browser still shows the app? I have turned the cache off for chrome devtools. How can I show the latest version of my app with webpack?
I have a webpack configuration that works perfect in itself. I'm trying to install React Hot Loader together with HMR as suggested, which require webpack-dev-server. Here I cannot get it to work. I can not find where my bundle is located. I want it to be just at localhost:3000.
My webpack.config.js:
var webpack = require('webpack');
var path = require('path');
module.exports = {
watch: true,
devtool: 'eval',
// entry: './src/main.js', This runs just for webpack bundling
entry:[
'webpack-dev-server/client?http:localhost:9000', // WebpackDevServer host and port
'webpack/hot/only-dev-server', // "only" prevents reload on syntax errors
'./src/main.js' // Your appʼs entry point
],
output: {
path: path.resolve(__dirname, 'public', 'dist'),
filename: 'main.js'/*,
publicPath: '/dist/'*/
},
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel-loader?cacheDirectory=true,presets[]=react,presets[]=es2015'],
exclude: function(path) {
var isModule = path.indexOf('node_modules') > -1;
var isJsaudio = path.indexOf('jsaudio') > -1;
if (isModule && !isJsaudio) {
return true;
}
}
}, {
test: /\.json$/,
loader: "json-loader"
}]
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
resolve: {
extensions: ['', '.js', '.json', 'index.js'],
root: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname, 'node_modules', 'jsaudio', 'src')
]
},
target: 'web',
node: {
fs: 'empty',
net: 'empty',
tls: 'empty'
}
};
And the webpack-server.js:
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');
new WebpackDevServer(webpack(config), {
publicPath: '/dist/',
hot: true,
historyApiFallback: true
}).listen(9000, 'localhost', function (err, result) {
if (err) {
return console.log(err);
}
console.log('Listening at http://localhost:9000/');
});
Update: The linked question does not help, especially since it does not even have a confirmed answer.
I would suggest trying out react-hot-loader v3 as the updates to get hot-reloading working have been simplified (in my opinion!).
in webpack then try point now only needs:
entry: {
app: [
'react-hot-loader/patch',
'webpack-hot-middleware/client',
`${SRC}/client-entry.js`
]
}
here is a link to an example app, react-lego that i've created to help people add react-hot-loader v3 to their apps. hope it helps
I have the following webpack configuration file:
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const LiveReloadPlugin = require('webpack-livereload-plugin');
const path = require('path');
module.exports = {
entry: [
'webpack-dev-server/client?http://0.0.0.0:2000', // WebpackDevServer host and port
'webpack/hot/only-dev-server', // "only" prevents reload on syntax errors
'./app/index.tsx'
],
output: {
path: __dirname + '/dist/',
filename: 'bundle.js'
},
devtool: 'source-map',
resolve: {
extensions: ['', '.webpack.js', '.web.js', '.ts', '.tsx', '.js']
},
module: {
loaders: [
{
test: /\.tsx?$/,
loaders: ['react-hot', 'ts'],
include: path.join(__dirname, 'app')
}
],
preLoaders: [
'source-map-loader'.
{test: /\.js$/, loader: 'source-map-loader'}
]
},
plugins: [
new CopyWebpackPlugin([
{from: './app/index.html', to: './dist/index.html'}
]),
new webpack.HotModuleReplacementPlugin()
],
builds.
externals: {
'react': 'React',
'react-dom': 'ReactDOM'
}
};
and here is my server configuration:
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const config = require('./webpack.config');
new WebpackDevServer(webpack(config), {
contentBase: './dist',
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: true,
open: 'http://localhost:2000'
}).listen(2000, 'localhost', function (err, result) {
if (err) {
return console.log(err);
}
console.log('Listening at http://localhost:2000/');
});
I want to be able to access the application from root path: http://localhost:2000 and not http://localhost:2000/dist.
One more thing, is there any way to move all the external dependancies from node_modules to dist with webpack (without the need to include the script tag in the index.html file)?
First of all for set application start point you need to set publicPath to "/" or publicPath: 'http://localhost:2000'
Your second question
Is there any way to move all the external dependancies from node_modules to dist with webpack?
Yes
You can use different file just for external modules and bundle that file. You don't need to take care of index.html file let webpack plugin HtmlWebpackPlugin take care of it.
First step set entry points for your app
entry: {
'vendors': './src/vendors.ts',//your external libraries
'app': './src/main.ts' //your app
}
and out put
output: {
publicPath: '/',
filename: '[name].js'//this will generate two different files app.js, vendor.js
}
How to add HtmlWebpackPlugin?
Add this in you plugins
new HtmlWebpackPlugin({
template: "./src/index.html",
minify:false
})
Now it will place script tags for you
on you server configuration change your public path to
publicPath: '/',
I need bunch of global variables in my reactjs components(example: hostnames, token, api urls, etc) based on the environment. but I don't want to add it to the js individually. I would like to create project.config file to set up prod:{hostname:example.com, api-url:prod, etc} and dev:{hostname:localhost.com, api-url:dev, etc}, I installed loose-envify, but I have to specify for each var.
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://example.com:3000',
'webpack/hot/only-dev-server',
'./src/index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify('production')}),
new ExtractTextPlugin("static/super.css", {
allChunks: true
})
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel'],
include: path.join(__dirname, 'src')
},
{ test: /\.scss$/,
loaders: ["style", "css", "sass"],
include: path.join(__dirname, 'src')
}
]
}
};
Did you try to stringify a config json that can have some common and overridden properties for dev or prod?
Which will be given to the new webpack.DefinePlugin({...})?
I was trying to try something similar and tried following which seems to work fine.
In your webpack config add a DefinePlugin. Following is my webconfig:-
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify(process.env.environment),
}
})
],
Now while compiling use the following commands:-
environment=local webpack (for local)
environment=development webpack(for dev)
environment=production webpack(for prod)
Now if you see I have set 'NODE_ENV' with the cli input so when 'NODE_ENV' is production as value, the webpack automatically minifies your output bundle.
Now say you have API url declared in a file(I had Constants.jsx), so I added following to constants.jsx. So basically you can read the NODE_ENV set in webpack config in this Constants.jsx and import them in your components from where APIS are called by exporting it from here.
const api_url=function(){
let api_url='';
if(process.env.NODE_ENV == 'local'){
api_url= 'http://localhost:8002/api/v0';
}
else if(process.env.NODE_ENV == 'development'){
api_url = 'https://development/api/v0';
}
else if(process.env.NODE_ENV == 'production'){
api_url = 'https://production/api/v0';
}
return api_url;
}
export const url= api_url();
Hope it helped!