How to add less-loader to react-app-rewired config? - less

I am using react-app-rewired and I want to add the less-loader to the config-overides.js but it doesn't work,
I tried with
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
loader: [
// compiles Less to CSS
"style-loader",
"css-loader",
"less-loader",
],
},
],
},
};
and
module.exports = function override(config, env) {
config.module.rules[1].oneOf.push({
test: /\.less$/,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader", // translates CSS into CommonJS
},
{
loader: "less-loader", // compiles Less to CSS
},
],
})
but nothing works, any help please ?
Am using:
react-app-rewired: "^2.2.1"
less: "^4.1.2"
less-loader: "^10.2.0"
react-scripts: "^5.0.0"

it worked with:
module.exports = function override(config, env) {
config.module.rules[1].oneOf.splice(2, 0, {
test: /\.less$/i,
exclude: /\.module\.(less)$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{
loader: "less-loader",
options: {
lessOptions: {
javascriptEnabled: true,
},
},
},
],
})
return config
}

Related

Webpack 5: how to disable copying static files to build folder?

I am used webpack 2 for project, and some days ago I have upgraded to version 5.6.
2-3 hours and project compiling OK, but I have just one problem.
All static files (images, fonts) I store in /static/ folder.
CSS file:
.link-yellow{
background-image: url("/static/wifi2.png");
}
.link-red{
background-image: url("/static/wifi4.png");
}
.link-grey{
background-image: url("/static/wifi3.png");
}
Webpack 2 after compiling JS bundle file don't touch css url(...) links but webpack 5 copying files to folder /build/ and finally I have this:
4e4b4524859364a45966.png
5b97c8a6a9b9aa05b4be.otf
7ed064d8178174fa9ce1.woff2
14d3902c59ccd98328c8.png
440e51cee01b3e78fed5.png
664550a92a1dbb39a80a.png
build.js
And this records (like 4e4b4524859364a45966.png) in build.js:
...3197:function(t,e,n){"use strict";t.exports=n.p+"4e4b4524859364a45966.png"}...
Build progress:
I tried to use file-loader with this params:
module: {
rules: [
....
{
test: /\.(png|svg|jpg|jpeg|gif|gif|woff|woff2|eot|ttf|otf)$/,
loader: 'file-loader',
options:{
emitFile: false,
name: '[name].[ext]'
}
}
....
]
}
but after that I have the same files in /build/ folder with texts inside like this:
export default __webpack_public_path__ + "wifi2.png";
export default __webpack_public_path__ + "exo2.otf";
export default __webpack_public_path__ + "wifi3.png";
I moved some images files to style="..." attributes in vue files:
<div id="mainFooter" style="background: transparent url('/static/wifi3.png') no-repeat 0 0">
and webpack don't touch this text and not generate copies of static files in /build/ folder and all works fine. It is that I need.
Full source of webpack.config.js:
var path = require('path');
var webpack = require('webpack');
const { VueLoaderPlugin } = require('vue-loader');
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
mode: 'production',
plugins: [
new VueLoaderPlugin()
],
module: {
rules: [
{
test: /\.styl$/,
use: ['style-loader', 'css-loader', 'stylus-loader']
},
{
test: /\.css$/,
use: ['vue-style-loader','css-loader']
},
{
test: /\.scss$/,
use: ['vue-style-loader','css-loader','sass-loader'],
},
{
test: /\.sass$/,
use: ['vue-style-loader','css-loader','sass-loader?indentedSyntax'],
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
'scss': [
'vue-style-loader',
'css-loader',
'sass-loader'
],
'sass': [
'vue-style-loader',
'css-loader',
'sass-loader?indentedSyntax'
]
}
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|svg|jpg|jpeg|gif|gif|woff|woff2|eot|ttf|otf)$/,
loader: 'file-loader',
options:{
emitFile: false,
name: '[name].[ext]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['*', '.js', '.vue', '.json']
},
devServer: {
historyApiFallback: true,
client: {
overlay: true,
},
static: './'
},
performance: {
hints: false
},
devtool: 'eval-source-map',
optimization: {
minimize: true,
portableRecords: true,
removeAvailableModules: true,
minimizer: [
new TerserPlugin({
parallel: true,
terserOptions: {
format: {
comments: false,
},
},
extractComments: false
})
]
}
};
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = 'inline-nosources-cheap-source-map';//source-map
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
Maybe someone know how to disable generating static files in /build/ folder and leave files url's in css with no modifying paths?
UPDATE:
I have some progress. Code disabling touching urls in css files, but fonts still copying:
{
test: /\.css$/,
use: ['vue-style-loader']
},
{
test: /\.css$/,
loader: 'css-loader',
options: {
url: false,
},
},
UPDATE2: Done. Adding:
{
test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
type: "asset",
}
finally disabling generate other files. At now generating only /build/build.js file

