Webpack import multiple less files using glob expr

2019-09-14 16:12发布

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!

2条回答
聊天终结者
2楼-- · 2019-09-14 16:45

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

查看更多
够拽才男人
3楼-- · 2019-09-14 17:06

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.

查看更多
登录 后发表回答