Webpack creates unnecessary .js file for my CSS stylesheet - css

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?

Related

How to stop WebPack from including CSS file in the html even though it is already included in the produced js file

I am using WebPack to build a chrome extension. I import the css file in the popup.js file and it correctly styles my page but bundler also inserts the css file to the html which is unnecessary if I know correctly since it is injected to the output js file. Because the css file is included in the hmtl, I get a "Failed to load resource: net::ERR_FILE_NOT_FOUND". I want to know how to exclude the CSS file from the html and basically dont have the following line.
<link rel="stylesheet" href="popup-styles.css" />
This is my webpack.config.js file.
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
entry: {
popup: "./src/popup.js",
background: "./src/background.js",
content: "./src/content.js",
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js",
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env", "#babel/preset-react"],
},
},
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/popup.html",
filename: "popup.html",
chunks: ["popup"],
}),
new CopyPlugin({
patterns: [{ from: "public" }],
}),
],
};

Correct way to transpile SCSS files but not CSS files in Webpack 5

I have two entrypoints for stylesheets.
src/css/preprocess.scss
src/css/skippreprocessing.css
I want my Webpack 5 project to preprocess the SCSS file, but NOT the CSS file--I want the CSS file to just be published to the dist folder as-is.
I've included my best guess below. Something is wrong with it though; it breaks hot-reloading. Or rather, hot-reloading only works for the non-preprocessed file. It's like the two rules become linked somehow (I'm guessing because of the shared MiniCssExtractPlugin).
So I'm wondering, what's the correct way to make those two rules (handling CSS files and SCSS files) be considered completely separate things.
(Note: In my actual case I'm compiling JS files too, but I've removed those below for the sake of brevity.)
My Best Guess
const webpack = require('webpack');
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
target: 'web',
entry: {
preprocess: [
'./src/css/preprocess.scss',
],
skippreprocessing: [
'./src/css/skippreprocessing.css',
]
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].min.js',
},
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
],
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader'
],
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './src/index.html'),
filename: 'index.html',
minify: false,
}),
],
devServer: {
static: {
directory: path.resolve(__dirname, './dist'),
},
hot: true,
port: 8080,
},
};

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']
}
}

React-filepond external CSS is not being applied. I suspect it's a webpack issue

This is beating my head in. I'm using react-filepond module in my react app, but the external CSS is not being applied. The module works but has no style. I suspect it's a loader issue in webpack but I'm still learning webpack and probably missed something. Thanks!
Here are the imports as per react-filepond:
import { FilePond } from 'react-filepond';
import 'filepond/dist/filepond.css'; // located in node_modules
Here's my webpack.config.js.
I'm using webpack 3.12.0
const path = require('path');
const autoprefixer = require('autoprefixer');
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
chunkFilename: '[id].js',
publicPath: '/'
},
resolve: {
extensions: ['.js', 'jsx', '.css']
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
options: {
presets: ['react']
},
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
autoprefixer({
browsers: [
"> 1%",
"last 2 versions"
]
})
]
}
}
]
},
{
test: /\.(png|jpe?g|gif)$/,
loader: 'url-loader?limit=8000&name=images/[name].[ext]'
}
]
},
devServer: {
historyApiFallback: true
},
plugins: [
new htmlWebpackPlugin({
template: __dirname + '/src/index.html',
inject: 'body',
filename: 'index.html'
})
]
};
I found the solution for others wondering about this.
Issue: I am using CSS modules in react (note the line modules:true in the configuration of my css-loader in my webpack-config.js
The external react module I was trying to use does NOT use CSS modules.
Solution:
create a second rule for external CSS. Thus I have one for my CSS (as in the source above) and then I added this rule:
{
/* External CSS from node_modules */
test: /\.css$/,
include: /node_modules/,
loader: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
minimize: true,
},
}
]
},
Most importantly, I did NOT turn on CSS Modules
And then, in my other CSS rule, I added:
exclude: /node_modules/,

Importing vendor css when using webpack + css components

I'm trying to use things like font-awesome and foundation with React and css modules but I can't figure it out how to import them into my project properly.
Note that I'm using HotModuleReplacementPlugin and ExtractTextPlugin to get a single css file.
Somewhere in the top-level component's css file I'd like to be able to just do #import 'font-awesome'; but how can I do it so that the file will be treated as-is and the classes won't end up localised to font_awesome__fa-check and such?
This is my webpack config:
var paths = {
app: path.join(__dirname, './app/'),
dist: path.join(__dirname, './dist/'),
external: path.join(__dirname, './node_modules/'),
}
module.exports = {
entry: {
site: [
'webpack-dev-server/client?http://localhost:5000',
'webpack/hot/dev-server',
path.join(paths.app, '/index.js'),
]
},
output: {
path: paths.dist,
publicPath: '/',
filename: 'scripts/[name].[hash].js',
chunkFilename: '[name].[chunkhash].js'
},
resolve: {
extensions: ['', '.js'],
root: paths.app,
alias: {
'font-awesome.css': path.join(paths.external, '/font-awesome/css/font-awesome.min.css')
}
},
module: {
loaders: [
{
test: /\.jsx?$/,
loaders: ['babel'],
include: path.join(__dirname, 'app')
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?modules&localIdentName=[name]__[local]&importLoaders=1', 'postcss-loader')
}
]
},
postcss: [
require('autoprefixer-core'),
],
devtool: 'inline-source-map',
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new ExtractTextPlugin("styles/[name].[chunkhash].css", {allChunks: true}),
new HtmlWebpackPlugin({
template: path.join(paths.app, '/site.html'),
filename: 'index.html',
inject: 'body',
chunks: ['site']
}),
]
};
Thanks.
You could leverage include / exclude option when configuring loaders.
E.g. given that all of your custom css is somewhere in the /app/ directory, while foundation and font-awesome are not.
...
module: {
loaders: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?modules&localIdentName=[name]__[local]&importLoaders=1', 'postcss-loader'),
include: path.join(__dirname, 'app')
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader!css-loader'),
exclude: path.join(__dirname, 'app')
}
]
},
Another option is to use different extension for the files that use css-modules syntax. You could use .mcss.
...
module: {
loaders: [
{
test: /\.mcss$/,
loader: 'css-loader?modules&localIdentName=[name]__[local]&importLoaders=1'
},
{
test: /\.css$/,
loader: 'css-loader')
}
],
postLoaders: [
{
test: /\.(css|mcss)$/,
loader: ExtractTextPlugin.extract('style-loader')
}
]
},

Resources