Webpack slow build for Bootstrap 5

When i import Bootstrap scss in my project, Webpack build is very slow. It is building all Bootstrap dependencies on every code changes. So i have to wait 5-6 sec every file savings. There is any way improve this build time? Maybe build bootsrap only when bootsrap-variables.scss file changed?
Here is my webpack configuration:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const sass = require('sass');
const path = require('path');
module.exports = (env, argv) => {
return {
entry: {
bundle: ['./src/index.js', './src/index.scss'],
admin: ['./src/admin.js', './src/admin.scss'],
print: './src/print.scss',
},
output: {
path: path.resolve(process.cwd(), 'dist'),
filename: '[name].js',
},
optimization: {
minimizer: [
new TerserJSPlugin(),
new OptimizeCSSAssetsPlugin({
cssProcessorOptions: {
map: {
inline: false,
annotation: true,
},
},
}),
],
},
plugins: [
new CleanWebpackPlugin({
cleanAfterEveryBuildPatterns: ['!fonts/**/*'],
output: {
path: path.resolve(process.cwd(), 'dist'),
},
}),
],
devtool:
argv.mode === 'development'
? 'cheap-module-source-map'
: 'source-map',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
plugins: [
'#babel/plugin-proposal-class-properties',
],
presets: ['#babel/preset-env'],
},
},
},
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true,
},
},
'resolve-url-loader',
{
loader: 'sass-loader',
options: {
implementation: sass,
},
},
{
loader: 'sass-resources-loader',
options: {
resources: ['./src/scss/_variables.scss'],
},
},
],
},
{
test: /\.(ttf|eot|woff|woff2|svg)$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts',
publicPath: 'fonts',
},
},
exclude: /images/,
},
{
test: /\.(png|jpe?g|gif|svg)$/i,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
publicPath: 'img',
outputPath: 'img',
},
},
],
},
],
},
externals: {
jquery: 'jQuery',
},
};
};

Vue+Webpack configuration

I try to use Vue2 with Webpack4. Command webpack-dev-server finished with success, but it shows me only folders:
My webpack.config.js is:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
entry: './src/main.js',
output: {
publicPath: './',
path: path.join(__dirname, '/dist'),
filename: 'result.js',
},
devServer: {
compress: true,
port: 8532,
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.s[ac]ss$/i,
use: [
{ loader: 'vue-style-loader' },
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
},
{
test: /\.(png|jpg|gif)$/,
exclude: [path.resolve(__dirname, "public/fonts")],
use: ['file-loader'],
},
],
},
plugins: [
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
template: './public/index.html',
minify: false,
})
],
};
This is my first experience with Vue.
What am I doing wrong?
Before that I tried to use vue-cli, but as I understood I can't use scss and Pug without Webpack.
Am I right?

Set the output for image-webpack-loader

I'm trying to load images through the image-webpack-loader module, it works correctly, but instead of saving the image where the outputPath indicates, it saves it in the root directory of the project, does anyone know how to define the output of the images? I have read the entire documentation (webpack-image-loader) and I can not find any place where it says how to configure the output of files. Here I leave the my webpack.config.js
const autoprefixer = require('autoprefixer')
module.exports = {
entry: ['./assets/src/scss/index.scss', './assets/src/service/clanService.js', './assets/src/service/locationService',
'./assets/src/model/Clan.js', './assets/src/model/Location.js', './assets/src/model/Player.js',
'./assets/src/utils/material.js', './assets/src/utils/constants.js', './assets/src/utils/auxFunctions.js',
'./assets/src/fonts/Supercell-magic-webfont.generated.woff','./assets/src/images/Clash_Royale.png'],
output: {
filename: './dist/bundle.js',
},
module: {
rules: [
{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
bypassOnDebug: true, // webpack#1.x
disable: true, // webpack#2.x and newer
outputPath: '/dist/images/' // <-- Thats not work
},
},
],
},
{
test: /^(?!.*\.generated\.ttf$).*\.ttf$/,
use: ['css-loader', 'fontface-loader'],
}, {
test: /\.generated.(ttf|eot|woff|woff2)$/,
use: [{
loader: 'file-loader',
options: {
outputPath: '/dist/fonts/',
},
}],
},
{
test: /\.scss$/,
use: [
{
loader: 'file-loader',
options: {
name: './dist/bundle.css',
},
},
{loader: 'extract-loader'},
{loader: 'css-loader'},
{
loader: 'postcss-loader',
options: {
plugins: () => [autoprefixer()],
},
},
{
loader: 'sass-loader',
options: {
includePaths: ['./node_modules'],
},
}
],
},
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015'],
plugins: ['transform-object-assign']
},
}
],
},
}
As you can see I also have to enter the files one by one at the entry point, is it possible to add whole directories?
Answering a pretty old post here but I had the same issue today.
At least it may help someone else having the same problem.
Setting the outputPath for file-loader prior to image-webpack-loader solved it for me.
{
test: /\.(gif|png|jpe?g|svg)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: '/dist/images/'
}
},
{
loader: 'image-webpack-loader',
options: { ... }
}
]
}

