Custom s3 base URLs for Vite compiled asset in Laravel App - laravel

I'm using Laravel 9 application. Laravel latest version has replaced webpack to vite. I was able to successfully run the app into my local environment but, while deploying the compiled assets to the AWS S3 I'm getting CORS error in the browser console.
Steps I did after running in local environment.
added ASSET_URL=https://****.s3.ap-south-1.amazonaws.com in my .env file
run npm run build
run aws s3 sync public/ s3://****/ --delete --exclude index.php --acl public-read
I can see that my .css and other files are loaded perfectly, but I'm getting CORS error only in the compiled js file.
I also added policy in my s3 bucket:
{
"Version": "2012-10-17",
"Id": "Policy1617109982386",
"Statement": [
{
"Sid": "Stmt1617109981105",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::****/*"
}
]
}
But this isn't helping me out.
My Vite config file looks like:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel({
input: 'resources/js/app.js',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
});
I also tried declaring cors in 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({
input: 'resources/js/app.js',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
server: {
cors: true
}
});
I'm unable to find any solution. Help me out.
Thanks.

Hey Have a look at setting CORS in the s3 bucket.
https://docs.aws.amazon.com/AmazonS3/latest/userguide/ManageCorsUsing.html

Related

Why does my Vite build process need to scan the host's hard drive?

I am getting an error when starting a dev server:
Error: EPERM: operation not permitted, scandir '/var/www/html/rootfs/host_mnt/c
I have a Laravel - Inertia - Vue3 application that I am trying to build with Vite for development.
From vite.config.js
import {defineConfig} from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel({
input: 'resources/js/app.js',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
]
});
devcontainer.json
{
"name": "Mangrove Development Environment",
"dockerComposeFile": [
"../docker-compose.yml"
],
"service": "mangrove",
"workspaceFolder": "/var/`your text`www/html",
"settings": {},
"customizations": {
"vscode": {
"extensions": [
"felixfbecker.php-debug",
"ms-vsliveshare.vsliveshare",
"eamodio.gitlens",
"bmewburn.vscode-intelephense-client",
"mikestead.dotenv",
"amiralizadeh9480.laravel-extra-intellisense",
"ryannaddy.laravel-artisan",
"onecentlin.laravel5-snippets",
"onecentlin.laravel-blade",
"EditorConfig.EditorConfig",
"jcbuisson.vue",
"redhat.vscode-yaml"
]
}
},
"remoteUser": "sail",
//"postCreateCommand": "chown -R 1000:1000 /var/www/html"
"postCreateCommand": ""
// "forwardPorts": [],
// "runServices": [],
// "shutdownAction": "none",
}
I tried using "postCreateCommand": "chown -R 1000:1000 /var/www/html" in the devcontainer.json file, but this simply tries to turn over ownership of every single file on my Windows system's hard drive.
I have also tried inserting
server: {
watch: {
ignored: [
"rootfs/**/*",
],
}
}
Into the vite.config.js to perhaps ignore those files.

how to set laravel vite config directory?

I have here my configuration below. Is there a way to select the directory, instead of specifying each css file? I want to modularize loading of css.
export default defineConfig({
plugins: [
laravel({
input: [
'resources/css/app.css',
'resources/css/login.css',
'resources/css/register.css',
'resources/css/about.css',
'resources/css/profile.css',
..
],
refresh: true,
}),
],
...
});
I already tried the following, but none worked for me.
'resources/css'
'resources/css/*.css'
'resources/css/**.css'

Fullcalendar doesn't load CSS

