Vuetify works locally but breaks when deployed to firebase, why might this be happening? - firebase

I have a website that is hosted through Firebase that uses Vue and Vuetify. Vuetify is only used for one component and the rest of the app uses SCSS for styling. Vuetify has been a recent addition to the project and getting it set up and working locally went fine. However when I tried to deploy my changes to Firebase for the first time since adding Vuetify, the app renders with no styling at all - no Vuetify and no SCSS.
Below are the files I had to change in order to get Vuetify working locally following the installation guide + my firebase.json because it seems relevant.
Part of package.json
{
"scripts": {
"serve": "vue-cli-service serve",
"build": "npm run lint && vue-cli-service build --mode test",
},
"dependencies": {
"core-js": "^2.6.12",
"firebase": "^9.5.0",
"regenerator-runtime": "^0.13.11",
"register-service-worker": "^1.7.2",
"vue": "^2.6.12",
"vuetify": "^2.6.12",
"vuex": "^3.6.2"
},
"devDependencies": {
"#babel/preset-env": "^7.20.2",
"#vue/cli-plugin-babel": "^3.8.0",
"#vue/cli-plugin-eslint": "^3.8.0",
"#vue/cli-plugin-pwa": "^3.8.0",
"#vue/cli-service": "^3.8.0",
"babel-eslint": "^10.1.0",
"imagemin-webpack-plugin": "^2.4.2",
"sass": "^1.32.8",
"sass-loader": "^10.1.1",
"vue-cli-plugin-vuetify": "~2.5.8",
"vue-cli-plugin-webpack-bundle-analyzer": "^4.0.0",
"vue-template-compiler": "^2.6.12",
"vuetify-loader": "^1.7.0"
},
}
plugins/vuetify.js
import Vue from "vue";
import Vuetify from "vuetify/lib/framework";
import "vuetify/dist/vuetify.min.css";
//have deployed with and without the above line to no avail, some stackoverflow threads suggested it but was not in the documentation
Vue.use(Vuetify);
export default new Vuetify({
theme: {
options: {
customProperties: true,
},
themes: {
light: {
primary: "#007BFF",
secondary: "#424242",
accent: "#82B1FF",
error: "#FF5252",
info: "#2196F3",
success: "#4CAF50",
warning: "#FFC107",
},
},
},
icons: {
iconfont: "fa",
},
});
Part of main.js
import "core-js";
import "regenerator-runtime/runtime";
import Vue from "vue";
import vuetify from "#/plugins/vuetify";
var createApp = function() {
if (!app) {
app = new Vue({
router,
store,
vuetify,
data: {},
render: (h) => h(App),
}).$mount("#app");
}
};
bable.config.js
//bable.config.js
module.exports = {
presets: ["#vue/app", "#babel/preset-env"],
};
firebase.json
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"functions": {
"predeploy": [],
"source": "functions"
},
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"headers": [
{ "source":"/service-worker.js", "headers": [{"key": "Cache-Control", "value": "no-cache"}] }
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
},
"storage": {
"rules": "storage.rules"
},
"database": {
"rules": "database.rules.json"
}
}
Lastly, my vue.config.js also contains the line
transpileDependencies: ["vuetify"],
I've cleared the web browser cache several times and made sure to wrap my Vuetify component within v-app.
npm run build and firebase deploy both run without error but since my app lacks styling after deployment I think something is going wrong with my firebase.json.
Relatively new to Vue, Vuetify, and Firebase so appreciate any explanations or guesses as to why this behavior might be occurring.
Thanks

Related

Vue3 Vite Hot Reload (HMR) no working in the browser

