Smallest possible Vuetify CSS/JS size 0.5Mb? - vuetify.js

I created a brand new NUXT app and included in it the following minimum setup:
// package.json
{
"scripts": {
"generate": "nuxt generate",
"analyze": "nuxt build --analyze"
},
"dependencies": {
"nuxt": "^2.11.0",
"vuetify": "^2.1.3"
},
"devDependencies": {
"#nuxtjs/vuetify": "^1.9.0"
}
}
// nuxt.config.js
export default {
buildModules: [["#nuxtjs/vuetify"]]
};
<!-- pages/about.vue -->
<template>
<p>Hello world!</p>
</template>
Note that I am not actually USING any of the Vuetify components. So if I run npm generate, what do I get?
./dist/about.index.html --- 243KB, almost all of it vuetify CSS
./_nuxt/'vendors.app' --- 266KB, 265KB of it Vuetify
Contrast this with what happens when I make a single change to the above setup: I simply delete the entire nuxt.config.js file, falling back to the default file. After running npm generate, I get:
./dist/about.index.html --- 2KB
./_nuxt/'vendors.app' --- 0KB, The file is gone!
What happened to the tree shaking of Vuetify? (I tried forcing treeshaking by setting it to true in nuxt.config.js, and no change) Is 250KB of vendors.app and 250KB of CSS the minimum you have to 'pay' in order to use Vuetify? Or am I making some kind of mistake in this setup?

Related

Windi CSS HMR not working for Svelte + vite app

I created a Svelte project with Vite and added windicss. I am using Yarn as build tool. I added WindiCSS to vite using https://windicss.org/integrations/vite.html#install. It works fine when I start the project using,
yarn dev
But HMR (Hot Module Reload) for Windi CSS does not work. But when I kill the server and restart it picks up the Windi CSS changes. Even the Devtool changes are working fine, only HMR is not working.
package.json file,
{
"name": "svelte-in",
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview"
},
"devDependencies": {
"#sveltejs/vite-plugin-svelte": "^1.0.0-next.11",
"svelte": "^3.37.0",
"vite": "^2.6.4",
"vite-plugin-windicss": "^1.4.11",
"windicss": "^3.1.9"
}
}
vite.config.js file,
import { defineConfig } from 'vite'
import { svelte } from '#sveltejs/vite-plugin-svelte'
import WindiCSS from 'vite-plugin-windicss'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
svelte(),
WindiCSS()
]
})
And main.js is,
import App from './App.svelte'
import 'virtual:windi.css'
import 'virtual:windi-devtools' // To enable windi in dev tools
const app = new App({
target: document.getElementById('app')
})
export default app
Not sure if I am missing anything else.
I had to put WindiCSS() before svelte() for HMR to work.

Getting svelte-material-ui working with snowpack and sass

I'm trying to get svelte material UI working with snowpack.
I have installed Snowpack and Snowpacks svelte template like so:
npm install --save-dev snowpack#next
npx create-snowpack-app xpapp --template #snowpack/app-template-svelte
This works, the sample svelte page shows up. Next I followed the Svelte Material UI instructions to "bundle this in your own code" as cited on the Usage chapter in the instructions here: https://github.com/hperrin/svelte-material-ui#usage
So I installed Sass and configured it in my snowpack.config.json file like this:
{
"extends": "#snowpack/app-scripts-svelte",
"scripts": {
"build:scss": "sass"
},
"devOptions": {},
"installOptions": {}
}
I followed the (very concise) instructions here: https://www.snowpack.dev/#sass
I've also added an empty src/theme/_smui-theme.scss file to my source files as the instructions say, and I installed the nessecary #smui components.
The problem is that I'm currently getting this error when starting the snowpack dev server:
> snowpack dev
Snowpack Dev Server (Beta)
NOTE: Still experimental, default behavior may change.
Starting up...
⠙ snowpack installing... #smui/icon-button, #smui/top-app-bar, svelte/internal
✘ /home/erik/Projects/svelte-xpapp/xpapp/node_modules/#smui/icon-button/_index.scss
Error: Unexpected character '#' (Note that you need plugins to import files that are not JavaScript)
at error (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:161:30)
at Module.error (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:15120:16)
at tryParse (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:15009:23)
at Module.setSource (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:15410:30)
at ModuleLoader.addModuleSource (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:17460:20)
at async ModuleLoader.fetchModule (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:17521:9)
at async /home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:17491:36
at async Promise.all (index 0)
at async ModuleLoader.fetchModule (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:17522:9)
at async Promise.all (index 0)
It seems that the #import statements in Material UI's _index.scss aren't recognized. I figure Snowpack should interpret/transpile .scss files, but it doesn't seem to be doing that.
So I came across the same problem using Svite as well as Snowpack. I was able to use the bare implementation:
// component.svelte <script>
import Button, { Label } from '#smui/button/bare'
import '#smui/button/bare.css'
That's all that's required with Svite.
With Snowpack, I needed to add rollup-plugin-svelte and update snowpack.config.js
// snowpack.config.js
module.exports = {
// ...
installOptions: {
rollup: { plugins: [require('rollup-plugin-svelte')()] }
},
// ...
}
I got it working with these install options:
installOptions: {
rollup: {
plugins: [
require("rollup-plugin-svelte")({
include: ["./node_modules"],
}),
require("rollup-plugin-postcss")({
use: [
[
"sass",
{
includePaths: ["./src/theme", "./node_modules"],
},
],
],
}),
],
},
},
Unfortunately, you'll have to run npx snowpack dev --reload for changes to the theme to take effect.
This won't extract css into .css files.
I also got an error message with the Dialog component during a production build.
Here is a full example: https://github.com/LeanderG/svelte-smui

