I have been trying to import less files automatically using webpack's less-loader, but glob expressions don't work in root.less file.
In detail, I am replacing gulp builder with webpack and I can use this pattern:
@import 'widgets/**/*.less';
to import less files in gulp automatically (Please check this link glob expressions). However, this pattern is not valid in webpack and less-loader seems that do not support as well.
I tried to use require.context the method of webpack, but I cannot adjust the order or file imports. I need to require less files in a logical sequence because I use global variables(mixins, color codes etc). So, this option is not available as well.
import '../components/variables.less';
importAll(require.context('../components/', true, /\.less$/)); // Cannot set a sequence.
// 'Variables' cannot be found even though I added it above
So, it seems I have to import each file manually which is really painful. That's why I wonder that is there any way to import files automatically?
Thank you for any help!
I've added paths
option and it works:
...
{
loader: 'less-loader',
options: {
paths: [
path.resolve(path.join(__dirname, 'app'))
],
plugins: [
require('less-plugin-glob')
]
}
}
More details here: https://stackoverflow.com/a/43621947/2393499
Working example: https://github.com/notagency/webpack2-with-less-plugin-glob
I could not find a proper solution for glob pattern paths, but I decided to create my entry less file dynamically. Anyone who encounter this issue may consider this solution:
// update entry less file
var dir = require('node-dir');
function updateEntryLessFile() {
dir.readFiles(path.resolve(__dirname, 'path-for-less-files-folder'), {
match: /.less$/
},
(err, context, next) => { next() },
(err, files) => {
if (err) throw err;
var wstream = fs.createWriteStream(
path.resolve(__dirname, 'path-to-entry/entry.less')
);
_.each(files, path => {
const relativePath = path.split('client/')[1]; // get relative path from full path
wstream.write(`@import '~${relativePath}';\n`);
});
wstream.end();
});
}
// When less files are added or removed, it updates entry.less file.
var watcher = require('chokidar').watch(path.resolve(__dirname, 'client/'), {
persistent: true,
ignoreInitial: true
});
// Something to use when events are received.
var log = console.log.bind(console);
// Add event listeners.
watcher
.on('add', path => {
if (new RegExp('.less').test(path)) {
log(`Less file: ${path} has been added`)
updateEntryLessFile();
}
})
.on('unlink', path => {
if (new RegExp('.less').test(path)) {
log(`Less file: ${path} has been removed`)
updateEntryLessFile();
}
});
updateEntryLessFile();
So, you may run this before your webpack building or inside your webpack config would be fine.
If you find better way, please feel free to post it! Thanks.