Closed yantakus closed 9 years ago
I am not sure what are you trying to do and what is happening. Can you explain it wider?
(Using webpack with gulp seems like a weird idea to me, though)
I'm new to webpack. I used gulp with browserify before, then switched to webpack.
If you want to use some build system for ES6 with gulp, then use browserify/systemjs+babel/traceur. Webpack is quite more then build system, it should work standalone, because in a way you're trying to use it, you're missing some important things like caching, etc.
So, stay with browserify if you want to use gulp. Or, If you want to switch, google for webpack+babel (or any other loader) tutorials.
Along this same topic, seems that hot reload does not work when using Browsersync. The page will reload instead.
My assumption is that something in Browsersync triggers a reload when Webpack pushes a change and I assume this problem is in Browsersync itself and not this plugin.
I have now looked at this more closely and found the problem on why the page reloads when it should just hot swap the code and it's with this plugin.
if (self.browserSyncIsRunning) {
self.browserSync.reload();
} else {
https://github.com/Va1/browser-sync-webpack-plugin/blob/master/index.js#L23
What does this code do, why is it needed?
Obviously, if webpack is in watch mode and browserSync is running, the page is being reloaded after compilation is finished (on webpack "done" event). This is what those lines are about.
I still not quite understand what are you guys trying to do. Can you @DLMR please give me detailed description? I can not get what approach you go with so you don't need reload after compilation (smth connected with this maybe?).
Also, feel free to submit a PR if you know how to fix this.
Thank you.
I'm building a React application that is using React Hot Loader during development along with hot reload of CSS using Webpack. It's related to what you linked to.
What this does is that CSS and React components can be updated in the browser without needing to reload the page.
How is your use case where this is needed, do you use Webpack Dev Server?
I'm not entirely sure what the best approach is here but I see two options.
That line is removed completely and instead the developer uses Webpack Dev Server to do the updates as described here http://webpack.github.io/docs/hot-module-replacement-with-webpack.html#what-can-i-do-with-it
webpack/hot/dev-server reloads the entire page after the HMR update fails. If you want to reload the page on your own, you can add webpack/hot/only-dev-server to the entry point instead.
I can gladly create a PR for this, I just need to know what you think is the best solution to handle this.
Aha, hm. I think, now I see.
The thing is - browserSync here is serving stuff instead Webpack Dev Server. So, yeah, since those things about code update without page reload require Webpack Dev Server (as far as I know), they won't work.
Regarding proposed solutions:
Removing browserSync from the plugin scenario is wrong imo, because the idea of this plugin was to use browserSync with webpack. Adding Hot Loader/Hot Module Replacement tricks support is a nice idea as long as browserSync serve and reload functionality is the main objective of the plugin.
So far, I can't see an easy way to do this. Probably, I just lack the understanding of Hot Loader/Hot Module Replacement stuff and should try 'em out myself.
What I want from Browsersync is that it syncs the state between all browsers as well debugging tools. The reloading part is provided by Webpack Dev Server as you say.
I would do the following change to make my use case work, and potentially also work for @web2style.
if (self.browserSyncIsRunning && self.options.reload) {
self.browserSync.reload();
} else {
self.browserSync(self.options.browsersyncOptions);
https://github.com/Va1/browser-sync-webpack-plugin/blob/master/index.js#L22-L25
It would then be included in the following way.
var BrowserSyncPlugin = require('browser-sync-webpack-plugin');
module.exports = {
...
plugins: [
new BrowserSyncPlugin({
reload: false,
browsersyncOptions: {
host: 'localhost',
port: 3000,
server: { baseDir: ['public'] }
}
})
]
}
This is just a example and not a completed solution.
This change would require bumping the version number with a major. If this is something one really wants to avoid a backwards compatible variant of this is also possible.
An update around this would be great when you have time @Va1
@DLMR Hey, sorry that I did not give any update, but I am kinda on vacation during last days. I am going to finally deal with this issue on Wednesday when I am back.
Sounds great! :+1:
OK, so!
if (self.browserSyncIsRunning && self.options.reload) {
self.browserSync.reload();
} else {
self.browserSync(self.options.browsersyncOptions);
Regarding this piece of code. If I change stuff this way, the use case you are approaching would work fine? @DLMR
I have not tested that approach but I do believe so! However I do think we also need change the else
to an else if
.
Like this:
if (self.browserSyncIsRunning && self.options.reload) {
self.browserSync.reload();
} else if (!self.browserSyncIsRunning) {
self.browserSync(self.options.browsersyncOptions);
So we not initiate it more than once. Forgot that in my example previously. And as I said before, this change would bring the version up to 1.0.0 to follow SemVer correctly.
OK, makes sense. I'll do this way now.
Done. Please, take a look and test it with your use case.
@DLMR, could you please share your webpack config? I'd like to compare it with my own.
@Va1 Works like a charm, thanks for the update! :+1:
@web2style I'm unfortunately not allowed to share directly since it is for a project at work. Does it still not work for you, even with the new version? Maybe you could ask a more direct question and I will try to answer.
@DLMR You're welcome! Thanks for the assistance.
I am not closing the issue because @web2style is still having troubles.
Reopening by @web2style request.
@DLMR, do you use browserSync with webpack-dev-server? I get EADDRINUSE error when I try. I'm using both of them at 3000 port, this is the reason I think. But it doesn't work at all if I change browserSync's port (an empty page opens without bundle.js, etc.).
Here is my config:
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var path = require('path');
var BrowserSyncPlugin = require('browser-sync-webpack-plugin');
var devFlagPlugin = new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false'))
});
var AUTOPREFIXER_BROWSERS = '"ie >= 10","ie_mob >= 10","ff >= 30","chrome >= 34","safari >= 7","opera >= 23","ios >= 7","android >= 4.4","bb >= 10"';
var entry = [
'./app/scripts/index.jsx',
'./app/scss/all.scss',
];
if (process.env.DEV) {
entry = [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
].concat(entry);
}
var plugins = [
];
if (process.env.DEV) {
plugins = plugins.concat([
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
devFlagPlugin,
new BrowserSyncPlugin({
host: 'localhost',
port: 8000,
server: { baseDir: ['app'] }
})
]);
}
config = {
devtool: 'source-map',
entry: entry,
output: {
path: __dirname + '/build',
filename: 'bundle.js',
hot: true,
},
plugins: plugins,
module: {
loaders: [
{
test: /\.jsx?$/,
loaders: ['react-hot', 'babel?stage=0'],
exclude: /node_modules/,
},
{
test: /\.json?$/,
loaders: ['json-loader']
},
{
test: /\.css$/,
loaders: [
"style-loader",
"css-loader?sourceMap",
"autoprefixer-loader?{browsers:[" + AUTOPREFIXER_BROWSERS + "]}",
],
},
{
test: /\.scss$/,
loaders: [
"style-loader",
"css-loader?sourceMap",
"autoprefixer-loader?{browsers:[" + AUTOPREFIXER_BROWSERS + "]}",
"sass-loader?sourceMap",
],
},
{
test: /\.png$/,
loader: "url-loader?limit=100000",
},
{
test: /\.jpg$/,
loader: "url-loader?limit=100000",
},
{
test: /\.svg$/,
loader: "url-loader?limit=100000",
},
]
},
resolve: {
root: [
path.resolve(__dirname, 'app/scripts'),
],
extensions: ['', '.js', '.jsx', '.json', '.scss'],
},
devServer: {
contentBase: './app',
},
};
module.exports = config;
@web2style We proxy the webpack server, it seems to work fine
new BrowserSyncPlugin(
{
host: 'localhost',
port: 3050, // or something else not in use
proxy: 'http://0.0.0.0:3030/' // location of webpack-dev-server
}, {
reload: false // You can drop this if you want, of course
}
);
@web2style Yes, it works fine and I'm using 3000 for BrowserSync.
new BrowserSyncPlugin({
host: 'localhost',
port: 3000,
logFileChanges: false
}, {
reload: false
});
However BrowserSync starts on port 3002 with the GUI at 3003 and Koa runs on 3000 with Webpack Dev Server runs on 3001. A bit strange that I'm not getting the same error as you...
If it still does not work for you I can take another look at it, sorry for the late reply.
This one is resolved, I assume. Thanks everyone.
Hi @Va1
I can't get it to work - and I actually don't see how it possible since webpack serves from memory and not the file system.
Webpack serves well on localhost:8080
but BrowserSyncPlugin on localhost:3000
returns 404.
This is the config I use with BUILD = false
and TEST = false
:
// Modules
var webpack = require('webpack');
var autoprefixer = require('autoprefixer');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var BrowserSyncPlugin = require('browser-sync-webpack-plugin');
module.exports = function makeWebpackConfig (options) {
/**
* Environment type
* BUILD is for generating minified builds
* TEST is for generating test builds
*/
var BUILD = !!options.BUILD;
var TEST = !!options.TEST;
/**
* Config
* Reference: http://webpack.github.io/docs/configuration.html
* This is the object where all configuration gets set
*/
var config = {};
/**
* Entry
* Reference: http://webpack.github.io/docs/configuration.html#entry
* Should be an empty object if it's generating a test build
* Karma will set this when it's a test build
*/
if (TEST) {
config.entry = {}
} else {
config.entry = {
app: './src/app.js'
}
}
/**
* Output
* Reference: http://webpack.github.io/docs/configuration.html#output
* Should be an empty object if it's generating a test build
* Karma will handle setting it up for you when it's a test build
*/
if (TEST) {
config.output = {}
} else {
config.output = {
// Absolute output directory
path: __dirname + '/public',
// Output path from the view of the page
// Uses webpack-dev-server in development
publicPath: BUILD ? '/' : 'http://localhost:8080/',
// Filename for entry points
// Only adds hash in build mode
filename: BUILD ? '[name].[hash].js' : '[name].bundle.js',
// Filename for non-entry points
// Only adds hash in build mode
chunkFilename: BUILD ? '[name].[hash].js' : '[name].bundle.js'
}
}
/**
* Devtool
* Reference: http://webpack.github.io/docs/configuration.html#devtool
* Type of sourcemap to use per build type
*/
if (TEST) {
config.devtool = 'inline-source-map';
} else if (BUILD) {
config.devtool = 'source-map';
} else {
config.devtool = 'source-map'; //'eval';
}
/**
* Loaders
* Reference: http://webpack.github.io/docs/configuration.html#module-loaders
* List: http://webpack.github.io/docs/list-of-loaders.html
* This handles most of the magic responsible for converting modules
*/
// Initialize module
config.module = {
preLoaders: [],
loaders: [{
// JS LOADER
// Reference: https://github.com/babel/babel-loader
// Transpile .js files using babel-loader
// Compiles ES6 and ES7 into ES5 code
test: /\.js$/,
loader: 'babel',
exclude: /(node_modules|bower_components)/
}, {
// ASSET LOADER
// Reference: https://github.com/webpack/file-loader
// Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to output
// Rename the file using the asset hash
// Pass along the updated reference to your code
// You can add here any file extension you want to get copied to your output
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$/,
loader: 'file'
}, {
// HTML LOADER
// Reference: https://github.com/webpack/raw-loader
// Allow loading html through js
test: /\.html$/,
loader: 'raw'
}]
};
// ISPARTA LOADER
// Reference: https://github.com/ColCh/isparta-instrumenter-loader
// Instrument JS files with Isparta for subsequent code coverage reporting
// Skips node_modules and files that end with .test.js
if (TEST) {
config.module.preLoaders.push({
test: /\.js$/,
exclude: [
/(node_modules|bower_components)/,
/\.test\.js$/
],
loader: 'isparta-instrumenter'
})
}
// CSS LOADER
// Reference: https://github.com/webpack/css-loader
// Allow loading css through js
//
// Reference: https://github.com/postcss/postcss-loader
// Postprocess your css with PostCSS plugins
var cssLoader = {
test: /\.css$/,
// Reference: https://github.com/webpack/extract-text-webpack-plugin
// Extract css files in production builds
//
// Reference: https://github.com/webpack/style-loader
// Use style-loader in development for hot-loading
loader: ExtractTextPlugin.extract('style', 'css?sourceMap!postcss')
};
// Skip loading css in test mode
if (TEST) {
// Reference: https://github.com/webpack/null-loader
// Return an empty module
cssLoader.loader = 'null'
}
// Add cssLoader to the loader list
config.module.loaders.push(cssLoader);
/**
* PostCSS
* Reference: https://github.com/postcss/autoprefixer-core
* Add vendor prefixes to your css
*/
config.postcss = [
autoprefixer({
browsers: ['last 2 version']
})
];
/**
* Plugins
* Reference: http://webpack.github.io/docs/configuration.html#plugins
* List: http://webpack.github.io/docs/list-of-plugins.html
*/
config.plugins = [
// Reference: https://github.com/webpack/extract-text-webpack-plugin
// Extract css files
// Disabled when in test mode or not in build mode
new ExtractTextPlugin('[name].[hash].css', {
disable: !BUILD || TEST
})
];
// Skip rendering index.html in test mode
if (!TEST) {
// Reference: https://github.com/ampedandwired/html-webpack-plugin
// Render index.html
config.plugins.push(
new HtmlWebpackPlugin({
template: './src/index.html',
inject: 'body'
})
)
}
// Add build specific plugins
if (BUILD) {
config.plugins.push(
// Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
// Only emit files when there are no errors
new webpack.NoErrorsPlugin(),
// Reference: http://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
// Dedupe modules in the output
new webpack.optimize.DedupePlugin(),
// Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
// Minify all javascript, switch loaders to minimizing mode
new webpack.optimize.UglifyJsPlugin()
)
}
// Add dev specific plugins
if (!TEST && !BUILD) {
config.plugins.push(
// Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
// Only emit files when there are no errors
new BrowserSyncPlugin({
host: 'localhost',
port: 3000,
server: { baseDir: ['public'] }
})
)
}
/**
* Dev server configuration
* Reference: http://webpack.github.io/docs/configuration.html#devserver
* Reference: http://webpack.github.io/docs/webpack-dev-server.html
*/
config.devServer = {
contentBase: './public',
stats: {
modules: false,
cached: false,
colors: true,
chunk: false
}
};
return config;
};
after passing several time I found that, when you select file you need to give extension .css or .js etc. to work browsersync properly, and it worked with reload : false
new BrowserSyncPlugin(
// BS Options
{
files: ['public/css/**/*.css', '**/*.php', '!resources/assets/**/*'],
proxy: "http://chatapp.dev",
port: 3000
},
// plugin options
{
// prevent BrowserSync from reloading the page
// and let Webpack Dev Server take care of this
reload: false
}
)
Here is my gulpfile:
Browsersync starts, but it doesn't inject CSS, the page just reloads.
Did I do smth wrong?