Name is getting mangled by Webpack 5 while mini-css-extract-plugin loader - bundler

Trying to export scss file with bootstrap 5.2 to a css file and linking that file to a index.php file but class names i guess are getting mangled somehow so I can't use bootstrap class like for a button btn btn-primary, as the generated classes names are like GcpZ2uTclIsK3IUwa3qT XWJXtmqteXQMN_oydssO
I have tried many webpack config but unable to find a solution. My current configs are shared below.
how can I use bootstrap exported scss in webpack build ?
webpack.config.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
mode: "development",
devtool: "source-map",
entry: "./src/js/main.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
plugins: [
new MiniCssExtractPlugin({
linkType: "text/css",
}),
],
module: {
rules: [
{
test: /\.scss$/,
use: [
{ loader: MiniCssExtractPlugin.loader },
{
loader: "css-loader",
options: {
modules: true,
},
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: () => [require("autoprefixer")],
},
},
},
{
loader: "sass-loader",
},
],
},
],
},
};
styles.scss
#import "~bootstrap/scss/bootstrap";
main.js
import "../scss/styles.scss";
import * as bootstrap from 'bootstrap'
import {addNumber} from './sum'
import {divideNumbers} from './division'
import {buttonClickAction} from './events'

I'm so new to webpack so I didn't exactly know what was I doing wrong.
The problem was in webpack config file css-loader as bootstrap works with global css selector not module based i had to remove
{
options: {
modules: true,
},
},

Related

How to use preload webpack plugin with blade templates

So i have a laravel/vuejs app , i'm trying to preload the css chunks that i have generated upon splitting components, it works fine but it generates an index.html. Is it possible to somehow do it in blade templates? What could be the solution?
Here is my webpack.config.js
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const {VueLoaderPlugin} = require("vue-loader");
const PreloadWebpackPlugin = require('preload-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require("path");
module.exports = {
entry: {
main: "./resources/js/app.js",
},
output: {
publicPath: '/',
path: path.resolve(__dirname, "public"),
},
plugins: [
new HtmlWebpackPlugin(),
new VuetifyLoaderPlugin(),
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: `components/[name].css`
}),
new PreloadWebpackPlugin({
rel: 'preload',
include: 'asyncChunks', // can be 'allChunks' or 'initial' or see more on npm page
fileBlacklist: [/\.map|.js/], // here may be chunks that you don't want to have preloaded
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
"css-loader"
]
},
{
test: /\.js$/,
loader: 'babel-loader',
},
{
test: /\.s[ac]ss$/i,
use: [
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
{
test: /\.vue$/,
loader: "vue-loader",
options: {
extractCSS: true
}
},
],
},
resolve: {
extensions: ['.js', '.vue'],
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/](vue|axios|jquery|bootstrap)[\\/]/,
name: 'vendor',
chunks: 'all'
}
}
}
}
}
And one final question , is it better to preload/prefetch the js chunks too? ( to optimize the performance )

Webpack add query string to bundle for cache-busting

so in my index.html, I have this line to include the webpack bundle
<script src="/dist/bundle.js"></script>
And my webpack config looks like this:
const path = require("path");
const webpack = require("webpack");
module.exports = {
entry: "./src/main.js",
mode: "development",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
loader: "babel-loader",
options: { presets: ["#babel/env"] }
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
resolve: { extensions: ["*", ".js", ".jsx"] },
output: {
path: path.resolve(__dirname, "dist/"),
publicPath: "/dist/",
filename: "bundle.js"
},
devServer: {
contentBase: path.join(__dirname, "public/"),
port: 3000,
publicPath: "http://localhost:3000/dist/",
hotOnly: true
},
plugins: [new webpack.HotModuleReplacementPlugin()]
};
How could I modify this, to add a query string (?v=some_nr) to the bundle when I run webpack --mode production. I can copy the index.html to dist/index.html or some other location, if needed, I'll be moving it to the webroot automatically anyway afterwards.

Laravel 5.4 webpack custom iconfont / webfont plugin

