Pusher referencing development app key in production - laravel

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.

Related

I can't run 'npm run dev' since Laravel updated with Vite

Taylor Otwell announced that new Laravel projects now will run with Vite and that Vite is installed by default. I can't seem to be able to run dev environment 'npm run dev'
I installed new laravel project, installed Laravel JetStream with SSR and teams support hit the 'npm install command'.
Every time I run npm run dev it shows this:
And if I open the local link, it shows this:
Why can't I user npm run dev and compile my files?
This is package.json for my brand new laravel app
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build && vite build --ssr"
},
"devDependencies": {
"#inertiajs/inertia": "^0.11.0",
"#inertiajs/inertia-vue3": "^0.6.0",
"#inertiajs/progress": "^0.2.7",
"#inertiajs/server": "^0.1.0",
"#tailwindcss/forms": "^0.5.2",
"#tailwindcss/typography": "^0.5.2",
"#vitejs/plugin-vue": "^2.3.3",
"#vue/server-renderer": "^3.2.31",
"autoprefixer": "^10.4.7",
"axios": "^0.25",
"laravel-vite-plugin": "^0.2.1",
"lodash": "^4.17.19",
"postcss": "^8.4.14",
"tailwindcss": "^3.1.0",
"vite": "^2.9.11",
"vue": "^3.2.31"
}
}
and if I try hitting 'vite' in the terminal I get this:
If you don't want to use vite but mix instead in your new laravel project, you can just get the usual behavior of npm run dev back with the following changes:
Install Laravel Mix (because by the new installation it is not there anymore):
npm install --save-dev laravel-mix
Create a webpack.mix.js file, if it is not there, and make sure it has the following content:
const mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel applications. By default, we are compiling the CSS
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css', [
//
]);
Update package.json:
"scripts": {
- "dev": "vite",
- "build": "vite build"
+ "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"
}
Remove vite helper functions (if they are there):
- import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
createInertiaApp({
title: (title) => `${title} - ${appName}`,
- resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
+ resolve: (name) => require(`./Pages/${name}.vue`),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props) })
.use(plugin)
.mixin({ methods: { route } })
.mount(el);
},
});
Update environment valiables (in .env, VITE_ prefix to MIX_):
- VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
- VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
+ MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
+ MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
Remove Vite and the laravel Plugin
npm remove vite laravel-vite-plugin
Remove the Vite config file:
rm vite.config.js
Remove these paths from .gitignore:
- /public/build
- /storage/ssr
If you created some code already with vite, you must have some more changes in your blade files, check out this article. But if it is a new project, you just good to go.
For anyone experiencing the problem:
With Vite, running npm run dev will only build your frontend and start watching any changes to your code to rebuild automatically.
To actually start your server, you need to run php artisan serve in a separate command window.
Source (See With Laravel section): https://laravel-vite.dev/guide/essentials/development.html#with-laravel
Had the same issue, but none of the mentioned solutions worked for me. Instead I saw an issue with the <script> src's in the head-section of the rendered html.
screenshot of script src's buggy
Added in vite.config.js the following code which solved the issue.
server: {
hmr: {
host: 'localhost',
},
}
Edit:
The issue was reported in laravel's vite-plugin repo and it will be fixed with this PR
I was having the same issue, I did the following and it finally worked!
I did:
Upgraded my Laravel Project to Latest (v9.19.0). Infact i upgraded all my packages to latest one too.
Remove the node_modules and install the dependency using npm install
Make sure you follow the upgrade guides properly.
Run the server using php artisan serve
And run the dev server using npm run dev
If you done properly, it should start the dev server and all your javascript code should compile. (If it succeed, you will see the desired output.)
I fixed the issue in the above steps.
Vite needs an updated node version.
You can download the latest node version then run npm install and npm run dev
To create the server you can use php artisan serve
If you are using laragon as a local deployment you can set the --host flag to the virtual host url of the app ,it worked for me
Try:
.env :
APP_URL=http://localhost:8000
welcome.blade.php :
<head>
<title>my project</title>
#vite(['/resources/js/app.js', '/resources/css/app.css'])

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.

