How to proxy static files with wepack devserver? - vue.js

My publicPath is /static/dist. How i can proxy static/dist to / when my dev server running?
I know i can:
let publicPath;
if (process.env.NODE_BUILD_DEPLOYMENT_PATH) {
// Change process.env.NODE_BUILD_DEPLOYMENT_PATH to match the path to your files
// in production (could be S3, CloudFront, etc.)
publicPath = process.env.NODE_BUILD_DEPLOYMENT_PATH;
} else {
publicPath = 'http://localhost:8099/';
}
But i need proxy. It's for pre-render. After render i need static/dist prefix for all my static files. But when my dev server running i want proxy static/dist to /.
For example: static/dist/js -> /js.

Solution is:
server: {
port: options.devServer.port,
proxy: {
'/static/dist/*': {
target: 'http://localhost:8099',
pathRewrite: {'^/static/dist/': ''}
}
}
},

Related

Proxy requests in a vue.js application

In vue.js to make Cross-Origin Resource Sharing(CORS) requests, we can configure a proxy rule in the vue.config.js file:
vue.config.js:
module.exports = {
//configure webpack-dev-server behavior
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000/',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
}
Considerations:
My Vue client application run on http://localhost:8080, my api server run on http://localhost:3000.
'/api': { target: 'localhost:3000' ........ }
All requests made to /api' from within my vue application will be forwarded to target: 'localhost:3000'
So if there are requests that start with /api resource path, these requests will be proxied to the target address: localhost:3000
for example:
request localhost:8080/api will be proxied to localhost:3000/api
request localhost:8080/api/1 will be proxied to localhost:3000/api/1 and so on.
pathRewrite: { '^/api': '' }
^/api is a regex.
pathRewrite matches /api path in the target address and replaces it (/api) with empty string
for example, proxied request to localhost:3000/api/1 will become localhost:3000/1
changeOrigin: true enable CORS requests
At the end, With the above proxy rule, every requests starts with /api :(localhost:8080/api, localhost:8080/api/1 ..........) will be proxied to localhost:3000, localhost:3000/1 ........
are my considerations correct??
The official documentation is not very clear.
Thanks

Why am I getting ERR_CONNECTION_TIMED_OUT in Vue.js?

After creating a new project with vue cli 3 I get this error:
GET http://192.168.1.13:8080/sockjs-node/info?t=1538257166715 net::ERR_CONNECTION_TIMED_OUT sockjs.js?9be2:1605
Operation system: Windows 10
Create vue.config.js with the following code:
module.exports = {
devServer: {
host: 'localhost'
}
};
https://cli.vuejs.org/config/#devserver
To expand on Alexey's answer...
If your frontend app and the backend API server are not running on the same host, you will need to proxy API requests to the API server during development. This is configurable via the devServer.proxy option in vue.config.js. https://cli.vuejs.org/config/#devserver
module.exports = {
devServer: {
proxy: 'http://localhost:8080'
}
}

Replacing nginx as a reverse-proxy with express

I would like to replace nginx, serving as a reverse proxy, with an node js express application so I can set-up the rules dynamically and have better logging and testing possibilities.
My nginx set-up looks like:
http {
include mime.types;
default_type application/octet-stream;
sendfile off;
keepalive_timeout 65;
gzip on;
server {
listen 8023;
server_name localhost;
sendfile off;
location / {
proxy_pass https://main.app.url.com/;
}
location /module1/v1/ {
client_max_body_size 30000M;
client_body_buffer_size 200000k;
# local backend of module 1
proxy_pass http://localhost:8080/module1/v1/;
}
location /module1/v1/web/ {
# local front end files for module 1
alias /some/local/path/build/dist;
}
location /module2/v1/web/ {
# local front end files for module 1
alias /some/other/local/path/build/dist;
}
}
}
I tried to use the express-http-proxy middleware, but I am struggling with applying the above rules to it. First, I do not fully understand the difference between proxy_pass and alias directives.
Second I tried following:
const express = require('express');
const app = express();
const proxy = require('express-http-proxy')
const path = '/some/local/path/build/dist';
app.all('/module1/v1/web/', proxy(path, {
proxyReqPathResolver: (req) => {
return '';
}
})
);
};
I got an error:
TypeError: Cannot read property 'request' of undefined
at /Users/user1/Dev/local-dev-runner/node_modules/express-http-proxy/app/steps/sendProxyRequest.js:13:29
at new Promise (<anonymous>)
at sendProxyRequest (/Users/user1/Dev/local-dev-runner/node_modules/express-http-proxy/app/steps/sendProxyRequest.js:11:10)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
Although cont path = 'http://www.google.com' returned an valid response.
So this is what I came with:
The trick is to serve local files and to proxy web requests. Apparently, nginx can automatically recognize whether the requests URI is an local or remote path.
I decided to use the nmp packages is-url and express-http-proxy so, the working solution looks like:
const express = require('express');
const app = express();
const isUrl = require('is-url');
const proxy = require('express-http-proxy');
...
/**
* Function adding new redirects to the current server instance. If the target URL is an URL the request will be
* handeled with the express-http-proxy middleware. If the target URL is some local directory the content will be serverd using the express-static middleware.
* #param matchedPath The path (endpoint) for which the redireciton should be configured.
* #param targetUrl The target URL or directory for the redirection.
*/
const setUpRedirect = (matchedPath, targetUrl, name) => {
// Use proxy for Urls
if (isUrl(targetUrl)) {
app.use(matchedPath,
proxy(targetUrl,
{
memoizeHost: false,
limit: '50mb',
proxyReqPathResolver: function(req) {
// I do not have (yet) any clue why I had to do this but it fixed the behavior
return req.originalUrl;
},
}),
)
}
else { // When targetUrl is directory serve static files from there
app.use(matchedPath,
express.static(targetUrl),
);
};
};
...
setUpRedirect('/module1/v1/web/:major([0-9]+).:minor([0-9]+).:bugfix([0-9]+)', '/some/local/path/build/dist';)
setUpRedirect('/module2/v1/web/:major([0-9]+).:minor([0-9]+).:bugfix([0-9]+)', 'http://some/remote/url/';)
server = app.listen(8080);