How to combine `css-modules` with normal `sass`, preferably in `webpack`

TLDR: How to combine css-modules with normal sass, preferably in webpack.
The Setup:
I am working on the styling build process for an e-commerce website. The site's styles are currently done in sass along with the js through a gulp browserify build process.
I have recently added a single page app that is built using react with webpack and babel. Inside of that application I am taking advantage of css-modules provided by webpack to scope the class names to each react component.
The problem:
I would like to incorporate the styles from the webpack css-modules build in with the main styling bundle for the site. To do this, I was considering building a webpack configuration to build the styles for the whole site. The problem I have is how to get the styles which are currently built by the single page webpack configuration and inject just the style chunk into a global webpack configuration that handles styles for the whole site. I should mention that I would like to keep the two configurations as separate as possible
The Questions:
Is there a proper way of having decoupled webpack builds where one is still able to use chunks from the other?
If so, how do I do it so that the css-module setup stays in the single page configuration, and the extract-text-webpack part along with a boring sass build goes into a global configuarion?
If not, how should I go about having one section of sass go through the css-modules workflow, and still combine it with the bundle from the rest of the site.
Thanks in advance.
EDIT
based on #Alexandr Subbotin's answer, I have updated my webpack to look something like the code below. I did have to change names and paths because of the code belongs to my employer, so there may be slight errors.
var ExtractTextPlugin = require('extract-text-webpack-plugin');
const JSDIR = './build/js/';
const STYLES = './build/css/bundle.css';
module.exports = {
entry : {
'styles' : './src/styles.scss',
'app' : './src/index.js',
// a javascript file that includes the root of the single page app.
'single-page' : './src/single-page/styles-entry.js',
},
output : {
path : JSDIR,
filename : '[name].js', // normally compiles my
publicPath: 'http://localhost:8080/',
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader : 'babel-loader',
query : {
presets: [
'react','es2015','stage-0',
]
},
},
{
test : /\.scss$/,
loader: ExtractTextPlugin.extract('style?sourceMap', 'css?-url&sourceMap!sass?sourceMap'),
exclude : /\/single-page\//,
},
{
test : /\.scss$/,
loader: ExtractTextPlugin.extract(
'style?sourceMap',
'css?-url&modules&importLoaders=1&localIdentName=SinglePage__[name]__[local]!sass?sourceMap'
),
include : /\/single-page\//,
}
]
},
plugins : [
new ExtractTextPlugin(STYLES, {
allChunks : true,
}),
],
resolve : {
alias: {
"eventEmitter/EventEmitter": "wolfy87-eventemitter",
},
extensions: ['', '.js','.jsx'],
},
}
If I understood your question you want to apply css-modules only to one part of your application and leave simple sass building process in other parts.
To do this you can use exclude and include options in loaders. I.e. if you have your single page application inside single-page directory your webpack config can be:
module: {
entry: {
// it is your global sass styles
application_css: './css/application.scss',
// it is main file of your SPA bundle. Somewhere inside you will use require('./styles.scss') that should be processed by css-modules
spa_index: './single-page/index.js'
},
loaders: [
...,
{
// This loader will build all your sass that are not in `single-page` directory
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style', 'css!sass'),
exclude: /\/single-page\//
},
{
// This loader will handle all your css module in `single-page` directory
test: /\.scss$/,
loader: 'style!css?modules!sass',
include: /\/single-page\//
},
],
...
}
So, in this case all css from single-page/ will use css modules, and the rest won't.
EDIT:
If you take a look in API section of ExtractTextPlugin documentation you find
The ExtractTextPlugin generates an output file per entry, so you must use [name], [id] or [contenthash] when using multiple entries.
In your example you have have two chunks with css (styles and single-page), but only one output ./build/css/bundle.css. If you change your output to ./build/css/[name].css your will have two css files: styles.css with your global css and single-page.css with SPA styles.

Webpack 2 - compile scss to css and miniffy, together with sourcemaps

