Laravel websockets failed after reinstall npm - laravel

I was using Laravel websockets and it worked fine till last night I did remove **node_modules** folder and **package-lock.json** file for some reasons.
I used these commands after that:
npm install
npm run dev
I expect that everything workes like before because I removed all changes.
But know there's log message in console without any try and immediately after page load with this message:
This is my echo setting, Just for information:
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
wsHost: window.location.hostname,
wsPort: 6001,
wssPort: 6001,
disableStats: true,
encrypted: false,
enabledTransports: ['ws', 'wss']
});
UPDATE :
I did clean npm cache using npm cache clean --force and did above scenario again but there's no difference in result.
Does anyone knnow where's my mistake?
Thanks in Advance

By removing the package-lock.json file you are now using different versions of all packages (within the constraints of your package.json file). You could solve this by:
Restoring package-lock.json
Removing node_modules
Run npm install
Run npm run dev
This will install the verious which you previously had since the the lock file is used exactly for that purpose.

Related

Pusher referencing development app key in production

I've been trying to diagnose an issue with pusher not working on production, when it works fine locally. This morning I discovered after tinkering around in the console, that when I do this on production:
Echo.private('App.Models.User.1');
I get this output:
which is the key from my development .env file:
PUSHER_APP_KEY=f9d9********011e
My production key shown in pusher is:
key = "07ae********2d4"
My production .env file also references this correct production key:
PUSHER_APP_KEY=07ae*********2d4
HOWEVER, that is NOT what's actually being used by the production application (see prior screenshot).
I'm not doing anything different from the "stock" implementation of importing pusher in my bootstrap.js file:
import Echo from 'laravel-echo';
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
encrypted: true
});
After searching my codebase, I found that the key gets hard-coded into the public/js/app.js file when you run npm run dev locally. I verified this by changing the key in my .env file and running npm run dev which then updated the key reflected in the app.js file.
I then went out to my production site's FTP and downloaded the app.js file, and sure enough, the development key is hard-coded in the app.js file.
If I update the app.js file to reflect the correct key, and then run Echo.private('App.Models.User.1'); again, this is the output, which shows the correct key:
And also, notifications start working as expected after making that change. However, that's obviously problematic as every time I deploy, it will be overwritten by the dev value.
Could it be my build process? (also see this SO question I asked yesterday)
What the actual *** is going on here?
I've not had any other issues with npm not building things correctly (that I'm aware of), but it seems that the code in my app.js file must be getting generated via the .env file and somehow my production environment is not referencing the correct key?
Here are some details around my build process (I use Github Actions).
Here is my github actions .yml file:
steps:
- name: Set up MySQL
run: |
sudo systemctl start mysql
mysql -e 'CREATE DATABASE testdb;' -uroot -proot
mysql -e 'SHOW DATABASES;' -uroot -proot
- uses: actions/checkout#main
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
- name: Clean Install
run: npm ci
- name: Compile assets
run: npm run prod
- name: Execute tests (Unit and Feature tests) via PHPUnit
run: vendor/bin/phpunit
from my package.json file:
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
UPDATE:
My public folder, and in turn my public/js/app.js file is getting pushed to source control. I just deleted it from my repo and pushed the code to production, and now I'm getting a jquery not defined error, which tells me that the app.js file isn't getting re-created during my build process.
UPDATE:
My .env file is not in source control, so the github action is using .env.example which has the variables but no values, and has a couple of other "mix" variables, which may be the problem.
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
as mentioned earlier in the question, my bootstrap.js file is referencing those 2 MIX_PUSHER_* variables:
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
encrypted: true
});
I guess I need to set up a github environment variable for the app key for each environment?
UPDATE:
I found this SO answer that details how to create a github secret and basically put your whole environment file in it, but it's saying it's an invalid:
The environment file is invalid!
Failed to parse dotenv file. Encountered unexpected whitespace
The problem occurs from your js. It seems that you are using the development env in your js for production. Make sure that you are compile your js files for production in your live environment.

