Reputation: 4202
I apologise by the confusing title but I am completely baffled by this and I think it has something to do with how Express serves static files but cannot be of that for sure.
I am creating a simple Vue app served by Express statically.
server/app.js (entry point)
import express from "express";
import morgan from "morgan";
import path from "path";
import bodyParser from "body-parser";
const app = express();
// Sends static files from the public path directory
app.use(express.static(path.join(__dirname, "..", "public")));
// Use morgan to log request in dev mode
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true,
}));
app.listen(process.env.PORT || 3000, () => {
console.log(`Listening on port: ${process.env.PORT}`);
});
// Server index.html page when request to the root is made
app.get('/', (req, res, next) => {
res.sendFile("index.html", {
root: path.join(__dirname, "..", "public"),
});
});
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Hello World</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
public/main.js
import Vue from "vue";
import BootstrapVue from "bootstrap-vue";
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap-vue/dist/bootstrap-vue.css";
import App from "./App";
Vue.use(BootstrapVue);
Vue.config.productionTip = false;
/* eslint-disable no-new */
new Vue({
el: "#app",
components: { App },
template: "<App/>",
});
public/App.vue
<template>
Hello World!
</template>
<script>
export default {
name: "App",
};
</script>
<style>
#app {}
</style>
App.vue and main.js will only be loaded in if I uncomment that statically serving line.
This is just a simple UI page, nothing extravagant. In Chrome, I get a blank page with just the title "Hello World" on the tab. I am not able to open DevTools either and the Chrome extension I have does not recognise Vue as running on the page
In Mozilla, same result as Chrome but can see DevTools and it is just the basic HTML and there is no sign of other files (even if I serve the files in public
) being loaded. There are also no errors in the logs here.
There are no errors in the server logs. I used to get a response in the logs when hitting the root endpoint but, for some reason, I no longer am.
I realise this is not a lot to go off but if anyone has any initial thoughts they would be much appreciated :)
EDIT
To clarify, when I serve files from public
dir, I can hit them in the browser i.e. http://localhost:3000/App.vue
EDIT 2
I have added a basic webpack.config
to bundle my Vue and JS files but I am getting the same behaviour.
webpack.config.js
const path = require("path");
const nodeExternals = require("webpack-node-externals");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: `${__dirname}/public/main.js`,
output: {
path: path.join(__dirname, "dist", "client"),
filename: "client.min.js",
},
target: "node",
resolve: {
extensions: [
".js",
".vue",
],
modules: [
"node_modules",
],
},
externals: [
nodeExternals(),
],
module: {
loaders: [
{
test: /\.vue$/,
loader: "vue-loader",
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
query: {
presets: [
"es2015",
],
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true,
}),
],
};
When looking at the DevTools in Firefox, the <script>
to include client.min.js
is present but there is still nothing displayed.
Upvotes: 1
Views: 1289
Reputation: 165065
Your current project structure needs a bundler like Webpack. As mentioned in the comments, this is not something you can simply "add later".
First, single-file .vue
components must be built. Browser's don't know how to interpret the format. This task is usually done by a loader (see https://github.com/vuejs/vue-loader).
Second, browsers don't generally support module imports (this is changing though) so you need something to turn all those import
statements into a bundle of scripts that can execute in your HTML page.
I highly recommend starting your project via the vue-cli tools. See https://github.com/vuejs/vue-cli.
You can work with Vue by including it in your HTML page, ie
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
but this will fundamentally change how your source code is organised and you may find it impossible to make use of some 3rd party inclusions unless they too support general <script>
tag use. You'll need to create components using the Vue.component()
(or similar) syntax.
Upvotes: 1