webpack-dev-server 4 with ngrok - javascript

In older versions of webpack-dev-server (i.e 3 and below), we can simply expose webpack and webpack-dev-server's websock using ngrok tunnels by setting the value of devServer.public, as shown below:
// WDS v3
devServer: {
public: 'react-tunnel.ngrok.io',
// other webpack devServer config
}
This is particularly useful in developing apps in frameworks like React, as we can create a secure tunnel from the local machine, to a public URL to allow the web application to be easily tested.
However, in the latest versions of webpack-dev-server (v4), the public property has been replaced in favour client.webSocketURL object (source). I am unable to find any resources to make this work with ngrok, as the websockets are not properly connected when I point the devServer.client.webSocketURL.hostname to my ngrok tunnel.
// WDS v4
devServer: {
client: {
webSocketURL: {
hostname: 'react-tunnel.ngrok.io',
},
},
}
The above implementation is only a partial solution, as the websocket was not properly set up, thus it does not hot-reload.
Does anyone know what is the solution to this, such that ngrok will once again work well with webpack-dev-server?

You also need to provide port and protocol to make it work.
For example,
devServer: {
client: {
webSocketURL: {
hostname: 'react-tunnel.ngrok.io',
port: 0,
protocol: 'wss',
},
},
}
With above settings, your website may work in ngrok tunnel, but wont work in localhost.
To connect to the web socket regardless of url, you can set webSocketURL to auto://0.0.0.0:0/ws, which uses protocol, hostname, and port from browser. doc
This should fix hot-reloading problem as well.
devServer: {
client: {
webSocketURL: 'auto://0.0.0.0:0/ws'
},
}

I'm not sure if this is the complete solution, but this works for me. You can put the hostname as localhost and some port as your needs. After running the dev-server, you could expose the port using ngrok http {port}.
Example: ngrok http 3000.

I also stumbled onto the same issue and couldn't resolve it using any of the methods mentioned above. Took a little while before I stumbled across this simple solution, but this seems to work. Hope it helps:
devServer: {
allowedHosts: [".ngrok.io"],
},

Related

how to resolve conflict of webpack in specific port (vue.js)

I use npm webpack in vue.js project.
npm run dev
In webpack.dev.conf.js, I use proxy table.
proxy: {
"/api": {
target:"http://localhost:5000",
changeOrigin: true
}
},
It worked well, but now I can't.
Once I changed proxy url to https://my-domain.com, and it never works.
I rolled back to "http://localhost:5000", but error message says proxy can't access to https://my-domain.com.
For reference, I ran it again(npm run dev) whenever I changed it.
And it doesn't work at 8080 port, but it works well at 8082 port. How can I resolve conflict of webpack for specific port?

nuxt.js - unable to define host and port

nuxt.js always defaults to localhost despite host being defined as frontend.gradez.loc in nuxt.config.js
Contents of nuxt.config.js:
server: {
host: 'frontend.gradez.loc',
port: 3000
},
Contents of package.json:
"config": {
"nuxt": {
"host": "frontend.gradez.loc",
"port": "3000"
}
}
nuxt launch script as dev:
"dev": "nuxt --hostname frontend.gradez.loc --port 3000",
For some odd reason when starting the development script it always defaults to: Listening on: http://localhost:3000/
I tried to do exactly the same on react and the only thing I had to do was create a .env file and inside it I added host=frontend.gradez.loc and it worked just like that.
To create your server, under the hood Nuxt uses Node's http.createServer, then calls listen({ host, port }) on that server.
So if on your local machine the hostname frontend.gradez.loc is mapped to 127.0.0.1, which I assume is the case, then that server is running on the IP 127.0.0.1.
To create the url you see printed in Listening on..., Nuxt gets the IP of that underlying server, and maps it back to a hostname string. It statically maps the IP 127.0.0.1 to the string 'localhost', so no matter what host you configure, if it maps to 127.0.0.1 then Nuxt will always map that to localhost in that url. The code that does this is here.
There's nothing incorrect per-se about reporting the server is running on localhost:3000 rather than frontend.gradez.loc:3000. It's literally true, in a networking sense, because both ultimately point to 127.0.0.1:3000. So nothing is broken here from the perspective of the dev server, it's working as designed.
I'm not sure if you have anything automatically loading that url in the browser when you start the server - if so I can see how this is inconvenient from the perspective of other things in your workflow coupled to that hostname such as cookies, proxy servers etc - but if you manually type frontend.gradez.loc:3000 into your browser everything will just work.

Browsersync on remote development VM will not work in local browser

