html-webpack-plugin - How to insert webpack bundle.js without executing the EJS template - node.js

I am trying to insert bundle.js dynamically without executing the EJS template but I get the below error. Is there a way to insert just the JS without executing the EJS template?
ERROR in Template execution failed: ReferenceError: description is not defined
ERROR in ReferenceError: description is not defined
I am actually rendering the template using node and I just want the bundle file to be dynamically inserted in the template.ejs
res.status(200).render('template',
{
description: description,
title:title
});
webpack config:
output: {
path: path.join(__dirname, 'dist'),
filename: "output.[hash].bundle.js",
publicPath: '/'
},
new HtmlWebpackPlugin({
inject: 'body',
template: 'views/template.ejs'
}),
template.ejs
<!DOCTYPE html>
<html lang="en" class="ddhub-site">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="format-detection" content="telephone=no">
<meta description=<%=description%>/>
<title> <%= title %> </title>
</head>
<body></body>
</html>

I ended up using a simple custom plugin with the information posted on one of the github issue.
var fs = require("fs");
const path = require('path')
function UpdateBundleJsPlugin(options) {
// Setup the plugin instance with options...
}
UpdateBundleJsPlugin.prototype.apply = function(compiler) {
compiler.plugin("done", function(statsData) {
const stats = statsData.toJson();
if (!stats.errors.length) {
const htmlFileName = "search.ejs";
const html = fs.readFileSync(path.join('./views',htmlFileName), "utf8");
// need to read the final js bundle file to replace in the distributed index.html file
const asset = stats.assets[0];
let htmlOutput = html.replace(/static\/.*bundle\.js/, 'static/'+asset.name);
fs.writeFileSync(
path.join('./views', htmlFileName),
htmlOutput);
}
});
};
module.exports = UpdateBundleJsPlugin;

Why not use:
plugins: [
new HtmlWebpackPlugin({
hash: true,
template: 'ejs-render!./dev/index.ejs',
inject: 'body'
})
]
With the ejs-render-loader:
https://github.com/tracker1/ejs-render-loader

Related

Node, Ejs, Express, passing variables to partial views. issues with re-using the same code in the express routes. Need to condense code

I am a newbie to node, express and ejs. I am creating a blog website project. I want to make use of EJS partials to stop repeating elements of code on my website. The simplified structure is
Blog
--js
--sql-helpers.js
--routes
--routes.js
--views
--homepage.ejs
--aboutpage.ejs
--header(Partial).ejs
The partial header ejs file is to be used on all webpages as it displays the title and author of the blog.
Here is a snippet of code from the routes file:
routes.js
router.get('/homepage', (req, res) => {
const sql = 'SELECT * FROM authors';
global.db.all(sql,[], function(err,rows){
const blogInfo = rows[0];
const params = {
authorName:blogInfo.author_name,
authorBlogTitle:blogInfo.authors_blog_title,
authorSubtitle:blogInfo.authors_blog_subtitle
};
res.render('homepage', params);
});
});
router.get('/aboutpage', (req,res) => {
const sql = 'SELECT * FROM authors';
global.db.all(sql,[], function(err,rows){
const blogInfo = rows[0];
const params = {
authorName:blogInfo.author_name,
authorBlogTitle:blogInfo.authors_blog_title,
authorSubtitle:blogInfo.authors_blog_subtitle
};
res.render('aboutpage', params);
});
});
As you can see I am having to re-use the same code in each of the routes to fill the variables in the header(partial).ejs file.
The homepage.ejs file code is as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home Page</title>
</head>
<body>
<%- include('header(Partial)') %>
</body>
</html>
The header(partial).ejs file looks like this:
<header>
<section>
<h1 ><strong><%= authorBlogTitle %></strong></h1>
<span><%= authorSubtitle %></span>
<p ><small><%= authorName %></small></p>
</section>
</header>
To try and stop re-peating the same code i created a sql-helpers js file. as follows
const blogheader = function(callback){
const sql = 'SELECT * FROM authors';
global.db.all(sql,[], function(err,rows){
const blogInfo = rows[0];
const params = {
authorName:blogInfo.author_name,
authorBlogTitle:blogInfo.authors_blog_title,
authorSubtitle:blogInfo.authors_blog_subtitle
};
callback(params);
});
}
module.exports = {blogheader};
updated routes.js file:
const helpers = require("../public/js/sql_scripts");
router.get('/settings', (req,res) => {
let bloginfo = helpers.blogheader()
res.render('settings', blogheader);
});
My problems is I when i try and use this sql helper function in the routes I am getting a undefined value. Is this the best way to do it? How can wrap up my sql query so i dont have to repeat the same code in the routes? Is there a better way to use ejs partials?
I have been stuck on this issue for a number of days, searching the internet for an answer but I just havent found anything that helps me.

routing a webpage error, nodejs and expressjs

