I'm working on my app.js in node.js
-- trying to deploy server-side script.
Many fine node.js modules need a require('something');
I use NPM locally, which works for require, as modules are nicely visible in the local node_modules folder structure. but now I'm ready to upload or bundle to a host. I can't run npm on this hosted server.
const Hapi = require('hapi');
will result in
Error: Cannot find module 'hapi'
because I don't know how to copy/install/bundle/ftp files to my host.
Hapi is just an example. Most anything that has a require will need something on the host.
I used webpack to create a server side bundle.js but just sticking bundle.js under /node_modules doesn't do anything.
Most modules have a complex folder structure underneath --- I'm trying to avoid copying a ton of folders and files under /node_modules. Ideally, I want to combine the modules into a bundle.js and have those modules visible to app.js
but I am open to other ideas.
I have not yet tried using webpack to bundle app.js TOGETHER with the various modules. Have you had luck with that approach?
thanks.
I've tried to upload hapi files a folder-ful at a time, reaching a new require('something') error at every step.
'use strict';
const Hapi = require('hapi'); // <-- how can I deploy hapi on my node.js server?
// Create a server with a host and port
const server=Hapi.server({
host:'localhost',
port:8000
});
// Add the route
server.route({
method:'GET',
path:'/hello',
handler:function(request,h) {
return'hello world';
}
});
// Start the server
async function start() {
try {
await server.start();
}
catch (err) {
console.log(err);
process.exit(1);
}
console.log('Server running at:', server.info.uri);
};
start();
one approach that worked: using webpack to bundle the back end js.
thanks to
https://medium.com/code-oil/webpack-javascript-bundling-for-both-front-end-and-back-
end-b95f1b429810
the aha moment... run webpack to create bundle-back.js then
tie bundle-back.js to my node server
**You start your backend server with ‘bundle-back.js’ using:
node bundle-back.js
In other words, include app.js in the bundle with the modules.
Related
I've got a question regarding building applications. I'm using simple VPS with node.js support. Now I do not know how to build my next.js application to production.
I want to deploy my application as static files.
I thought that I should use next build && next export then copy out dir to the server but during this process, I faced some issues - when I change route - everything is okay, but if I refresh the page - the page is not found because the server is looking for this file in directories. So how can I deploy my nextjs application in production mode with VPS server and static files?
I tried one thing which is not working fine probably or I did something wrong.
I added nodejs express server with
const express = require('express');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const app = next({dev});
const router = express.Router();
const handle = app.getRequestHandler();
app.prepare()
.then(() => {
const server = express();
server.get('*', (req, res) => {
return handle(req, res);
});
server.listen(3000, (err) => {
if (err) throw err;
console.log('> Ready on http://localhost:3000');
});
});
and start server with forever library NODE_ENV=production node server.js and it's working fine, but seems this is working in a wrong way - seems it's normal server like in dev mode - so it shouldn't be like that. (I see thunder icon on the right-bottom corner and I see all files which are same as in dev mode).
I want to deploy everything as static files.
Thank you for your help!
After you build and export you need to serve those files somehow. The reason the Express server works is because you are starting a HTTP server to serve the files.
So you need to serve those files either by using a static hosting provider (i.e. Vercel or Amazon S3). Otherwise you should start a server on your linux machine using something like serve to serve it at a port, similar to your Express server serving it as localhost:3000 which is then exposed on your VPS.
I'm trying to set up a Node.js project that uses Express to provide a few backend APIs and serve a SPA built with Vue.js.
When I use the Vue cli to initialize a project, I get e.g. src/main.ts main file and commands npm run serve to run a dev server and watch for changes and npm run build to build a production release.
When I use the Express application generator to create a project, I get ./app.js main file and npm start to start the server and watch for changes.
How can I combine these into a single project, both served by the same Express server? Preferably so that a single command would watch + update changes to both server and client? I want to use Vue single file components and TypeScript, which (probably?) require a build step.
(I don't need dynamic server-side rendering of Vue templates, just the static SPA app provided. I prefer TypeScript, but JavaScript answers are fine as well.)
These will be different for your dev and prod environments...
For development look into concurrently - it basically allows you to create a single script in your package.json to start both the client and server concurrently and will watch for changes etc...
For production, you would need something like this in your app.js:
if (process.env.NODE_ENV === 'production') {
app.use(express.static('client/build'));
const path = require('path');
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}
(The code above assumes that your directory structure has a client folder with a build folder after having run npm run build I'm more familiar with React than Vue... but the logic should be the same...)
I'm trying to deploy a basic nodejs app to OpenShift. I'm not sure how to do it with webpack though. Do I build the bundle.js file locally and just deploy that along with the index.html? I tried that by putting the bundle.js file in a /public directory and pointing to that using a relative path in the index.html, but I get bundle.js not found error. (It works when I run it locally.) What step am I missing? Must I not use relative paths in OpenShift? I find the documentation for OpenShift rather complicated. If anybody out there can break this down I'd much appreciate it!
I did miss a step: You need to add the directory in the server.js like so:
self.initializeServer = function() {
self.createRoutes();
self.app = express.createServer();
self.app.configure(function() {
self.app.use('/public', express.static(__dirname+'/public'));
});
// Add handlers for the app (from the routes).
for (var r in self.routes) {
self.app.get(r, self.routes[r]);
}
};
I am working off of Yeoman's gulp-webapp generator. I have modified my gulp serve task to use my Express server, rather than the default connect server it ships with. My issue is with Livereload functionality. I am trying to simply port the connect-livereload to work with my Express server rather than having to install new dependencies. It's to my understanding that most connect middleware should work fine with Express, so I am assuming connect livereload is compatible with Express 4.
Here are the contents of the relevant tasks in my gulpfile:
gulp.task('express', function() {
var serveStatic = require('serve-static');
var app = require('./server/app');
app.use(require('connect-livereload')({port: 35729}))
.use(serveStatic('.tmp'));
app.listen(3000);
});
gulp.task('watch', ['express'], function () {
$.livereload.listen();
// watch for changes
gulp.watch([
'app/*.ejs',
'.tmp/styles/**/*.css',
'app/scripts/**/*.js',
'app/images/**/*'
]).on('change', $.livereload.changed);
gulp.watch('app/styles/**/*.css', ['styles']);
gulp.watch('bower.json', ['wiredep']);
});
gulp.task('styles', function () {
return gulp.src('app/styles/main.css')
.pipe($.autoprefixer({browsers: ['last 1 version']}))
.pipe(gulp.dest('.tmp/styles'));
});
gulp.task('serve', ['express', 'watch'], function () {
require('opn')('http://localhost:3000');
});
With this simple setup, when I run gulp serve in my cmd everything spins up fine and I can accept requests at http://localhost:3000.
Now if I go and change the body's background color from #fafafa to #f00 in main.css and hit save, my gulp output will respond with main.css was reloaded, as seen in the bottom of this screenshot.
However, my webpage does not update. The background color is still light-grey instead of red.
Is there perhaps a conflict between my express server config and the way gulp handles its files? Is my Express server forcing the use of app/styles/main.css rather than the use of .tmp/styles/main.css? Shouldn't the livereload script handle the injection of the new temporary file?
Thanks for any help.
EDIT:
I was able to move forward a bit by adding livereload.js to the script block of my index file, like so:
<script src="http://localhost:35729/livereload.js"></script>
I am now able to get live changes pushed to the client. Why was this file not getting injected before? How can I ensure this is getting used programatically as opposed to pasting it into my files?
I was able to get past this issue by removing the app.use(require('connect-livereload')({port: 35729})) from my gulpfile, along with a couple of other lines, and having that instantiate in my Express server's app.js file.
My gulpfile's express task now looks like this:
gulp.task('express', function() {
var app = require('./server/app');
app.listen(3000);
});
I added in the connect-livereload just above where I specify my static directory in Express:
if (app.get('env') === 'development') {
app.use(require('connect-livereload')());
}
app.use(express.static(path.join(__dirname, '../app')));
Once I started using this setup, I was getting the livereload.js script injected into my document, and client-side changes are now auto-refreshed just how I wanted.
Hope this helps someone!
I am just trying gulp + angular + browserify app and got a huge browserified file, about 2M. While all it does just require angular and a sample controller.
// setup gulp task
gulp.task('browserify', function() {
gulp.src([util.format('%s/app/main.js', JS_BASE_DIR)])
.pipe(browserify({
insertGlobals: true,
debug: true
}))
// Bundle to a single file
.pipe(concat('bundle.js'))
// Output it to our dist folder
.pipe(gulp.dest(util.format('%s/js/', BUILD_BASE_DIR)));
});
//in the main.js
(function() {
'use strict';
var angular = require('angular');
var indexCtrl = require('./controllers/indexCtrl');
var app = angular.module('wohu.app', []);
app.controller('ctrl', indexCtrl);
})();
angular is installed via
npm install angular
The bundle.js is not minified but it shouldn't be that huge. Wonder what the problem is.
Browserify will include a source map in the bottom of the file which can make it seem HUGE. You can strip this out (and you should) for production. You can use exorcist for this (https://www.npmjs.com/package/exorcist) which pulls the source map into an external file for you and can be hooked up to your build process (I use Grunt but will work for Gulp too).