如何在不使用require语句的情况下使用webpack加载目录中的所有文件

How to load all files in a directory using webpack without require statements

本文关键字:文件 加载 webpack require 语句 情况下      更新时间:2023-09-26

在我的应用程序中,我有大量的javascript文件分为4个子目录。在grunt中,我获取所有这些,并将它们编译为一个文件。这些文件没有module.exports函数。

我想使用webpack并将其分成4部分。我不想手动进入并需要我的所有文件。

我想创建一个插件,在编译时遍历目录树,然后获取所有.js文件名和路径,然后需要子目录中的所有文件并将其添加到输出中。

我希望每个目录中的所有文件都编译到一个模块中,然后我可以从我的入口点文件中要求该模块,或者包括在http://webpack.github.io/docs/plugins.html提及。

当添加一个新文件时,我只想把它放在正确的目录中,并知道它会被包括在内。

有没有一种方法可以用webpack或某人编写的插件来做到这一点?

这就是我所做的:

function requireAll(r) { r.keys().forEach(r); }
requireAll(require.context('./modules/', true, /'.js$/));

在我的应用程序文件中,我最终放入了所需的

require.context(
  "./common", // context folder
  true, // include subdirectories
  /.*/ // RegExp
)("./" + expr + "")

由本帖提供:https://github.com/webpack/webpack/issues/118

它现在正在添加我的所有文件。我有一个html和css的加载程序,它似乎工作得很好。

一个文件夹中所有文件的映射如何?

// { 
//   './image1.png':  'data:image/png;base64,iVBORw0KGgoAAAANS',
//   './image2.png':  'data:image/png;base64,iVBP7aCASUUASf892',
// }

这样做:

const allFiles = (ctx => {
    let keys = ctx.keys();
    let values = keys.map(ctx);
    return keys.reduce((o, k, i) => { o[k] = values[i]; return o; }, {});
})(require.context('./path/to/folder', true, /.*/));

如何获取当前文件夹中所有图像的映射的示例。

const IMAGES_REGEX = /'.(png|gif|ico|jpg|jpeg)$/;
function mapFiles(context) {
  const keys = context.keys();
  const values = keys.map(context);
  return keys.reduce((accumulator, key, index) => ({
    ...accumulator,
    [key]: values[index],
  }), {});
}
const allImages = mapFiles(require.context('./', true, IMAGES_REGEX));

@splintor的所有优点(谢谢)。

但这是我自己的衍生版本。

优点:

  • 导出的模块收集在{module_name: exports_obj}对象下。
    • module_name是根据其文件名构建的
    • 。。。没有扩展,用下划线代替斜线(在子目录扫描的情况下)
  • 添加注释以简化自定义。
    • 也就是说,如果根级模块手动需要文件,那么您可能不希望在子目录中包含这些文件

EDIT:如果像我一样,您确信您的模块不会返回除常规javascript对象之外的任何其他内容(至少在根级别),那么您还可以"装载"它们,复制它们的原始目录结构(请参阅末尾的代码(深度版本)部分)。

代码(原始版本):

function requireAll(r) {
    return Object.fromEntries(
        r.keys().map(function(mpath, ...args) {
            const result =  r(mpath, ...args);
            const name = mpath
                .replace(/(?:^[.'/]*'/|'.[^.]+$)/g, '') // Trim
                .replace(/'//g, '_') // Relace '/'s by '_'s
            ;
            return [name, result];
        })
    );
};
const allModules = requireAll(require.context(
    // Any kind of variables cannot be used here
    '@models'  // (Webpack based) path
    , true     // Use subdirectories
    , /'.js$/  // File name pattern
));

示例:

最终console.log(allModules);:的样本输出

{
  main: { title: 'Webpack Express Playground' },
  views_home: {
    greeting: 'Welcome to Something!!',
    title: 'Webpack Express Playground'
  }
}

目录树:

models
├── main.js
└── views
    └── home.js

代码(深度版本):

function jsonSet(target, path, value) {
    let current = target;
    path = [...path]; // Detach
    const item = path.pop();
    path.forEach(function(key) {
        (current[key] || (current[key] = {}));
        current = current[key];
    });
    current[item] = value;
    return target;
};
function requireAll(r) {
    const gather = {};
    r.keys().forEach(function(mpath, ...args) {
        const result =  r(mpath, ...args);
        const path = mpath
            .replace(/(?:^[.'/]*'/|'.[^.]+$)/g, '') // Trim
            .split('/')
        ;
        jsonSet(gather, path, result);
    });
    return gather;
};
const models = requireAll(require.context(
    // Any kind of variables cannot be used here
    '@models'  // (Webpack based) path
    , true     // Use subdirectories
    , /'.js$/  // File name pattern
));

示例:

使用此版本的上一个示例的结果:

{
  main: { title: 'Webpack Express Playground' },
  views: {
    home: {
      greeting: 'Welcome to Something!!',
      title: 'Webpack Express Playground'
    }
  }
}

这对我有效:

function requireAll(r) { r.keys().forEach(r); } 
requireAll(require.context('./js/', true, /'.js$/));

注意:这可能需要的子目录中的.js文件/js/递归。