Nuxtjs + Vuetify + Purgecss - vue.js

Seeing as Vuetify adds around 300-340kb worth of icons when using icons: 'mdi' with the nuxt#vuetify-module, I've found answers indicating that purgeCSS is a good solution to shave off the unnecessary and unused icons.
I initially imported the icons manually from 'mdi/font' but quickly realized this was a very ineffective solution because it forced me to constantly come up with solutions of adding the icons manually to components.
I can't seem to get purgecss to remove the icons though (which is the most important to me).
I installed "#nuxtjs/vuetify": "^1.11.3",
I installed "nuxt-purgecss": "^1.0.0",
I installed "#mdi/font": "^5.9.55",
Looking at this answer I tried to create my settings
why do i see vuetify css in view source?
They also discuss it here:
https://github.com/vuetifyjs/vuetify/issues/7265
vuetify: {
customVariables: ['~/assets/variables.scss'],
treeShake: true,
defaultAssets: {
font: {
family: 'Ubuntu',
},
icons: {
iconfont: 'mdi',
},
},
theme: {
dark: false,
themes: {
light: {
primary: '#fec655',
primarytext: '#23263e',
},
}
}
},
purgeCSS: {
enabled: true,
paths: [
'components/**/*.vue',
'layouts/**/*.vue',
'pages/**/*.vue',
'plugins/**/*.js',
'./node_modules/vuetify/dist/*.js',
'./node_modules/vuetify/dist/*.css',
'./node_modules/vuetify/src/**/*.ts',
'./node_modules/#mdi/fonts/*',
],
styleExtensions: ['.css'],
// whitelist: ['body', 'html', 'nuxt-progress', ''],
whitelist: ['v-application', 'v-application--wrap','layout','row','col'],
whitelistPatterns: [
/^v-((?!application).)*$/,
/^theme--*/,
/.*-transition/,
/^justify-*/,
/^p*-[0-9]/,
/^m*-[0-9]/,
/^text--*/,
/--text$/,
/^row-*/,
/^col-*/,
/leaflet/,
/marker/
],
whitelistPatternsChildren: [/^v-((?!application).)*$/, /^theme--*/],
extractors: [
{
extractor: content => content.match(/[A-z0-9-:\\/]+/g) || [],
extensions: ['html', 'vue', 'js']
}
]
},
Yet still, this request is being made with the original size, any ideas? What am I doing wrong here? The fonts clearly are pulled from locally and not the CDN.

Aside from working with PurgeCss, Have you tried using #mdi/js instead of mdi icons ?
This's from dev.materialdesignicons.com guide:
Using the webfont while easy to use is highly discouraged due to performance and overall request size
So you may roll that by switching to #mdi/js pachage:
https://www.npmjs.com/package/#mdi/js
then specify usage in vuetify options in nuxt.config.js
icons: {
iconfont: 'mdiSvg',
}
Now you have saved considerably in the bundle size.

Related

Skipping larger chunks while running "Npm run build"

Facing this problem while trying to run "npm run build"
(!) Some chunks are larger than 500 KiB after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/guide/en/#outputmanualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
If you don't want to increase the chunkSizeWarningLimit and focus more on solving the actual size issue, Try this solution:
export default defineConfig({
....
build: {
rollupOptions: {
output:{
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString();
}
}
}
}
}
});
EDIT: This is a work around and only hides warnings
Add command in vite.config.js
build: {
chunkSizeWarningLimit: 1600,
},
full code
// https://vitejs.dev/config/
export default defineConfig({
base: "/Stakepool-Frontend/",
plugins: [vue()],
resolve: {
alias: {
"~": path.resolve(__dirname, "node_modules"),
"#": path.resolve(__dirname, "src"),
},
},
build: {
chunkSizeWarningLimit: 1600,
},
});
While these solutions may seem valid I am not really satisfied with the details provided:
The answer given by Haseeb essentially hides the warning and may lead to more confusion.
MohKomas answer is on the right track but doesn't explain the whys.
I was facing the same issue while working on a Svelte project which relies heavily on the Apache ECharts library (which is quite big when importing it as a whole package). The key was to just import the parts needed and make use of the tree-shakeable interface by the library. Doing this shaved off over 500KiB from the built application.
it worked for me on vite
import { defineConfig } from "vite"
‌
export default defineConfig({
build: {
chunkSizeWarningLimit: 100000000
},
})

