WebPack require context from list in external json file WebPack require context from list in external json file json json

WebPack require context from list in external json file


I had got similar problem. Webpack does not allow to create dynamic requires. It takes all modules before the code is executed.But you can use require.context to load necessary modules according to some regexp rules. You can read more here: webpack docs

You can name modules, that you want to load in some specific way, eg. module.* and use require.context("./modules/", false, /^module\..+$/).Then all modules that begin with module. will be required before the code execution.

I remember that I was struggling with that for a couple of hours and that was the best solution for me.


In case you need just to execute your modules

You need to set entry property in webpack config. This property accepts array as value of files to include in bundle.

// webpack.config.jsconst fs = require('fs');const path = require('path');const getModulePath = module => path.resolve(__dirname, './relative/path/to/modules/directory', module);const fileContent = fs.readFileSync('./your.json');const entries = JSON.parse(fileContent).map(getModulePath);module.exports = {  // all entries will be built during one build process  // if you need you can split each entry to separate config file  entry: {    bundle1: entries, // build modules from JSON file to single bundle    bundle2: [ './file1', './file2' ], // build static modules to single bundle    bundle3: './sindle/file', // "classic" build    all: [ ...entries, './file1', './file2', './sindle/file' ], // you can combine everything to 1 bundle  },};

In case you need to export something from your modules

Unfortunately webpack's entry as array won't help you because it will export only last file in array.

I didn't heard something about such plugins that can combine certan files and use it as entry point. But you can create such file by yourself.

// webpack.config.jsconst fs = require('fs');const path = require('path');// saving tmp file locationconst pathToCreatedFile = path.resolve(__dirname, './path/to/created/file');// implement fn to get relative path to modules from tmp fileconst getModulePath = module => path.relative(pathToCreatedFile, path.resolve(  __dirname,  './relative/path/to/modules/directory',  module,));// read jsonconst fileContent = fs.readFileSync('./path/to/your.json');// prepare modules for tmp fileconst entries = JSON.parse(fileContent)  .map(item => ({    name: item.slice(7),    relpath: getModulePath(item),  }));// here generate import directive for each module. I used `import * as modules_name from 'path';` format// you can choose anyconst importsString = entries.map(({ name, relpath }) => `import * as ${name} from '${relpath}';`).join('\n');// here generate exports from tmp file. It contain of all importsconst exportsString = `export {${entries.map(({name}) => name).join(',\n')}};`;// and here just concatenate imports ad exportsconst content = [  entries.map(({ name, relpath }) => `import * as ${name} from '${relpath}';`).join('\n'),  `export {${entries.map(({name}) => name).join(',\n')}};`,].join('\n');// and save tmp file content to fsfs.writeFileSync(pathToCreatedFile, content);module.exports = {  // and here use saved tmp file path as entry point  entry: pathToCreatedFile,};

After you import builded bundle it will return plain object with your modules. You can use Object.values or similar to get your dependencies as array.

And another aproach, you can format exportString to export array of imports.

I used import * as name from ... format to show you more common way to create file. If you don't have any default exports or you have only default export it's better to use export * from ... or export {default as name} from ... formats respectively.