PostCSS & Webpack configuration - css

I'm really disheartened, because I can't find any useful resource on the subject.
I merely want to watch my .css files, use post css' plugins to transform them and finally export them to my /public folder as I already do with my .jsx files
Here's my web pack configuration
const path = require('path');
const webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: path.resolve('src/index.jsx'),
output: {
path: path.resolve('public'),
filename: 'bundle.js'
},
resolve: {
extensions: ['*', '.js', '.jsx']
},
devServer: {
publicPath: "/",
contentBase: "./public"
},
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
}, {
loader: 'postcss-loader',
options: {
plugins: function() {
return [require('lost'), require('postcss-cssnext'), require('postcss-import')]
}
}
}
]
})
}, {
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['es2015', 'react']
}
}
],
exclude: /(node_modules|bower_components)/
}
]
},
plugins: [new ExtractTextPlugin("main.css")]
}

I assume you are using webpack2
If you want your css file dumped out separately, you would need ExtractTextPlugin. Here is my css loader which works
I define the post css plugins right within the webpack config, because then it stays in one place. Hope this helps:
var ExtractTextPlugin = require('extract-text-webpack-plugin');
...
...
module.exports = {
...
...
module: {
rules: [
...
...
{
test: /\.css$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract(
{ fallback: 'style-loader',
use: [{
loader: 'css-loader',
options: {
modules: true,
localIdentName:'[name]__[local]___[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
plugins: function() {
return [
require('autoprefixer')
]
}
}
},
]
})
},
}

Maybe your plugins are incorrectly created.
Try
return [require('lost')(), require('postcss-cssnext')(), require('postcss-import')()]
(Note the () to invoke the plugin creation).
Also are you actually using import/require() to include your css? If not you should, no magic stuff will glob your css :)

Related

How can I load CSS styles using Webpack in React app?

I am having an issue with my React app. I have added Webpack and it is compiling successfully but, at the moment of serving the content, the app shows no styles at all.
This is what I have so far in my webpack.config.js file:
const path = require('path');
const BUILD_DIR = path.resolve(__dirname + '/public/build');
const APP_DIR = path.resolve(__dirname + '/src');
// This is the main configuration object.
// Here, you write different options and tell Webpack what to do
module.exports = {
experiments: {
asyncWebAssembly: true,
topLevelAwait: true,
layers: true // optional, with some bundlers/frameworks it doesn't work without
},
resolve: {
extensions: ['', '.js', '.jsx', '.css']
},
// Path to your entry point. From this file Webpack will begin its work
entry: [APP_DIR + '/index.js', APP_DIR + '/index.css', APP_DIR + '/App.css'],
// Path and filename of your result bundle.
// Webpack will bundle all JavaScript into this file
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
// Default mode for Webpack is production.
// Depending on mode Webpack will apply different things
// on the final bundle. For now, we don't need production's JavaScript
// minifying and other things, so let's set mode to development
mode: 'development',
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
},
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: true,
},
},
{ loader: 'sass-loader' },
{ loader: 'postcss-loader' }
],
},
]
}
};
Is there anything I am missing to get my css to work? I only have two files, located at /src: App.css and index.css. None of them seem to be loaded and I have no errors in the console.
rules: [
{
test: /\.js|jsx$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.(sass|scss|less|css)$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
},
{
test: /\.(png|jpe?g|svg|gif)$/,
loader: 'file-loader'
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader',
]
},
{
test: /\.css$/,
use: [
{
loader: 'url-loader',
options: {
limit: false
}
}
]
}
]

webpack not getting seperate css file for extract text plugin

Hi everyone I am using web-pack to try to replace a gulp build that was overly complicated. but was running into some issues when it came to the Css. We are using sass. We also have a project structure that has the sass files right by each of the the angular component so that means for every class there is a separate folder. Currently our gulp magically goes into the folders and downloads the sass.
But I can't get the extract-text-webpack-plugin to output me a separate Css file the source I am using for trying to do this is.
https://itnext.io/sharing-sass-resources-with-sass-resources-loader-and-webpack-ca470cd11746
here is my code
const config = {
entry: {
'app': './app/app.js',
// 'vendor': './src/vendor.module.js'
},
devtool: 'source-map',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist/dev')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: [ 'ng-annotate-loader', 'babel-loader' ]
},
// for fixing of loading bootstrap icon files
{
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
loader: 'url-loader?limit=10000',
options: {
name: './fonts/[name].[ext]'
}
},
{
test: /\.(eot|ttf)$/,
loader: 'file-loader',
options: {
name: './fonts/[name].[ext]'
}
},
{
test: /\.html$/,
loader: 'html-loader',
options: {
attrs: [ 'attrs=false' ]
}
},
{
test: /\.scss$/,
use: ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
filename: path.resolve(__dirname, 'dist/dev') + 'app.css',
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
},
{
loader: 'sass-resources-loader',
options: {
resources: require(path.join(process.cwd(), './app/appscss.js'))
}
}
]
}),
},
/* ,
{
test: /\.(scss)$/,
use: ExtractTextWebpackPlugin.extract({
use: [
{
loader: "css-loader",
options: {
minimize: true
}
},
{
loader: "sass-loader"
}
]
})
} */
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
comments: false,
sourceMap: true,
}),
new ExtractTextWebpackPlugin('app.css', {
allChunks: true
}),
new webpack.DefinePlugin({
GULP_REPLACE_ENV_URL: JSON.stringify(environementUrl())
})
],
devServer: {
port: 5000,
contentBase: path.resolve(__dirname, 'dist/dev'),
historyApiFallback: true,
// needed since we set api to something other than host
// http://flummox-engineering.blogspot.com/2017/10/webpack-dev-server-invalid-host-header-host-0.0.0.0-not-working-npm-dev-server.html
disableHostCheck: true
}
};
module.exports = config;
Any help would be much appreciated.

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/,