How to include node module for Babel using Webpack

when running
npm run build
I encounter an es6 related syntax error from uglify, so I'm guessing babel isn't handling the node module (sec-to-min) properly.
My .babelrc
{
"presets": ["es2015", "stage-0"],
"plugins": ["transform-runtime"],
"comments": false,
"env": {
"test": {
"plugins": [ "istanbul" ]
}
}
}
My Webpack config:
var path = require('path')
var config = require('../config')
var utils = require('./utils')
var projectRoot = path.resolve(__dirname, '../')
var env = process.env.NODE_ENV
// check env & config/index.js to decide whether to enable CSS source maps for the
// various preprocessor loaders added to vue-loader at the end of this file
var cssSourceMapDev = (env === 'development' && config.dev.cssSourceMap)
var cssSourceMapProd = (env === 'production' && config.build.productionSourceMap)
var useCssSourceMap = cssSourceMapDev || cssSourceMapProd
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath,
filename: '[name].js'
},
resolve: {
extensions: ['', '.js', '.vue', '.json'],
fallback: [path.join(__dirname, '../node_modules')],
alias: {
'vue$': 'vue/dist/vue.common.js',
'src': path.resolve(__dirname, '../src'),
'assets': path.resolve(__dirname, '../src/assets'),
'components': path.resolve(__dirname, '../src/components')
}
},
resolveLoader: {
fallback: [path.join(__dirname, '../node_modules')]
},
module: {
preLoaders: [
{
test: /\.vue$/,
loader: 'eslint',
include: [
path.join(projectRoot, 'src')
],
exclude: /node_modules/
},
{
test: /\.js$/,
loader: 'eslint',
include: [
path.join(projectRoot, 'src')
],
exclude: /node_modules/
}
],
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
{
test: /\.js$/,
loader: 'babel',
include: [
path.join(projectRoot, 'src'),
'node_modules/sec-to-min'
],
exclude: /node_modules/
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url',
query: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
eslint: {
formatter: require('eslint-friendly-formatter')
},
vue: {
loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }),
postcss: [
require('autoprefixer')({
browsers: ['last 2 versions']
})
]
}
}
& the ERR:
ERROR in static/js/vendor.8d64852626f0513309d9.js from UglifyJs
SyntaxError: Unexpected token: operator (>)
[./~/sec-to-min/index.js:3,0]
How can I direct babel to compile this module?
please note that on Windows the slashes in the path will be \ so the above solution would have to be changed to exclude: /node_modules\\(?!(sec-to-min)\/).*/
This was the solution that worked for me, with webpack 4.3 and babel-loader 8.0.5, and using the recommended #babel/preset-env, adapted from here https://github.com/webpack/webpack/issues/2031#issuecomment-283517150
{
test: /\.(js|jsx|mjs)$/,
include: [paths.appSrc, paths.appNodeModules],
exclude: function(modulePath) {
return (
/node_modules/.test(modulePath) &&
!/node_modules\\react-dev-utils/.test(modulePath)
);
},
loader: require.resolve('babel-loader'),
options: {
compact: true,
presets: ['#babel/preset-env']
}
},
I found it helpful to use the function for exclude as I was able to add console logs within the function to check which modules were being matched by the regex.
In babel section of webpack config change to this :
{
test: /\.js$/,
loader: 'babel',
include: [
path.join(projectRoot, 'src')
],
exclude: /node_modules\/(?!(sec-to-min)\/).*/
}
Looks like exclude has priority over include.
Install following packages
npm install babel-preset-es2015 --save-dev
npm install babel-preset-stage-0 --save-dev
Add es2015 and stage-0 in your babel presets
{
"presets": ["es2015", "stage-0"],
}
UPDATE
Try this
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'react', 'stage-0'],
},
},
include: [
path.join(projectRoot, 'src'),
'node_modules/sec-to-min'
],
exclude: /node_modules/
},
Work for me in Webpack v4:
rules: [{
include: [
path.resolve(__dirname, 'src'),
/node_modules\/(dom7|swiper)/
],
loader: 'babel-loader',
presets: [['#babel/preset-env', {
'modules': false
}]]
},
test: /\.(js)$/
}]