I'm developing a vue3 project with vite.
The HMR doesn't working fine in my dev enviroment.
When a vue file edited, vite handle the change and send a message thru websocket correctly
{"type":"update",
"updates":[{"type":"js-update","timestamp":1669740364450,"path":"/src/views/user/LoginView.vue","explicitImportRequired":false,"acceptedPath":"/src/views/user/LoginView.vue"}]}
but in the browser (I tried different ones) nothing happened.
Any solution?
my package.json
{
"name": "frontendq",
"private": true,
"version": "0.9.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"#quasar/extras": "^1.15.5",
"axios": "^1.1.3",
"moment": "^2.29.4",
"quasar": "^2.10.2",
"vue": "^3.2.45",
"vue-i18n": "9",
"vue-recaptcha": "^2.0.3",
"vue-router": "^4.1.6",
"vue3-cookies": "^1.0.6",
"vuex": "^4.1.0"
},
"devDependencies": {
"#quasar/vite-plugin": "^1.2.3",
"#vitejs/plugin-vue": "^3.2.0",
"sass": "1.32.12",
"vite": "^3.2.4"
},
"packageManager": "yarn#3.2.4"
}
I've been dealing with this issue in a project with Vue 3, TypeScript and Vite 4. I added the next to my vite.config.ts to fix the hot reload:
server: {
watch: {
usePolling: true,
}
},
My entire vite.config.ts:
import {defineConfig} from "vite";
import vue from "#vitejs/plugin-vue";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
server: {
watch: {
usePolling: true,
}
},
});

My SASS variables into :root are not interpolated

I'm fairly new to the Nuxt ecosystem. Awesome package that makes our lives much easier.
I'm trying to add sass to my project. After following the documentation my build runs perfectly but my scss files are not being compiled. An example of the problem:
Notice that --thm-font is set to $primaryTypography and not the actual value from the .scss.
I'm expecting to see --thm-font: 'Barlow', sans-serif. I'm assuming that the sass is not being compiled. It is important to note I'm not looking for a component base style but I'm trying to have a main.scss where I will import the component, layouts and many other styles.
_variables.scss
// Base colors
$base: #ee464b;
$baseRgb: (238, 70, 75);
$black: #272839;
$blackRgb: (39, 40, 57);
$grey: #f4f4f8;
// Typography
$primaryTypography: 'Barlow', sans-serif;
#debug $primaryTypography; // -> this one outputs the correct value
:root {
--thm-font: $primaryTypography;
--thm-base: $base;
--thm-base-rgb: $baseRgb;
--thm-black: $black;
--thm-black-rgb: $blackRgb;
--thm-gray: $grey;
}
nuxt.config.js
export default {
mode: 'universal',
loading: { color: '#fff' },
css: [
'~assets/scss/main.scss'
],
plugins: [
],
buildModules: [
],
modules: [
],
optimizedImages: {
optimizeImages: true
},
build: {
extend (config, ctx) {
},
loaders: {
sass: {
prependData: '#import "~#/assets/scss/main.scss";'
}
}
},
server: {
port: process.env.APP_PORT
}
}
package.json
{
"name": "zimed",
"version": "1.1.0",
"description": "Zimed - Vue Nuxt App Landing Page Template",
"author": "Layerdrops",
"private": true,
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate"
},
"dependencies": {
"#bazzite/nuxt-optimized-images": "^0.3.0",
"nuxt": "^2.0.0",
"sass-loader": "10"
},
"devDependencies": {
"fibers": "^5.0.0",
"sass": "^1.38.2"
}
}
Which configuration am I missing so that .scss files get compiled?
You need to interpolate the variable like this --thm-font: #{$primaryTypography}; in the scope of :root.
Not sure the why of this behavior, but this answer was my way of finding this out.

Vuetify CSS missing when i build for production