I'm implementing fullcalendar in my project that has Laravel 9 and Vue 3.
I think it is not loading the css as the on-screen calendar is looking like this: Calendar Image.
I have already made several settings. Even the Vue part is working because the calendar is working.
Below in the images are the settings that are today.
package.json
{
"private": true,
"scripts": {
"dev": "vite --host",
"build": "vite build"
},
"devDependencies": {
"axios": "^1.1.2",
"bootstrap": "^4.6.2",
"laravel-vite-plugin": "^0.6.0",
"lodash": "^4.17.19",
"postcss": "^8.1.14",
"sass": "^1.32.11",
"script-loader": "^0.7.2",
"vite": "^3.0.0"
},
"dependencies": {
"#fullcalendar/core": "^5.11.3",
"#fullcalendar/daygrid": "^5.11.3",
"#fullcalendar/interaction": "^5.11.3",
"#fullcalendar/list": "^5.11.3",
"#fullcalendar/timegrid": "^5.11.3",
"#fullcalendar/vue3": "^5.11.2",
"#popperjs/core": "^2.11.6",
"#vitejs/plugin-vue": "^3.1.2",
"laravel-echo": "^1.9.0",
"socket.io-client": "^2.3.0",
"vue": "^3.2.41",
"vue-toastification": "^2.0.0-rc.5"
}
}
vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
import fs from 'fs';
const host = 'site.com.br';
export default defineConfig({
plugins: [
laravel({
input: ['resources/sass/app.scss', 'resources/js/app.js'],
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
}
}
})
],
server: {
host,
hmr: { host },
https: {
key: fs.readFileSync('C:\\laragon\\etc\\ssl\\privada25296.key'),
cert: fs.readFileSync('C:\\laragon\\etc\\ssl\\certificado25296.crt'),
},
},
});
index.vue
<script>
import { useToast } from "vue-toastification";
import '#fullcalendar/core/vdom' // solves problem with Vite
import FullCalendar from '#fullcalendar/vue3'
import dayGridPlugin from '#fullcalendar/daygrid'
import timeGridPlugin from '#fullcalendar/timegrid'
import interactionPlugin from '#fullcalendar/interaction'
import { INITIAL_EVENTS, createEventId } from './event-utils'
export default {
components: {
FullCalendar // make the <FullCalendar> tag available
},
data() {
return {
calendarOptions: {
plugins: [ dayGridPlugin, timeGridPlugin, interactionPlugin ],
initialView: 'dayGridMonth',
initialEvents: INITIAL_EVENTS, // alternatively, use the `events` setting to fetch from a feed
}
}
},
mounted() {
const toast = useToast();
this.loadUserCustomers();
Echo.channel('agendamentos_database_user_customer_created')
.listen('UserCustomerCreated', (e) => {
toast.success('Novo cliente vinculado!')
});
},
methods: {
loadUserCustomers() {
axios.get('/api/calendar')
.then(response => {
console.log( response.data.data );
//this.userCustomers = response.data
})
.catch(response => {
console.log('Erro')
})
}
},
}
In the fullcalendar documentation, the following is mentioned about CSS.
CSS: All of FullCalendar’s CSS will be automatically loaded as long as your build system is able to process .css file imports. See Initializing with an ES6 Build System for more information on configuring your build system. https://fullcalendar.io/docs/vue#:~:text=ticket%20%23152.-,CSS,-All%20of%20FullCalendar%E2%80%99s
When I access link about ES6 Build System, it is described that I need to use webpack, and in the Laravel application, vite is used.
Can anyone help me with this problem please?
I solved it by loading allocate the size of the calendar
hope this solve your problem and I did it with the cdn
calendar.render();
calendar.setOption('height', 700);

npm run watch/hot only successful on the first run

