Laravel Vue production instance - laravel

I have a Laravel Vue project that works fine in development. I have been trying to get it to our production server for some hours now. However, when I visit the URL, I get a blank page. Upon inspection in the console, I notice all the js chunk files return status of 200, but their contents are "We're sorry, but Project Name doesn't work properly without Javascript."
The following is a snippet of my webpack.mix.js.
mix
.js('resources/js/app.js', 'public/js')
.webpackConfig({
resolve: {
alias: {
'#': path.resolve(__dirname, 'frontend/src/'),
'#themeConfig': path.resolve(__dirname, 'frontend/themeConfig.js'),
'#core': path.resolve(__dirname, 'frontend/src/#core'),
'#validations': path.resolve(__dirname, 'frontend/src/#core/utils/validations/validations.js'),
'#axios': path.resolve(__dirname, 'frontend/src/libs/axios')
}
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths: ['frontend/node_modules', 'frontend/src/assets']
}
}
}
]
},
{
test: /(\.(png|jpe?g|gif|webp)$|^((?!font).)*\.svg$)/,
loaders: {
loader: 'file-loader',
options: {
name: 'images/[path][name].[ext]',
context: '../vuexy-vuejs-bootstrap-vue-template/src/assets/images'
// context: 'frontend/src/assets/images'
}
}
}
]
}
})
.sass('resources/sass/app.scss', 'public/css')
.options({
postCss: [require('autoprefixer'), require('postcss-rtl')]
})
// ------------------------------------------------
// If you are deploying on subdomain/subfolder. Uncomment the below code before running the 'yarn prod' or 'npm run production' command.
// Please Change below 'publicPath' and 'setResourceRoot' options as per your sub-directory path.
// ------------------------------------------------
if (mix.inProduction()) {
mix.version()
mix.webpackConfig({
output: {
publicPath: '/app/',
chunkFilename: 'js/chunks/[name].[chunkhash].js'
}
})
mix.setResourceRoot('/app/')
}else{
mix.webpackConfig({
output: {
chunkFilename: 'js/chunks/[name].js'
}
})
}
I set up production using the ff on my local machine:
npm run prod
Then I run the following via ssh on the server:
composer install --optimize-autoloader --no-dev
php artisan key:generate
In the console, the js chunk files show this as their response from the server:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="csrf-token" content="j9kLqaAInZ4043rRqT9Zn3kNMHaSfCdF7h5ejnnZ">
<link rel="icon" href="/favicon.ico">
<title>project Title</title>
<link rel="stylesheet" href="https://app.myprojects.com/css/app.css?id=bff15ac59733e85aedce">
<link rel="shortcut icon" href="https://app.myprojects.com/images/logo/favicon.png">
</head>
<body>
<noscript>
<strong>We're sorry but this platform doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app">
</div>
<script src="https://app.myprojects.com/js/app.js?id=a74eb61fbd09ea2e1e92"></script>
</body>
</html>
Any help would be appreciated!

Upon lots of further investigations, i noticed that both app.css and app.js loads properly and only the chunk files had the issue. Apparently they were loading from
https://app.myproject.com/app/js/chunks/1.edcb1b13fece690b424f.js
instead of from
https://app.myproject.com/js/chunks/1.edcb1b13fece690b424f.js
I was able to get the page to load properly by setting publicPath and resourceRoot to /

Related

Laravel Breeze (vue) and Homestead - npm run dev and HMR not working