Vuetify + Nuxt + locally add md icons

How would one import the 'md' icons locally, similar to how they import the mdi ones in this post:
How to import the mdi icons module inside nuxt.config.js in Nuxt
Either the standard package or the custom repo
https://github.com/jossef/material-design-icons-iconfont
I'm using the nuxt-vuetify plugin.
All my attempts have failed, e.g adding this:
nuxt.config.js
css: ['~/assets/main.css', './node_modules/material-design-icons-iconfont/dist/material-design-icons.css'],
vuetify: {
customVariables: ['~/assets/variables.scss'],
treeShake: true,
defaultAssets: {
font: false,
icons: 'md',// this just fetches it from the repo
// icons: {iconfont: 'md'} // this doesn't seem to work for me
enter code here
},
theme: {
dark: false,
themes: {
light: {
primary: '#fec655',
},
}
}
},
I ended up solving it right after I posted it.
In the end, the settings in the original questions are correct.
One simply has to install the 'md' package from the original source or https://www.npmjs.com/package/material-design-icons-iconfont
After that, it's just a matter of changing the global CSS import.
E.g
css: ['./node_modules/material-design-icons-iconfont/dist/material-design-icons.css'],
A sidenote is that it seems to be possible to use both 'md' and 'mdi' by installing mdi/js for the treeshaken version & making imports manually.
This way, you can use the default icons for all the components but still add more icons from MDI if needed. Since the 'mdi' bundle is around 330kb while the 'md' one is only around 80kb this saves quite a lot of space.

Cannot find module '#/assets/<file-name-here>.svg'. #vue/cli Version: 4.2.3 and 4.3.1

General jist:
import Image from '#/assets/default-profile-picture.svg'
//ERROR: Cannot find module '#/assets/default-profile-picture.svg'.Vetur(2307)
I have spent the better part of today trying to find a solution to this. I know there are a lot of other posts like this one, but they are all outdated (all over a year old).
I've just generated a clean Vue CLI app, and still have the same issue.
I'm using Vue CLI Version 4.2.3, and just attempted using Vue CLI Version 4.3.1, but ran into the same issue.
I have checked that the file is in assets.
I have checked that the filename is spelled correctly.
I have a feeling this is a webpack issue, as require() would not work when called using typescript.
I have tried creating vue.config.js and manually setting the path for assets.
Project setup configuration:
Features: Babel, TS, Router, ESLint
not class-style syntax
Babel used alongside Typescript
No history mode for router
eslint with error prevention only
Lint on save
Configs placed in package.json.
Error in Component.vue
<script lang="ts">
import Vue from 'vue'
/* Cannot find module '#/assets/default-profile-picture.svg'.Vetur(2307) */
import Image from '#/assets/default-profile-picture.svg'
export default Vue.extend({
components: {
},
props: [
'employeeImage',
'employeeName',
'employeeAge',
'employeeSalary'
],
data () {
return {
marked: false,
result: [],
name: this.employeeName,
age: this.employeeAge,
salary: this.employeeSalary
}
},
computed: {
compClasses: function () {
return {
marked: this.marked
}
},
imageDefault: function () {
if (this.employeeImage === '') {
console.log('employee image empty: ' + this.employeeImage)
return '#/assets/default-profile-picture.svg'
} else {
console.log('employee image set: ' + this.employeeImage)
return this.employeeImage
}
}
}
})
</script>
Typescript Config
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env"
],
"paths": {
"#/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"/src/**/*.*",
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}
What am I doing wrong?
Thanks in advance!
Please keep this in mind, that this answer is not a solution but more like a work-around for this issue by the time this question has been asked/answered for vue-svg-loader(#vue/cli Version: 4.2.3 and 4.3.1).
You can use absolute path instead of using # to reference the file when you want to import .vue components. Here is an example:
Instead of this:
Read more about this issue and any possible solutions on official repository for this issue on GitHub:
Typescript Cannot find module '#/assets/svg/register.svg?inline' #92
Typescript does not support svg files.
Create a svg.d.ts file in your project source folder with the following content:
declare module '*.svg';
and restart your editor

Default colors does not work for `tailwind.macro`

I have a React app, attempting for tailwind.macro to work within
emotion notations.
I am using customize-cra to rewire the app, and ${twWHATEVER} is successfully working.
However, it does not seem to inherit the original color themes from
tailwind and I am looking for a solution.
Here is the project:
https://github.com/minagawah/cra-ts-emotion-tailwind-solution
As described in the README, I tried
(1) using babel macro,
and (2) using PostCSS plugins.
I thought it's the backgroundSize problem
as it is discussed in
this issue, but no luck.
Here is how I use the tw macro notation in the app:
# ./src/App.tsx
import styled from '#emotion/styled';
import tw from 'tailwind.macro';
const Button = styled.button`
${tw`mt-4 p-2 text-white bg-red-600`}
`;
And it currently works
because I applied a workaround
for this.
It should apply the default tailwind color themes without the workaround I've applied.
I have been trying to figure out ways, but so far, no luck...
Please, I desperately need a help on this...
EDIT: (2019-09-22)
While I was struggling for bg-red to work, I just found out there's no such thing as bg-red by default... That was something I needed to manually add in tailwind.config.js.
Problem solved.
module.exports = {
theme: {
extend: {
colors: {
red: '#e53e3e',
},
},
},
variants: {},
plugins: [],
}
theme: {
extend: {
colors: {
red: '#e53e3e',
},
},
},
variants: {},
plugins: [],
}
i had the same issues i fixed by copying the default value from the tailwindcss github in tailwind.config.js.
here is the link to tailwindcss default value
https://github.com/tailwindcss/tailwindcss/blob/master/stubs/defaultConfig.stub.js#L5

