Aurelia skeleton sample - dist/main.js not found? - aurelia

I’m trying to run skeleton-navigation-typescript-vs on my windows machine but it fails – I see only welcome screen and in developer tools there is a message:
http://localhost:9000/dist/main.js Failed to load resource: the server responded with a status of 404
I do everything from the docs – step by step. http://aurelia.io/docs.html#/aurelia/framework/1.0.0-beta.1.0.8/doc/article/a-production-setup.
When I check in chrome developer tools in Sources tab there are only css, jspm_packages, lib and index.html – there is no dist dir.
Is this working sample? What I’m doing wrong?

You are not using the index.html provided by the tutorial. Go to your index.html and replace this:
<body aurelia-app="main">
with this:
<body aurelia-app>
When you specify a value to the aurelia-app attribute, the framework will look for a js file to start the application. More information at http://aurelia.io/docs.html#/aurelia/framework/1.0.0-beta.1.0.8/doc/article/app-configuration-and-startup
EDIT
Create a main.js file inside src folder, like this:
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging();
aurelia.start().then(() => aurelia.setRoot());
}
Re-run gulp-watch and see what happens now.

Related

Statically served vue-router app by Flask shows 404 for custom pages on Heroku

I've gone through several Stack Overflow pages and the official Vue guide, but my app still returns 404 results when going to a different page.
The structure of my app looks like this, with a client folder that has the Vue app and a server folder containing app.py that statically serves the index.html in the client/dist folder through Flask.
Contents of static.json are as outlined in the guide:
{
"root": "client/dist",
"clean_urls": true,
"routes": {
"/**": "index.html"
}
}
with just modified root folder to go to client/dist. Running the app locally with npm run serve works, as does opening it up on its Heroku page and clicking on the nav. However, directly going to a page, such as /translate, always returns 404.
I have installed the following buildpacks:
=== readiglot Buildpack URLs
1. heroku/nodejs
2. heroku/python
3. https://github.com/heroku/heroku-buildpack-static
The app is hosted here: https://www.readiglot.herokuapp.com.
On npm run build from the root directory, the dist folder is built by Heroku in the client folder.
Am I missing something? Could anyone advise as to additional configuration?
The answer is in the app.py file - you need to statically serve the file using a catch all route.
#app.route("/", defaults={"path": ""})
#app.route("/<string:path>")
#app.route("/<path:path>")
def index(path):
return app.send_static_file("index.html")
By putting the serve_static_file in the Flask app to redirect from all other routes, 404 only shows up on a true 404.

How to get Flask to see Vue build files without using webpack?

