Øystein Seel Øystein Seel - 7 months ago 76
Less Question

Rearrange style order in ccs bundle

After a migration from grunt, the styles are not working as intended with webpack. All the styles were concatenated in the

gruntfile
like this:

target: {
files: {
"all.css": [
"node_modules/bootstrap/dist/css/bootstrap.css",
"bower_components/toastr/toastr.css",
"bower_components/angular-ui-select/dist/select.css",
"node_modules/font-awesome/font-awesome.css",
"bower_components/angular-loading-bar/build/loading-bar.css",
"bower_components/angular-ui-tree/dist/angular-ui-tree.css",
"content/styles/awesome-bootstrap-checkbox.css",
"content/styles/tradesolution.css",
"content/styles/site.css",
"content/styles/ts.css",
"content/styles/nyKladd.css"
]
}
}


My current config in webpack:

var webpack = require('webpack');
var globby = require('globby');
var path = require('path');

var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var AssetsPlugin = require('assets-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var DashboardPlugin = require('webpack-dashboard/plugin');

const ConcatPlugin = require('webpack-concat-plugin');
const extractCSS = new ExtractTextPlugin('[name].css');
const extractLESS = new ExtractTextPlugin('[name].css');

module.exports = {
entry: {
app: globby.sync(['./app/app.js','./app/app.run.js', './app/app.config.js', './app/**/*.js']),
Ztyles: globby.sync(['./content/styles/less/*.less']),
styles: globby.sync(['./content/styles/*.css']),
images: globby.sync(['./content/images/**/*.*']),
vendor: [
// removed to save space
],
},
output: {

filename: './scripts/[name].bundle.js',
path: path.join(__dirname, "public")

},
devServer: {
port: 1384,
contentBase: './public/'
},

// Enable sourcemaps for debugging webpack's output.
devtool: (() => {
if(NODE_ENV = "devlopment") return 'source-map'
else return 'cheap-module-eval-source-map'
}) (),

module: {
rules: [
{
test: /\.html$/,
loader: 'raw-loader',
exclude: [/node_modules/]
},
{
test: /\.css$/,
loader: extractCSS.extract(
{ fallback: 'style-loader', use: 'css-loader' }
),
//'style-loader', 'css-loader'
},
{ test: /\.less$/,
use: extractLESS.extract(
{fallback:'style-loader', use: ['css-loader','less-loader']}
)
//'style-loader', 'css-loader!less-loader'
},
{
test: /\.(ico)$/,
loader: "url-loader?name=./[name].[ext]",
include: path.resolve(__dirname, "content", "images")
},
{
test: /\.(jpg|jpeg|gif|png|PNG|tiff|svg)$/,
loader: 'file-loader?name=/[path]/[name].[ext]',
include: path.resolve(__dirname, "content", "images"),
},
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=10000&minetype=application/font-woff&name=./fonts/[name].[ext]' },
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file-loader?name=./fonts/[name].[ext]' },
{
test: require.resolve('adal-angular/lib/adal'),
loader: 'expose-loader?AuthenticationContext'
},
{
test: /\.js$/,
enforce: "pre",
loader: 'source-map-loader'
}
],
},

plugins: [
new webpack.DefinePlugin({
ADMIN_API_URL: JSON.stringify('http://localhost:41118/api/'),
API_URL: JSON.stringify('http://epdapi.tradesolution.no/'),
GLOBAL_ADMIN_URL: JSON.stringify('https://adminapi.tradesolution.no/')
}),
new HtmlWebpackPlugin({
template: './app/layout.html',
filename: 'index.html'
}),
extractCSS,
extractLESS,
new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: './scripts/vendor.bundle.js' }),
new ExtractTextPlugin({ filename: './[name].bundle.css' }),
new AssetsPlugin({
filename: 'webpack.assets.json',
path: './public',
prettyPrint: true
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'window.$': 'jquery',
"window.AuthenticationContext": "AuthenticationContext",
_: 'underscore'
}),
new CopyWebpackPlugin([
{from: './app/**/*.html', to: './'}
]),
new DashboardPlugin()
],
externals: [
{ xmlhttprequest: '{XMLHttpRequest:XMLHttpRequest}' }
],

}


elements tab devtools
From this picture you can see that the default bootstrap styles are overriding the styles written for the nav-bar.

What i have done so far is to implement all the other css files into one less file, like this:

@import "../tradesolution.css";
@import "../site.css";
@import "../nykladd.css";
@import "for";
@import "kladd.less";
@import "~bootstrap/less/bootstrap";
@import "~bootstrap/less/alerts.less";
@import "~bootstrap/less/mixins/buttons.less";
@import "~font-awesome/less/font-awesome.less";


Then the less file is compiled to css and loaded in the
Ztyles.css
, but regardless of where I put the imports, my styles are still overridden. I have also tried changing the order of the webpack rules and the order of
extractCSS
and
extractLESS
in plugins

I dont think my intended solution is good practice, so any approach to solving this issue is very welcome.

Answer Source

After a while i stumbled over a new css framework postcss they have all kinds of plugins, and with this configuration I got it to work:

{
                test: /\.css$/,
                use: [ 
                    'style-loader',
                    { loader: 'css-loader', options: { modules: true, importLoaders: 1 }, 
                     loader: 'postcss-loader', 
                    },
                ]
            },
            {    test: /\.less$/,
                use: extractLESS.extract(
                    {fallback:'style-loader', use: ['css-loader', 'less-loader']}
                )
            },

Here are some resources that helped:

https://github.com/postcss/postcss

https://webdesign.tutsplus.com/tutorials/using-postcss-together-with-sass-stylus-or-less--cms-24591

https://github.com/Crunch/postcss-less

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download