How to set vscode format Vue template automatically on save?

I've modified the settings.json file, but it doesn't work.
Here it is:
{
"eslint.autoFixOnSave": true,
"vetur.format.defaultFormatter.html":"js-beautify-html"
}
In your settings.json you should have:
editor.formatOnSave: true
[vue]: {"editor.defaultFormatter": "octref.vetur"} if you have several formatters registered for .vue files you need to specify which one to use (otherwise format on save will not know which one to use and it will default to do nothing. This will select "Vetur" as the default.
"vetur.format.defaultFormatter.html": "js-beautify-html" to tell Vetur how to format the part inside <template> tags:
{
"editor.formatOnSave": true,
"vetur.format.defaultFormatter.html": "js-beautify-html",
"[vue]": {
"editor.defaultFormatter": "octref.vetur"
}
}
Note: How do you know that there are several formatters registered for .vue? If when you use the Format Document action you get the dialog There are multiple formatters for 'Vue' files. Select a default formatter to continue then it means that you have more that one formatter registed for '.vue' files.
use plugin:vue/recommended replace plugin:vue/essential
// .eslintrc.js
module.exports = {
extends: [
'plugin:vue/recommended',
'#vue/standard'
]
}
enable eslint fix on save
// .vscode/settings.json
{
"eslint.validate": [
"javascript",
"html",
"vue"
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
},
"vetur.validation.template": false
}
To get the auto-save of templates to work using the combination of ESLint and Vetur, I used the following combination of VS Code settings:
{
"eslint.validate": [
"vue",
"html",
"javascript",
"typescript"
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.formatOnSave": true,
"vetur.format.defaultFormatterOptions": {
"prettier": {
"singleQuote": true
}
}
}
The "editor.formatOnSave": true did the trick for me. This lead to the problem of converting single quotes to double quotes in the script section, therefore I added the prettier singleQuote config as well.
My answer is just loosely coupled to the question but as this question is the top result for googling "vetur auto format not working" I would like to add a possible solution to that.
My template had the lang attribute set like this <template lang="">. After removing the attribute auto formatting started to work again.