I am just starting out with webpack.js and Laravel 5.4 (upgrading from 5.2)
I have just about everything sorted out but my build and sass requires an iconfont generator from svg.
In gulp and grunt this hasn't been an issue but cannot seem to figure out how to add a custom node and plugin to webpack in laravel 5.4
I am currently trying to use https://github.com/itgalaxy/webpack-webfont
in which there are minimal usage instructions, and I am totally lost as to how I A: call this plugin and B: where do I actually place this code? in the webpack.config.js? or do I call it from the webpack.mix.js?
import WebfontPlugin from '../../Plugin';
import path from 'path';
export default {
entry: path.resolve(__dirname, '../entry.js'),
output: {
path: path.resolve(__dirname, '../build'),
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.css/,
loaders: [
'style',
'css'
]
},
{
test: /\.scss$/,
loaders: [
'style',
'css',
'sass'
]
},
{
loader: 'url-loader',
test: /\.(svg|eot|ttf|woff|woff2)?$/
},
]
},
resolve: {
modulesDirectories: ["web_modules", "node_modules"]
},
plugins: [
new WebfontPlugin({
files: path.resolve(__dirname, '../svg-icons/**/*.svg'),
css: true,
cssFormat: 'scss',
cssTemplateFontPath: './fonts/',
dest: {
fontsDir: path.resolve(__dirname, '../scss/fonts'),
css: path.resolve(__dirname, '../scss/_webfont.scss'),
}
})
]
};

Sass doesn't get compiled

My scss files are not getting compiled. It doesn't understand what I do with my code. I want to be able to use Sass instead of CSS but I can't find the right way to compile Sass.
I am using the webpack template with Vue.js
My webpack config file looks like this:
var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
entry: {
app: './src/main.js',
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'#': resolve('src'),
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.scss$/,
use: [ 'style-loader','css-loader','sass-loader' ],
loaders: ['style', 'css', 'sass']
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
}
One way of doing it is to have a single scss file as an entry. This is where all your different scss file gets imported. Something like this. Then you import that scss file in source code of your js entry file (in this case ./src/main.js). So when webpack reads your main.js it will see import './myscssfile.scss' and looks for a loader (or I think it does). Here is how I do my scss module in webpack2:
module: {
rules: [
// my js stuff
{ test: /\.js$/, enforce: 'pre', loader: 'eslint-loader', exclude: /node_modules/ },
// my scss stuff
{
test: /\.scss$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 2,
sourceMap: true,
localIdentName: '[local]___[hash:base64:5]'
}
},
{
loader: 'autoprefixer-loader',
options: {
browsers: 'last 2 version'
}
},
{
loader: 'sass-loader',
options: {
outputStyle: 'expanded',
sourceMap: true
}
}
]
}
]
}
I hope it works.
Just use <style lang="sass"></style in your component. Let me know if it helps.

Is it possible to load SASS in Webpack without bundling fonts BUT with source maps?

I don't want to bundle fonts and images but i need sourceMaps
I have this config (irrelevant parts ommited):
output: {
path: './build/',
publicPath: 'http://localhost:3000/',
filename: '[name].js'
},
module: {
loaders: [
{ test: /\.scss$/, loaders: ['style','css?-url,sourceMap', 'sass?sourceMap'] }
]
}
With this config I get multiple errors in Chrome:
Failed to decode downloaded font: http://localhost:3000/
(index):1 OTS parsing error: invalid version tag
I read a lot of answers and some solutions for similar problem:
1. get rid off 'sourceMap' - it works, and fonts are correctly displayed BUT ... no sourceMaps
2. change publicPath to URL - done it
I cannot find any solution that allows me load fonts outside bundle AND have CSS with sourceMaps...
I just figured it out. The key to solution is ExtractTextPlugin that makes normal link tags instead of 'blobs' and all fonts work super, css are external (even better when they are large), source maps work. Here is my full config if anyone interested:
var path = require('path');
var webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: {
demo: ['./demo/index.ts', 'webpack-dev-server/client?http://localhost:3000'],
lib: ['./src/js/index.js']
},
output: {
path: './build/',
publicPath: '/',
filename: '[name].js'
},
debug: true,
devtool: 'source-map',
resolve: {
extensions: ['', '.ts', '.js']
},
module: {
loaders: [
{ test: /\.tsx?$/, loader: 'ts' },
{ test: /\.coffee$/, loader: 'coffee' },
{ test: /\.(png|jpg)$/, loader: 'url' },
{ test: /\.jsx?$/, loader: 'babel', query: { presets: ['es2015'] }, exclude: /node_modules/, },
{ test: /\.scss$/, loader: ExtractTextPlugin.extract('style', 'css?sourceMap!sass?sourceMap') },
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style', 'css?sourceMap') },
{ test: /\.(ttf|eot|svg|woff(2)?)(\?[\s\S]+)?$/, loader: 'url' }
]
},
devServer: {
contentBase: './demo'
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
new ExtractTextPlugin("[name].css", { allChunks: true })
]
};

Resources