Live edit, live reload with Chrome Workspaces, grunt and Less - less

I have setup a project with Bootstrap's less files and gruntjs in order to be able to have live edit in the Chrome Workspaces.
Hereunder is my Gruntfile.js. It auto-compiles less files into the desired style.css and creates a source map file when I save my changes. I'm also able to edit and save less files from Chrome Workspaces after adding the project directory to the Workspaces.
module.exports = function(grunt) {
'use strict';
require('matchdep').filterDev('grunt-!(cli)').forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
less: {
dev: {
options: {
sourceMap: true,
sourceMapFilename: 'public/css/style.map',
sourceMapBasepath: 'public/css'
},
files: {
'public/css/style.css': 'less/style.less'
}
}
},
watch: {
all: {
files: ['less/**/*.less'],
tasks: ['less'],
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['less', 'watch']);
};
The problem I'm having is that I'm unable to see the live reload of my modifications on the less files via Sublime Text 2 or Chrome Workspaces directly in the browser without refreshing the page.
What am I missing? I have to map files? What file to what file exactly? Will I need to map multiple the same way or only one file.
I've also added an image where you can see the files tree.
FYI, also please note that the style.less imports the bootstrap less files and my custom less files.
// Core variables and mixins
#import "bootstrap/bootstrap";
#import "showtime/lib";
#import "showtime/intro";
#import "showtime/nav";
#import "showtime/portfolio";
#import "showtime/contact";
#import "showtime/footer";
#import "showtime/album";
Update If edit from the Elements tab, my style.less file gets overwritten with the content that is also in style.css and then it works. What am I doing wrong ?
Many thanks for your time and help.

OK the only I was able to make everything work is by putting the less files in my css folder.

Related

How to extract all the CSS to a single file in Nuxt?

I'm currently building a UI Kit for a client who is using ASP.NET for the main application/backend for their project. The UI Kit that I'm building is created using NuxtJS and I want to compile all of the SCSS files along with Bootstrap into a single compiled CSS file, from what I've gathered on the Nuxt Docs they recommend compiling the SCSS files into single CSS files for each component.
Before I start making a mess of the config file, is there a way to compile them into a single file so the client can just enqueue it on their end? It doesn't need to be the most performative which is why we're going to push it into a singular file.
Here is the part of the doc for Nuxt2, I quote
You may want to extract all your CSS to a single file. There is a workaround for this:
nuxt.config.js
export default {
build: {
extractCSS: true,
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.(css|vue)$/,
chunks: 'all',
enforce: true
}
}
}
}
}
}
This part is not directly written but still available for Nuxt3, so I guess that it should work in a similar approach.
There is only one discussion on Nuxt3's repo, but you may start trying the snippet above already, to see if it fill some of your needs.

how to override vue cli-service entry settings

I'm trying to integrate a vue project that I built with the vue cli into an existing .net app. I'm very new to vue, so I'm trying to follow guides and such, but am left with lots of questions.
While trying to compile this, I found that the vue cli-service node module has the following for setting the main.js file located in it's base.js file.
webpackConfig
.mode('development')
.context(api.service.context)
.entry('app')
.add('./src/main.js')
.end()
.output
.path(api.resolve(options.outputDir))
.filename(isLegacyBundle ? '[name]-legacy.js' : '[name].js')
.publicPath(options.publicPath)
I need to override this since my .net app doesn't have a src directory and the usage of this vue app won't follow that path structure. I'm not seeing a way to do it in my vue.config.js file. I would expect that if I can override it, that would be the spot.
I could overwrite the base.js file where this exists, but when a co-worker runs npm install, they would get the default value rather than what I have. The only option I see there is checking in all the node modules to git which we really don't want to do.
For anyone in a similar situation, I found what worked for me. It's not the ideal solution due to the fact that it forces you to build into a js folder. That resulted in the file being put in Scripts\build\vue\js. Would be nice to be able to just dump it in the vue folder, but at least this works. Code below.
vue.config.js
module.exports = {
publicPath : "/",
outputDir: "Scripts/build/vue", //where to put the files
// Modify Webpack config
// https://cli.vuejs.org/config/#chainwebpack
chainWebpack: config => {
// Not naming bundle 'app'
config.entryPoints.delete('app'); //removes what base.js added
},
// Overriding webpack config
configureWebpack: {
// Naming bundle 'bundleName'
entry: {
quote: './Scripts/Quote/index.js' //where to get the main vue app js file
},
optimization: {
splitChunks: false
}
},
filenameHashing: false,
pages: {
quoteApp: { //by using pages, it allowed me to name the output file quoteApp.js
entry: './Scripts/Quote/index.js',
filename: 'index.html'
}
}
}

