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.
Related
I am trying to create a simple ui window, where i can quickly test react code.
So the idea is that i am typing react jsx code into the window and in the other window i am getting app rendered from that code.
Input (with react jsx code) is sent to the nodejs process that converts it to normal js code that can be processed with in browser react library. The problem i am having is with this error regeneratorRuntime is not defined.
my current code:
const babel = require("#babel/core");
// body comes from window input
console.log(
babel.transform(body, {
"presets": ["#babel/env", "#babel/react"],
"plugins": ["#babel/plugin-proposal-class-properties"]
}).code
);
I read few topics about this error and most seem to recommend to add "#babel/plugin-transform-runtime"
so it becomes:
console.log(
babel.transform(body, {
"presets": ["#babel/env", "#babel/react"],
"plugins": ["#babel/plugin-proposal-class-properties", "#babel/plugin-transform-runtime"]
}).code
);
However at this point code returned by babel transform contains these at beginning:
"use strict";
var _interopRequireDefault = require("#babel/runtime/helpers/interopRequireDefault");
var _regenerator = _interopRequireDefault(require("#babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("#babel/runtime/helpers/asyncToGenerator"));
var _classCallCheck2 = _interopRequireDefault(require("#babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("#babel/runtime/helpers/createClass"));
var _assertThisInitialized2 = _interopRequireDefault(require("#babel/runtime/helpers/assertThisInitialized"));
var _inherits2 = _interopRequireDefault(require("#babel/runtime/helpers/inherits"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("#babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("#babel/runtime/helpers/getPrototypeOf"));
var _defineProperty2 = _interopRequireDefault(require("#babel/runtime/helpers/defineProperty"));
But since this code is processed by browser it throws error Uncaught ReferenceError: require is not defined
How can this be solved to feed browser with already "ready" code that doesnt contain any requires?
Basically to run the plugin-transform-runtime, you will need some kind of bundler. Have a look at babelify.
I had this issue while testing a module meant for both web and node targets (front and backend). When the bundle was ready, pasting it on the browser console to check the functionality threw up the exact same eror.
Things that worked for me when I had this issue:
Check the version of Nodejs in your system. if you see type: module in your package.json this would throw an error on require usage since it is expecting es6 import. If you see, try changing it to type: commonjs or remove it from package.json
Yes #babel/polyfill which is now #babel/plugin-transform-runtime has all the builtins, helpers to support Promise, Symbol, Set, and other ES6 builtins. Earlier we relied on Bluebird to backup Promise in browsers. Babel runtime and Babel plugin transform runtime needs a check.
As an alternative you could try #babel/register to run files using babel on the fly. The require hook will bind itself to the node’s require and will automatically compile files at runtime.
If you're using nodeexternals then it would expect node's require function. Set the target as umd
Add this "modules": "commonjs" to your .babelrc file.
I had to specify libraryTarget: 'umd' in the webpack.config output. It is needed for nodeExternals as well if used. The UMD (Universal module definition) format allows JavaScript modules to be imported using commonjs.
The last step 6 may or may not be applicable for you, but for me steps 1,2,3 and 6 resolved all issues.
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
})
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(...)
}
I have my code
app.set('views', path..);
originally placed in server.js and I tried to segregate/factor it into a config.server.js (see link), there I implemented underscoreJS each to loop through the modules by their folders' names in my modules/ directory. ['core', 'xt_syncs']. Problem with this trick I try playing is that, app.set('views',..) can't be a Singleton (which loads many things at once). The app.set('views',..) can only have 1 URI for 'views' (module specific, my app contains several modules: core, xt_syncs as you see in the structure), and the app.set appear to fail, and be overwritten by the static uri to modules/second_module.
I write the app myself, picking the middlewares/components I want. I'm trying to reuse some of the assets from MEANjs, mean-stack-relational (MVC, I prefer modules architecture to MVC, that's why my attempt is to build mine), and SEANjs (quite too complex, the stack requires Redis and MySQL5.7, I try building mine so I can get a good understanding of things flow on the fly and exclude Redis and MySQL upgrade).
Now back to the question, obviously, you see in MEANjs and SEANjs , they do in their default.js file:
views: ['modules/*/client/views/**/*.html'],
routes: ['modules/!(core)/server/routes/**/*.js', 'modules/core/server/routes/**/*.js']
QUESTIONS:
1/ How can I implement similar pattern in my app? Notice in the MEANjs and SEANjs, there is * as in modules/*/client and ! as in modules/!(core)/server. app design advices and coding help, please. (this part of the question is not yet addressed)
2/ How related the default.js is to the config.js (initGlobalConfigFolders,initGlobalConfigFiles,...)? I try to wrap my head around to understand config.js and find clues of the glueing. Maybe, my modules[module] as in
modules[module] = {
client: {},
server: {}
};
is one step closer to what they built in the initGlobalConfigFolders method.
3/ Is using build tool (Grunt, Gulp, or Webpack) a must here to achieve that? If so, Can you show me how? (build tool incorporation is in my planning). How can you
Thank you very much.
This patch hinted at implementing app.set('views', view_paths); // where view_paths can be an array of views folders.
2 & 3. Awaiting help and answers.
I'm building an isomorphic React/React-Router/Redux/Webpack application and I'm attempting to implement server side rendering.
My directory looks like:
/client
/actions
/components
/containers
/server
/server.js
In my webpack config, I have aliases set up for all the folders inside client:
var path_base = path.resolve(__dirname, '..');
const resolve = path.resolve;
const base = function() {
var args = [path_base];
args.push.apply(args, arguments);
return resolve.apply(resolve,args);
};
const resolve_alias = base.bind(null, 'src/client');
const aliases = [
'actions',
'components',
'constants',
'containers',
'middleware',
'reducers',
'routes',
'store',
'styles',
'utils',
'validation'
];
so that inside the code that gets bundled by webpack, I can do:
import { Widget } from 'components';
and that import gets resolved by webpack.
Now in my server code, in order to do the rendering, I have to import some of my client files, like routes/index.js. The problem I'm running into when I import my routes file, it's using a webpack alias to another file, say components or containers so naturally, the node js require system can't resolve it.
How do I fix something like that? I looked at this question and it talks about essentially setting up the same aliases that exist in webpack with mock-require. But then the issue becomes that my routes file imports all my components which then all import things like stylesheets, images, etc. Should I then be using something like webpack-isomorphic-tools?
The guides I've been looking at (this for example) are all great at showing how server side rendering is accomplished but none of them really talk about how to resolve all the requires and whatnot.
After battling with this issue for 2 days I settled on babel-plugin-webpack-alias.
What you need to do to resolve paths with that is:
$ npm install --save-dev babel-plugin-webpack-alias
Add the plugin to your .babelrc
Add the aliases to your webpack.config (make sure you use path.join())
Refer to this post if you have problems loading styles
The other option I tried was universal-webpack but I found it to be a bit verbose. If you want to see roughly how the whole server-side loading works, you can check out this video.
If you really want them, run your server side code through babel and use this plugin: https://www.npmjs.com/package/babel-plugin-module-alias which will let you do the same thing as webpack.
Edit: This one works a lot better: https://github.com/jagrem/babel-resolve-relative-module it allows multiple paths
Try to use NODE_PATH. Node will always look for a module in this path during require calls. It allows to short cut your relative paths as you want.
// turn this
import {Widget} from '../../components';
// into this
import {Widget} from 'components';
See Node.js docs for more information.
P.S. this thing is very sensitive, so use it carefully. Now your code tightly depends from the environment and may break somewhere.
If you use webpack-isomorphic-tools then it'll take your webpack config into account for your server side which will make all your aliases work.
https://www.npmjs.com/package/webpack-isomorphic-tools