Vue js deploying in production seems harder then it is - nginx

I've created simple Vue JS App using Vue-cli 3. I have a digitalocean droplet with Nginx + php.
My goal is to host Vue App on the same droplet.
I have already tried:
Add certain location / to nginx conf.
Used this simple node server: https://router.vuejs.org/guide/essentials/history-mode.html#example-server-configurations
And what I get i sUncaught SyntaxError: Unexpected token <:
Interesting thing, when I use npm run build to make production resources into dist directory and use php -S localhost:8080 it is hosted like a charm. But the same thing with simple node js server causes the result on the screenshot above.
I've been struggling for 2 days straight. Halp me please.

I was struggling with the same issue. The problem was that when the browser requests the javascript and css files, the contents of the index file is sent instead.
Solved it by following step 3 of this tutorial.
Since Vue is only a frontend library, the easiest way to host it and
do things like serve up assets is to create a simple Express friendly
script that Heroku can use to start a mini-web server. Read up quickly
on Express if you haven’t already. After that, add express:
npm install express --save
Now add a server.js file to your project’s root directory:
// server.js
var express = require('express');
var path = require('path');
var serveStatic = require('serve-static');
app = express();
app.use(serveStatic(__dirname + "/dist"));
var port = process.env.PORT || 5000;
app.listen(port);
console.log('server started '+ port);
After that, since the idea is to serve index.html in the first place, I borrowed this idea and added the following to my code (notice I used sendFile if the request is html):
app.use((req, res, next) => {
res.status(404)
if (req.accepts("html")) {
res.sendFile(path.join(__dirname + "/dist/index.html"))
return
}
if (req.accepts("json")) {
res.send({error: "Not found"})
return
}
res.type("txt").send("Not found")
})

A little bit late, but I have used this to sendFile index.html up on 404 response.
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(404).sendFile(path.resolve(__dirname, "dist", "index.html"));
})
Explanation:
err will be defined when the request is erroneous. res.status will set the status to 404 code and the app will sendFile the resolved index.html. (Notice that I used __dirname and path.resolve together to build an absolute path to be safe.

Related

#Babylonjs (ES6) in Nextjs failes with unexpected token 'export'

I'm building my website with Nextjs and importing Bablyonjs was throwing up the following error.
syntaxError: Unexpected token 'export'
module.exports = require("#babylonjs/core")
I'm using the standard nextjs setup with tsconfig.json
I'm refering to this Babylon documentation and using the examples verbatim.
https://doc.babylonjs.com/extensions/Babylon.js+ExternalLibraries/BabylonJS_and_ReactJS
https://doc.babylonjs.com/divingDeeper/developWithBjs/treeShaking
After a not so insignificant amount of time searching i finally learned the following.
#babylon (es6) is not compiled into javascript and is instead nicely defined (es6) typescript friendly library of source code. (helps when wanting to treeshake)
Nextjs out of the box isn't configured to compile anything in node_modules. It expects precompiled javascript ready to consume.
Point 2. is why i received the error, nextjs was expecting compiled js and it was getting uncompiled source.
To fix this you need to add a next.config.js and configure it with next-transpile-modules and next-compose-plugins.
yarn add next-transpile-modules
yarn add next-compose-plugins
next.config.js
//const withTM = require('next-transpile-modules')(['#babylonjs']);
const withTM = require('next-transpile-modules')(['#babylonjs/core']); // As per comment.
const withPlugins = require('next-compose-plugins');
const nextConfig = {
target: 'serverless',
webpack: function (config) {
/// below is not required for the problem described. Just for reference.(es6)
config.module.rules.push({test: /\.yml$/, use: 'raw-loader'})
return config
}
}
module.exports = withPlugins([withTM], nextConfig);
It compiled without error after this.
References
Handy links i came across solving this issue.
https://github.com/vercel/next.js/issues/706
https://www.npmjs.com/package/next-transpile-modules
https://www.npmjs.com/package/next-compose-plugins
https://www.typescriptlang.org/tsconfig
https://doc.babylonjs.com/divingDeeper/developWithBjs/treeShaking
https://doc.babylonjs.com/extensions/Babylon.js+ExternalLibraries/BabylonJS_and_ReactJS
Links that helped some on the way to understanding the problem.
Test ES6 modules with Jest
https://forum.babylonjs.com/t/jest-is-crashing/12557/7
https://github.com/MichalLytek/type-graphql/issues/689
For Next.js 11, I had to slightly revise the answer from Emile:
Install the following package:
yarn add next-transpile-modules
In your next.config.js file add the following:
const withTM = require('next-transpile-modules')(["package2", "package2"]);
module.exports = withTM({
reactStrictMode: true
})
Put assets folder inside public folder. To access assets can be done by calling full path url.
await SceneLoader.Append(
'http://localhost:3000/assets/characters/avatar.glb'
);

Access variables in NextJs

I want to use variables in NEXTjs application. For this i did:
created file: .env.local with:
DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword
And i want to access this: console.log(process.env.DB_HOST, 'local variables') When i do this i get undefined. Why it happens, and how to get the variables?
If you want to access to your environment variables on client side and server side, they must be prefixed with NEXT_PUBLIC
NEXT_PUBLIC_DB_HOST=localhost
NEXT_PUBLIC_DB_USER=myuser
NEXT_PUBLIC_DB_PASS=mypassword
if you are going to use them only on the server side, then your example will work
DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword
If you are using nextjs higher than 9.4 you can use next.config.js
Snippet from nextjs documentation
https://nextjs.org/docs/api-reference/next.config.js/environment-variables
To add environment variables to the JavaScript bundle, open next.config.js and add the env config:
module.exports = {
env: {
customKey: 'my-value',
},
}

Firebase Hosting: Function not working with ServerMiddleware (Vue/ Nuxt)

I am building a project that utilises ServerMiddleware to render some pages client side only (I can't find another way of getting this working well without ServerMiddleware. Problems on refreshing pages and so on...)
The problem: Unfortunately every time I try and deploy to my Firebase Function through 'firebase deploy' I get an error:
Error: Cannot find module '~/serverMiddleware/selectiveSSR.js'
The function builds OK if I exclude the following line. Nuxt/ Vue is not including ~/serverMiddleware/ as part of its build as far as I can see.
Here is the code in nuxt.config.js to reference my serverMiddleware:
serverMiddleware: ['~/serverMiddleware/selectiveSSR.js']
Adding either the directory or path (as above) to the file itself within Build in nuxt.config.js does not help either. Maybe I am doing it wrong?
Everything works perfectly when testing (Not building) locally.
Any ideas on how I can resolve this please?
Thanks!
Ok so for anyone else who hits this, here is how I got around it.
Firstly, I don't know if this is the fault of Firebase Hosting or Nuxt (I would guess Nuxt but I stand to be corrected), but here is what to do....
1) Remove any reference to ServerMiddleware from nuxt.config.js
2) Add the following to nuxt.config.js
modules: [
'~/local-modules/your-module-name'
],
3) Create directory ~/local-modules/your-module-name in your project root
4) In the new directory, create a package.json:
{
"name": "your-module-name",
"version": "1.0.0"
}
and index.js - key thing, this.addServerMiddleware allows you to call middleware server-side
module.exports = function(moduleOptions) {
this.addServerMiddleware('~/serverMiddleware/')
}
5) Create directory ~/serverMiddleware
6) Add your middleware function to index.js in the new directory:
export default function(req, res, next) {
// YOUR CODE
next() // Always end with next()!
}
7) Update package.json with your new local module under "dependencies":
"your-module-name": "file:./local-modules/your-module-name"
Don't forget you need to do this within the functions directory too or Firebase will complain it can't find your new module