Symfony 4 - Heroku - Can't use my images (webpack-encore)

in my project symfony 4 I use all kinds of images.
I have static images for the decoration of the site. I put them in assets/images, and I generated them in the public/build/images with webpack-encore.
And these pictures, I manage their size with LiipImagineBundle
So I deployed my project on Heroku. It installs the bundles, the node_modules, generates the files with webpack-encore from the assets, and generates the database
composer.json:
"compile": [
"php bin/console doctrine:schema:drop --full-database --force --env=prod",
"php bin/console d:m:m",
"php bin/console d:f:l --no-interaction --env=PROD"
]
package.json:
"scripts": {
"dev-server": "encore dev-server",
"dev": "encore dev",
"watch": "encore dev --watch",
"build": "encore production --progress",
"heroku-postbuild": "node_modules/.bin/encore production"
},
However when I go on the application from Heroku, the site works but the images that must be displayed through LiipImagineBundle are not. Instead I have a 500 error telling me that resources do not exist. And actually if I go in the section "Sources", in the public / build / images, there are missing images. Yet they must be generated because in local (in dev), everything works perfectly.
All my required bundle for prod are in "require" and not "require-dev". And I haven't devDependencies in my package.json, all is in 'depedencies'
Has anyone ever had the same problem?
You can used heroku-buildpack
It uses Composer for dependency management, supports PHP or HHVM (experimental) as runtimes, and offers a choice of Apache2 or Nginx web servers.

How to have multiple Vue projects in one laravel project

I have one laravel project where i'm going to have multiple backends, i need to do the same thing in frontend, another laravel project where i'm going to have multiple frontends in Vue using the laravel-vue integration, for example, inside resource/js folder to have frontend1, frontend2, etc. Is there any guide or tutorial about how to do this? How to make Folder structure inside resources/js, Laravel Mix configuration, etc.?
thanks!
I did this recently in a project where i created resources/backend/js and resources/frontend/js where i wanted the output to be in public/frontend and public/backend. I stumbled on some issues with the manifest file but got it working in the end.
You can do this by creating a new frontend.mix.js and change the output paths to
const mix = require('laravel-mix');
mix.setPublicPath('public/frontend')
.setResourceRoot('/frontend')
mix.js('resources/frontend/js/app.js', 'public/frontend/js')
.sass('resources/frontend/sass/app.scss', 'public/frontend/css')
You will need to create a few new command to use frontend.mix.js
"scripts": {
"frontend-dev": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --env.mixfile=frontend.mix --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"frontend-watch": "npm run frontend-dev -- --watch",
}
Inside the original webpack.mix.js file i changed the paths to backend and left the commands untouched.
Hope this helps you.

Laravel & Vue - separate assets for admin and public page

I'm new to Vue but I really like it. Right now I have my own CMS based on Laravel. I want to build new CMS as SPA in Vue. But one thing is not clear to me. How should I separate assets for frontend and admin?
For example I would like to have COMPONENTS folder with another folder ADMIN - there will be only admin components.
I also don't want to have webpack building everything together.
I was thinking about solution like having multiple webpack commands:
npm run dev
npm run dev admin
But maybe I'm completely wrong...
If you want to have 2 different commands - you just need to specify different configuration files to webpack --config option
like:
package.json
{
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"dev-admin": "webpack-dev-server --inline --progress --config build/webpack.dev-admin.conf.js",
}
}
Another option is to use webpack`s "multiple pages" option. It would allow you to build 2 entry .js files and all of the chunks for both of your apps.
Take a look here: https://webpack.js.org/concepts/entry-points/#multi-page-application
And if you use Vue-cli - https://cli.vuejs.org/config/#pages

Resources