express.js (static server) isn't loading my javascript - javascript

My I'm using express.js as a static server and the code is looking like this:
var express = require('express'),
app = express();
app
.use(express.static('./public'))
.get('*', function (req, res) {
res.sendfile('public/main.html');
})
.listen(3000);
My file structure:
.
├── bower_components
│   ├── angular
│   ├── bootstrap
│   └── jquery
├── node_modules
│   └── express
├── public
│   ├── main.html
│   ├── src
│   └── views
└── server.js
My HTML is looking like this:
<!DOCTYPE html>
<html ng-app="ContactsApp">
<head lang="en">
<meta charset="UTF-8">
<title> Contacts </title>
<base href="/" />
<link rel="stylesheet" href="src/bootstrap.min.css"/>
</head>
<body>
<script src="../bower_components/jquery/dist/jquery.min.js"></script>
<script src="../bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="../bower_components/angular/angular.min.js"></script>
<script src="src/app.js"></script>
</body>
</html>
The Browser is not loading the angular library und I'm getting a error Resource interpreted as Script but transferred with MIME type text/html: "http://localhost:3000/bower_components/angular/angular.min.js"..
What I'm doing wrong? I couldn't find any answers from the previous questions.

This line says that you are serving your static files from ./public
use(express.static('./public'))
So only this tree will be exposed to the public:
├── main.html
├── src
└── views
Your bower_components diretory is not in public, thus it is not exposed.
To fix this, you can create a .bowerrc file in the root of your application with the following:
{
"directory": "public/bower_components/"
}
It will tell to bower to install the bower components in public instead of the default bower_components directory. Just run bower install after creating this file, and don't forget to update your index.html with the updated paths.
EDIT: Dont be tempted to change use(express.static('./public')) by use(express.static('./')) cause it will easily resolve your issue. It will expose your whole directory structure (and all your files) and is not good for obvious security reasons :)

Related

What is the purpose of the 'main.js' file in a Vite.js app?

I am building a Vite.js app and am not sure I understand the purpose of the main.js file. I am having a hard time finding a clear explanation of this in the vite docs. I found an S/O post with a similar question in regards to a Vue app, but am not sure if the answers apply to Vite as well.
I am new to working with these frontend build tools, as well as modules in general, and want to make sure I understand what's happening. I know that index.html serves as the entry point to the app during development, but what is the purpose of main.js exactly?
My file structure is as follows:
├── package.json
├── vite.config.js
├── index.html
├── main.js
├── styles.css
├── pages
│ ├── login
│ │ ├── login.html
│ │ ├── login.js
│ ├── home
│ │ ├── home.html
│ │ ├── home.js
│ │
In the main.js you create the app instance, configure it and then mount it to a divtag. This is the way forward for any vue3 application and is independent on the bundling tool used (such as vite). A typical example for a main.jsis as follows:
import {createApp} from 'vue'
import store from './store.js'
import router from './routes.js'
import i18n from './i18n.js'
import App from '../components/App.vue'
// mount is the last one ...
const myApp = createApp(App);
myApp.use(store)
.use(router)
.use(i18n)
.mount('#app');
In the index.html you would load this main.js:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>MyApp</title>
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<meta name="theme-color" content="#ffffff">
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/js/main.js"></script>
</body>
</html>

Vue CLI 3 SPA in Subfolder, Static HTML Pages in Root

Using Vue CLI 3 how can I create a project that contains some static html files at the root of the public directory and an SPA inside of an app folder?
I'd like several static html files including an index.html at the root of the project. I want these static HTML files served outside of the SPA for SEO purposes.
Right now, my project structure looks like this:
.
├── README.md
├── babel.config.js
├── package.json
├── public
│   ├── app
│   │   └── index.html
│   ├── favicon.ico
│   └── index.html
├── src
│   ├── App.vue
│   ├── assets
│   │   └── logo.png
│   ├── components
│   │   └── HelloWorld.vue
│   └── main.js
├── vue.config.js
└── yarn.lock
I've tried many different combinations of publicPath and indexPath values in my vue.config.js file. None have achieved what I'm hoping for. I'd like yarn serve to serve both the static HTML files and SPA locally for development. More importantly, I'd like the static HTML files and the SPA properly bundled into the dist folder when I run yarn build. I haven't been able to achieve either goal.
With the configuration below, the public/index.html file that's meant to be static and only displaying at / is being served at both http://localhost:8080/ and http://localhost:8080/app/. Interestingly, at http://localhost:8080/app/ the js resources are being injected into the response along with what's meant to be static HTML.
After running yarn build with the config below I'm left with a /dist/app/index.html file that has the static index.html file code with no javascript injected instead of the SPA code with javascript injected. The /dist/index.html file has the static HTML I expect but all the javascript that's meant for the SPA is injected.
// vue.config.js
module.exports = {
publicPath: '/app/',
indexPath: 'index.html'
}
How can I configure this project to support static html files at the project root and an SPA in the app folder?
You can leverage the feature of Vue CLI to build multipage apps and actually have only one page...
// vue.config.js
module.exports = {
pages: {
index: {
// entry for the page
entry: "src/main.js",
// the source template
template: "public/app/index.html",
// output as dist/app/index.html
filename: "app/index.html",
// when using title option,
// template title tag needs to be <title><%= htmlWebpackPlugin.options.title %></title>
title: "App Index Page",
// chunks to include on this page, by default includes
// extracted common chunks and vendor chunks.
chunks: ["chunk-vendors", "chunk-common", "index"]
}
}
};

Generate i18n static HTML using Parcel bundler