Background:
I added TypeScript support to my existing project, so I added ts-loader and typescript. I think, I configured everything right and it is working fine in dev and prod mode.
I would like to update gradually, keeping all the JavaScript code in place and using TypeScript for everything new or where there is a need for refactoring. So it may be important to note that TableValue.vue is an old js component.
Problem:
Edit: It also occurs with npm run watch
When I run npm run hot in package.json: "scripts": { ..., "hot": "mix watch --hot", ...} it only works on the first try. As soon as I change any file and trigger a recompile, I get:
√ Mix: Compiled successfully in 19.15s
webpack compiled successfully
// Here the recompile is triggered
i Compiling Mix
√ Mix: Compiled with some errors in 509.01ms
ERROR in C:\fakepath\resources\js\components\test\component.vue.ts
24:23-41
[tsl] ERROR in C:\fakepath\resources\js\components\test\component.vue.ts(24,24)
TS2307: Cannot find module './TableValue.vue' or its corresponding type declarations.
webpack compiled with 1 error
I suspect that this error comes from ts-loader, but why is everything working on the first try?
I could just ignore this error, but then hot module replacement is unusable, because I have to manually trigger a new build process every time anyway.
Has someone got such an setup working?
What can I do to solve this error?
Infos:
I'm working with:
Laravel 8.58
Laravel Mix 6.0.25
Vue 2.6.14
ts-loader 9.2.5
typescript 4.4.2
Here the script tag from the test component:
<script lang="ts">
import Vue, { PropType } from 'vue';
import TableValue from "./TableValue.vue";
import Model from "#/js/types/model.js";
export default Vue.extend({
name: "TestComponent",
components: {
TableValue
},
props: {
'model': {
type: Object as PropType<Model>,
required: true
}
},
data() {
return {};
},
});
</script>
Project Structure:
app/
bootstrap/
config/
database/
node_modules/
public/
resources/
js/
components/
store/
types/
views/
app.js
bootstrap.js
routes.js
shims-vue.d.ts
lang/
sass/
views/
routes/
storage/
tests/
vendor/
composer.json
composer.lock
tsconfig.json
package-lock.json
package.json
phpunit.xml
vs.code-workspace
webpack.mix.js
webpack.mix.js:
const mix = require('laravel-mix');
const ResolveTypeScriptPlugin = require("resolve-typescript-plugin").default;
mix.webpackConfig({
module: {
rules: [
{
test: /\.tsx?$/,
loader: "ts-loader",
options: { appendTsSuffixTo: [/\.vue$/] },
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.js', '.ts', '.vue'],
alias: {
'#': __dirname + '/resources'
},
fullySpecified: false,
plugins: [new ResolveTypeScriptPlugin()]
},
devtool: 'source-map'
}).sourceMaps();
mix.ts('resources/js/app.js', 'public/js')
.sass('resources/sass/app.sass', 'public/css').sourceMaps()
.vue();
mix.extract();
tsconfig.json:
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"noImplicitAny": false,
"importHelpers": true,
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"allowJs": true,
"checkJs": false,
"sourceMap": true,
"baseUrl": ".",
"paths": {
"#/*": [
"resources/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"files": [
"resources/js/shims-vue.d.ts"
],
"include": [
"resources/js/**/*.ts",
"resources/js/**/*.vue",
],
"exclude": [
"node_modules",
".vscode",
"app",
"bootstrap",
"config",
"database",
"public",
"routes",
"storage",
"tests",
"vendor"
]
}
Update:
When I remove shims-vue.d.ts, I get the error immediately.
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
It looks like this file is only read/applyed once and not after? Not sure.
It looks like ts-loader doesn't support HMR yet.
https://github.com/TypeStrong/ts-loader#hot-module-replacement
I installed fork-ts-checker-webpack-plugin and updated webpack.mix.js to:
const mix = require('laravel-mix');
const path = require('path');
const ResolveTypeScriptPlugin = require("resolve-typescript-plugin").default;
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
mix.webpackConfig({
module: {
rules: [
{
test: /\.tsx?$/,
loader: "ts-loader",
options: {
appendTsSuffixTo: [/\.vue$/],
transpileOnly: true
},
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.js', '.ts', '.tsx', '.vue'],
alias: {
'#': path.resolve(__dirname + '/resources'),
'#store': path.resolve(__dirname + '/resources/js/store'),
'#components': path.resolve(__dirname + '/resources/js/components')
},
fullySpecified: false,
plugins: [new ResolveTypeScriptPlugin()]
},
plugins: [new ForkTsCheckerWebpackPlugin()],
devtool: 'source-map'
}).sourceMaps();
mix.ts('resources/js/app.js', 'public/js')
.sass('resources/sass/app.sass', 'public/css').sourceMaps()
.vue();
mix.extract();
Now everything is working fine but I'm still not sure why watch was also affected and where exactly the problem was.
I'm not using Typescript, but the same thing was happening to me, when i ran npm run watch/hot where only successful on the first change of the code, then, you can not see the changes until you run npm run watch/hot or npm run dev again. The strange thing was that everything was compiling successfully on every change I made.
I manage to debug it with git, and found out that I was importing a component with a wrong name but did not get an error on the console.
My component name was WhosApplying.vue
I got:
import WhosApplying from "#/whosApplying.vue"
And change it for:
import WhosApplying from "#/WhosApplying.vue";
That mistake in the w instead of W make me lose hours. 😅
I ran into this using laravel-mix after adding typescript to an Inertia / Vue 3 project.
Using Volar (Not Vuter)
To fix it I changed my webpack.config.js file from:
const path = require('path');
module.exports = {
resolve: {
alias: {
'#': path.resolve('resources/js'),
},
},
};
to:
const path = require('path');
module.exports = {
module: {
rules: [
{
test: /\.tsx?$/,
loader: "ts-loader",
options: {
appendTsSuffixTo: [/\.vue$/],
transpileOnly: true
},
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.js', '.ts', '.tsx', '.vue'],
alias: {
'#': path.resolve(__dirname + '/resources/js'),
},
},
};

How enable gatsbyjs client-only routes on heroku

I have a gatsbyjs app with client-only routes that works fine locally but in production I can only access those routes when following a link but when typing the url directly in the browser i get a 404.
I had expected following the answer in this thread, but issue persists. Any hints or suggestions?
// app.json
{
"name": "User Resource",
"repository": "https://github.com/guanacone/fullstack_app",
"stack": "container",
"buildpacks": [
{
"url": "heroku/nodejs"
},
{
"url": "https://github.com/heroku/heroku-buildpack-static"
}
]
}
//static.json
{
"root": "public/",
"clean_urls": true,
"routes": {
"/user/**": "user/index.html"
}
}
// gatsby-config.js
module.exports = {
/* Your site config here */
plugins: [
'gatsby-plugin-layout',
{
resolve: 'gatsby-plugin-create-client-paths',
options: { prefixes: ['/user/*'] },
},
'gatsby-plugin-styled-components',
'gatsby-plugin-use-query-params',
],
};
// src/pages/user.js
import React from 'react';
import { Router } from '#reach/router';
import UserIndex from '../components/UserIndex';
import UserProfile from '../components/UserProfile';
import UserNew from '../components/UserNew';
import UserEdit from '../components/UserEdit';
import UserActivation from '../components/UserActivation';
const User = () => (
<Router basepath='/user'>
<UserIndex path='/' />
<UserProfile path='/:id' />
<UserNew path='/new' />
<UserEdit path='/:id/edit' />
<UserActivation path='/activation' />
</Router>
);
export default User;
I solved it by removing the heroku-buildpack-static and adding the following code to my express.js server.
app.get('/user/**', (req, res) => {
res.sendFile(path.join(`${__dirname}/public/user/index.html`));
});

Resources