I am making an express web app and I am unable to import a javascript file.
In board.js, I have a line const utility = require('./utility');. This statement gives an error: ReferenceError: require is not defined.
VSCode suggests to convert const utility = require('./utility'); to an ES6 module. The result after accepting that suggestion is: import { generateRandomData } from './utility';.
If I do this, the previous error goes away but a new error appears SyntaxError: import declarations may only appear at top level of a module.
This is the folder structure of the project:
server.js:
const express = require("express");
const app = express();
const path = require('path');
const PORT = process.env.PORT || 5000
app.listen(PORT, () => {
console.log("server started")
});
app.use(express.static(path.join(__dirname + '/public')))
app.get('/', (req,res) => {
res.sendFile(__dirname + "/index.html")
});
utility.js:
const hello = () => {
console.log('hello');
}
module.exports.hello = hello;
How else am I supposed to import javascript files in board.js?
Your public directory is made static via express.static in your server.js. Therefore, calling a public file from client-side will not pass by express but by the client's browser.
If your JS is played directly within a browser, instead of require you should use import and export.
<script src="utility.js"></script>
I added this line in index.html and it solved the problem.
Edit: Sorry, I thought I pasted the line.
Related
I'm writing a simple nodejs app that I want to pack using pkg. The app will give to the user the ability to upload some files that after are processed from the embedded server script will be sended back to the vue client app.As I know, I need to add multipart/form-data to the vuejs form?Since I'm new to express, what's the best way to handle multiple files upload?Since pkg will pack the app to work with a virtual filesystem, how I can create a temp dir in the folder where the app is executed when the files are uploaded?I've seen the provided example on the express website but it uses some dependencies and I don't want to have too many libraries for my project.
This is the basic code I have at the moment
const http = require('http');
const express = require('express');
const path = require('path');
const app = express();
class eCrypt {
constructor(){
this.app = app;
this.assets = path.format({dir: __dirname, base: 'assets/'})
}
async init(){
this.app.use(express.static())
this.app.use(express.json());
this.app.use(express.urlencoded({
extended: true
}));
this.app.get('/', (req, res) => {
res.sendFile('index.html', {root: this.assets});
});
this.app.post('/compressEncrypt', (req, res) => {
//here I need to manage uploaded files
});
}
async encryptAndCompress(data){
//in this method I'm processing the files
}
}
this is my first question here. I need some help with my code structure. My api in node with express have to do the following:
receipt GET /api/file/{filename}
return the file content, its could be a big one (a few GB).
For now, I could get the files with streams, but I don't the best practice to handle error in this case.
'use strict';
const fs = require('fs');
const express = require('express');
const app = express();
const path = require('path');
const filePath = path.join(__dirname, `../file`);
console.log(filePath)
app.get('/api/:filename', (req, res) => {
let filename = req.params.filename
const streamFile = fs.createReadStream(`${filePath}/${filename}`);
streamFile.pipe(res);
} );
module.exports = app;
Should I make another dir, maybe 'modules', and there code an async function to read and pipe the files, and call the function from app.get in routes dir ?
Remember that Express is an "un-opinionated, minimalist web framework for Node.js applications", unopinionated means that it doesn't decide for you a lot of aspects of what tool you use for each specific task, and that is the main difference with another frameworks like Rails. Said that, you could use the classical and and old try and catch, in this case around your I/O operation. A module is a way to mantain separation of concerns and it's a way to organize your code so you can fastly identify what is the part of your code that is causing a malfunction. So in this case i don't consider it necessary because your router's callback is doing one thing and that is ok.
app.get('/api/:filename', (req, res) => {
let filename = req.params.filename
try{
const path = `${filePath}/${filename}`;
if (!fs.existsSync(path)) return res.status(404).send('You could send any message here...');
const streamFile = fs.createReadStream(path);
streamFile.pipe(res);
} catch {
res.status(500).send();
};
});
So maybe it sounds pretty tricky at a first look.I'll explain what I actually want to do :
I'm working with NodeJS & expressJS and I'm trying to modularize the project,here is what I want to do:
Let's say I have the in the main server .js file the router.get / post / put / delete etc splitted in some other files for every type :
Ex :
...
app.use(require('./routes/account_method1.js'));
app.use(require('./routes/account_method2.js'));
app.use(require('./routes/games_method1.js'));
app.use(require('./routes/games_method3.js'));
app.use(require('./routes/emails_method5.js'));
...
I performed that pretty easy : I just used the code mentioned above in the main .js file and in the required files I've just put :
module.exports = router;
And that's pretty much it.But the problem is :
Now I want do to something like :
...
app.use(require('./routes/account/panel.js'));
app.use(require('./routes/games/panel.js'));
app.use(require('./routes/emails/panel.js'));
...
And in every ./routes/x/panel.js file to have the specific .js files required withing , for just an example in ./routes/account.panel.js I would like to have and work :
app.use(require('./account_method1.js'));
app.use(require('./account_method2.js'));
Assuming account_method1.js and account_method2.js are in the same directory with the specific panel.js file.And then,require these panel.js files in the main server .js file.
So if now I have :
Server ---> ./routes/account_method1.js
---> ./routes/account_method2.js
I would want to make it :
Server ---> ./routes/account/panel.js ---> ./routes/account_method1.js
./routes/account_method2.js
I won't paste here any code because it's just a problem about a way of importing files and I've already mentioned how I require my .js files on the main server.
Soo...what do you think?
EDIT :
I think will show you where is the problem :
./routes/test.js ( this file have to add to app another file,register.js)
const express = require('express');
const router = express.Router();
console.log("BEFORE ROUTER.USE");
router.use(require('./register.js'));
console.log("AFTER ROUTER.USE");
module.exports = router;
./app.js (the main .js server file)
....
var test = require('./routes/test.js');
app.use(test);
....
./routes/register.js
const express = require('express');
const router = express.Router();
...
//some router.post / get / delete
...
module.exports = router;
And when I try to access the URLs from that register.js file they aren't working
Better way is using router:
eg: controller/api.js
const express = require('express')
const router = express.Router()
router.get('/', function(req, res) {
//console.log(res.apiData);
res.json({message:'ok'});
});
module.exports = router;
and later
app.use('/api', require('controller/api'))
Router can be imported to another router. I'm use this:
main.js:
app.use(require('./controller'));
controller/index.js:
const express = require('express')
const router = express.Router()
const isAuth = require('../middlewares/is-auth')
const isValidApiKey = require('../middlewares/is-api-key')
const isAdmin = require('../middlewares/is-admin')
router.use('/auth', require('./auth'));
router.use('/profile', isAuth, require('./profile'));
router.use('/api', isValidApiKey, require('./api'));
router.use('/admin', isAuth, isAdmin, require('./admin'))
If the request service code is long, you can also move it to a separate file, but I think it's better to divide it into smaller, reusable parts and use it as middleware, eg:
route.all('/:orderId(\\d+)', fileOrderMiddleware, fileAltMiddleware, hasTransferMiddleware, orderServeMiddleware);
Motive: basic express routing. since there are many files in one directory, i want this directory path handled by variable. But the other file handled sparately. So when i code the path, it will require file name only. This will make easy coding off course.
Lets see i have main file app.js located on "./ "
and here i code:
var next = require('./routes');
app.get('/', next.index);
The path is handled by variable next. I also have file index.js located on "./routes "
and here i code:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
Instead of doing respond, it return error as ->
Error: Route.get() requires a callback function but got a [object Undefined]
But when i replace next variable as follow from app.js:
var next = require('./routes/index');
app.get('/', next);
It work. So where do i need to change?
Simple..
In Node.js, when your use require, you aim to load a module
If you print (with console.log) the result of require('./routes') you will see that this module is not exposing index whatsoever
When you use require('./routes/index') you are loading a different module which contains the functionality you need
This code causes an error because when you use require it will automatically require the index.js file of the directory. So these 2 lines of code are the same.
var next = require('./routes');
var next = require('./routes/index');
So when you do this code it will cause an error because next.index does not exist.
var next = require('./routes');
app.get('/', next.index); // This will cause an error
The proper way to do this is:
var next = require('./routes');
app.get('/', next);
I want to change the static path based on the route. For example (not working):
const app = express();
const appRouter = express.Router();
const adminRouter = express.Router();
appRouter.use(express.static('/path/to/app/static/assets');
adminRouter.use(express.static('/path/to/admin/static/assets');
app.use('/', appRouter);
app.use('/admin', adminRouter);
This also does not work:
const app = express();
app.use('/', express.static('/path/to/app/static/assets');
app.use('/admin', express.static('/path/to/admin/static/assets');
What I do not want to do is set both paths as static for the entire app:
// the following will expose both paths as static for the entire app
// this does not accomplish what I am trying to do
const app = express();
app.use(express.static('/path/to/app/static/assets');
app.use(express.static('/path/to/admin/static/assets');
Is this possible?
What you are trying to accomplish is not possible from your approach with express.static(). Your #2 approach does create virtual path prefix (where the path does not actually exist in the file system) for files that are served by the express.static function. Follow this for more info.
But what seems can be done is changing the path of express.static() in run time. Please follow through this git issue. Hope it helps.
I don't think it is possible with Express static middleware.
I was able to come up with a solution following the git issue posted by Tolsee. I published it to npm under the name express-dynamic-static.
Here is quick example of how to use it:
const express = require('express');
const dynamicStatic = require('express-dynamic-static')(); // immediate initialization
const path = require('path');
const app = express();
app.use(dynamicStatic);
app.get('/', (req, res) => {
dynamicStatic.setPath(path.resolve(__dirname, 'path/to/app/assets'));
// res.render...
}
app.get('/admin', (req, res) => {
dynamicStatic.setPath(path.resolve(__dirname, 'path/to/admin/assets'));
// res.render...
}