Safari can't connect to secure laravel websocket

I'm running an app, where I use laravel-websockets, with the pusher replacement and a self created websocket instance. For SSL I used a letsencrypt certificate and the nginx reverse proxy "Same location for websockets and web contents" approach. On my nginx TLS 1.2 and 1.3 is enabled. Now on Firefox and Chrome all is working fine, but on Safari (version 14.1.2, tested on a macOS Mojave 10.14.6) I get the following error in the console:
WebSocket connection to 'wss://example.com/app/asdfasdf?protocol=7&client=js&version=7.0.3&flash=false' failed: Unexpected response code: 401
These are my echo options:
const echoOptions = {
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
wsHost: window.location.hostname,
wsPort: 80,
wssPort: 443,
forceTLS: true,
enabledTransports: ['ws', 'wss'], // <-- disable pusher api fallback
disableStats: true,
};
window.Echo = new Echo(echoOptions);
I searched a lot for any kind of similar issues, but I can't find an answer.
Any ideas or help would be awesome!
I finally figgered it out:
In the "getting started" installation section mentioned here:
https://beyondco.de/docs/laravel-websockets/getting-started/installation
They say install the latest stable version with:
composer require beyondcode/laravel-websockets
This installs version 1.12.0
To fix this issue I just removed the stable version and installed the latest beta:
composer remove beyondcode/laravel-websockets
composer require beyondcode/laravel-websockets "2.0.0-beta.36"
I had some dependencies that can't be resolved, so I needed to downgrade doctrine/dbal from version 3.1 to 2.9.
Then I backed up my old config/websocket.php and published the new one of the new package with:
cp config/websocket.php config/websocket.old.php
rm config/websocket.php
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"
There I adjusted some values, e.g. allowed_origin and enable_client_messages.
Finally don't forget to kill to old websockets:serve process (if its running) by searching the process id with ps aux | grep websocket and restart the websocket with:
kill <process id>
php artisan websockets:serve
PS:
I also updated pusher/pusher-php-server to version 5.0 not 3.0 as they mentioned here and used the lates npm pusher-js package 7.0.3

Laravel Nova tool wouldn't update if symlink is set to true on composer.json

So I am running into a weird issue. I used Laravel Nova (2) command to generate a tool. It sits at ./nova-components/CustomNovaDashboard. In order for the deployment to work on Laravel Vapor, I had to add the below to my parent composer.json.
{
"type": "path",
"url": "./nova-components/CustomNovaDashboard",
"options": {
"symlink": false
}
}
This above allows the code to get deployed, because the absence of symlink in options would otherwise throw the following error:
include(/tmp/vendor/composer/../acme/custom-nova-dashboard/src/ToolServiceProvider.php): failed to open stream: No such file or directory
But the problem now is that when I run npm run watch inside ./nova-components/CustomNovaDashboard, the code in development never updates, because somehow there is a copy of the code that sits in vendor/acme/custom-nova-dashboard that doesn't pick up the changes.
How can I solve this?
I found a solution, it was quite simple.
In my vapor.yml, I had to add COMPOSER_MIRROR_PATH_REPOS=1 before composer install.
build:
- 'COMPOSER_MIRROR_PATH_REPOS=1 composer install'
- 'php artisan event:cache'
- 'npm ci && npm run dev && rm -rf node_modules'
This ensures the symbolic link generated by nova:tool works on dev and prod similarly.
Just don't forget to set "symlink": true in your composer.json. Or leave it as is originally generated by the nova:tool command.

Vue.js App on Heroku Server: Cannot GET /. How Do I Solve This?