I followed the instructions from the documentation:
Homestead: https://laravel.com/docs/9.x/homestead#installation-and-setup
Breeze with Vue and inertia: https://laravel.com/docs/9.x/starter-kits#breeze-and-inertia
When I run npm run build everything works fine. I can visit my new app over http://homestead.test/. When I try to use the dev server with hot reload npm run dev, the debug console in my browser (host) tells:
GET http://127.0.0.1:5173/#vite/client net::ERR_CONNECTION_REFUSED
GET http://127.0.0.1:5173/resources/js/app.js net::ERR_CONNECTION_REFUSED
I already tried to change my package.json file to from "dev": "vite", to "dev": "vite --host homestead.test", but this only results in the errors
GET http://homestead.test:5173/#vite/client net::ERR_CONNECTION_REFUSED
GET http://homestead.test:5173/resources/js/app.js net::ERR_CONNECTION_REFUSED
In app.blade.php the scripts are imported with #
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title inertia>{{ config('app.name', 'Laravel') }}</title>
<!-- Fonts -->
<link rel="stylesheet" href="https://fonts.bunny.net/css2?family=Nunito:wght#400;600;700&display=swap">
<!-- Scripts -->
#routes
#vite('resources/js/app.js')
#inertiaHead
</head>
<body class="font-sans antialiased">
#inertia
</body>
</html>
#routes seems to be a part of the Laravel Ziggy package. No error from this side.
But the #vite('resources/js/app.js') and #inertiaHead are throwing errors. These directives link to a wrong destination.
How to solve this?
I've found the solution. Add the server part in your vite.config.js. And add the app.css to the inputs
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
export default defineConfig({
server: {
hmr: {
host: "192.168.56.56",
},
host: "192.168.56.56",
watch: {
usePolling: true,
},
},
plugins: [
laravel({
input: ['resources/js/app.js', 'resources/css/app.css'],
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
});
My Solution is to turn on the HTTPS with Vite SSL cert generation plugin
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '#vitejs/plugin-react';
import basicSsl from '#vitejs/plugin-basic-ssl'
export default defineConfig({
server: {
https: true,
},
plugins: [
basicSsl(),
laravel({
input: 'resources/js/app.jsx',
refresh: true,
}),
react(),
],
});
I will share a little of my experience when I get a problem like this. This is because the existing IP is not detected on the device.
http://127.0.0.1:5173 that's the route that made this error occur. So I tried building with
npm run build
after that I refreshed my page and the page was successfully opened.
looks like it was not accessible during development stage. that's all I understand. sorry if there is an error that I convey.

Laravel Vite - Configuration does not exist

I tried to create Laravel project with Vite and followed Laravel documentation. But the problem occurred when I tried to access the resource and it says Configuration "resources/js/app.js" does not exist..
This is vite.config.js file:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue'
export default defineConfig({
plugins: [
laravel([
'resources/css/app.css',
'resources/js/app.js',
]),
vue(),
],
});
And this is my blade file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Test</title>
{{-- #vite('resources/css/app.css') --}}
</head>
<body>
<div id="app"></div>
#vite('resources/js/app.js')
</body>
</html>
Anyone know the problem?
I think you want something like this in vite.config.js.
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: [
'resources/css/app.css',
'resources/js/app.js',
],
refresh: true,
}),
],
});
And then make sure that you run npm run build in your terminal.
use #vite('default') in you blade file not : #vite('resources/js/app.js') more info go to :
https://laravel-vite.dev/guide/extra-topics/multiple-configurations.html#configuring-the-laravel-package

PostCSS does not process tailwind

This is using Laravel with Vite. I have gone through guides on how to do this from multiple sources, and while there seems to be several different approaches that should work, nothing seems to result in tailwind directives being processed by postcss.
In package.json
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"autoprefixer": "^10.4.7",
"axios": "^0.27",
"laravel-vite-plugin": "^0.4.0",
"lodash": "^4.17.21",
"postcss": "^8.4.14",
"tailwindcss": "^3.1.6",
"vite": "^3.0.0"
},
"dependencies": {
"amqplib": "^0.10.0"
}
}
In vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel([
'resources/css/app.css',
'resources/js/app.js',
]),
],
});
In postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
In tailwind.config.js
module.exports = {
content: [
"./resources/**/*.blade.php",
"./resources/**/*.js",
],
theme: {
extend: {},
},
plugins: [],
}
In resources/css/app.css
#tailwind base;
#tailwind components;
#tailwind utilities;
and finally in app.blade.php
<!DOCTYPE html>
<html land="en">
<head>
<meta charset="UTF-8" />
<meta name="viewpoint" content="width=device-width, initial-scale=1.0" />
<title> ISAD </title>
#vite('resources/css/app.css')
</head>
<body>
<h1 class="text-3xl font-bold underline">
Hello world!
</h1>
</body>
</html>
Which renders as
<!DOCTYPE html>
<html land="en">
<head>
<meta charset="UTF-8" />
<meta name="viewpoint" content="width=device-width, initial-scale=1.0" />
<title> ISAD </title>
<script type="module" src="http://127.0.0.1:5173/#vite/client"></script><link rel="stylesheet" href="http://127.0.0.1:5173/resources/css/app.css" />
</head>
<body>
<h1 class="text-3xl font-bold underline">
Hello world!
</h1>
</body>
</html>
With app.css still containing just
#tailwind base;
#tailwind components;
#tailwind utilities;
There is probably something very small that I am overlooking.
This is more than likely because your vite server is being blocked by an adblocker...
Verify by opening the network tab, does the vite server and assets return an err_blocked_by_client?
You more than likely have to whitelist your vite server with your adblocker... You can read more on this issue here: https://github.com/laravel/vite-plugin/issues/47
Just try to re-run Vite if it's running
Ctrl+C to terminate
npm run dev or yarn dev

Clean old workbox cache in a SPA served by Pyramid