I'm pretty new to Vue and modern web development in general, so I apologize in advance. Here's the situation.
I'm trying to make a simple Flask app that uses Vue and Vuetify on the frontend. When I look up tutorials for how to marry Flask to Vue (like this one), it relies on webpack, and I can get it working just fine. When I tried to add Vuetify to the project based on the instructions of their Quick start guide, I discovered that it requires you must follow the Existing Applications guide since the project was not initialized using vue-cli3 (see bug report here). I tried following those instructions but gave up after a few confusing hours with no results.
After reading up on webpack, I've decided that for my specific application, I can afford not to use it. So I went back to the Vuetify Quick Start guide and followed the New Applications instructions, fired up Flask and this is what I get:
127.0.0.1 - - [21/May/2019 18:31:20] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [21/May/2019 18:31:20] "GET /js/app.c12f4ec0.js HTTP/1.1" 404 -
127.0.0.1 - - [21/May/2019 18:31:20] "GET /css/chunk-vendors.b7bc2226.css HTTP/1.1" 404 -
127.0.0.1 - - [21/May/2019 18:31:20] "GET /js/chunk-vendors.2eb58769.js HTTP/1.1" 404 -
127.0.0.1 - - [21/May/2019 18:31:21] "GET /js/app.c12f4ec0.js HTTP/1.1" 404 -
127.0.0.1 - - [21/May/2019 18:38:22] "GET /index.html HTTP/1.1" 404 -
The code in question:
from flask import Flask, render_template
app = Flask(__name__,
static_folder="./test/dist",
template_folder="./test/dist")
#app.route('/')
def index():
return render_template("index.html")
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True)
For the most part the Vue code is just a new project with Vuetify installed. The only change I made was in main.js where I changed what the delimiters would be so that they don't conflict with Jinja2.
import Vue from 'vue'
import './plugins/vuetify'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
delimiters: ["[[", "]]"],
}).$mount('#app')
My three main questions are:
What's wrong with the path the Flask is using to look for the static and template files?
Is it possible to use Vue with Flask without webpack?
If it is not possible, would someone kindly do an eli5 of how to integrate Vuetify into a webpack based Vue project?
Thanks in advance!
Okay so I found the answer, and it turned out to be way easier than I was making it out to be. To make it easier to replicate my steps, I'm going to start from the top.
app.py
from flask import Flask, render_template
app = Flask(__name__,
static_folder="./test/dist", # place that webpack builds to
template_folder="./test/dist")
#app.route('/')
def index():
return render_template("index.html")
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True)
In the same directory as app.py run these commands (assuming you already have vue-cli installed):
$ vue init webpack vue-app-name
$ cd vue-app-name
$ yarn add vuetify # or use npm install vuetify --save
Now you basically just follow the instructions from the Existing Applications section of the Vuetify Quick Start page:
Top of main.js
import Vue from 'vue'
import App from './App'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css' // Ensure you are using css-loader
Vue.config.productionTip = false
Vue.use(Vuetify)
<head> section of index.html
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>frontend</title>
<link href='https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons' rel="stylesheet">
</head>
And finally in the build section of index.js change the directory that web pack outputs its build to:
// Template for index.html
index: path.resolve(__dirname, '../../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../../dist'),
At this point, if you run
$ yarn build # or npm run build
$ cd ..
$ python app.py
and pop open your web browser, you should see the default Vue HelloWorld page, and you have Flask working with Vue, Vuetify and webpack all in one.
This is where I got confused. If you follow the instructions for a new Vuetify project and run the dev server, they have their own custom Hello World page. However because the Hello World page was still the default Vue page, I took it to mean that Vuetify was not installed. Really what's happening is that they have different App.vue and HelloWorld.vue files. If you replace the regular App.vue and HelloWorld.vue files with the Vuetify ones, copy the logo.svg file into the assets folder and rerun the dev server, you will get the Vuetify landing page.
Anyways, I feel like an idiot, but hopefully, this helps out another Flask/Vue/Vuetify/Webpack newbie.
This was done using python 3.7.3 and vue-cli 3.7.0
I have multiple projects with Vue and Flask and have found that webpack is the best approach. I disliked the Vue-CLI becuase it was too difficult to specify the paths of local files and bundled files on build. I know it is a learning curve at first but worth the day or two if you invest the time.
You should use Flask-Webpack to allow flask to locate assets which have been hashed and bundled. Along with a webpack plugin to create the manifest JSON that provides the link. When using flask webpack you also need to specify you folder paths directly as you have done.
I have this setup in my webpack config:
const ManifestPlugin = require('webpack-manifest-plugin')
...
plugins: [
new ManifestPlugin({
writeToFileEmit: true,
seed: {
publicPath: '/'
},
generate: (seed, files) => ({
...seed,
'assets': files.reduce((manifest, { name, path }) => ({ ...manifest,
[name]: path }), {})
})
})
]
this creates a manifest.json file which looks like this:
{"assets":{"base_css.css":"static/css/base_css.1bf3ff18.css",
"base_css.js":"static/js/base_css.1e6b291b.js",
"chunk-vendors.js":"static/js/chunkvendors.f92da40c.js",},
"publicPath":"/"}
Having setup your project I envision it is fairly straight forward to add Vuetify following the add to existing project using npm and imports.
Do note that when using Vue-Cli and/or webpack you cannot change the vue delimiters. From the API docs on delimiters: "Restrictions: This option is only available in the full build, with in-browser compilation."
But this last point shouldn't be a problem since your html templates and vue templates will be separately decoupled so the {{ }} crossovers wont matter, they are contextual.
I was facing a similar issue. The answer provided by #clayton-ramstedt provided 200 status code but it was loading a blank page instead of the required static UI. Reason being that the index.html referred various other JS and CSS files and the above answer returned index.html for all of them.
The below code worked for me.
from flask import Flask, send_from_directory
import os
app = Flask(__name__,
static_folder="./test/dist",
template_folder="./test/dist")
#app.route("/", defaults={"path": ""})
#app.route("/<path:path>")
def serve_frontend(path):
if path != "" and os.path.exists(app.static_folder + '/' + path):
return send_from_directory(app.static_folder, path)
return send_from_directory(app.static_folder, 'index.html')
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True)
This will render JS and CSS files properly and when we hit some other routes (like /login or /dashboard) those will be handled by index.html accordingly.
Make sure to provide path converter type because the default string type will not render the JS and CSS files which contain slashes.

Can't find static assets from express/npm module

