0

How do I configure Webpack to create UMD bundle, so that package name for AMD and CommonJS will be named in lowercase (spinal-case), and for global context will have CamelCase name?

For example I expect my bundle to start with

(function webpackUniversalModuleDefinition(root, factory) {
    if(typeof exports === 'object' && typeof module === 'object')
        module.exports = factory(require("dependency"));
    else if(typeof define === 'function' && define.amd)
        define("my-library", ["dependency"], factory);           // spinal-case
    else if(typeof exports === 'object')
        exports["my-library"] = factory(require("dependency"));  // spinal-case
    else
        root["MyLibrary"] = factory(root["dependency"]);         // CamelCase
})...

This is how it looks in ReactDOM:

(function(f) {
  // CommonJS
  if (typeof exports === "object" && typeof module !== "undefined") {
    module.exports = f(require('react'));

  // RequireJS
  } else if (typeof define === "function" && define.amd) {
    define(['react'], f);

  // <script>
  } else {
    var g;
    if (typeof window !== "undefined") {
      g = window;
    } else if (typeof global !== "undefined") {
      g = global;
    } else if (typeof self !== "undefined") {
      g = self;
    } else {
      // works providing we're not in "use strict";
      // needed for Java 8 Nashorn
      // see https://github.com/facebook/react/issues/3037
      g = this;
    }
    g.ReactDOM = f(g.React);
  }
})(function(React)...
Alexander Shutau
  • 2,660
  • 22
  • 32

1 Answers1

0

You also should have the property umdNamedDefine set to true. This is what my output block commonly looks like when I do a UMD wrapped library. I will use an example from an npm package that I currently have as it will be the most illustrative:

output: {
    path: './lib',
    filename: 'dom-regex.js',
    library: 'DomRegex',
    libraryTarget: 'umd',
    umdNamedDefine: true
},

Given that my npm package is named dom-regex in the package.json, this allows me to use my packages in the following ways:

ES6:

import DomRegex from 'dom-regex';

RequireJS

var DomRegex = require('dom-regex');

On the window: (if the file is exposed directly to the window)

window.DomRegex

What the name is exported as in the UMD wrapped section isn't as important as what you name it when you import it. Using dom-regex as an example, even if I had it locally in my project (not in node_modules), and the filename was dom-regex.js, I could still do all the previous examples, because it is UMD wrapped:

You're welcome to explore the repo for dom-regex and test download the package to see how this works.

KevBot
  • 17,900
  • 5
  • 50
  • 68
  • As an example, when using ES6 you do `import ReactDOM from 'react-dom;', `var ReactDOM = require('react');' with RequireJS and when simply adding script to a file, you just call `ReactDOM` (`window.ReactDOM`). See ReactJS bundle https://npmcdn.com/react-dom@15.4.2/dist/react-dom.js – Alexander Shutau Jan 23 '17 at 19:14
  • @AlexanderShutov, I've updated my answer with a better example, and a repo you can explore / experiment with. – KevBot Jan 24 '17 at 02:42
  • Finally to get what I need I had to remove `umdDefineName`, so that AMD and CommonJS section go without name. CommonJS is left by Webpack for some reason, but luckily is ignored when importing in Webpack or Rollup. Finally, look, [how React team do it](https://github.com/facebook/react/blob/046f7448d7224da5b33441248a32a319a6464bc5/grunt/config/browserify.js#L98). – Alexander Shutau Jan 24 '17 at 14:00