How to serve data for AJAX calls in a Vue.js-CLI project?

I have a Vue.js CLI project working.
It accesses data via AJAX from localhost port 8080 served by Apache.
After I build the project and copy it to a folder served by Apache, it works fine and can access data via AJAX on that server.
However, during development, since the Vue.js CLI website is being served by Node.js which is serving on a different port (8081), I get a cross-site scripting error) and want to avoid cross-site scripting in general.
What is a way that I could emulate the data being provided, e.g. some kind of server script within the Vue.js-CLI project that would serve mock data on port 8081 for the AJAX calls during the development process, and thus avoid all cross-site scripting issues?
Addendum
In my config/index.js file, I added a proxyTable:
dev: {
env: require("./dev.env"),
port: 8081,
autoOpenBrowser: true,
assetsSubDirectory: "static",
assetsPublicPath: "/",
proxyTable: {
"/api": {
target: "http://localhost/data.php",
changeOrigin: true
}
},
And now I make my AJAX call like this:
axios({
method: 'post',
url: '/api',
data: {
smartTaskIdCode: 'activityReport',
yearMonth: '2017-09',
pathRewrite: {
"^/api": ""
}
}
But now I see in my JavaScript console:
Error: Request failed with status code 404
Addendum 2
Apparent axios has a problem with rerouting, so I tried it with vue-resource but this code is showing an error:
var data = {
smartTaskIdCode: 'pageActivityByMonth',
yearMonth: '2017-09'
}
this.$http.post('/api', data).then(response => {
this.pageStatus = 'displaying';
this.activity = response.data['activity'];
console.log(this.activity);
}, response => {
this.pageStatus = 'displaying';
console.log('there was an error');
});
The webpack template has its own documentation, and it has a chapter about API proxying during development:
http://vuejs-templates.github.io/webpack/proxy.html
If you use that, it means that you will request your data from the node server during development (and the node server will proxy< the request to your real backend), and the real backend directly in production, so you will have to use different hostnames in each environment.
For that, you can define an env variable in /config/dev.env.js & /config.prod.env.js

grunt qunit in conjunction with grunt server

While running grunt server for developing, How can I separately use the grunt qunit task to run the tests.
While trying to pass ["test/**/*.html"] to the all property, but that fails to run and returns (Warning: 0/0 assertions ran (0ms) Use)
It looks like, it doesn't fire off a phantomjs instance and doesn't find these pates.
So I tried the following
grunt.initConfig({
....
qunit: {
all: {
options: {
urls: ['http://localhost:<%= connect.options.port %>/test/tests/foo.html']
}
}
}
....
});
It only works if when manually include all test html pages (like in the example).
The problem is
My Question is, can grunt qUnit work properly even while using grunt server.
And how can i have ["test/**/*.html"] syntax work correctly. I am sure there must be a better way this should work!
Also, how can use grunt.file.expand be utilized to programmatically add matching files to run in the grunt qunit task.
I've done something like this:
grunt.initConfig({
...
'qunit': {
'files': ['test/**/*.html']
}
...
});
...
// Wrap the qunit task
grunt.renameTask('qunit', 'contrib-qunit');
grunt.registerTask('qunit', function(host, protocol) {
host = host || 'localhost';
protocol = protocol || 'http';
// Turn qunit.files into urls for conrib-qunit
var urls = grunt.util._.map(grunt.file.expand(grunt.config.get('qunit.files')), function(file) {
return protocol + '://' + host + '/' + file;
});
var config = { 'options': { 'urls' : urls } };
grunt.config.set('contrib-qunit.all', config);
grunt.task.run('contrib-qunit');
});