NodeJS - Paths break after deployment - node.js

I deploy my NodeJS Projects with supervisord. Strangely most of the paths, which are paths
inside the served index.html: links to static files (stylesheets and js files)
inside javascript files, require statements to other files(e.g.: require('./scripts/'))
I believe the reason for that to be the command node "path/to/my/application/app" since it runs the application from a different directory.
How can i avoid changing the paths whenever i push a new version of my application to production?
Can you recommend any tools to solve this problem? Is there a clean way of setting the paths so that the application works so i can run it from anywhere(my local machine/my webspace)?

Use a relative path. For example if index.html is in a directory as same as a .js file referring it u can use ('./index.html'). If it were in a parent directory u could use (../index.html)

Related

Why does require() not require an absolute path but an express.static() does?

I am trying to run my index.js script from outside the project directory. My project structure is as follows:
app
- config
- config.js
- public
- index.html
- src
- index.js
Now when I run my src/index.js from outside my app folder, require() is able to resolve the relative paths
const config = require(`../config/config`);
On the other hand express.static is not able to resolve such relative paths.
e.g. app.use(express.static("../public"));
Why do I need to use path.join and get the absolute path?
require() works off __dirname which is independent of what the current directory was when your app was loaded. It's always the directory where the module is located in, so it is consistent.
express.static() when used with relative paths uses the directory that the main app was launched form, so if you use relative paths, its behavior varies depending upon how you launch the app.
From the express doc for serving static files:
However, the path that you provide to the express.static function is
relative to the directory from where you launch your node process. If
you run the express app from another directory, it’s safer to use the
absolute path of the directory that you want to serve
So, if you want the directory to be module relative, you have to manually combine your path with __dirname to make a full path, as you have discovered.

How do I specify the root directory Intern serves for http://localhost:9000?

I have a project called delite where all of its dependencies are at the same level as delite itself, rather than in delite/node_modules.
Previously, running Intern 3, I specified baseUrl: ".." and http://localhost:9000 served one directory above my project, so it could load both delite (http://localhost:9000/delite) and its sister projects (ex: http://localhost:9000/dcl).
Is there a way to do the same thing in Intern 4? Currently, http://localhost:9000 serves the contents of the delite directory only, so I can't load dependencies.
You can use the basePath config option. The path is relative to the location of the test config (intern.json)

Set webpack environmental variable for apache2

Is it possible to fetch a webpack envvar outside the node / js scope?
I'm developing with vueJS and TYPO3 and want to load the JS files from node server, when it runs. Otherwise, I want to load the built JS files from the project folder.
TYPO3 has conditions for file loading, in dependence of an Apache envvar.
SetEnv TYPO3_CONTEXT Development
Questions:
Is it possible to set an apache2 envvar when launching a node devserver by webpack?
If not, is it possible to hook in that process and write a temporary htaccess file with the var in it, place it in a specific directory and delete it, when I stop the node server?
Background:
In TYPO3, js and css includes are configured by TypeScript.
In Prod Env:
page.includeJSFooter.app = path/to/build/name.js
This load can be changed by condition:
[applicationContext = Development]
page.includeJSFooter.app = http://192.168.100.38:8080/app.build.js
[end]
Now I want to set this context, as soon as I start my node dev server that builds the files on the fly:
webpack-dev-server --open --config webpack.dev.js
I doubt this is possible but as a solution I would propose to implement a custom condition (described here in the manual https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/TypoScriptSyntax/TypoScriptParserApi/CustomConditions.html) and check within that e.g with a request if the node server is responding.
Hi Georg and all others,
a custom condition would be a solution, but I don't want to influence the production environment (e.g. pinging for a response from node server).
I made it with two shell scripts, executed by webpack-shell-plugin.
The first script is triggered "onBuildStart", looking for an .htaccess file and adding
SetEnv TYPO3_CONTEXT Development/NodeServer
to the end of the file.
Unfortunately there is no event fired when the node server is shut down. As a workaround, I added a new npm run script, which just executes a shell script to delete that line from .htaccess again.
I guess there is a besser solution, but at this time, it solves my (very little) problem to avoid changing the JS includes every time I start to develop.

NodeJS/CloudFoundry - failed: The app upload is invalid: Symlink(s) point outside of root folder

I'm testing CloudFoundry on IBM and are running NodeJS.
When trying to cf push my application I get the following error:
failed: The app upload is invalid: Symlink(s) point outside of root folder
In my appllcation I have the following code:
return res.sendFile(path.join(__dirname +'/tvshows/'+ guide +'.html'));
When not using path.join and simply use:
return res.sendFile(path.join('./tvshows/'+ guide +'.html'));
I get this error instead:
TypeError: path must be absolute or specify root to res.sendFile
What to do?
I've also tried stuff like path.join((process.env.BUILD_DIR || __dirname), and return res.sendFile('index.html', { root: path.join(__dirname, 'tvshows', guide) }); but no luck.
The fail came from my node_modules folder.
Adding .cfignore with node_modules/ fixed the issue.
You didn't mention the version of the cf cli that you're using, but I think that this is expected behavior starting with version 6.34.0.
push now preserves relative symlinks in app files. This makes it easier to work with Node.js apps using npm link, but note that it now errors when it detects a symlink pointing outside the app folder (e.g. a node_modules folder containing external symlinks).
https://github.com/cloudfoundry/cli/releases/tag/v6.34.0
I think you're running into the second part, "how errors when it detects a symlink pointing outside the app folder". It's nothing to do with the code in your app, but rather somewhere in your project folder there is a symlink which references another file that is not under the root of your project.
If you're on a unix-like system you can run find . -type l to find all the symlinks under the current directory. Then you just need to figure out which one is pointing outside of the project root.
Options are to remove that symlink, point it to something under your project root or use .cfignore to ignore that file (which is what you ended up doing).
Hope that helps!

Installed Node + vue-cli on AWS. But get a blank page?

Ok, learning here. Installed the default vue-cli app on AWS. I do a npm run build. When I launch the default index.html I'm served a blank page. If I go into dist, there is another index.html, that serves links to js files, but still a blank page.
I'm guessing webpack wants me to launch an index.html, but don't see how I can hit that with a browser. No errors anywhere. But no Hello World either. thanks for help.
What I'm seeing in the browser:
<!DOCTYPE html><html><head><meta charset=utf-8><title>hello-world</title><link href=/static/css/app.87e65e7c83fb67c04e58d4461a7fd8e8.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.fa7eecfb52900d1cfb0a.js></script><script type=text/javascript src=/static/js/vendor.9baeef453ba99a70f46a.js></script><script type=text/javascript src=/static/js/app.cdfbb21001bbc43de4bc.js></script></body></html>
When you npm run build Webpack should produce an index.html file along with a static/ directory that contains all of your javascript and css. The link to static/ is an absolute link (i.e. http://example.org/static). When you try to open index.html as a file, the browser will look for the /static/ folder on the root of your file system, which of course it won't find.
To run it locally you need to fire up an http server locally. One option is to cd into the directory with a terminal app and run python -m http.server. Then go to http://localhost:8000/. That should work because the root of the directory tree will be the folder from where you are serving it.
Getting it running on AWS S3 will be a matter of making sure you get the static directory in the right place and get the links pointing to it. Hard to say exactly how without knowing details of how you are organizing the site in your bucket.
You can change how the static folder is saved in the webpack config if you need to: https://vuejs-templates.github.io/webpack/static.html
You will find a folder named /dist in your project directory.Just point the index.html file within the /dist directory and rest will work fine I think. I have just done that and it's working fine.
Hope it will work.
Thanks.

Resources