Vue CLI v3 - How does it know what JS files should be chunked in a different file(s)

I am having hard times wrapping my mind around new CLI and configuration.
In the official documentation, I couldn't really find anything about CSS and how to add it as an entry point and not import it directly into an component or main.js file.
I realized that some JS files are being chunked into separate file, from main.js and the rest gets compiled where supposed to - into the app.js.
I was wondering, how does it know in the background what should be stored as "vendor" for the JS, but when I try to import some "vendor" SASS files into main.js it does not and it merges all within a single app.css file.
Can anyone tell me, how does one create/modify the vue.config.js and tell the bundler that I also want app.scss to be an entry point and vendor.scss to be another entry point.
I am unsure what are best practices for such purpose, but I always did it this way with my own webpack config...
Partial example below:
entry: {
vendor: [
'./styles/vendor.scss',
'./scripts/vendor.js'
],
app: [
'./styles/app.scss',
'./scripts/app.js'
]
}
EDIT #1
I think I got the first one...
"How does it know what should be chunked in "vendor" files?
Whatever gets imported from node_modules, it is being chunked.
What I did not figure out yet is... What if I am having my personal assets/styles/vendor directory where I #import those SASS files from NPM and do some modifications of variables or whatever.
Importing this file to main.js does not get chunked in this case... So there must be a way to tell bundler that I want everything within that directory or everything within vendor.scss file where everything is being imported, to be chunked out.
EDIT #2
I figured I can use WebPack's magical comments to import the main vendor SCSS file, such as:
import(/* webpackChunkName: "vendor" */ './assets/styles/vendor.scss')
I don't have a problem with this, but apparently the bundler does. It generates an empty vendor.[hash].js file as well.
EDIT #3
I did further research and learned that there's a command vue inspect which would output the webpack configuration.
So when making tweaks to vue.config.js, we can look a the output with this command if there's a bug or something is not working as expected.
Further more, I learned that if we specify entry directly in our vue.config.js file, that we will get an error that entry cannot be specified within our configuration file.
The following is forbidden to do so, but it's what I actually want to achieve...
// vue.config.js
module.exports = {
entry: {
app: [
'./src/main.js',
'./src/assets/styles/app.scss'
],
vendor: [
'./src/assets/styles/vendor.scss'
]
}
}
The actual proper way to do this will be an answer to my own question...
The way to achieve this is by using WebPack's Chain API.
However, if I did everything correctly, I still see a problem of generated vendor.[hash].js file with some WebPack module boilerplate. This JS file is also being injected to the index.html template.
Which leads to the same outcome as the attempt of my EDIT #2, except that we're no longer importing our Sass files within main.js
To modify entry points for my purpose of this question, we can do it the following way:
// vue.config.js
module.exports = {
chainWebpack: config => {
config
.entry('app')
.add('./src/assets/styles/app.scss')
.end()
.entry('vendor')
.add('./src/assets/styles/vendor.scss')
.end()
}
}
Note
We're not specifying the app entry JS file, which would be main.js by default, because we're not overriding the current entry point. Instead, we're extending it, so everything works as expected.
UPDATE
Until WebPack resolves this in future major releases, I found a great package - fqborges/webpack-fix-style-only-entries. It solves this issue that I was having and I'd suggest you to use it.
Final configuration would look like this:
const FixStyleOnlyEntries = require('webpack-fix-style-only-entries')
module.exports = {
chainWebpack: config => {
config
.entry('app')
.add('./src/assets/styles/app.scss')
.end()
.entry('vendor')
.add('./src/assets/styles/vendor.scss')
.end()
},
configureWebpack: {
plugins: [
new FixStyleOnlyEntries()
]
}
}
UPDATE #2
After further investigation and use of such configuration for projects, I realized that I had to use !important in styles where I had a need to override anything vendor related.
This is simply because WebPack will inject app, before vendor (both JS and CSS) and it will cause such issue.
Even if we modify the configuration from above and move app entry, below the vendor entry, it will still fail. Reason being, because we're modifying the entry point which already exists by default within vue-cli config. We're adding more entries to the app and we're adding new vendor entry.
To fix this issue of ordering, we must delete the app entirely and then create it ourselves.
const FixStyleOnlyEntries = require('webpack-fix-style-only-entries')
module.exports = {
chainWebpack: config => {
config.entryPoints.delete('app')
config
.entry('vendor')
.add('./src/assets/styles/vendor.scss')
.end()
.entry('app')
.add('./src/main.js')
.add('./src/assets/styles/app.scss')
.end()
},
configureWebpack: {
plugins: [
new FixStyleOnlyEntries()
]
}
}

