Minimize SCSS to CSS with webpack keeping file/folder structure - css

I am having trouble understanding how to compile and minify my scss files to css, while keeping the same folder and file structure. I am using MiniCssExtractPlugin to extract everything, as well as style-loader, css-loader, postcss-loader, and sass-loader
Here is the file structure in my src folder
app.scss contains all the imports. importing from folders 1-7. I am first having trouble with the imports, and then have trouble compiling and minimizing the remaining scss files.
The end goal is to have an compiled folder look like this with each file being minimized and app.scss bundle all the imports
Here is a run down of the code I have so far for webpack.config.js
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css',
chunkFilename: '[id].css'
})
],
module: {
rules: [
{
test: /\.(scss|css)$/,
use: [
'style-loader',
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { sourceMap: true } },
{ loader: 'postcss-loader', options: { sourceMap: true } },
{ loader: 'sass-loader', options: { sourceMap: true } },
]
}
]
},
optimization: {
minimizer: [new TerserJSPlugin({extractComments: false}), ],
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/](lodash)[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
When running this code, I just get an app.css file under a css folder that does not have imports included, and no other files are included as well. Can someone help my understand the process I need to take? I've been all over docs for each loader and not really understanding what I am looking for.
Thanks!

Related

Webpack sass-loader generating wrong / broken source maps

I'm trying to generate correct source maps for an large project (using monorepo, aliases for loading files from other sibling project, and bootstrap). Below is my webpack.config.js file. Currently, it generates hit or miss source map, sometimes it generates ok (for bootstrap files for instance, the map is perfect), sometimes it points to an completly diferent file and line from the original, and sometimes, it generates even an wrong scss file map. I've tried to enable compressed: true, but it just makes everything more messy, some files it point right but most of them to the wrong line or file.
the SCSS files are compiling as it should, but the source map is hit or miss. Is there something wrong with my configuration? Any simple boilerplate for generating correct sourcemaps?
{
mode: 'none',
name: 'scss',
entry: scssFiles, // list of entries generated by function
devtool: 'source-map',
stats: 'errors-warnings',
output: {
path: path.resolve(__dirname),
filename: '[name].css'
},
module: {
rules: [{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
use: [
{
loader: 'css-loader',
options: {
sourceMap: true,
url: false,
minimize: false
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true,
plugins: [
require('autoprefixer')()
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
// outputStyle: 'compressed', // Have tried it on too.
includePaths: [
path.resolve('node_modules'),
path.resolve('node_modules/flag-icon-css/sass')
]
}
}
]
})
}]
}

Minificating and bundling SASS into minified css file with Webpack?

Very, very new to webpack, but I'm trying to set it up to translate my typescript and my sass code and minify and bundle each into a single file apiece. I followed this tutorial but it didn't work in the end.
I got it to translat the typescript into js and minify it, but not the sass.
It will compile the sass in css, but I need it to be minified and this isn't doing that.
I'm making a ASP.NET app in visual studio. My webpack.config.js file looks like this:
const path = require('path');
module.exports = {
entry:'./wwwroot/scripts/site.ts',
output: {
path: path.resolve(__dirname, 'wwwroot/js'),
filename: 'site.bundle.js'
},
module:{
rules: [{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
}]
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
optimization: {
minimizer: [new UglifyJsPlugin()]],
}
}
module.exports = {
entry:'./wwwroot/sass/site.scss',
output: {
path: path.resolve(__dirname, 'wwwroot/css'),
filename: 'site.bundle.css'
},
module:{
rules: [{
test: /\.scss$/,
use: ['style-loader', 'css-laoder', 'sass-laoder']
}]
}
resolve: {
extensions: ['.css']
}
}

Webpack 4 - Style-loader/url not working

I'm having my webpack set up and it's running all fine, but in development it is serving my compiled scss stylesheets inline instead of using an URL.
module: {
rules: [
{
test: /\.scss$/,
use: [
{ loader: "style-loader"},
{ loader: "css-loader" },
{ loader: 'postcss-loader',
options: {
plugins: () => [require('autoprefixer')]
}
},
{ loader: "sass-loader" }
]
}
]
}
So I grabbed the docs and read up on how to use a single CSS file instead. I updated my webpack config to the following and since all loaders are running in reverse order this should be working;
module: {
rules: [
{
test: /\.scss$/,
use: [
{ loader: "style-loader/url"},
{ loader: "file-loader" },
{ loader: "css-loader" },
{ loader: 'postcss-loader',
options: {
plugins: () => [require('autoprefixer')]
}
},
{ loader: "sass-loader" }
]
}
]
}
It results in no errors, and inserts the following stylesheet into my header;
<link rel="stylesheet" type="text/css" href="6bbafb3b6c677b38556511efc7391506.scss">
As you can see it's creating an scss file, whereas I was expecting a .css file. I tried moving the file-loader around but that didn't work either and resulted in several crashes. Any idea how to turn this into a working css file?
I can't use mini-css-extract in my dev env since I'm using HMR. I already got this working on my prod env.
Update: When removing css-loader it compiles and shows my css applied to the page. But when I inspect the elements everything is on line 1 and the file it refers to can not be found
I'm importing my css like this in index.js by the way;
import '../css/styles.scss';
You can install extract-text-webpack-plugin for webpack 4 using:
npm i -D extract-text-webpack-plugin#next
The you can define the following constants:
// Configuring PostCSS loader
const postcssLoader = {
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
// Write future-proof CSS and forget old preprocessor specific syntax.
// It transforms CSS specs into more compatible CSS so you don’t need to wait for browser support.
require('postcss-preset-env')()
]
}
};
// Configuring CSS loader
const cssloader = {
loader: 'css-loader',
options: {
importLoaders: 1
}
};
Then in your SASS loader section, you can use the following:
ExtractTextPlugin.extract({
use: [cssloader, postcssLoader, 'sass-loader']
})
Then in you plugins section, you need to use the following:
new ExtractTextPlugin({
filename: 'css/[name].css'
)
Now suppose that your entry section is like below:
entry: {
app: 'index.js'
}
The generated CSS will be named as app.css and placed inside the css folder.
Another useful plugins for handling these type of post creating operations are:
HtmlWebpackPlugin and HtmlWebpackIncludeAssetsPlugin
Working with these plugins along with extract-text-webpack-plugin gives you a lot of flexibility.
I had a similar issue with webpack, after searching for a long time i found the soluton of combining a few plugins:
This is my result config: (as a bonus it preserves your sass sourcemaps;))
watch: true,
mode: 'development',
devtool: 'source-map',
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css", //make sure you use this format to prevent .scss extention in the hot reload file
chunkFilename: "[id].css"
})
],
module: {
rules: [
{
test: /\.scss$/,
use: [
'css-hot-loader', //5. this will hot load all the extracted css.
MiniCssExtractPlugin.loader, //4 this will extract all css
{
loader: "css-loader", //3. this is where the fun starts
options: {
sourceMap: true
}
},
{
loader: "postcss-loader", //2. add post css
options: {
sourceMap: true
}
},
{
loader: "sass-loader", //1 . you can ingore the globImporter
options: {
importer: globImporter(),
includePaths: ["node_modules"],
sourceMap: true
}
}
]
},
]
}