I'm completely new to webpack (been using gulp since... forever).
However, I've just decided to use webpack. Decided to go with webpack 2 (2.1.0-beta.20 currently).
Been looking all over, still couldn't do a simple task as "give webpack my bootstrap.scss file (which imports all other bootstrap partial scss files needed) and have returned bootstrap.custom.min.css and bootstrap.custom.min.css.map".
I have my own bootstrap.scss file which only imports what I need from bootstrap (not using all of it), but after a custom custom-variables.scss file imported at the top, to overwrite some default bootstrap variables - like colors, grid columns etc. Anyway, I'm sure this is not relevant... The issue is compiling scss to css with custom output file name and sourcemap.
Not that it would make any difference, but to start with, here's my custom bootstrap.scss:
#import "custom-variables"; // to overwrite default bootstrap variables
/**
* Twitter Bootstrap
* This is actually copy/paste from the original bootstrap file, just changed paths
*/
// Core variables and mixins
#import "../../../../node_modules/bootstrap/scss/variables";
#import "../../../../node_modules/bootstrap/scss/mixins";
// and so on... only what I need. I don't need tables, forms and a few other.
In addition to this, I also have my own style.scss for which I need to do the same (to have returned style.min.css and style.min.css.map).
As for my webpack.config.js file, this is all I have:
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const sassLoaders = [
'css-loader',
'postcss-loader',
'sass-loader?indentedSyntax=sass&includePaths[]=' + path.resolve(__dirname, './dev')
];
const config = {
entry: {
'bootstrap.custom.min': ['./wp-bootstrap'], // this file only contains 1 line: require('./dev/css/overwrite/bootstrap/bootstrap.scss');
'style.min': ['./wp-style'], // this file also contains 1 line: require('./dev/css/style.scss');
},
module: {
loaders: [
{
test: /\.scss$/,
loader: 'file',
// or, other examples I've found said to use:
// loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loaders: 'css!sass' }),
// but if I try like that, I get: "Cannot read property 'query' of undefined"
query: {
name: '[name].css'
}
}
]
},
plugins: [
new ExtractTextPlugin('[name].css')
],
postcss: [
autoprefixer({
browsers: ['last 2 versions']
})
],
resolve: {
modules: [
path.resolve('./'),
'node_modules'
]
}
};
module.exports = config;
These are all the related packages I have installed:
"devDependencies": {
"autoprefixer": "^6.4.0",
"css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^2.0.0-beta.3",
"node-sass": "^3.8.0",
"postcss-loader": "^0.9.1",
"sass-loader": "^4.0.0",
"style-loader": "^0.13.1",
"webpack": "^2.1.0-beta.20"
}
If I use a version of extract-text-webpack-plugin which is <2.x, then I get other errors, it's not compatible with webpack 2.
So, baby steps in the code above... Simply tried to at least obtain my bootstrap.scss and style.scss transformed into 2 separate css files: bootstrap.custom.min.css and style.min.css (don't know what to do about sourcemaps yet).
This is all I could come up with after searching google and trying to follow some examples. No solid tutorial out there that could make me understand how to use webpack for what I need to accomplish. I'm only guessing here, blind-folded.
But when I type webpack in the console and hit Enter, I don't get any css file, instead I get the following 3 files:
bootstrap.css - with the exact same content as the source
bootstrap.scss, like it just copies the file content over, instead of compiling scss to css;
bootstrap.custom.min.js which has a bunch of javascript code in
it;
style.min.js - which also has a bunch of javascript code in it.
I've been stuck here for days, didn't even get to all the rest I need (sourcemaps and a destination folder of my choosing for the css files and css.map files).

Grunt Watch not observing any changes to any file aside from html files

Here is a basic view of my "watch" grunt task:
module.exports = function(grunt){
require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);
grunt.initConfig({
watch: {
options: {
livereload: true,
},
gruntfile:{
files:['gruntfile.js'],
tasks:['default']
},
html: {
files: ['index.html', 'assets/templates/*.html'],
tasks: ['default']
},
js: {
files: ['assets/js/*.js'],
tasks: ['default']
},
sass: {
options:{
livereload:false
},
files:['assets/sass/*.scss'],
tasks:['buildcss'],
},
css:{
files:['assets/sass/*.scss'],
tasks:[]
},
},
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['htmlhint','buildjs', 'buildcss', 'browserSync', 'watch','serve']);
};
So I have buildcss that compiles and minifies my scss into a master.css file. I've set up watch to watch the scss for changes, run the buildcss task, and then run the default task once the master.css file is updated. Then it should then refresh the page.
However, whenever I make a change to the scss file and save it, terminal shows no file updates even though it is apparently "watching files...". The only files that show as updated when I make changes are the html files: index and templates. It makes no sense to me. Sorry, I'm configuring Grunt for the first time here.
I was confusing watch and browserSync instead of using them together. First, I had to add watchTask: true, to browserSync, then I had to ensure that browserSync was being called before watch, and then I had to add the snippet of code the console prodded me to add to my index.html. Now it works perfectly. Here is the site I used to find my way: http://blog.teamtreehouse.com/getting-started-with-grunt

Resources