I am trying to route directly to the html file using express.js, getting an unknown error, being new to express.js, I couldn't get how to resolve this one:-
here is the js code :-
const express = require('express');
const path = require();
const app = express();
const port=process.env.PORT || 8000;
// public static path
const static_path = path.join(__dirname,"../public");
app.use(express.static(static_path));
app.get("",(req,res)=>{
res.send("welcome to this main page");
})
app.get("/about",(req,res)=>{
res.send("welcome to this about page");
})
app.get("/weather",(req,res)=>{
res.send("welcome to this weather page");
})
app.get("*",(req,res)=>{
res.send("404 Error page oops");
})
app.listen(port,()=>{
console.log(`listening to the port ${port}`);
})
static web page:-
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather App</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1>Welcome to the static web</h1>
</body>
</html>
getting this error:-
internal/validators.js:124
throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "id" argument must be of type string. Received undefined
ok, I was using "type nul > filename" command for creating new files in attached folders. When I used directly the VSCode feature of creating files, it's working fine now,... don't know why, but I think that old command might have expired, tell me if I am wrong, but I just solved my issue...

How to change the line "var domToPdf = require('dom-to-pdf');"

I want to use a NodeJs Module on the browser. I read, that I can do this with http://browserify.org/.
Concret I want to use this NodeJs Module: https://github.com/ovvn/dom-to-pdf
So I create a bundle.js form this like explained here: http://browserify.org/
You can see my bundle in my github repo: https://github.com/astridx/dom-to-pdf/blob/javascriptexport_browserify/bundle.js
But now I do not know how to go on. I created an example: https://github.com/astridx/dom-to-pdf/blob/javascriptexport_browserify/example/index.html
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./../bundle.js"></script>
</head>
<body>
<div id="test">TODO write content</div>
<script>
var domToPdf = require('dom-to-pdf');
var element = document.getElementById('test');
var options = {
filename: 'test.pdf'
};
domToPdf(element, options, function () {
console.log('done');
});
</script>
</body>
</html>
But I do not know how to change the line var domToPdf = require('dom-to-pdf');
Can someone give me a hint?
Try using import instead, but you might need babel for that to work properly.
e.g import domToPdf from 'dom-to-pdf';

How to expose a static html page from ionic

I have a static html page which intercept authorization message, I'd like to expose this on the domain. It looks like so:
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>JwtAuthDemo - Facebook Auth</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="assets/util.js"></script>
</head>
<body>
<script>
// if we don't receive an access token then login failed and/or the user has not connected properly
var accessToken = getParameterByName("access_token");
var message = {};
if (accessToken) {
message.status = true;
message.accessToken = accessToken;
}
else
{
message.status = false;
message.error = getParameterByName("error");
message.errorDescription = getParameterByName("error_description");
}
window.opener.postMessage(JSON.stringify(message), "http://localhost:5000");
</script>
</body>
</html>
If I place this page next to the index.html page it is not exposed, however when I place it inside the assets folder it can be access. I'm guessing I have to explicitly expose the page in one of the json config files however I'm not to sure how to do so?
I'd prefer not to have my redirect url be www.mydomain.com/assets/oauth-response-parser.html. I'd like to keep this in my application seeing as it's part of the application.
How can I expose a static html page from Ionic as a sibling to the index.html page ?
You can automatically get files to your assets directory by specifying that you want to run a custom script during your ionic builds.
In your package.json you'd have a 'config' section where you can specify this script:
...
"config": {
"ionic_copy": "./config/customCopy.config.js"
},
...
and then your customCopy.config.js would contain an entry to copy over your html into assets:
module.exports = {
copyAssets: {
src: ['{{SRC}}/assets/**/*'],
dest: '{{WWW}}/assets'
}
}
More info on this process at the ionic app scripts page
I hope this steers you in the right direction.

How to import Nightmarejs into angular-cli component

I'm going to make GUI scraper with Electron & Nightmare.
However when I use just plain html/js as described in Electron quickstart, all works well.
But I'd like to make Electron app nicely by using Anugular2(angular-cli webpack).
I created project ng new Scraper then made some routes for components e.g. HomeComponent, SettingsComponent.
I installed nightmare in angular project folder by npm install --save nightmare
and I would like import it in SettingsComponent like:
import {Nightmare} from 'nightmare';
and use it like:
ngOnInit{
this.nightmare = new Nightmare({
show: true,
electronPath: require('node_modules/electron')
})
}
What have I tryied:
in index.html including
<script src="node_modules/nightmare/lib/nightmare.js"></script>
then in my component
declare var Nightmare: any;
ngOnInit(){
this.nightmare = new Nightmare({})
Gettings errors about missing other js files inside node_modules/nightmare/lib/*.js
CODE:
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Scrape</title>
<base href="/">
<link rel="stylesheet" href="assets/semantic.min.css">
<script src="assets/require.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root>Loading...</app-root>
</body>
</html>
component:
import { Component, OnInit } from '#angular/core';
declare var require: any;
var Nightmare = require('nightmare');
#Component({
selector: 'app-work',
templateUrl: './work.component.html',
styleUrls: ['./work.component.css']
})
export class WorkComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
error:
Failed to compile.
./~/nightmare/lib/nightmare.js
Module not found: Error: Can't resolve 'child_process' in 'C:\Users\admin\Desktop\Scrape\node_modules\nightmare\lib'
# ./~/nightmare/lib/nightmare.js 18:11-35
# ./src/app/work/work.component.ts
# ./src/app/app.module.ts
# ./src/main.ts
# multi webpack-dev-server/client?http://localhost:4200 ./src/main.ts
It is possible to interact with Angular2/Nightmare inside Electron App?

Resources