如何使用 webpack 加载目录中的所有文件而不需要语句

我有大量的 javascript 文件分裂成4个子目录在我的应用程序。我咕哝着把它们全部抓起来编译成一个文件。这些文件没有 module.export 函数。

我想使用网络包,并分为4个部分。我不想手动进入并要求我所有的文件。

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

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

当添加一个新文件时,我只想把它放到正确的目录中,并且知道它将被包含在其中。

有没有一种方法可以做到这一点与网络包或插件,有人已经写了这样做?

100771 次浏览

In my app file I ended up putting the require

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

courtesy of this post: https://github.com/webpack/webpack/issues/118

It is now adding all my files. I have a loader for html and css and it seems to work great.

This is what I did to achieve this:

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

How about a map of all the files in a folder?

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

Do this:

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, /.*/));

this works for me :

function requireAll(r) { r.keys().forEach(r); }


requireAll(require.context('./js/', true, /\.js$/));

NOTE: this can require .js files in subdirs of ./js/ recursively.

Example of how to get a map of all images in the current folder.

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));

All merits to @splintor (thanks).

But here it is my own derived version.

Benefits:

  • What modules export is gathered under a {module_name: exports_obj} object.
    • module_name is build from its file name.
    • ...without extension and replacing slashes by underscores (in case of subdirectory scanning).
  • Added comments to ease customization.
    • I.e. you may want to not include files in subdirectories if, say, they are there to be manually required for root level modules.

EDIT: If, like me, you're sure your modules won't return anything else than (at least at root level) a regular javascript object, you can also "mount" them replicating their original directory structure (see Code (Deep Version) section at the end).

Code (Original Version):

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
));

Example:

Sample output for eventual console.log(allModules);:

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

Directory tree:

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

Code (Deep Version):

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
));

Example:

Result of previous example using this version:

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