Importing "gitlab" package from MeteorJS returns empty object

I've installed gitlab in my Meteor project with meteor npm install --save gitlab and imported the package in the imports/api/foo.js file with all the following variations (the comment on the front is the log of the Gitlab object):
import Gitlab from 'gitlab'; // {}
import * as Gitlab from 'gitlab'; // { default: {}, [Symbol(__esModule)]: true }
import { Gitlab } from 'gitlab'; // undefined
const Gitlab = require('gitlab'); // {}
const Gitlab = require('gitlab/dist/es5'); // {}
const Gitlab = require('gitlab/dist/latest'); // {}
If I run just console.log(require('gitlab')) with NodeJS, I get the correct result.
How am I supposed to import 'gitlab' from a meteor application?
I tried to reproduce the issue with a clean Meteor 1.8.0.2 project and it is working fine for me:
/server/main.js:
import Gitlab from 'gitlab'
Meteor.startup(() => {
console.log(Gitlab) // [Function: Bundle]
const api = new Gitlab({
url: 'http://example.com', // Defaults to https://gitlab.com
token: 'abcdefghij123456' // Can be created in your profile.
})
console.log(api) // full API as in documentation
})
So what options do you have here?
Make sure you use gitlab on the server
Check the node_modules folder, whether it is really installed there.
Try to reset your project using meteor reset and then start again so all node_modules a rebuild and all Meteor packages are rebuild and the local dev build is rebuild. This will often fix things.
Create a fresh project and start to reproduce the issue step by step, starting from my working example and change the file structure stepwise to the structure of your project.

Ionic2 with Meteor

I have a problem using Meteor in an Ionic2 project.
The project itself should run, as it is a clone of the Meteor-tutorial:
git clone https://github.com/Urigo/Ionic2CLI-Meteor-WhatsApp
When I start the Meteor server I get this
=> Started proxy.
server/publications.ts (24, 10): Property 'publishComposite' does not exist on type 'typeof Meteor'.
server/main.ts (14, 28): Property '_options' does not exist on type 'typeof Accounts'.
server/main.ts (51, 14): Property 'createUserWithPhone' does not exist on type 'typeof Accounts'.
=> Started MongoDB.
=> Started your app.
=> App running at: http://localhost:3000/
Then I start the ionic app with ionic serve and get this in the terminal
Running live reload server: http://localhost:35729
Watching: www/**/*, !www/lib/**/*, !www/**/*.map
√ Running dev server: http://localhost:8100
When I open the App I get this error in the browser's console:
Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:8100/sockjs/info?cb=_07sz35uj7
As I understand it means that it tries to grab data from meteor but couldn't reach it. When I open the URL in the browser manually and change the port to 3000 I get back a message from meteor.
I found two hints on Google:
1) start the ionic app without livereload
ionic serve --nolivereload
2) to set __meteor_runtime_config__ to the correct URL:PORT
But hint 1 doesn't work and for hint 2 I have no idea where to place it.
While writing this I found out, that in the file node_modules/meteor-client-side/meteor-runtime-config.js the correct port is defined by
__meteor_runtime_config__ = {};
__meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL = 'http://localhost:3000';
So it looks like hint 2 is also already done.
Why is it still trying to reach the meteor server on wrong port, or is there maybe another problem?
Ok, solved it on my own again.
I had to add those lines of code to the index.html file of my ionic2 project:
<script>
__meteor_runtime_config__ = {
DDP_DEFAULT_CONNECTION_URL: 'http://localhost:3000'
};
</script>
No idea, why the config in the node_modules/meteor-client-side/meteor-runtime-config.js file is ignored.
Edit: Looks like there was a bug that is fixed in version 1.3.5
https://github.com/idanwe/meteor-client-side/issues/28#issuecomment-263252756

Resources