Stencil and Sass file

I am trying to port a React component to Stencil.
The component .scss file has an #import for another A.scss file. That A.scss file #import the bootstrap-sass/assets/stylesheet/bootstrap/_variables and #import another B.scss file.
Can Stencil handle that or do I need to merge everything in one file?
You can import other Sass files; you don't need to merge everything to one single file.
You can keep using Sass as you are using it with React. Just keep in mind that to be able to use Sass with Stencil, you have to install the Sass plugin and add the plugin to the plugins array in your stencil.config.js file.
For more information, check the Sass documentation on the Stencil website.
In your stencil.config.ts (or stencil.config.js) file:
export const config: Config = {
plugins: [
sass({
includePaths: [path.resolve(__dirname, 'path/to/styles')]
})
]
};
Yes, it can handle Sass files and their imports.
Install package stencil/sass:
npm i #stencil/sass -D
In your stencil.config.ts file:
import { Config } from "#stencil/core";
import { sass } from "#stencil/sass";
export const config: Config = {
// ... You configuration
plugins: [
sass({
includePaths: ["./node_modules/"],
}),
],
};
In the above example, we're telling the Stencil compiler to compile Sass files. The includePaths array tells the compiler the directories/files it should look into for the Sass files.
In order to use #import from a Node.js package, all you need is:
#import "~bootstrap-sass/assets/stylesheet/bootstrap/_variables";
Note: The ~ operator here is necessary when not importing using relative paths(./style.scss, ../../style.scss, etc.)
If you are importing the b.scss file using relative paths (./b.scss, ../b.scss, etc.), you won't need to add anything else to Sass plugin configuration.
I never tried multiple imports, but I can't see why this wouldn't work.
To get Stencil working with .scss, you should install this plugin, as described here.
npm install #stencil/sass --save-dev
Then add this property to config in file stencil.config.ts.
plugins: [
sass()
]

Server a static pdf - Vue CLI - Webpack - issue

I build a little front thanks to VueCLI (+ Vuetify).
I wanted to render a button where onClick open a new tab with a pdf located in the folder's tree of the project.
I have an error and after hours looking why, it's seems to be a webpack conf to modify.
I finally read this answer on S/O ; Serving static pdf with react webpack file loader
But I got an error saying include: paths -> paths is not defined
I have to admit that I have no clue how webpack works behind the scene so any help would be find.
You probably don't need Webpack for this: you can just put it in your static folder and link to it pdf. If you want to go the Webpack route, put it in your src/assets directory and import it and add it to data object:
import pdf from '../assets/mypdf.pdf'
//...
data: () => ({ pdf })
//...
Then use the link in your component:
<a :href="pdf">pdf</a>
You probably added include: paths to the loader config but you didn't define it, instead of modifying your image loader, add a new one for PDFs:
{
test: /\.(pdf)(\?.*)?$/,
loader: 'url-loader',
options: {
name: utils.assetsPath('[name].[hash:7].[ext]')
}
}
You can change [name].[hash:7].[ext] if you want, say you want to add a pdfs directory in assets instead of using the base assets directory you would use: pdfs/[name].[hash:7].[ext]