tldr;
My project is an NPM module that is used by an ExpressJS server. The server needs to specify an endpoint and my module will do the rest. How do I get my module to load the correct html page and grab the correct js/css files from the correct path?
The Problem
I'm running into a problem where I can see the directory structure of the site, using the serveIndex library, and all the files are in their correct directories but for some reason when I try to load any of the files, whether from the serveIndex view or from the actual endpoint where it should load, I get nothing but 404 errors.
Here's an example if someone wanted to use this NPM module from their project.
app.js (their server)
const express = require('express')
const { adminAreaConfig } = require('express-admin-area')
const app = express()
const adminArea = adminAreaConfig(express) // my module being passed the "express" library
app.use('/admin', adminArea) // specify a URL to use my module
app.listen(3000, () => console.log('\n\nServer Online\n\n'))
Here's an image of my projects dir structure after it's been built.
Going off of a console.log(__dirname), which returns <long path string>/express-admin-area/build/src, I then tell my module, using the express reference passed by the actual server in the code above, to look in the views directory with
... import libraries etc ...
const adminAreaConfig = express => {
const adminArea = express.Router()
adminArea.use('/', express.static(__dirname + '/views') // sets my modules views to the "http://localhost:3000/admin" path
adminArea.use('/dirs', serveIndex(__dirname)) // will get into this later
... some other stuff like exports etc ...
This then attempts to load the index.html file in the express-admin-area/build/src/views directory but fails because it can't locate the CSS and JS files inside express-admin-area/build/src/views/static/css or .../js.
First, I know it fails because instead of looking for http://localhost:3000/admin/static/css/styles.css it looks for http://localhost:3000/static/css/styles.css, so that's another problem I need to solve entirely.
Second, looking back at the small code sample above, adminArea.use('/dirs', serveIndex(__dirname)), I'm using the serveIndex library in an attempt to view the directory structure. If I go to http://localhost:3000/admin/dirs I get the correct directories and files in the browser
But now, if I try to view an actual file I'm met with the error Cannot GET /admin/dir/main.js for example if I were to go to http://localhost:3000/admin/dir/main.js, but I can continue going deeper in the directories if I wanted such as the controllers or routes directories from the image.
What I want
I need a way to get these static assets to load. If I point my module to a basic html page with a simple <h1>Hello, World!</h1> then that's what Ill get but trying to load any outside scripts/stylesheets is when I get the 404 errors and nothing loads.
I'll be answering my own question.
The solution is actually pretty simple. The view layer of this module is handled by React, CRA to be specific. CRA will look for some specific environment variables, one of them being PUBLIC_URL. All I had to do was
Create a .env file in the root directory of my CRA
add PUBLIC_URL="/admin"
Afterward, it's just rebuilding the project, yarn build, and reset the server. CRA will then look at http://localhost:3000/admin/static/... instead of http://localhost:3000/static/... for static assets.

Deployed Vue app managed with 'webpack-simple' doesn't work

I'm working on my first Vue app, which uses the Moment library and Firebase (if that matters). I use default Webpack simple. To deploy the app I did npm run build.
But when opening directly index.html (the app is deployed here) I get "Failed to load resource: the server responded with a status of 404 (Not Found)" error message and the app doesn't work at all as a result.
I have no idea how to troubleshoot this issue since there's no more information that this in DevTools...
Any idea about what I can do next?
App source code
Remove the first forward slashes of all your assets path.
It should fix your problem.
<script src="/dist/build.js"></script> // No!
<script src="dist/build.js"></script> // Yes!
Vue adds it by default during the build process, in order to make your assets relative to the root folder.

Upgrading to Durandal 2.0 from 1.2 - shell.html not found

i'm getting a 404 error when trying to activate my shell. it seems to find shell.js but then indicates that it can't find shell.html because it's looking in the wrong place!
i tried forcing the convention to expressly tell it where to look, but it's still not working. like so: viewLocator.useConvention('viewmodels', 'views', '');
but i still get:
App/viewmodels/shell.html 404 (Not Found)
Obviously it shouldn't be looking in app/viewmodels/, it should look in app/views/
the difference in my project is that i'm not using the '/scripts/' folder for 3rd party stuff, i am using my own folder called '/content/'. i'm also putting almost everything that has to do with durandal in the '/app/' folder.
here's the structure of some key files in my project:
+app (folder)
main.js
> durandal (folder)
app.js
r.js
require.js
text.js
viewEngine.js
viewLocator.js
> plugins (folder)
router.js
> viewmodels (folder)
shell.js
> views (folder)
shell.html
in main.js >
here's where i set the shell to be called:
app.setRoot('viewmodels/shell');
and here's the paths also in main.js:
paths: {
'text': 'durandal/text',
'durandal': 'durandal',
'plugins': 'durandal/plugins',
'transitions': 'durandal/transitions'
}
in shell.js >
well, it doesn't really matter because it's already thrown the 404 by this point.
any ideas?
i see now. i had the wrong path to the defined modules in main.js. not sure why they weren't throwing an error, but anyhow, here's what i changed:
from:
define(['../app/durandal/system', '../app/durandal/app', '../app/durandal/viewLocator'], function (system, app, viewLocator) {
to:
define(['durandal/system', 'durandal/app', 'durandal/viewLocator'], function (system, app, viewLocator) {
seems to work now.