I'm using Parceljs to bundle html and js. It works really well with less configuration.
Now, I'm facing i18n issue.
Google recommends using different URLs for each language version of a page.
https://support.google.com/webmasters/answer/182192
So, I want to generate language specific static html from one template like below.
.
├── dist
│ ├── ja
│ │ └── index.html
│ ├── app.c328ef1a.js
│ └── index.html
├── i18n
│ ├── default.json
│ └── ja.json
└── source
├── app.js
└── index.html
source/index.html
<html>
<body>
<h1>__TITLE__</h1>
<script src="/app.js"></script>
</body>
</html>
i18n/default.json
{
"__TITLE__": "Hello world!"
}
i18n/ja.json
{
"__TITLE__": "こんにちは 世界!"
}
Is there a way to deal with this issue using parceljs?
Or, should I write a code for prebuild?
Thank you.
Self answer:
I found a great answer here.
It mentions node-static-i18n package that generates i18n static HTML.
This tool isn't a plugin of parceljs, but it seems to be able to generate expected results.
Welcome yet another answer.

Copy NPM module/library to distribution folder using Gulp

Most web applications these days include various prebuilt libraries e.g. Backbone.js.
I want, when I compile my web application with Gulp, to output a single compressed JavaScript file of the library/module I installed using NPM e.g. backbone-min.js.
For example, when you install Backbone.js from NPM the following is installed into the node_modules folder:
.
├── backbone
│   ├── LICENSE
│   ├── README.md
│   ├── backbone-min.js
│   ├── backbone-min.map
│   ├── backbone.js
│   └── package.json
I want to be able to run gulp compile and get the following result in my web application distribution folder:
.
├── index.html
├── scripts
│   ├── backbone-min.js // this is the file I want to copy or generate
│   ├── main.min.js
The way I see it Gulp either needs to either:
compile and minify the library/module and write it to a file called backbone-min.js to the scripts folder, or
copy the backbone-min.js in the backbone module folder to the scripts folder.
What is the best way of doing this?
Short Answer
gulp-useref concatenates all the file references in your main .html file encapsulated by <!--build:js /lib.js--> for javascript files and <!--build:css /lib.css--> followed by <!--endbuild-->
The result will be:
index.html
├── scripts
│ ├── backbone-min.js // this is the file I want to copy or generate
│ ├── main.min.js
as you and every good developer wants it to be.
Long Answer
My recommendation would be to use Bower as your app dependencies manager and npm as your development dependencies manager.
Use gulp-wiredep to automatically inject dependencies as you install/uninstall them and that way you don't have to maintain library css and js files in your index.html.
Uset gulp-inject to automatically inject your own css and js files as your add/remove them. This will result in never ever having to maintain application dependencies manually.
With wiredep, inject and useref you never have to touch your dependencies again.
This is what my index header and end of body look like:
<!---------------------------- Bower Managed Styles ----------------------------->
<!--build:css css/lib.css-->
<!--bower:css-->
<link rel="stylesheet" href="../bower_components/..."
<!--endbower -->
<!--endbuild -->
<!---------------------------- Application Styles ------------------------------->
<!--build:css css/app.css-->
<!--inject:css-->
<link rel="stylesheet" href="content/css/bootstrap ..."
<!--endinject-->
<!--endbuild-->
<!--------------------------- Bower Managed Javascript ------------------------->
<!--build:js js/lib.js-->
<!--bower:js -->
<script src="../bower_components/ ..."> </script>
<!--endbower -->
<!--endbuild -->
<!-------------------------- Application Javascript --------------------------->
<!--build:js js/app.js-->
<!--inject:js-->
<script src="app/ ..."> </script>
<!--endinject-->
<!--inject:templates:js-->
<!--endinject-->
<!--endbuild-->
The comments are tags used by the tools I just mention in order for them to know where to insert the dependencies of interest.
My application entry is a single template reference. Needless to say I never visit index.html. I never have a reference to a file that does not exist. I never have a file that does not have a reference.

OpenShift unable to find css and js files

When running my openshift app none of the CSS or javescript files are loading.
I have specified the directory in the server.js:
app.use(express.static(__dirname));
In the index.html I have specified the location of the folders:
<link rel="stylesheet" href="style.css" type="text/css" media="screen">
<script src = "controllers/controller.js"></script>
The structure of the folder looks like:
mytest
├── README.md
├── controllers
│   └── controller.js
├── deplist.txt
├── index.html
├── node_modules
├── package.json
├── server.js
└── style.css
When I open the website and open the developer console in chrome I get the following errors:
http://mytest-jamestreasure.rhcloud.com/controller.js 404 Not Found
http://mytest-jamestreasure.rhcloud.com/controllers/controller.js 404 Not Found
I'm not aware of anything else that needs to be added.
Link to the my openshift: http://mytest-jamestreasure.rhcloud.com/
Your construct for defining static content access seems to be correct. Make sure that you are using it with your app context though, e.g.:
myApp.app.use(express.static(__dirname));
Such a problem could be revealed either locally when trying to run the server.js or using rhc tail mytest to check the OpenShift remote logs.
I would also recommend using a dedicated directory for static content that is meant to be used publicly, rather than exposing everything:
app.use(express.static(__dirname + '/public'));
The issue was because of the following warning, which I was ignoring:
Warning: express.createServer() is deprecated, express
applications no longer inherit from http.Server,
please use:
var express = require("express");
var app = express();
It meant I had to change:
self.app = express.createServer();
to:
self.app = app;
This was in the self.initialise = function()

Categories

Resources