We purchased a web app written in Vue from someone and we developing to change/improve it. One thing we added was Vuetify so we can use the Vuetify elements and everything has been working great while in development mode, but when we build for production the CSS for Vuetify elements is missing.
I have searched for this online already and have already tried what everybody is suggesting without any luck.
Anybody has an idea of what could be wrong and why npm run build would be missing some of the CSS?
What's weird is that all the UI functionality for Vue elements is working perfectly, just the CSS is missing.
Please see code samples below.
main.js:
import '#fortawesome/fontawesome-free/css/all.css'
import Vue from "vue";
import App from "./App.vue";
import VueMoment from "vue-moment";
import VueAnalytics from "vue-analytics";
import VueMeta from "vue-meta";
import { library } from "#fortawesome/fontawesome-svg-core";
import {
faCoffee,
faPlusCircle,
faChartLine,
faChevronDown,
faMobile,
faEnvelope,
faClock,
faUsers,
faPaperPlane,
faCheckCircle,
faCheck,
faLeaf,
} from "#fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "#fortawesome/vue-fontawesome";
import axios from "axios";
import router from "./router";
import store from "./store";
import vuetify from './plugins/vuetify';
import Vuetify from 'vuetify/lib'
library.add([
faCoffee,
faPlusCircle,
faChartLine,
faChevronDown,
faMobile,
faEnvelope,
faClock,
faUsers,
faPaperPlane,
faCheckCircle,
faCheck,
faLeaf,
]);
Vue.use(VueAnalytics, {
id: "xxx",
router,
});
Vue.use(VueMoment);
Vue.use(VueMeta);
Vue.component("font-awesome-icon", FontAwesomeIcon);
Vue.use(Vuetify)
axios.interceptors.response.use(undefined, async function (error) {
if (error.response.status === 401) {
await store.dispatch("auth/logout");
router.push("/login");
}
return Promise.reject(error);
});
// Plugins
// ...
// Sass file
require("./assets/styles/main.css");
Vue.config.productionTip = false;
new Vue({
router,
store,
vuetify,
render: (h) => h(App)
}).$mount("#app");
App.vue:
<template>
<v-app>
<v-main>
<router-view/>
</v-main>
</v-app>
</template>
<style>
.text-white {
color: #fff !important;
}
.text-gray-600 {
color: #757575 !important;
}
.font-semibold, .text-gray-700 {
color: #616161 !important;
}
</style>
package.json:
{
"name": "reviewgrower-spa",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"deploy": "git push dokku master"
},
"dependencies": {
"#fortawesome/fontawesome-svg-core": "^1.2.25",
"#fortawesome/free-solid-svg-icons": "^5.11.2",
"#fortawesome/vue-fontawesome": "^0.1.8",
"#fullhuman/postcss-purgecss": "^1.3.0",
"axios": "^0.19.0",
"chart.js": "^2.9.4",
"core-js": "^2.6.10",
"i": "^0.3.6",
"jquery": "^3.5.1",
"npm": "^6.13.0",
"tailwindcss-spinner": "^0.2.0",
"tailwindcss-toggle": "github:TowelSoftware/tailwindcss-toggle",
"url-parse": "^1.4.7",
"vue": "^2.6.10",
"vue-analytics": "^5.17.2",
"vue-chartjs": "^3.5.1",
"vue-click-outside": "^1.0.7",
"vue-clickaway": "^2.2.2",
"vue-feather-icons": "^4.22.0",
"vue-js-toggle-button": "^1.3.3",
"vue-meta": "^1.6.0",
"vue-moment": "^4.0.0",
"vue-router": "^3.1.3",
"vue-stripe-elements-plus": "^0.2.10",
"vuetify": "^2.4.0",
"vuex": "^3.0.1",
"vuex-persist": "^2.1.1"
},
"devDependencies": {
"#fortawesome/fontawesome-free": "^5.15.2",
"#vue/cli-plugin-babel": "^3.12.1",
"#vue/cli-plugin-eslint": "^3.12.1",
"#vue/cli-service": "^3.12.1",
"babel-eslint": "^10.0.3",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.2.3",
"sass": "^1.32.0",
"sass-loader": "^7.1.0",
"tailwindcss": "^1.1.3",
"vue-cli-plugin-vuetify": "~2.1.0",
"vue-template-compiler": "^2.5.21",
"vuetify-loader": "^1.7.0"
}
}
It's a little tough to understand what is missing where. If you think that is just missing then please try adding css onto the HTML file from the cdn and check the working.
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
I see that you are using webpack to compile the code. So, this could be also something related to webpack configuration. In your webpack rules do you have rules for css and scss. Because vuetify files are in scss.
My webpack configuration is as below when I do these type of circus.
--webpack.config.js--
const path = require("path");
const VuetifyLoaderPlugin = require("vuetify-loader/lib/plugin");
const { VueLoaderPlugin } = require("vue-loader");
module.exports = {
watch: true,
entry: {
main: 'main.js'
},
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.vue$/,
use: "vue-loader",
},
{
test: /\.s(c|a)ss$/,
use: [
"vue-style-loader",
"css-loader",
{
loader: "sass-loader",
// Requires sass-loader#^8.0.0
// options: {
// implementation: require('sass'),
// sassOptions: {
// fiber: require('fibers'),
// indentedSyntax: true // optional
// },
// },
},
],
},
],
},
plugins: [
new VueLoaderPlugin(),
new VuetifyLoaderPlugin({
/**
* This function will be called for every tag used in each vue component
* It should return an array, the first element will be inserted into the
* components array, the second should be a corresponding import
*
* originalTag - the tag as it was originally used in the template
* kebabTag - the tag normalised to kebab-case
* camelTag - the tag normalised to PascalCase
* path - a relative path to the current .vue file
* component - a parsed representation of the current component
*/
match(originalTag, { kebabTag, camelTag, path, component }) {
if (kebabTag.startsWith("core-")) {
return [
camelTag,
`import ${camelTag} from '#/components/core/${camelTag.substring(
4
)}.vue'`,
];
}
},
}),
],
}
Check your postcss.config.js, see if it has something to do with the purgecss.
You have to config the whitelist to ignore the vuetify styles.
Here is a sample for your reference:
const autoprefixer = require("autoprefixer");
const postcssImport = require("postcss-import");
const purgecss = require("#fullhuman/postcss-purgecss");
const IS_PROD = ["production", "prod"].includes(process.env.NODE_ENV);
let plugins = [];
if (IS_PROD) {
plugins.push(postcssImport);
plugins.push(
purgecss({
content: [
"./src/**/*.vue",
"./public/**/*.html",
`./node_modules/vuetify/src/**/*.ts`,
`./node_modules/vuetify/dist/vuetify.css`
],
defaultExtractor (content) {
const contentWithoutStyleBlocks = content.replace(/<style[^]+?<\/style>/gi, '')
return contentWithoutStyleBlocks.match(/[A-Za-z0-9-_/:]*[A-Za-z0-9-_/]+/g) || []
},
safelist: [ /-(leave|enter|appear)(|-(to|from|active))$/, /^(?!(|.*?:)cursor-move).+-move$/, /^router-link(|-exact)-active$/, /data-v-.*/ ],
whitelist: [
'container',
'row',
'spacer',
'aos-animate',
'col',
'[type=button]',
'v-application p',
],
whitelistPatterns: [
/^v-.*/,
/^col-.*/,
/^theme-.*/,
/^rounded-.*/,
/^data-aos-.*/,
/^(red|grey)--text$/,
/^text--darken-[1-4]$/,
/^text--lighten-[1-4]$/
],
whitelistPatternsChildren: [
/^post-content/,
/^v-input/,
/^swiper-.*/,
/^pswp.*/,
/^v-text-field.*/,
/^v-progress-linear/
]
})
);
}
module.exports = {
plugins:[
require('cssnano')({
preset: 'default'
}),
require('postcss-pxtorem')({
remUnit:15, //每个rem对应的px值
threeVersion:true
}),
...plugins,autoprefixer
]
}``
You are simply missing an include in your main.js (see vuetify docs):
import 'vuetify/dist/vuetify.min.css'
This will ensure that webpack includes the vuetify styles in the bundled CSS for production. This fixed the same issue for me (i.e. it worked locally but not in production).

