laravel-mix / webpack, ignore sass loaded file (font) to be exported - laravel

I am trying to skip a dependency loaded font (with url() ) to be exported.
I used ignore-loader module.
mix.webpackConfig({
module: {
rules: [
{
test: /context-menu-icons\.(eot|ttf|otf|woff|woff2)$/,
loader: 'ignore-loader'
}
]
}
});
The issue is it produce empty files. The behavior I am expecting is to not output these files at all.
The reason for this is this in a dependency in node_modules
#font-face {
font-family: '#{$context-menu-icon-font-name}';
src: url('#{$context-menu-icon-font-path}#{$context-menu-icon-font-name}.eot?#{$context-menu-icons-cachebust}');
src: url('#{$context-menu-icon-font-path}#{$context-menu-icon-font-name}.eot?#{$context-menu-icons-cachebust}#iefix') format('embedded-opentype'),
url('#{$context-menu-icon-font-path}#{$context-menu-icon-font-name}.woff2?#{$context-menu-icons-cachebust}') format('woff2'),
url('#{$context-menu-icon-font-path}#{$context-menu-icon-font-name}.woff?#{$context-menu-icons-cachebust}') format('woff'),
url('#{$context-menu-icon-font-path}#{$context-menu-icon-font-name}.ttf?#{$context-menu-icons-cachebust}') format('truetype');
font-weight: normal;
font-style: normal;
}
Is there a way to just ignore these files from output / copy in my dist folder ?

I could not find a solution because, font-face is loaded from a scss file.
So using options with file-loader to prevent emitting files won't work.
There would be a string in these file with module.exports = ...
In all cases the font files would be emmited empty or not.
So I used clean-webpack-plugin with these options
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
...
mix.webpackConfig({
plugins: [
new CleanWebpackPlugin({
// dry: true,
verbose: true,
// Automatically remove all unused webpack assets on rebuild
cleanStaleWebpackAssets: false,
// Do not allow removal of current webpack assets
protectWebpackAssets: false,
cleanOnceBeforeBuildPatterns: [
'**/*', // clean all
'!views','!views/**/*', // ignore views folder
'!lang','!lang/**/*', // ignore lang folder
],
cleanAfterEveryBuildPatterns: [
'fonts/vendor' // remove fonts/vendor folder after build and watch
],
}),
]
});
...

Related

How to load scss variables and fonts file from node_modules in Vite

I am using nuxt-vite in a SSR nuxt project, here is my code
nuxt.config.js
module.exports = {
css: [
'~/assets/fonts.scss',
]
}
I want to use #mdi/font in my project, and here is where it located in node_modules:
First, I try to import the css directly:
#import '#mdi/font/css/materialdesignicons.css
But the browser can not find the fonts files
Then, I try to load the raw scss variables just like what I did when using webpack whick works without any issues.
#import "#mdi/font/scss/variables";
#import "#mdi/font/scss/functions";
#font-face {
font-family: '#{$mdi-font-name}';
src: url('#mdi/font/fonts/#{$mdi-filename}-webfont.eot?v=#{$mdi-version}');
src: url('#mdi/font/fonts/#{$mdi-filename}-webfont.eot?#iefix&v=#{$mdi-version}') format('embedded-opentype'),
url('#mdi/font/fonts/#{$mdi-filename}-webfont.woff2?v=#{$mdi-version}') format('woff2'),
url('#mdi/font/fonts/#{$mdi-filename}-webfont.woff?v=#{$mdi-version}') format('woff'),
url('#mdi/font/fonts/#{$mdi-filename}-webfont.ttf?v=#{$mdi-version}') format('truetype');
font-weight: normal;
font-style: normal;
}
#import "#mdi/font/scss/core";
#import "#mdi/font/scss/icons";
#import "#mdi/font/scss/extras";
#import "#mdi/font/scss/animated";
But the vite can not load the scss variables correctly:
How can I use the fonts in node_modules when using vite?
I googled it and read the doc but helped little.
Greate thanks to anyone help!
add this to nuxt.config.js
vite: {
css: {
preprocessorOptions: {
scss: {
additionalData: `#import "~/assets/styles/Variables.scss";\n#import "~/assets/styles/Mixins.scss";\n`
}
}
}
},

Laravel Mix and PurgeCss chain, not purging specified file after mix.copy

Trying to build out specific purgedCSS files for a project with rather large complete CSS file. However PurgeCSS refuses to only purge the specified file after mix.copy(), and still purges the main app.css file.
mix.sass('resources/sass/app.scss', 'assets/css').options({
processCssUrls: false,
postCss: [],
autoprefixer: {
options: {
browsers: ['last 6 versions']
}
}
})
.copy('assets/css/app.css', 'purge/css/home.css')
.purgeCss({
enabled: true,
extend: {
content: [
path.join(__dirname, '/purge/html/home.html')
],
css: [
path.join(__dirname, '/purge/css/home.css')
]
}
}).copy('purge/css/home.css', 'assets/css');
The above ends up with 3x CSS files, purged successfully based on the home.html file, however only the copied home.css should be being purged, then copied back to assets/css/home.css.
I've tried using promises after each chain function, but it still refuses to only purge the specified file instead always purging the file compiled with mix.sass() at the top of the chain.
Any ideas?

Add Background image in SCSS with rollup bundle?

