nunjucks: Template not found - node.js

Trying to render a nunjucks template but getting Error: template not found: email.html.
server/
views/
email/
email.html
workers/
email.worker.js
//email.worker.js
function createMessage(articles) {
console.log(__dirname) // /<path>/server/workers
nunjucks.configure('../views/email/');
return nunjucks.render('email.html', articles);
}
No idea what's wrong here.

I had the same issue my solution was using path module:
const njk = require('nunjucks');
return njk.render(path.resolve(__dirname, '../views/email/' + 'email' + '.html'), articles);

I had same issue. I found this at the documentation:
In node, 'views' would be a path relative to the current working directory.
If you run the node server at the root directory, the template path would be server/views.
nunjucks.configure('server/views/email/');
return nunjucks.render('email.html', articles);
In my case, the server script is in public directory.
So, when i run the server from the root directory, the nunjucks configuration will look like this:
nunjucks.configure('src/templates');
return nunjucks.render('index.html', { name : 'Dian' });
It works.
But if I run the server from the public directory, the tempate will not found.

Had the same issue, try this if it helps. If you're using express and you have a views folder:
From nunjucks docs
var app = express();
nunjucks.configure('views', {
autoescape: true,
express: app
});
You can use nodejs' __dirname to resolve the path for you as
nunjucks.configure(__dirname + '/views')...

The nunjucks templates (located under src) were not included in build folder in my case.
Such a configuration in my nest-cli.json file solved my issue:
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "#nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"assets": [
"**/*.njk"
]
}
}

Related

Node JS - no such file or directory filesystem module

I'm trying to use an email template while sending emails. here's my project structure.
project-name
client
server
email-templates
confirm-email.html
controllers
accounts.js (currently here)
I am reading the template file like so.
fs.readFile('../email-templates/confirm-email.html', async (error, html) => {
// do some stuff
})
I think have entered a correct path. but still I get an error.
Error: ENOENT: no such file or directory
I have checked other questions on SO. but they are using the variable __dirname because I am using ES6 modules I don't have access to that variable.
// package.json
"type": "module",
any suggestions ?
Try to use path module to resolve the absolute path the file when you are trying to access the file.
fs.readFile(path.resolve(__dirname, '../email-templates/confirm-email.html'), function(err, html) {// do some stuff})
I don't have access to __dirname because I'm using ES6 modules. I've used path.resolve() instead which fixed the error.
fs.readFile(
path.join(path.resolve(), 'email-templates', 'confirm-email.html'),
'utf8',
(error, html) => {
// do some stuff
}
);
to get access of the __dirname variable when can do:
const __dirname = path.resolve();

#google-cloud/speech - Error: ENOENT: no such file or directory, open 'protos.json

I'm trying to use the google cloud speech to text api.
I'm using the sample google code and when i create the client object i got this error.
{
"errno":-2,
"syscall":"open",
"code":"ENOENT",
"path":"protos.json",
"stack":"Error: ENOENT: no such file or directory, open 'protos.json'\n at Object.openSync (fs.js:440:3)\n at Object.readFileSync (fs.js:342:35)\n at fetch (transcript-server-js/node_modules/protobufjs/src/root.js:160:34)\n at Root.load (/transcript-server-js/node_modules/protobufjs/src/root.js:194:13)\n at Root.loadSync (/transcript-server-js/node_modules/protobufjs/src/root.js:235:17)\n at Object.loadSync (/transcript-server-js/node_modules/#grpc/proto-loader/build/src/index.js:221:27)\n at GrpcClient.loadFromProto /transcript-server-js/node_modules/google-gax/src/grpc.ts:165:40)\n at GrpcClient.loadProto (/transcript-server-js/node_modules/google-gax/src/grpc.ts:199:17)\n at new SpeechClient /transcript-server-js/lib/webpack:/src/v1/speech_client.ts:135:28)\n at createText$ (/transcript-server-js/lib/webpack:/src/transcriptGenerator.js:50:18)"
}
this is the code
const { Storage } = require('#google-cloud/storage');
const storage = new Storage();
const results = await storage.getBuckets();
const speech = require('#google-cloud/speech');
const client = new speech.SpeechClient();
google cloud storage api works.
can someone help me?
thanks
I ran into this with #google-cloud/firestore. Both #google-cloud/firestore and #google-cloud/speech use the same mechanism to to load protos.json, so my solution should be relevant here.
This happened to me because webpack was building the #google-cloud/firestore package into my bundle. The #google-cloud/firestore package uses __dirname to find protos.json. Since the #google-cloud/firestore code was in my bundle, the __dirname variable was set to my bundle's directory instead of to the node_modules/#google-cloud/firestore/ subdirectory that contains protos.json.
Possible fix #1
Set this in your webpack config to tell webpack to set the value of __dirname:
node: {
__dirname: true,
}
https://webpack.js.org/configuration/node/
Possible fix #2
Update your webpack config to exclude #google-cloud/speech from your bundle.
One way to do this is to use the webpack-node-externals package to exclude all dependencies from the node_modules directory:
var nodeExternals = require('webpack-node-externals')
...
module.exports = {
...
externals: [nodeExternals()],
target: 'node',
...
};
https://webpack.js.org/configuration/externals/
https://www.npmjs.com/package/webpack-node-externals
Thank you so much Gabriel Deal.
I faced the same issue like you in firestore package. I understood why this is occurring from your explanation. Unfortunately the fixes didn't help me. So I had to take an alternate. I copied the protos.json file to the path it is searching for in my dist folder.
Copy protos.json from the node_modules to a folder (I named it external_files)
In the webpack.config.js copy the protos.json file from the external_files directory to the path in which it is searching (In my case it was searching in node_modules/google-gax/protos). Use the plugin CopyWebpackPlugin to do that job as shown below.
module.exports = {
.
.
.
plugins: [
new CopyWebpackPlugin([
{ from: "external_files/protos.json", to: "dist/node_modules/google-gax/protos" }
])
]
}

How do I serve static files using Sails.js only in development environment?

On production servers, we use nginx to serve static files for our Sails.js application, however in development environment we want Sails to serve static files for us. This will allow us to skip nginx installation and configuration on dev's machines.
How do I do this?
I'm going to show you how you could solve this using serve-static module for Node.js/Express.
1). First of all install the module for development environment: npm i -D serve-static.
2). Create serve-static directory inside of api/hooks directory.
3). Create the index.js file in the serve-static directory, created earlier.
4). Add the following content to it:
module.exports = function serveStatic (sails) {
let serveStaticHandler;
if ('production' !== sails.config.environment) {
// Only initializing the module in non-production environment.
const serveStatic = require('serve-static');
var staticFilePath = sails.config.appPath + '/.tmp/public';
serveStaticHandler = serveStatic(staticFilePath);
sails.log.info('Serving static files from: «%s»', staticFilePath);
}
// Adding middleware, make sure to enable it in your config.
sails.config.http.middleware.serveStatic = function (req, res, next) {
if (serveStaticHandler) {
serveStaticHandler.apply(serveStaticHandler, arguments);
} else {
next();
}
};
return {};
};
5). Edit config/http.js file and add the previously defined middleware:
module.exports.http = {
middleware: {
order: [
'serveStatic',
// ...
]
}
};
6). Restart/run your application, e.g. node ./app.js and try to fetch one of static files. It should work.