Chrome is not communicating changes in my browser to my local files

The Issue:
I'm trying to use chrome workspaces / source maps to update my sass partials as I edit CSS in chrome dev tools. Chrome is detecting my sass partials from source maps I setup in webpack, but giving me the error "Changes to this file were not saved to the file system." when I try to save the changes from the sources tab in chrome dev tools.
Moreover, in the styles tab of chrome dev tools, despite chrome knowing which properties are connected to which sass partials, changing the styles there doesn't update the partial files in the sources tab.
Chrome is not communicating changes in my browser to my local files, despite the sass partials showing up as source mapped in the chrome dev tools, and despite me setting up a workstation.
So far:
I set up a workspace in chrome and added the folder for the project
Disabled all my chrome extensions
Made sure 'enable css source maps' was true in chrome settings
I believe the problem might be my webpack config, since this is the first time I've made a custom webpack config, and I basically fiddled around with it until it worked. It could (probably not) be a problem with with a dependency, so I'll also add my package.json file.
Sass partial detected in chrome inspector
Sass partials showing up in sources tab:
Error Message
Webpack config file:
const path = require('path')
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: ['#babel/polyfill', './src/index.js'],
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.js',
publicPath: '/'
},
devServer: {
contentBase: 'dist',
historyApiFallback: true
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/public/index.html'
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
],
module: {
rules: [
{
test: /\.sass$/,
use: [
"style-loader",
{ loader: 'css-loader', options: { sourceMap: true} },
{ loader: 'sass-loader', options: { sourceMap: true } }
],
},
{
test: /\.css$/,
use: [
"style-loader",
"css-loader"
]
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [
"babel-loader"
]
}
]
}
}
Package.json:
{
"name": "css",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production",
"start": "webpack-dev-server --mode development --open"
},
"author": "",
"license": "ISC",
"devDependencies": {
"#babel/core": "^7.6.4",
"#babel/plugin-proposal-class-properties": "^7.5.5",
"#babel/preset-env": "^7.6.3",
"#babel/preset-react": "^7.6.3",
"babel-eslint": "^10.0.3",
"babel-loader": "^8.0.6",
"css-loader": "^3.2.0",
"eslint": "^6.5.1",
"eslint-plugin-react": "^7.16.0",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.8.0",
"node-sass": "^4.12.0",
"sass-loader": "^8.0.0",
"style-loader": "^1.0.0",
"webpack": "^4.41.1",
"webpack-cli": "^3.3.9",
"webpack-dev-server": "^3.8.2"
},
"dependencies": {
"#babel/polyfill": "^7.6.0",
"react": "^16.10.2",
"react-dom": "^16.10.2",
"react-router-dom": "^5.1.2"
},
"eslintConfig": {
"extends": [
"eslint:recommended",
"plugin:react/recommended"
],
"env": {
"browser": true,
"node": true
}
},
"eslintIgnore": [
"webpack.config.js"
]
}
This is no longer supported in Chrome :( Relevant issue is marked as "won't fix".
https://bugs.chromium.org/p/chromium/issues/detail?id=996226

How do I add global styles without requiring an extra component?

I want to apply some global styles to my website (body, h1, h2, h3, etc).
To do this with Angular2, the view encapsultation of a component needs to be set thusly: encapsulation: ViewEncapsulation.None.
example:
#Component({
selector: 'app-root',
templateUrl: template(),
styleUrls: ['global.scss', 'app.component.scss'],
encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
title = 'Hello world!';
}
The problem is that this encapsulation rule applies to all of this components stylesheets, which means I must have a separate component just for global styles.
Is there another way to do this without requiring an extra component and without needing to edit Angular-CLI's build config?
(I'm using angular/core 2.0.0-rc.5 and angular-cli 1.0.0-beta.11-webpack.2)
The PR mentioned by drbishop has been merged and released as 1.0.0-beta.11-webpack.3.
To upgrade from 1.0.0-beta.11-webpack.2 to 1.0.0-beta.11-webpack.3, run:
npm uninstall -g angular-cli
npm cache clean
npm install -g angular-cli#1.0.0-beta.11-webpack.3
Note: if you get SyntaxError: Unexpected token ... errors on running ng version after upgrading you may need to upgrade to Node.js 6. See https://github.com/angular/angular-cli/issues/1883 for details.
If you generate a new project using 1.0.0-beta.11-webpack.3, you can add a styles.css file to your src directory which will be automatically included in your build. You can also add external CSS imports to the apps[0].styles property of angular-cli.json.
Your angular-cli.json should look something like this for a new project generated by 1.0.0-beta.11-webpack.3:
{
"project": {
"version": "1.0.0-beta.11-webpack.3",
"name": "demo"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": "assets",
"index": "index.html",
"main": "main.ts",
"test": "test.ts",
"tsconfig": "tsconfig.json",
"prefix": "app",
"mobile": false,
"styles": [
"styles.css"
],
"scripts": [],
"environments": {
"source": "environments/environment.ts",
"prod": "environments/environment.prod.ts",
"dev": "environments/environment.dev.ts"
}
}
],
"addons": [],
"packages": [],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "css",
"prefixInterfaces": false,
"lazyRoutePrefix": "+"
}
}
This is currently being designed and will be implemented before a final release. The general idea will be to provide a reference to a style file (CSS/SCSS/LESS...) and have it included within the application.
As mentioned before, it's being implemented for future releases. There's already a pull request to fix this. You can update it manually as a workaround for now.
Then, update your angular-cli.json file:
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": "assets",
"index": "index.html",
"main": "main.ts",
"test": "test.ts",
"tsconfig": "tsconfig.json",
"mobile": false,
"additionalEntries": [
{ "input": "polyfills.ts", "output": "polyfills.js" },
"styles.sass"
],
"environments": {
"source": "environments/environment.ts",
"prod": "environments/environment.prod.ts",
"dev": "environments/environment.dev.ts"
}
}
],

Resources