Webpack: extract css to its own bundle

I'm using webpack on a project. I use style-loader so I can import "my.css".
The css gets bundled with the javascript and will be rendered in a <style> tag when component mount, ok.
However, I would like to keep that import syntax and make webpack build a css bundle for every entry point.
So webpack output should be [name].bundle.js AND [name].bundle.css.
Is this something I can achieve ?
var config = {
entry: {
'admin': APP_DIR + '/admin.entry.jsx',
'public': APP_DIR + '/public.entry.jsx'
},
output: {
path: BUILD_DIR,
filename: '[name].bundle.js'
},
resolve: {
extensions: ['.js', '.jsx', '.json']
},
plugins: [],
devtool: 'cheap-source-map',
module: {
loaders: [{
test: /(\/index)?\.jsx?/,
include: APP_DIR,
loader: 'babel-loader'
},
{
test: /\.scss$/,
loaders: [
'style-loader',
'css-loader',
'sass-loader',
{
loader: 'sass-resources-loader',
options: {
resources: ['./src/styles/constants.scss']
},
}
]
}
],
}
};
along with this babel.rc:
{
"presets" : ["es2015", "react"],
"plugins": ["transform-decorators-legacy", "babel-plugin-root-import"]
}
Yes, you need to use extract-text-webpack-plugin. You might want to do it only on your production config. Config looks like this:
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
//resolve-url-loader may be chained before sass-loader if necessary
use: ['css-loader', 'sass-loader']
})
}
]
},
plugins: [
new ExtractTextPlugin('style.css')
//if you want to pass in options, you can do so:
//new ExtractTextPlugin({
// filename: 'style.css'
//})
]
}

Webpack - how to determine output style of CSS file?

When using Gulp to convert Sass to CSS, I can choose output style of the CSS file between: nested, expanded, compact and compressed. Do I have the same opportunity using Webpack? If yes, can you show me how to configurate Webpack to achieve my goal?
Below is my current webpack.config.js - it converts sass to css, translate ES6 to ES5 and it works perfectly:
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: [
"./js/app.js",
"./scss/main.scss"
],
output: {
filename: "./js/out.js"
},
watch: true,
module: {
loaders: [
{
test: /.js$/,
exclude: /node_modules/,
loader: "babel-loader",
query: {
presets: ["es2015"]
}
}
],
rules: [
{
test: /.scss$/,
use: ExtractTextPlugin.extract({
fallbackLoader: "style-loader",
use: ["css-loader?-url", "sass-loader?-url"]
})
}
]
},
plugins: [
new ExtractTextPlugin({
filename: "./css/main.css",
disable: false,
allChunks: true
})
]
}
Thanks in advance!
You are using sass-loader, which uses node-sass under the hood. The readme says that you can pass options directly to node-sass by specifying an options property. You can pass in the outputStyle setting this way. It would look like this:
{
test: /.scss$/,
use: ExtractTextPlugin.extract({
fallbackLoader: "style-loader",
use: [{
loader: 'css-loader'
}, {
loader: 'sass-loader',
options: {
outputStyle: 'expanded'
}
}]
})
}
#Arnelle Balane
That ticked solution won't work with upgraded webpack and sass-loader.
This is the latest working model using:
"webpack": "^4.44.1",
"sass-loader": "~9.0.3",
{
test: /.scss$/,
use: ExtractTextPlugin.extract({
fallbackLoader: "style-loader",
use: [
{
loader: 'css-loader'
},
{
loader: 'sass-loader',
options: {
sassOptions: {
outputStyle: 'expanded'
}
}
}
]
})
}
UPDATE Wepback 5: ExtractTextplugin is now replace to MiniCSSExtraPlugin.
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true,
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
sassOptions: {
outputStyle: "expanded",
},
}
},
]

Resources