I'm new to PWAs and service workers. I started to test workbox with a Pyramid application which serves a preact app bundled with webpack 4. This is the home.jinja2 template:
<!DOCTYPE html>
<html lang="{{request.locale_name}}">
<head>
...
<link href="{{request.static_url('app:static/app.css')}}" rel="stylesheet">
<script type="text/javascript" src="{{request.static_url('app:static/runtime.js')}}"></script>
<script type="text/javascript" src="{{request.static_url('app:static/vendor.js')}}"></script>
</head>
<body>
<div id="app"/>
{% block scripts %}
{% endblock %}
<script type="text/javascript">
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/service-worker.js');
});
}
</script>
</body>
</html>
The SPA makes calls to /api/v1/. I want to provide a network first experience. This is part of the webpack config:
optimization: {
runtimeChunk,
},
output: {
path: path.resolve(path.join(__dirname, '..', 'app', 'static')),
},
plugins: [
new OptimizeCSSAssetsPlugin({
cssProcessorOptions: { discardComments: { removeAll: true } },
canPrint: false,
}),
new ManifestPlugin({
publicPath: '',
}),
new WebpackCleanupPlugin({
exclude: [
'robots.txt',
],
}),
new GenerateSW({
clientsClaim: true,
skipWaiting: true,
runtimeCaching: [
{
urlPattern: /\//,
handler: 'networkFirst',
},
{
urlPattern: /https:\/\/fonts.(?:googleapis|gstatic).com\/(.*)/,
handler: 'staleWhileRevalidate',
},
],
navigateFallback: '/app-shell',
navigateFallbackBlacklist: [/^\/api/],
templatedUrls: {
'/app-shell': 'index.html',
},
}),
],
The generated index.html basically equals to the home.jinja2 layout (both contain the hashed assets urls). The problem I face is whenever I make changes to the frontend and deploy them, once the update process of the service worker is completed, the browser requests both the new and old assets (43f6a4e6 is the hash of the new assets).
Refreshing has no effect at all, even after 24 hours. I delete old assets on every deployment, therefore all requests to old assets error and a blank page is displayed. I temporarily had to redirect old assets requests to the new ones.
I implemented this recipe https://developers.google.com/web/tools/workbox/guides/advanced-recipes#warm_the_runtime_cache and the site is completely broken. Firefox displays a data corrupted error. Any ideas would be much appreciated.

Getting a karma test to work with a static HTML file

I've got a HTML file that I want to run some tests on:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />
<title>Karma Test</title>
<link rel="stylesheet" href="http://cdn.jsdelivr.net/normalize/3.0.3/normalize.css" />
</head>
<body>
<!-- Basic Buttons -->
<rui-button id="test1">Test</rui-button>
<!-- Disabled Buttons -->
<rui-button id="test2" disabled>Test</rui-button>
<rui-button id="test3" disabled="disabled">Test</rui-button>
<rui-button id="test4" disabled="{ true }">Test</rui-button>
<script src="http://cdn.jsdelivr.net/riot/2.6.2/riot.js"></script>
<script src="rui-full.js"></script>
<script>
riot.mount('*');
</script>
</body>
</html>
I've setup my karma.conf, I think correctly:
module.exports = function(config) {
config.set({
browsers: ['PhantomJS'],
frameworks: ['jasmine'],
plugins: [
'karma-jasmine',
'karma-jasmine-html-reporter',
'karma-html2js-preprocessor',
'karma-chrome-launcher',
'karma-phantomjs-launcher',
'karma-riot'
],
preprocessors: {
'**/*.html': ['html2js']
},
files: [
{ pattern: '../../build/demo/rui-full.js', included: true, watched: false, served: true },
'./**/*.html',
'./**/*.spec.js'
],
reporters: ['progress', 'kjhtml'],
singleRun: true,
html2JsPreprocessor: {
processPath: function(filePath) {
return filePath.split('/')[1];
}
}
});
};
And I've written a simple simple test:
describe('rui-button tests', function() {
beforeEach(function (done) {
document.body.innerHTML = __html__['ui-button.html'];
});
it('Create basic button', function() {
var el = document.querySelector('#test1');
expect(el).toBeTruthy();
console.log(el.innerHTML)
});
});
Now the beforEach works, and the html is set. But its not working as expected. I'm not sure if the rui-full.js script is loading or not. I don't think it is as el.innerHTML is just "Test", it's not been replaced with the riot.js tag.
Do I have things setup correctly? Is there a way to log out any errors?
I'm running my test with the cli:
karma start tests/karma.config.js
You have to mount the tags in your code like this
before(function() {
var html = document.createElement('rui-button')
document.body.appendChild(html)
tag = riot.mount('hello')[0]
});
it('mounts a rui-button tag', function() {
expect(tag).to.exist
expect(tag.isMounted).to.be.true
})
Here is a tutorial for testing Riot with mocha+chai+karma https://github.com/vitogit/tdd-mocha-chai-riot
Or if you donĀ“t want to use karma : https://github.com/vitogit/minimalistic-riotjs-testing online version: http://plnkr.co/edit/BFOijJ?p=preview

Resources