How to eval es6 code from NodeJS at runtime with Babel? - node.js

I'm trying to build a nodeJS tool to help me analyzing another AngularJS source code.
The idea is to :
read some of the angular project javascript files
for each file, grab the content
eval the content from the file
do some stuff
The problem I'm facing is that my Angular source code uses es6 features like import, export, arrow functions, ...Etc. and I using nodeJS which does not support these features yet.
So I tried to use #babel/core transform() from my Node app code, but it doesn't work. I keep getting error like Unexpected identifier which means it doesn't understand the import {stuff} from 'here'; syntaxe.
srcFiles.forEach(content => {
try {
(function() {
eval(require("#babel/core").transform(content.text).code)
}.call(window, angular));
} catch (e) {
console.log(e);
}
});
An sample test file :
import _ from 'loadash';
console.log("I'm a file with import and export");
export const = 42;
Any idea how I can get this stuff working ? Or maybe another approach ?

You can pass options as the second parameter of transform method. See examples here

Related

Node.js package script that runs every time a file is changed

I'm developing a node.js package that generates some boilerplate code for me.
I was able to create this package and if I run every module individual it works fine and generates the code as expected.
My idea now is to import this package in another project and have it generate the code.
I have no idea to how to achieve this or even if it's possible.
The perfect solution would be that every time a file changed in a set of folders it would run the package and generate the files but if this isn't possible it would be ok as well to expose or command to manually generate this files.
I have created a script to run the generator script but it only works on the package itself and not when I import it in another project.
Thanks
I think you want the fs.watch() function. It invokes a callback when a file (or directory) changes.
import { watch } from 'fs';
function watchHandler (eventType, filename) {
console.log(`event type is: ${eventType}`) /* 'change' or 'rename' */
if (filename) {
console.log(`filename provided: ${filename}`)
} else {
console.log('filename not provided');
}
}
const options = { persistent: true }
const watcher = fs.watch('the/path/you/want', options, watchHandler)
...
watcher.close()
You can use this from within your nodejs app to invoke watchHandler() for each file involved in your code generation problem.

Retrieve file contents during Gatsby build

I need to pull in the contents of a program source file for display in a page generated by Gatsby. I've got everything wired up to the point where I should be able to call
// my-fancy-template.tsx
import { readFileSync } from "fs";
// ...
const fileContents = readFileSync("./my/relative/file/path.cs");
However, on running either gatsby develop or gatsby build, I'm getting the following error
This dependency was not found:
⠀
* fs in ./src/templates/my-fancy-template.tsx
⠀
To install it, you can run: npm install --save fs
However, all the documentation would suggest that this module is native to Node unless it is being run on the browser. I'm not overly familiar with Node yet, but given that gatsby build also fails (this command does not even start a local server), I'd be a little surprised if this was the problem.
I even tried this from a new test site (gatsby new test) to the same effect.
I found this in the sidebar and gave that a shot, but it appears it just declared that fs was available; it didn't actually provide fs.
It then struck me that while Gatsby creates the pages at build-time, it may not render those pages until they're needed. This may be a faulty assessment, but it ultimately led to the solution I needed:
You'll need to add the file contents to a field on File (assuming you're using gatsby-source-filesystem) during exports.onCreateNode in gatsby-node.js. You can do this via the usual means:
if (node.internal.type === `File`) {
fs.readFile(node.absolutePath, undefined, (_err, buf) => {
createNodeField({ node, name: `contents`, value: buf.toString()});
});
}
You can then access this field in your query inside my-fancy-template.tsx:
{
allFile {
nodes {
fields { content }
}
}
}
From there, you're free to use fields.content inside each element of allFile.nodes. (This of course also applies to file query methods.)
Naturally, I'd be ecstatic if someone has a more elegant solution :-)

How can I use .vue files in Node.js *without* a bundler like webpack?

I'm trying to find a simple server-side rendering solution for Vue.js, but every example or tutorial I've found has dependencies I don't want to include that overcomplicate things: usually webpack, Vue Router, and Vuex.
I'm looking for a solution that runs in Node.js and can render a .vue file to a string, including any other .vue files it may reference.
const sfcContent = fs.readFileSync("./app.vue", "utf-8");
const props = {
foo: "bar",
};
const htmlString = await render(sfcContent, props);
console.log(htmlString);
async function render(sfcContent, props) {
// this is the function I'm looking for
}
http-vue-loader looks promising, as it does roughly what I'm looking for except in the browser instead of Node.js.
Any ideas what I should try?
You could look into the compiler-utils package https://github.com/vuejs/component-compiler-utils
Although, this will still require some tinkering on your end so I'm not sure if it'll be the way to go if you don't want to overcomplicate things.

Typedef not appearing in template when using gulp-jsdoc-to-markdown

I am trying to create automatically generated documentation for our node.js API. I am using jsDoc style comments and gulp to run the generation. I am using the plugin jsdoc2md and this gulp plugin to create markdown style documentation.
I am running into an issue of my typedefs not showing up in the generated documentation when i try to use a template. They show up when i do not use a template
Here is gulp task
gulp.task("docs", function() {
return gulp.src(["./documentation/typedefs.js", "./routes/**/*.js"])
.pipe(concat("README.md"))
.pipe(gulpJsdoc2md({ template: fs.readFileSync('./README.hbs', 'utf8') }))
.on("error", function(err) {
gutil.log(gutil.colors.red("jsdoc2md failed"), err.message);
})
.pipe(gulp.dest("./api"));
});
Here is my template
# My Super Cool API
This is where stuff happens
# Search API
{{#module name="search-api"}}
{{>body~}}
{{>member-index~}}
{{>separator~}}
{{>members~}}
{{/module}}
The output of this is a markdown with the appropriate functions and modules, but lacking the typedefs. So my question is:
How can I get my typdefs to render in the template?
The documentation doesn't have much. Any ideas?

How to use npm module in Meteor client?

I'm thoroughly confused on how to use an npm module in Meteor client code.
I understand modules like fs would only work server-side, but in this case I'd like to use a simple text module like this for displaying pretty dates:
https://github.com/ecto/node-timeago
I've tried installing the module under /public/node_modules,
and it works great on the server-side following these instructions from SO: (
How do we or can we use node modules via npm with Meteor?)
Meteor.startup(function () {
var require = __meteor_bootstrap__.require
var timeago = require('timeago')
console.log(timeago(new Date()))
...
However it doesn't work in the client-side code:
if (Meteor.is_client) {
var require = __meteor_bootstrap__.require
var timeago = require('timeago')
console.log(timeago(new Date()))
...
Uncaught ReferenceError: __meteor_bootstrap__ is not defined"
Server-side is sort of useless for me in this case, as I'm trying to render text on the client.
I don't believe you need to use the server side version. Use the npm stuff for server side only and btw, put it in your /public/ as well. Who knows maybe you can call it once it is in your /public/, try it. Or try this.
Use something like the jquery timeago.js
Put it in /client/ or something like /client/js
Create a /client/helpers.js or some such.
Use a handlebars helper.
Handlebars.registerHelper('date', function(date) {
if(date) {
dateObj = new Date(date);
return $.timeago(dateObj);
}
return 'a long long time ago in a galaxy far away';
});
Example of calling 'date' handlebars helper function from template.
{{ date created }}
Where date is the handebars helper and created is the date coming out of the meteor/mongo collection.
See the github Britto project. That is where I got this code snippet and used it in a chat room app I wrote. Works fine.
There are a couple of others floating out there. Go to madewith.meteor.com and peruse the source of some of the projects.

Resources