Thank you so much for taking the time to check out my little conundrum. This is my first StackOverflow question, so please forgive me if I accidentally leave out something important (I'll add any information that you require if you just let me know).
My issue is this: I have a personal development VM that I use to house all of my application code, including the application's server. I use PuTTY to connect to my development VM, and I forward the port that the vert.x application server runs on (which is 7443) to my localhost. Thus, when I connect to the server, I just enter:
https://localhost:7443
in the URL bar of the browser on my local machine. I also use Gulp.js to build the UI component and watch my files for changes. Currently, the gulp watch task just rebuilds Javascript and CSS bundle files that I link to in my index.html file, and I manually reload the browser whenever the bundles are done rebuilding. I recently stumbled upon Browsersync when I was researching live-reload technologies for the browser, and it looks awesome, but I cannot get it to work with my development setup.
Here is my gulp watch task:
const browserSync = require("browser-sync").create("browser-sync-server");
gulp.task("watch", () => {
console.info("=== Initializing BrowserSync Server ===");
browserSync.init({
proxy: "localhost:7443", // This is my dev server running on port 7443
open: false // I do not want a new browser to open up when I start BrowserSync
});
console.info("=== Listening for changes to reload === ");
const jsWatcher = gulp.watch(
myJsFiles,
{ awaitWriteFinish: true },
["reload-js"]
);
const templateWatcher = gulp.watch(
myHtmlFiles,
{ awaitWriteFinish: true },
["reload-templates"]
);
const lessWatcher = gulp.watch(
myLessFiles,
{ awaitWriteFinish: true },
["reload-less"]
);
});
When I start the watch task, in the console I see:
Starting 'watch'...
=== Initializing BrowserSync Server ===
=== Listening for changes to reload ===
Finished 'watch' after 126 ms
[Browsersync] Proxying: http://localhost:7443
[Browsersync] Access URLs:
Local: http://localhost:3000
External: http://192.168.1.11:3000
UI: http://localhost:3001
UI External: http://192.168.1.11:3001
I also forward ports 3000 and 3001 to my local machine so that I can access those endpoints in my browser.
I can get to the Browsersync UI just fine at port 3001 over HTTP, but when I click on the "NEW TAB" button under Local, a new tab pops, but the server never loads. It just spins and spins, until finally I get an error in Chrome that says "No data received". Does anyone have any ideas as to what the problem could be? My guess is that is has something to do with the fact that my team's application uses HTTPS for browser access, and that Browsersync needs some further configuration to work with HTTPS, but I do not know how to go about doing this.
Thank you all so much for helping me out! Please let me know if I can provide you all with any more information.
-- Tom
Edit 5/23/18:
I used openssl to generate localhost key and cert files for my development VM, and added them to my configuration for BrowserSync in my gulpfile.js.
Here is my modified config:
const proxy = require("http-proxy-middleware");
...
browserSync.init({
ui: {
port: 8080
},
https: {
key: "./conf/browsersync/localhost.key",
cert: "./conf/browsersync/localhost.crt",
},
server: {
baseDir: "./",
index: "index.html"
},
middleware: [
proxy("/api", {
target: "https://localhost:7443",
secure: false, // Do not validate SSL certs
changeOrigin: true, // Seems to be a highly recommended setting
xfwd: true,
prependPath: true, // Ensure that the API calls are prepended with the target URL
logLevel: "debug" // So that I can see verbose console output
})
],
port: 3000,
open: false
});
This has definitely gotten me farther, but it is still not quite right. Now, when I hit https://localhost:3000 in my browser, I am taken to the index page of my web application, but none of the asynchronous API calls are getting resolved correctly. In the console where I am running the gulp watch task, I see a lot of errors from HPM (the html-proxy-middleware software). Here is one example:
[HPM] Error occurred while trying to proxy request /api/settings/ from localhost:3000 to https://localhost:7443 (ECONNRESET) (https://nodejs.org/api/errors.html#errors_common_system_errors)
Also, if I open the Javascript console in my browser window for https://localhost:3000 (the BrowserSync session), I can see lots of 504 errors (Gateway Timeout). Any ideas? Thanks again so much for your time.
-- Tom
First of all, I agree, browsersync is awesome.
[Browsersync] Proxying: http://localhost:7443 Note the http instead of https. This cannot work. In your line proxy: "localhost:7443" you are not telling anything about the protocol. Try with a https:// prefix. Most likely you'll also need the "secure: false" or similar if your development server uses a self-signed certificate. The proxy will have to accept this certificate, not your browser.
If your backend also uses secure-only cookies, you'll have to use https on the browsersync and client side too, or your browser will refuse the secure cookie. Here is my working development config (Gruntfile syntax) doing that:
var proxy = require('http-proxy-middleware');
[...]
options: {
port: 3000,
server: {
baseDir: './',
index: '_index.html'
},
// redirect all calls to /api to the backend
https: true, // required for secure cookie to work
middleware: [proxy('/api', {
target: "https://external.backend.server",
secure: false, // required if server uses self-signed certificate
changeOrigin: true,
xfwd: true // add X-Forwarded-* headers
})],
watchTask: true,
logConnections: true,
scrollRestoreTechnique: 'cookie',
reloadDebounce: 500,
ghostMode: false
}

How to get access to webpack-dev-server from devices in local network?

There is some webpack dev server config (it's part of the whole config):
config.devServer = {
contentBase: './' + (options.publicFolder ? options.publicFolder : 'public'),
stats: {
modules: false,
cached: false,
colors: true,
chunk: false
},
proxy: [{
path: /^\/api\/(.*)/,
target: options.proxyApiTarget,
rewrite: rewriteUrl('/$1'),
changeOrigin: true
}]
};
function rewriteUrl(replacePath) {
return function (req, opt) { // gets called with request and proxy object
var queryIndex = req.url.indexOf('?');
var query = queryIndex >= 0 ? req.url.substr(queryIndex) : "";
req.url = req.path.replace(opt.path, replacePath) + query;
console.log("rewriting ", req.originalUrl, req.url);
};
}
I execute webpack with the following command:
node node_modules/webpack-dev-server/bin/webpack-dev-server.js --host 0.0.0.0 --history-api-fallback --debug --inline --progress --config config/webpack.app.dev.js
I can get access to dev server using http://localhost:8080 on my local machine, but I also want to get access to my server from my mobile, tablet (they are in the same Wi-Fi network).
How can I enable it? Thanks!
(If you're on a Mac and network like mine.)
Run webpack-dev-server with --host 0.0.0.0 — this lets the server listen for requests from the network, not just localhost.
Find your computer's address on the network. In terminal, type ifconfig and look for the en1 section or the one with something like inet 192.168.1.111
In your mobile device on the same network, visit http://192.168.1.111:8080 and enjoy hot reloading dev bliss.
You can set your ip address directly in webpack config file:
devServer: {
host: '0.0.0.0',//your ip address
port: 8080,
disableHostCheck: true,
...
}
It may not be the perfect solution but I think you can use ngrok for this.
Ngrok can help you expose a local web server to the internet.
You can point ngrok at your local dev server and then configure your app to use the ngrok URL.
e.g Suppose your server is running on port 8080. You can use ngrok to expose that to outer world via running
./ngrok http 8080
Good thing about ngrok is that it provides a more secure https version of exposed url which you give to any other person in the world to test or show your work.
Also it has lots of customization available in the command such as set a user friendly hostname instead of random string in the exposed url and lots of other thing.
If you just want to open your website to check mobile responsiveness you should go for browersync.
For me, what helped eventually was adding this to the webpack-dev-server config:
new webpackDev(webpack(config), {
public: require('os').hostname().toLowerCase() + ':3000'
...
})
and then also changing babel's webpack.config.js file:
module.exports = {
entry: [
'webpack-dev-server/client?http://' + require('os').hostname().toLowerCase() + ':3000',
...
]
...
}
Now just get your computer hostname (hostname on OSX's terminal), add the port you defined, and you're good to go on mobile.
Compared to ngrok.io, this solution will also let you use react's hot reloading module on mobile.
I could not comment in order to add additional information to forresto's answer, but here in the future (2019) you'll need to add a --public flag due to a security vulnerability with --host 0.0.0.0 alone. Check out this comment for more details.
In order to avoid "responding to other answers" as an answer here's forresto's advice plus the additional details you'll need to make this work:
Add both:
--host 0.0.0.0
and
--public <your-host>:<port>
where your-host is the hostname (for me it is (name)s-macbook-pro.local)) and port is whatever port you're trying to access (again, for me it's 8081).
So here's what my package.json looks like:
"scripts": {
...
"start:webpack": "node_modules/.bin/webpack-dev-server --host 0.0.0.0 --public <name>s-macbook-pro.local:8081",
...
},
I found this thread while searching for a solution that would satisfy the following requirements:
automatically open URL using the public IP. For example, http://192.168.86.173:8080. So it could be copied from the browser and sent to another device in the network.
dev server is available in the local network.
Webpack 4
devServer: {
host: '0.0.0.0',
useLocalIp: true,
}
Webpack 5
devServer: {
host: 'local-ip',
}
With webpack-dev-server v4.0.0+ you need
devServer: {
host: '0.0.0.0',
port: 8030,
allowedHosts: ['all'] // or use 'auto' for slight more security
}
If you tried everything stated in the other answers here, without success... also make sure there's no firewall running on you machine(s) or open the needed ports on it.

Run sails.js on a specific IP address during development

I am new to sails.js and trying to develop a simple app on a remote sandbox server. When I do 'sails lift' to test running the app, I cannot access it by 'localhost'.
I am wondering what's the right way of running sails on a specific IP during development. I tried 'sails lift --ip xxx.xxx.xx.xx', but it does not work, and the documentation on this seems lacking.
Does anyone know how to run sails.js on an IP without needing deployment?
You need to use local.js in config directoty to add this config:
{
host: your_ip,
port: your_port
}
Or add port and host in config/env/development.js
For anyone looking for Sails 1.x, as host is deprecated in new version, so new name for specifying host is, "explicitHost".
So one can mention in config/env/development.js
explicitHost: 'your_ip_Address'
port: 'your_port_number'
For more, sails documentation for these kind of settings

Categories