Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WARNING: No name was provided for external module 'X' in output.globals – guessing 'X'

WARNING: No name was provided for external module 'moment' in output.globals – guessing 'momentImported'
WARNING: No name was provided for external module 'odata-parser' in output.globals – guessing 'parser'

I receive this message when I try to bundle my library to Universal Module Definition. The warning can be fixed by adding umdModuleIds in ng-package.json.

The documentation gives us the following explanation:

When writing the UMD bundle, ng-packagr does its best to provide common default values for the UMD module identifiers. Also, rollup will do its best to guess the module ID of an external dependency. Even then, you should make sure that the UMD module identifiers of the external dependencies are correct. In case ng-packagr doesn't provide a default and rollup is unable to guess the correct identifier, you should explicitly provide the module identifier by using umdModuleIds in the library's package file section like so: ...

umdModuleIds:

A map of external dependencies and their correspondent UMD module identifiers. Map keys are TypeScript / EcmaScript module identifiers. Map values are UMD module ids. The purpose of this map is to correctly bundle an UMD module file (with rollup). By default, rxjs, tslib and @angular/* dependency symbols are supported.

How can I find or check for correctness the UMD ID of moment, odata-parser or any other module that must be added to the umdModuleIds?

like image 841
ROMAN Avatar asked Apr 24 '20 06:04

ROMAN


1 Answers

I found the docs hard to understand, too. The ng-packagr umdModuleIds setting in ng-package.json is a mapping of import names to module IDs that UMD registers in the javascript global object.

By import name I mean, in your typescript code:

import * as moment from 'moment';

The string moment should be the key under umdModuleIds.

The value should match up with the global variable registered in the UMD bundle for the package. If you take a look in the JS file you're importing, you'll see the global.X value being set. For moment.js the code block is:

//! moment.js

;(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    global.moment = factory()
}(this, (function () { 'use strict';

The line global.moment = ... gives you what you need. So, to import moment correctly, your ng-package.json should include:

  "lib": {
    "entryFile": "src/public-api.ts",
    "umdModuleIds": {
      "moment": "moment"
    }
  }

In this case, it turns out that ng-packagr's guess is correct - the import name matches the UMD global variable, but you need to specify it explicitly for ng-packagr to know for sure.

There should be another (and better) way that you can fix this for NPM dependencies, which is to add the library dependencies to the library package.json file (the package.json in the same dir as the ng-package.json file). I would try that first - I believe ng-packagr correctly finds the UMD module ids when the dependency is included in the package.json.

However, in the case that you're using local libraries (libraries in the same angular workspace), or libraries which otherwise can't be analyzed by ng-packagr, it's necessary to look at the UMD ids and make sure they match up. For example, if you're using scoped/namespaced names for your internal libs, like @mycompany/util, you'll see that the UMD module IDs are registered like this:

File: ~/dist/util/bundles/mycompany-util.umd.js

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define('@mycompany/util', ['exports'], factory) :
    (global = global || self, factory((global.mycompany = global.mycompany || {}, global.mycompany.util = {})));
}(this, (function (exports) { 'use strict';

so given the line global.mycompany.util = you'll need to specify UMD module IDs like:

    "umdModuleIds": {
      "@mycompany/util": "mycompany.util"
      ...
    }
like image 158
crimbo Avatar answered Sep 19 '22 12:09

crimbo