I have a Node.JS file that outputs page load analysis test results. I have stored the results in a file results.json, with JSON.stringify().
launchChromeAndRunLighthouse('https://www.microsoft.com/en-us/', flags, perfConfig).then(results => {
fs.appendFile('results.json', JSON.stringify(results), (err) => {
if(err){ throw err; }
console.log('Data was appended to file!');
var myObj = results.json; //problematic
var JSON_to_HTML = mustache.render('This test was generated at this time: {{generatedTime}}.', myObj); //problematic
});
});
Now I want to display the results in the browser, so I want to translate the JSON into HTML. I want to use mustache for this, but these lines aren't working for me:
var myObj = results.json;
var JSON_to_HTML = mustache.render('Test was generated at this time: {{generatedTime}}.', myObj);
I get the error "results isn't defined", the JSON file can't be read by mustache like this. I can't initialize "myObj" with the raw JSON, because it's about a million lines (and I need to later run tests for a whole bunch of pages, so I can't hardcode that right now).
I'm not sure how to translate this JSON file I have now into HTML. Does anyone have any ideas? I'm a beginner to Node and Mustache, any tips are highly appreciated.
A lot of googling led me to my own answer.
To read the JSON file of the test results and make an HTML page out of it, I had to create a package.json file for this Node module (ran npm init). After I created the file, I opened it in sublime and edited the scripts so a CLI command 'build' would take the .json file, take a .mustache file with the stuff I wanted to display from the .json file, and stick those in a .html file.
"scripts": {
"build": "mustache results.json basicTemplate.mustache > theDisplay.html",
"test": "echo \"Error: no test specified\" && exit 1"
},
results.json is where I stringified into, from the question. basicTemplate.mustache is for now
{{generatedtime}} {{initialurl}}
and theDisplay.html is just a basic html template (like this).
Now when I run node <name of node module>, the results file is generated. Then I run npm run build, and this script I just created in the package.json is run. That modifies theDisplay.html. You should now be able to double-click theDisplay.html in Finder, and a browser opens up with the time the tests were generated, as well as the url of the page tested.
Related
I am writing a node script that automates package updates within a package.json by reading the file, selecting the line with the package and giving the version a bump, and writing the new version of the file.
It runs fine when I run the script the first time. On the second run, readFileSync() gives a very different output, making the script break.
Here is the readFileSync function.
const data = fs.readFileSync("./package.json", {
encoding: "utf8",
});
On the first run, data logs like this:
PS C:\Projects\update-version-test> node updateversion.js
Updating package: webpack , version: patch
data {
"name": "update-version-test",
"version": "1.0.0",
"main": "index.js",
"author": "eendkonijn",
"license": "MIT",
"dependencies": {
"webpack": "^5.8.0"
}
}
The script works as expected, and the webpack package is bumped to 5.8.1. If I run the script again, however, the data logs like this:
PS C:\Projects\update-version-test> node updateversion.js
Updating package: webpack , version: patch
} } "webpack": "^5.8.1"",-test",
The package.json file is intact but somehow readFileSync() doesn't seem to pick it up correctly the second run?
When I make a manual change, the script seems to be working again. But only the one time.
I have a reproduction here:
https://github.com/eendkonijn/update-version-test
The problem is that you're trying to parse the json file using .split("\n") and later you assemble the resulting json content using .join(""). In the resulting file there will be no more line-breaks which is why your code does not work the second time.
Instead of manually parsing the json content, just parse it using JSON.parse, manipulate the webpack-property and finally overwrite the file content with the output of JSON.stringify. E.g:
const rawData = fs.readFileSync('./package.json', {
encoding: 'utf8',
});
const parsedData = JSON.parse(rawData);
parsedData.dependencies.webpack = 'callFunctionToManipulateTheVersionHere()';
fs.writeFileSync('./package.json', JSON.stringify(parsedData, null, 4));
I am trying to inject a json as an argument value within npm script, like this:
(https://medium.com/typeforms-engineering-blog/codeceptjs-puppeteer-setting-up-multiple-configurations-32d95e65adf2)
"scripts": {
"example": "bash -c 'cat ./sample.json | tr -d ' \t\n\r''",
"test:override": "codeceptjs run --steps --config ./codecept.conf.js --override <expecting_output_json_here_from_example_script>",
}
The first script command 'example' executes well and displays the output json correctly in the console (same as input):
{
"helpers":{
"Puppeteer":{
"url":"http://yahoo.com",
"show":false,
"windowSize":"1920x1080"
}
}
however, I couldn't find the way to pass it as an argument value for the --override in the "test:override" script
I have tried various StackOverflow questions/answers, however, I couldn't find a way to achieve it.
I am using Git Bash in VS Code in Win10.
Please suggest a solution/alternate approach or point me to the right document/SO question.
To the best of my knowledge and efforts, I believe that it is not a duplicate question.
I'm trying to build a desktop app for the first time, using the Electron framework, and I'm trying to use the Trilogy module. However, several errors keep popping out.
Basically, the main idea of my code is to have a button that enters a SQL database and checks whether the table "DATA" exists. (I know it's kind of lame, but I'm trying to test out the concept here so bear with me).
My main.js code is just the exact code found in the beginner tutorial, and seemed to be working fine before I imported Trilogy. The dependencies portion of my package.json was as follows:
"dependencies": {
"electron": "^2.0.16",
"sql.js": "^0.5.0",
"trilogy": "^1.4.5"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "electron ."
},
"devDependencies": {}
The head of my HTML code imported the script "tri.js", and then the body of my HTML code called that with:
<button onclick="search()">Produce Table</button>
<div id="table">table</div>
The file for "tri.js" contains the following code:
require('trilogy');
const db = new Trilogy('./storage.db');
function search()
{
var model = "THIS DOESN'T WORK";
document.getElementById('table').innerHTML = model;
if (db.hasModel('DATA')) {
model = "YES";
}
else {
model = "NO";
}
document.getElementById('table').innerHTML = model;
}
When this code is run using npm start, the outputted text in the div becomes "THIS DOESN'T WORK". I attempted to run it on my browser, but my browser wouldn't recognize "require" and "import" (I tried using both statements), with the error messages "Can't find variable require" and "Import calls expect exactly one argument", respectively. When the button is clicked, it then says "Cannot access uninitialized variable" at the line when I call the db.hasModel() function.
When I tried removing the import and require statement, and loading it straight into the HTML first, it outputs the error that "undefined is not a constructor".
Does anybody have any idea how to implement this so that I could do what I want to do? Or if not, any suggestions on how to further debug this would also be welcome. Thanks.
I use the FayeJS and the latest version has been modified to use RequireJS, so there is no longer a single file to link into the browser. Instead the structure is as follows:
/adapters
/engines
/mixins
/protocol
/transport
/util
faye_browser.js
I am using the following nodejs build script to try and end up with all the above minified into a single file:
var fs = require('fs-extra'),
requirejs = require('requirejs');
var config = {
baseUrl: 'htdocs/js/dev/faye/'
,name: 'faye_browser'
, out: 'htdocs/js/dev/faye/dist/faye.min.js'
, paths: {
dist: "empty:"
}
,findNestedDependencies: true
};
requirejs.optimize(config, function (buildResponse) {
//buildResponse is just a text output of the modules
//included. Load the built file for the contents.
//Use config.out to get the optimized file contents.
var contents = fs.readFileSync(config.out, 'utf8');
}, function (err) {
//optimization err callback
console.log(err);
});
The content of faye_browser.js is:
'use strict';
var constants = require('./util/constants'),
Logging = require('./mixins/logging');
var Faye = {
VERSION: constants.VERSION,
Client: require('./protocol/client'),
Scheduler: require('./protocol/scheduler')
};
Logging.wrapper = Faye;
module.exports = Faye;
As I under stand it the optimizer should pull in the required files, and then if those files have required files, it should pull in those etc..., and and output a single minified faye.min.js that contains the whole lot, refactored so no additional serverside calls are necessary.
What happens is faye.min.js gets created, but it only contains the content of faye_browser.js, none of the other required files are included.
I have searched all over the web, and looked at a heap of different examples and none of them work for me.
What am I doing wrong here?
For anyone else trying to do this, I mist that on the download page it says:
The Node.js version is available through npm. This package contains a
copy of the browser client, which is served up by the Faye server when
running.
So to get it you have to pull down the code via NPM and then go into the NPM install dir and it is in the "client" dir...
Is it possible to bind a whole directory of static files to an angular 4 application? The intention behind this is to get the content of this directory dynamically to see what files are inside the directory.
I know it´s possible to bind a directory to the application using
"assets": [
"favicon.ico",
"assets",
{
"glob": "**/*.svg",
"input": "../node_modules/#myModule/assets/images",
"output": "./assets/images"
}
]
With the above approach, you can only address the files by calling them explicit e.g. HOST:PORT/assets/images/myImage.svg
So the question is:
Is it possible to bind an directory, so I´m able to call HOST:PORT/assets/images and get all containing files dynamically?
If not:
Is there another way to get all files dynamically from my static directory in my Angular app?
The short answer: no.
The longer answer, not right out of the box. The icons (as mentioned in your comments) are accessible, but not listable. So you can create a list of icons on build time, something like this.
Add an enumerator script in your tools or similar directory. E.g.
const fs = require('fs');
const readdirSync = fs.readdirSync;
const writeFileSync = fs.writeFileSync;
const files = readdirSync('src/assets/svg');
const jsonObj = { files };
writeFileSync('src/app/svg-files.json', JSON.stringify(jsonObj, null, 2));
Run that script in your package.json. E.g.
"scripts": {
...
"listSvgs": "node tools/list-svgs"
}
Run that script in your build pipeline in package.json:
"scripts": {
...
- "build": "ng build -p",
+ "build": "npm run listSvgs && ng build -p"
...
}
(You'll know, I guess, which line goes out and which comes in its place.)
Generate the files first time manually, so you don't forget (npm run listSvgs).
Add a service to fetch the files in your Angular code:
#Injectable
export class SVGListingService {
constructor(private httpClient: HttpClient) {}
getSVGs() {
return this.http.get('svg-files.json');
}
}
You should be able to use it, remember to rerun it when you add svgs. And adjust paths.