I can't able to use image path in scss file as background with rollup bundle.
My rollup config looks like this.
import typescript from 'rollup-plugin-typescript2';
import commonjs from 'rollup-plugin-commonjs';
import external from 'rollup-plugin-peer-deps-external';
import resolve from 'rollup-plugin-node-resolve';
import scss from 'rollup-plugin-scss';
import image from 'rollup-plugin-img'; // module solves image add in source
import pkg from './package.json';
export default {
input: 'src/index.tsx',
output: [
{
file: pkg.main,
format: 'cjs',
exports: 'named',
sourcemap: true,
},
{
file: pkg.module,
format: 'es',
exports: 'named',
sourcemap: true,
},
],
plugins: [
image({
extensions: /\.(png|jpg|jpeg|gif|svg)$/,
limit: 10000
}),
scss(),
external(),
resolve({
broswer: true
}),
typescript({
rollupCommonJSResolveHack: true,
exclude: '**/__tests__/**',
clean: true,
}),
commonjs({
include: ['node_modules/**'],
namedExports: {
'node_modules/react/react.js': ['Children', 'Component', 'PropTypes', 'createElement'],
'node_modules/react-dom/index.js': ['render'],
},
})
],
};
I am trying to add an image path in scss.
.chipsComponent > div:last-child {
background: url("/assets/images/Close_Circle.svg") no-repeat;
background-size: cover;
height: 16px;
width: 16px;
float: right;
cursor: pointer;
}
image path is adding in browser but rollup is not serving asset folder.Attached screesnhot
The image should show in circled chips(red).
Have I missed anything in rollup config or scss image usage is wrong?
Thanks in Advance
The scss line below is not actually importing the image:
background: url("/assets/images/Close_Circle.svg") no-repeat;
The rollup plugin rollup-plugin-img relies on resources being used via import declarations, like in a js file:
import logo from './rollup.png';
You have two options:
Write your own SCSS processor plugin that resolves url(...) references to copy over assets into your bundle directory.
Use a more manual rollup plugin like rollup-plugin-copy.
With rollup-plugin-copy you can use the following code in your rollup config:
plugins: [
copy({
targets: [
{ src: 'src/assets/images', dest: 'dist/assets/images' },
],
}),
This will copy over all of your images from your source folder to your bundle output.

How I can pass environment variables to scss/ sass file using laravel mix and webpack?

I have an environment variable CDN_URL and I want to send this variable to the SCSS file.
I am also tried prependData of sass-loader.
I have to use Laravel 5.7, Laravel Mix 4.1.2 and webpack 4.27.1
error: Invalid CSS after "...load the styles": expected 1 selector or at-rule, was "var content = requi"
Below is my 'webpack.mix.js' file code.
mix.webpackConfig({
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'vue-style-loader',
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
indentedSyntax: true,
prependData: '$cdn-s3-static-url: ' + process.env.CDN_S3_STATIC_URL + ';',
},
},
],
},
],
},
});
Below is my '_functions.scss' file code:
#function asset($type, $file) {
#return url('#{$cdn-s3-static-url}#{$asset-base-path}#{$type}/#{$file}');
}
In my case I was running a gatsby site. Before each build, it runs gatsby-config.js, which has access to environment variables.
So at the top of the .js file that builds, before module.exports, I put this:
if(process.env.NODE_ENV === 'development') {
fs.writeFileSync('./src/styles/build-style.scss','$root: "/development-path/";');
} else {
fs.writeFileSync('./src/styles/build-style.scss','$root: "/production-path/";');
}
This results in a file which looks like:
$root: "/development-path/";
Then in the SCSS files where I needed ENV-dependent behaviour, I have:
#import './build-style.scss';
#font-face {
font-family: "MyFontFamily";
src: url($root + "font/MyFontFamily.woff") format('woff');
}
And now my asset (font in this example) loads from different spots depending on my dev/production environment variable.
It feels like a big hack and I'm sure there's a more correct way somewhere, but this got me moving again after an hour stoppage and it is working so far. I will probably extend it in the future to have build-style-dev.scss, build-style-prod.scss, and just copy them into build-style.scss at compile time. Or research the correct way.
You can prepend data to SASS using sass-loader
For example to pass the CDN_URL from .env
Extend webpack.mix.js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
prependData: '$env: ' + process.env.CDN_URL + ';',
},
},
],
},
],
},
};
You may inject environment variables into Laravel Webpack Mix by prefixing a key in your .env file with MIX_. After the variable has been defined in your .env file, you may access via the process.env object.
So in your example, you should create a new variable in .env file like MIX_CDN_URL and inside webpack.mix.js you can access it using
process.env.MIX_CDN_URL
You can sass-loader that will achieve the results you desire.

Grunt sass #import not making css

I'm trying to use sass with grunt and I'm having a weird behavior.
If I create any file with underscore it doesn't work anymore, and it doesn't import either.
That is my Gruntfile, really simple:
module.exports = function(grunt) {
'use strict';
require('load-grunt-tasks')(grunt);
grunt.initConfig({
watch: {
sass: {
files: 'scss/**/*.{scss,sass}',
tasks: ['sass']
}
},
sass: {
example: {
options: {
outputStyle: 'expanded'
},
files: {
'public/css/app.css': 'scss/**/*.{scss,sass}'
}
}
}
});
grunt.registerTask('default', ['watch']);
};
If I create a file, for example, application.scss in scss/, it works and creates the file app.css in public/css, but if I create any file with underscore, for instance: _variables in scss/ it doesn't work anymore, it doesn't create the file or changes anything and it doesn't import either.
application.scss:
#import "variables";
body {
background-color: $bg-color;
}
_variables.scss:
$bg-color: red;
Files with names starting with an underscore are considered as partial in the eyes of SASS. This means that SASS would not make an actual css file out of them. To prevent this, either create an index.scss file and import your partials in it or remove the underscore from their names.
Official DOcs
I solved it by using:
files: [{
expand: true,
cwd: 'scss',
src: '**/*.{scss,sass}',
dest: 'public/css',
ext: '.css'
}]

Resources