When I enter my URL for my Vue.js application (https://harrishealthtest.herokuapp.com/), the browser takes me to the homepage. Good. However, when I click on the 'Start' button, that's supposed to take me to '/test', I get this message 'Cannot GET /test'.
What am I doing wrong? I have history mode enabled in my routing. I'm not sure if that is causing issues. Or if it's something to do with the connectivity between my Vue.js app and my Laravel REST API. Both are on separate domains. When I click on 'Start', the app is supposed to take me to '/test', and that's where the data from the API is received.
This is what I currently have in my App.vue file:
mounted() {
fetch('https://pure-mountain-87762.herokuapp.com/', {
method: 'get'
})
.then((response) => {
return response.json()
})
// 'jsonData' refers to the json parsed response
.then((jsonData) => {
this.testData = jsonData.data
})
What kind of issue am I having here? Routing? API connectivity? Or something else?
It seems heroku is pointing to the server instead of the client. I had the same error a few weeks back. Two things:
If you are running two npm commands, resume them in the json file that heroku is pointing at. This is an example:
"scripts": {
"client-install": "npm install --prefix client",
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"heroku-postbuild":
"NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
Add that heroku-postbuild line.
You have to play with the commands in your dev environment, in your computer. Make sure it works in your computer, then push up.
Secondly and this is kinda hacky, however it works for me.
Got to Settings of your app in Heroku, click on Reveal Config Vars button and add this env variable:
DANGEROUSLY_DISABLE_HOST_CHECK=true
This helped me. Hope it helps you.

Laravel-Mix + BrowserSync Not Loading at localhost:3000

I'm trying to set up BrowserSync to work with my Laravel project. However, when I run npm run watch, localhost:3000 doesn't load. I'm not getting any compilation errors in the terminal. Interestingly enough, the UI dashboard on localhost:3001 works perfectly fine.
If I run php artisan serve, localhost:8000 loads up fine, but of course, it's not connected with BrowserSync.
My webpack.mix.js file looks like this:
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');
mix.browserSync({proxy:'localhost:3000'});
I'm using the following versions:
Laravel-Mix: 4.0.7
browser-sync: 2.26.7
webpack-dev-server: 3.8.0
browser-sync-webpack-plugin: 2.0.1
Any thoughts?
Install these two plugins:
"browser-sync": "^2.26.5"
"browser-sync-webpack-plugin": "^2.0.1",
mix.browserSync('http://localhost:8000/');
I was able to reload via brosersync adding injectChanges: false to my browsersync line.
you must do it like so:
mix.browserSync({
proxy: "http://localhost:8000"
});
The BrowserSync docs states that you can set ui: false
This way you can then set the port: 8080 or whatever value you want that's not being used. Here's how implement it.
if (!mix.inProduction()) return mix.browserSync({
hot: true,
ui: false,
open: true,
watch: true,
https: false,
files: [
'./app/*',
'./routes/*',
'./public/*',
'./storage/*',
'./stories/*',
'./resources/*'
],
port: 8080,
host: '0.0.0.0',
proxy: {
target: "http://yourlocal.dev",
ws: true
}
});
In your webpack.mix.js, add the following:
mix.browserSync({
proxy: "http://localhost:8000"
});
After that, run the following commands
**npm uninstall browser-sync-webpack-plugin**
**npm install browser-sync-webpack-plugin**
The above will automatically open **http://localhost:3000/** on your browser
Add this script before Tag:
document.write("<script async src='/browser-sync/browser-sync-client.js?v=2.27.7'><\/script>".replace("HOST", location.hostname));
If not work change your webpack.mix.js like this and the the above script before </ body> Tag:
const mix = require("laravel-mix");
//Compiling scss to css
mix.sass("public/assets/css/style.scss", "public/assets/css/style.css");
mix.browserSync({
proxy: "http://localhost/myapp/", //Your host
files: [ //Files for watching
"./app/**/*",
"./routes/**/*",
"./public/assets/css/*.css",
"./public/js/*.js",
"./resources/views/**/*.blade.php",
"./resources/lang/**/*",
],
});
Then run: npm run watch
When you start the Laravel server via php artisan serve, this will be printed in the terminal:
Starting Laravel development server: http://127.0.0.1:8000
After starting the Laravel server, I changed the code in the webpack.mix.js file from this:
mix.browserSync();
To that:
mix.browserSync({
proxy: "http://127.0.0.1:8000",
});

Resources