Cannot set express.static from another module

This works
var express = require('express');
var app = express();
var request = require('request');
// initialize session, redis server will be used if it's running otherwise will store in memory
require('./config/session.js')(app, function () {
// configurations
require('./config/bodyparser.js')(app);
require('./config/cookieparser.js')(app);
require('./config/compression.js')(app);
//require('./config/other.js')(app, express);
app.use(express.static('./public', { /*maxAge: 86400000*/}));
app.listen(3000, function () { console.log('running...'); });
});
But if I uncomment require other.js and comment app.use it doesn't. Here is the other.js file.
module.exports = function (app, express)
{
app.use(express.static('../public', { /*maxAge: 86400000*/}));
return app;
}
Tried different relatives paths but all failed. Here is the project structure
-config
--other.js
-public
-app.js
The error I get is
Cannot GET /index.html
on my browser, no error in console.
The issue here is that when you require the other.js file, the relative path is using the cwd of app.js. The best way to avoid this (and avoid the hassle with relative paths) is to use path.resolve and the __dirname variable.
__dirname is a special Node.js variable that always equals the current working directory of the file it's in. So combined with path.resolve you can always be sure that no matter where the file is being require'd it uses the correct path.
In other.js:
var path = require('path');
....
app.use(express.static(path.resolve(__dirname, '../public')));
Or you could simply update other.js to use ./public but I believe the above is better practice as if you move the app.js or require other.js in a different folder it won't resolve correctly
Info on path.resolve here

Aurelia-http-client 404 not found

I am trying to follow this tutorial but I am having import issues for aurelia-http-client.js.
Overview:
Working in Visual Studio Asp.Net 5 project. Through jspm I installed aurelia-framework and aurelia-bootstrapper.
jspm install aurelia-framework
jspm install aurelia-bootstrapper
I wanted my app.js to be included in a different folder than my root so:
<div aurelia-app>
<script src="~/jspm_packages/system.js"></script>
<script src="~/config.js"></script>
<script>
System.config({
"paths": {
"*": "js/aurelia/*.js"
}
});
System.import("aurelia-bootstrapper");
</script>
</div>
Now all seems fine it load app.js from the proper folder. I now need to use the aurelia-router so:
import {Router} from "aurelia-router";
export class App {
static inject() { return [Router]; }
constructor(router) {
this.router = router;
this.router.configure(config => {
config.title = "Reddit";
config.map([
{route: ["", "funny"], moduleId: "funny", nav: true, title: "Funny Subreddit"},
{route: "gifs", moduleId: "gifs", nav: true, title: "Gifs Subreddit"}
]);
});
}
}
There is where it blows up...I believe router is trying to grab aurelia http client because my console throws up with a 404 -> http://localhost:53342/js/aurelia/aurelia-http-client.js...Which I am curious why its looking in /js/aurelia for aurelia-http-client in the first place.
I thought aurelia-framework included aurelia-http-client it did not. jspm install aurelia-http-client did the trick.
There seems to be a new version of skeleton navigation template for ASP.NET 5...
System.js is usually configured via separate config.js file. Here's the one from skeleton application. Note that it also has paths for jspm packages:
paths: {
"*": "js/aurelia/*",
"github:*": "jspm_packages/github/*",
"npm:*": "jspm_packages/npm/*"
}
You might need to correct those paths to be relative to your application root.

Resources