Compiling a .less file to a specific .css file using webpack

I want to use webpack, to compile a style.less file to a module.css file.
I have found https://github.com/webpack-contrib/less-loader as a very popular package, which however does not seem to work for me, since I really need to create that module.css file.
So how can I do that with webpack?
Found the solution myself. The following webpack.config.js snippet works for me:
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = function(env) {
return {
...
module: {
loaders: [
{
test: /.*\.less$/,
loader: ExtractTextPlugin.extract({
loader:[ 'css-loader', 'less-loader' ],
fallbackLoader: 'style-loader'
})
}
]
},
plugins: [
new ExtractTextPlugin({ filename: 'module.css', disable: false, allChunks: true })
]
};
};
Where ... is a placeholder for other parts of the config, which are not relevant here.

Webpack creates unnecessary .js file for my CSS stylesheet

I have this Webpack config for compiling CSS, JavaScript and HTML
{
entry: {
main: ['babel-polyfill', path.join(__dirname, 'clientside', 'client.js')],
styles: path.join(__dirname, 'clientside', 'styles.css')
},
output: {
path: path.join(__dirname, 'public'),
filename: '[name].js'
},
module:
{
loaders: [
{ test: /\.js$/,
loader: 'babel',
query: { presets:['es2015', 'stage-0'] }
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
}
],
},
plugins: [
new ExtractTextPlugin('./styles.css'),
new webpack.optimize.UglifyJsPlugin({ minimize: true }),
new HtmlWebpackPlugin({
template: 'clientside/index.html',
inject: 'body',
chunks: ['main'],
minify: htmlMinifierObj
})
],
}
The problem with this config is it creates an unnecessary styles.js file, I don't need it.
I also know I can include styles.css inside my JS file but I don't think it's a good idea, because I want to keep JavaScript and CSS separated.
So, my question is: how can I edit my config to get rid of this unnecessary file?

Resources