I want to make my node cms (at this moment only login,reg, articles) modular. Like you can add or remove any module just be deleting or adding folder. But i cant find any correct or smart or any way to do it. Have you any experience, guides or examples that can help?
I am relatively new in node.
At this moment it looks like this.
This question is a bit too broad in the context of creating a modular cms, however when talking about node modules, even if you just add or delete a folder you still have to require them in your code.
I would say that there are 2 types of plugins that you can have:
Supported plugins - plugins that you create and give the users the option to include them or not
Anonymous plugins - plugins that everyone can create, and need to be included in your application via some kind of interface.
The second type of plugins are more complicated, so I will refer only to the first type. An easy way to include them in your code is to have a JSON where you list the properties of each plugin, and then require each plugin in your code. Using try/catch will prevent your application from crashing if the plugin does not exist:
var allowedPlugins = [
{name: "login", path: "login/index.js", loaded: false, module: null},
{name: "reg", path: "reg/reg.js", loaded: false, module: null},
{name: "articles", path: "articles/all.js", loaded: false, module: null}
];
allowedPlugins.forEach((plug) => {
try {
var module = require(plug.path);
plug.loaded = true;
plug.module = module;
} catch(err) {}
});
Later in your code you can do:
if (allowedPlugins.login.loaded) {
var login = allowedPlugins.login.module;
login.doLogic(...)
}
Related
How do I work with node modules?
tldr; How do I look at a node module I've installed and know where to go and what I'm looking for
If I use npm i googleapis for example, it downloads the node module for Googles APIs but how do I browse the module and work out what's useful for me?
To try and eliminate any ambiguity from the question, I'll use this use case.
I'm developing a Discord bot and I want to add statistics to one of
the commands. Here is the supplied code from Google:
<script src="https://apis.google.com/js/api.js"></script>
<script>
/**
* Sample JavaScript code for youtube.channels.list
* See instructions for running APIs Explorer code samples locally:
* https://developers.google.com/explorer-help/code-samples#javascript
*/
function authenticate() {
return gapi.auth2.getAuthInstance()
.signIn({scope: "https://www.googleapis.com/auth/youtube.readonly"})
.then(function() { console.log("Sign-in successful"); },
function(err) { console.error("Error signing in", err); });
}
function loadClient() {
gapi.client.setApiKey("YOUR_API_KEY");
return gapi.client.load("https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest")
.then(function() { console.log("GAPI client loaded for API"); },
function(err) { console.error("Error loading GAPI client for API", err); });
}
// Make sure the client is loaded and sign-in is complete before calling this method.
function execute() {
return gapi.client.youtube.channels.list({
"part": [
"snippet,contentDetails,statistics"
],
"id": [
"UC_x5XG1OV2P6uZZ5FSM9Ttw"
]
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error", err); });
}
gapi.load("client:auth2", function() {
gapi.auth2.init({client_id: "YOUR_CLIENT_ID"});
});
</script>
<button onclick="authenticate().then(loadClient)">authorize and load</button>
<button onclick="execute()">execute</button>
Now Google offers a supported library which means I can replace the external script tags and import from the node package, specifically the parts I need.
So I'll need to import or require whatever gives me access to things like:
gapi.auth2.getAuthInstance
gapi.client.setApiKey
gapi.client.youtube.channels.list
For someone who is new to nodejs, instead of copy and pasting from every piece of documentation and hoping it works, how do I comfortably look at a node package and find the things I need and can use?
Edit #1
I think my use of the google apis case threw off the direction of the question and changed the scope of what I asked so I'm going to correct the best I can.
The assumption should be made that there is no documentation on the package whether it's so poorly written, doesn't exist at all or the documentation is down for an extended period of time during a time sensitive development.
At that point, is there any possible way to look at the node_modules folder, the specific package that needs to be worked with and work out what's going on? Is there any way to look at the structure of a package and recognise "well most likely what I need is in this folder or file"
That's what documentation is for.
When someone writes an API for a package; to make things clearer for the consumer, he should document the exported functions well enough.
The best way to get the documentations for node packages is to search for the package at www.npmjs.com .
For google apis you can go to that page here to see the "get started" and some examples. And you can go here to see the full detailed APIs of that package.
Answering Edit #1
Well, in that case, it could be a difficult task, depends on the how structured and organized the package is.
Since we are talking about nodejs, you should look for the package.json file and search for the path of the main file "main": "<PATH HERE>".
Then, you can go to that main file and try to locate what exactly is being exported. You can search for module.exports or the export keyword.
Everything that is explicitly exported is intended to be used as an API.
I'm not familiar with any other way other than go deeper in the package's files and identify what exactly is being exported.
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 :-)
I am trying to read files in a directory but cannot because __dirname is undefined
nuxt.config.js
export default {
router: {
middleware: ['database']
},
build: {
extend: function (config, __ctx) {
config.node = {
fs: "empty",
module: "empty",
net: "empty",
};
},
},
}
What can be done to determine __dirname?
As far as I figured it out, Webpack always sets the __dirname to '/'. But probably not on server side.
Maybe this reference will help you resolve your issue: https://codeburst.io/use-webpack-with-dirname-correctly-4cad3b265a92
You didn't say much what you are trying to accomplish, but I will wrote down a solution for one of the most common issues which usually result in people trying to use __dirname constant. Maybe it will also help you ;)
Whenever I tried to use __dirname in Nuxt, it was because I had to make a workaround for the missing require.context functionality in server side process (SSR).
Doing some workarounds with require and __dirname usually caused even more issues.
The best solution if you are struggling with missing require.context in Nuxt server side process is to use Plugins. They can use require.context function and are available both on server side and on client side.
Overall, I think that you should try and find your files with webpack's context functionality and avoid using __dirname.
const files = require.context('~/', true, /\/your-file-name\/.*\.ts$/)
files.keys().map(key => {
// This is an example how to access your file's default export.
// You will probably have to amend it to make any use of it ;)
const file = files(key).default
})
Per several github docs, I have tried this, although it is really for the require keyword, as the very first line in the first server file fired [index.js]:
process.env.NODE_PATH = 'app';
require('module').Module._initPaths();
It didn't work. Then I read up in webpack to do this, but still it does not work:
resolve: {
root: path.resolve(path.join(__dirname + '/app')),
alias: {
app: 'app',
component: 'app/components',
utility: 'app/utils'
},
extensions: ['', '.js', '.jsx']
},
How do I avoid the endless '../../../../' as my project goes deeper as I do not want to keep doing this:
Import MyComponent from '../../../../../Whatever' ?
Thanks
Currently I am using quite the same solution, no 6 in this list.
process.env.NODE_PATH = __dirname;
require('module').Module._initPaths();
Which enables me to call all my js files by folder/filename wherever I am in my code base, e.g.
require('services/userService');
This is a quite ugly solution since it relies on a private Node.js core method, this is also a hack that might stop working on the previous or next version of node.
I also asked the same question on Quora with some answers.
I have an app running on the MEAN stack. I am using jade for templates and was wondering where to put page specific javascript. Right now my directory looks like:
app/
|- public
| |- js
| |- css
|- views
|- routes
|- schemas
One of my views, signup.jade, I need to include some javascript:
$(function() {
$.validator.addMethod("passwordStrength", function( value, element ) {
console.log("here")
var result = this.optional(element) ||
/^[a-zA-Z0-9- ]*$/.test(value) &&
/\d/.test(value) &&
/[a-z]/i.test(value);
if (!result) {
var validator = this;
}
return result;
}, "Your password must contain at least one number and one special character.");
$('#signup').validate({
rules: {
email: {
required: true
},
password: {
required: true,
passwordStrength: true,
minlength: 6
},
"repeat-password": {
required: true,
passwordStrength: true,
minlength: 6
}
}
});
});
Where is the best place to put this? Do I create a javascript file for each page inside of app/public/js?
If anyone has any good articles on MEAN file structure best practices as a whole those would be appreciated as well, thanks!
From my experience it is completely fine to keep script in the corresponding jade view if such script is used only once.
You can however create directory with helpers and move this script to this directory (just create a plain js file) and then add it on the page by adding a variable and set its value to the file content. It may look a little bit more clean (and allows you to apply js lint to helpers, etc) but requires a bit more work.
Here is how my code is organized. We are using angular fullstack generator by yeoman. In the image i provided, home.html is the partial view whose controller is home.js. I suggest you create a separate file for every html partial page you create. As a matter of fact, a good angular page should have user defined directives, and respective Controllers hooking scope into the directives and the directives managing the scope that has been provided. It keeps it neat/simple/beautiful. If you get a chance and can afford it, buy the ng-book. It is beautiful, else even angular's guide is amazing.