systemjs: registration[1] is not a function with a project containing libraries

I have been working with SystemJS for sometime without any issues. Our project does not make use of a framework such as Vue, React, or Angular. It is strictly typescript. Recently, we are in the process of importing other libraries, and I took the opportunity to update SystemJS to the latest version and adjust our software to reflect current practices.

After downloading 6.3.1 and modifying our project to use importmap, I received two different errors.

  • “Unable to resolve bare specifier”
  • “registration[1] is not a function”
<script type="systemjs-importmap">
       {
           "imports": {
             "uniFormUI": "./uniFormUI.js"                       
           }
        }
        </script>
        
 <script type="systemjs-module" src="import:uniFormUI"></script>   
 <script src="./node_modules/systemjs/dist/system.js"></script>    
 <script src="./node_modules/systemjs/dist/extras/named-register.js"></script>

After days of fiddling with it, I was able to get the import map working, but I used version 6.3.1 of System.js and 6.1.2 of named-register.js. It was a partial success. Weird! It intermittently worked on my home computer upon startup, generating a promise error attempting to instantiate a class that inherited another. However, my work computer is liking it as I write the description. I don’t get a warm fuzzy feeling with my solution.

To resolve that issue at home, I resorted back by importing my library from the <script> tags, and removing the systemjs-importmap settings. I think the library might not have been loaded before accessing the class, but I am guessing. It would definitely fail more often than succeed.

If I do not use systemjs-importmap, and install 6.2.5 of systemJS, it works perfectly. However, things go off the rails starting from 6.2.6.

system.js:533 Uncaught (in promise) Error: Unable to resolve specifier 'uniFormUI' from http://localhost:8080/uniWS/
    at throwUnresolved (system.js:533)
    at SystemJS.systemJSPrototype.resolve (system.js:529)
    at system.js:226

system.js:311 Uncaught (in promise) TypeError: registration[1] is not a function
    at system.js:311

Any suggestions would be greatly appreciated as I am running out of ideas. I don’t want to mix systemJS versions, and don’t want to remain at 6.2.5

I will attempt to create a code sandbox with the failed solution. But if I have issues, I have also attached the files of the solution to this issue.

I have created a new solution in VSCode containing similar errors that I have experienced, ranging from working perfectly to run-time errors. just modify index.html for different results by remarking/unremarking scripts


notes.txt: describes some of the project setup. results.txt: shows the results depending how index.html is defined. SystemTestWorkspace.code-workspace: VSCode workspace file

[.\MyLib]: library project MyClass_A MyClass_B extends MyClass_A [._OuputLibraries] the compiled “MyLib” project

[.\MyApp]: application project MyClass_C extends MyClass_B MyApp

[.\MyApp\wwwRoot]: web root folder Index.html

_SystemJSTest.zip

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 16 (4 by maintainers)

Most upvoted comments

Here’s a general explanation of this issue. Sharing for any reading who want to know its cause and how to diagnose:

To help you understand the registration[1] is a not a function error, I’ll define what registration is. The registration variable is the array of arguments passed to System.register().

Generally, build tools (including webpack) will produce a bundle that looks like this:

System.register(['react', 'react-dom'], function () {}))

In the above bundle, the registration array is the following:

[['react', 'react-dom'], function () {}]

The first item in the registration array is an array of dependencies. The second item is the function containing the code for your module.

So going back to registration[1] is not a function - this means that the second item in the array is not a function like it should be.

A common reason why this can happen is that a lot of build tools, including webpack and typescript, will output the following if configured to do so:

System.register('library-name', ['dep1'], function () {});

In that case, the second item in the registration array is [‘dep1’] which is not a function like SystemJS expects. The named-register.js SystemJS extra modifies the registration array by removing the string ‘library-name’ so that the remaining items correctly match what SystemJS core expects.

Other SystemJS extras can also impact the registration array. For example, the amd.js SystemJS extra converts a call to define() into a registration array.

To diagnose the cause of the problem in your case, I’d set a break point where the error is occuring, and inspect the registration array. If it has three items instead of two, due to a string name, then the named-register extra might help (or, even better, configure your tool not to output a name. In webpack, this is done by deleting output.library from your config). If it only has two items, but they are not an array of deps + function, then I’d figure out which module’s registration array you’re looking at (the load object in the devtools will help you see that) and then try to figure out why the registration array is wrong. In doing so, you might come across the getRegister() function within SystemJS - that is the function called within SystemJS core which must return the registration array. Generally the script-load.js file is where getRegister() is invoked.

I looked at this again. You should not use Typescript’s feature that concatenates all files in a project into a single file. Doing that results in a bunch of named modules in a single file, which is not the encouraged workflow for systemjs.

Here are a few options that would work better:

  1. Output multiple files instead of a single file. To change this, you can switch from outFile to outDir in your tsconfig. Use this typescript file extension extra to help resolve extensions. Examples: 1 2
  2. Use a bundler, such as rollup/webpack, to concatenate the files into a single file.

I modified your code and verified that doing these things work.

Encountered this issue with version 6.8.1.

I am using systemjs and named-register with code generated by Typescript 4 with --outfile and System.register("Name", ["Dependencies"]

I am modernizing an existing app and I don’t really want to completely change the workflow, so I would really like to be able to be able use the code as generated by Typescript.

Any workarounds I could try?