11

I have a folder structure for my JS modules. I want one module per page. This is not a single page app.

How can I output files in a folder structure?

From what I can see, the only possibility is to output [name].js. This could work if I make the names very unique, or I could make the names have a - for a folder separator. That would mean a/b/c.js would translate to name a-b-c. I really don't like this. I would like to be able to require("a/b/c").

From what I can tell, I can't use a single bundled file either because require is not available outside of the module. If it was, I could just build a single bundle and require("a/b/c") on every page.

If there is a good way to do this that I'm not finding on the internet, please let me know.

It looks like I'm able to easily do this with require.js using r.js, but I don't want to use require.js and would like CommonJS modules.

1
  • I'm doing something similar to this but not quite the same. In my webpack.config.js I created several different configurations that I switch between depending on the NODE_ENV environment variable that I set when i run different npm scripts. For example, in my package.json I have a script called build-dev which runs "set NODE_ENV=development&& webpack". Hope this gives you some ideas! Commented Feb 3, 2015 at 19:43

3 Answers 3

14

You can define an entry point using slash, like this:

entry: {
    "main-plugin/js/background":"./src/main-plugin/background"
}

And output like this:

output: {
    path: path.join(__dirname, 'public'),
    filename: '[name].js'
},

This setup will create a public/main-plugin/js folder and will place the background.js into it. It works at least on Win7x64.

Sign up to request clarification or add additional context in comments.

Comments

1

You can use [name] to make new folders too. Like this:

output: {
    path: __dirname,
    filename: '[name]/[name].js',
    chunkFilename: '[name].js',
    publicPath: '/assets/'
},

Comments

0

With a little wrangling with node you can create an entry object to pass in the config. In my case I used the name of the folders of the second level to create different bundles, but you can easily adapt to your needs.

const path = require('path');
var glob = require('glob')

const exportPath = path.resolve(__dirname,`./../public/javascripts/plugins`);

// create a glob of files
const entryArray = glob.sync('./plugins/**/{svg,src}/**/*.*');

/**
 * Create a dictionary of entries in format: folder: ['file', 'file2']
 * https://webpack.js.org/configuration/entry-context/#entry
 */

var folders = []
var entries = {};

// list unique folders
entryArray.map((item) => {
  const folderName = item.split('/')[2];
  if (!folders.includes(folderName)) {
    folders.push(folderName);
  }
});

// assign files to each folder
folders.map((folder) => {
  var imports = [];
  entryArray.map((item) => {
    const folderName = item.split('/')[2];
    
    if (folder == folderName) {
      imports.push(item);
    }

  });

  entries[folder] = imports
});

module.exports = {
    entry: entries,
    module: {
      rules: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: [
            {
              loader: 'babel-loader',
              query: {
                presets: [ '@babel/preset-env' ],
              },
            }
          ],
        },
        {
          test: /\.css$/,
          use: [
            'style-loader',
            'css-loader',
            {
              loader: 'postcss-loader',
              options: {
                plugins: [
                  require('postcss-nested-ancestors'),
                  require('postcss-nested')
                ]
              }
            }
          ]
        },
        {
          test: /\.svg$/,
          loader: 'svg-inline-loader?removeSVGTagAttrs=false'
        }
    ],
  },
  output: {
    path: exportPath,
    filename: '[name]/dist/bundle.js',
    libraryTarget: 'umd',
    libraryExport: 'default'
  }
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.