4

I'm using JSPM 0.16.42 which uses SystemJS, I've tried both angular-translate and angular-route, both of which are on github endpoints.

However, for both of them angular throws the same error

argument module is not a function

when using them in ES6 syntax as follows:

import AngularRoute from 'angular-route';

angular.module('app', [AngularRoute]);

I'm using babel as a transpiler. The object I get back from the import seems to be empty. Following is the relevant part of my config.js file:

System.config({
  baseURL: "/",
  defaultJSExtensions: true,
  transpiler: "babel",
  babelOptions: {
    "optional": [
      "runtime",
      "optimisation.modules.system"
    ]
  },
  paths: {
    "github:*": "jspm_packages/github/*",
    "npm:*": "jspm_packages/npm/*"
  },
  map: {
    "angular-route": "github:angular/bower-angular-route@1.5.8",
    "angular-translate": "github:angular-translate/bower-angular-translate@2.11.1",
  }...

EDIT: When I tried to install angular-translate with an npm endpoint I got the error http://errors.angularjs.org/1.5.8/$injector/unpr?p0=e on the following line in angular.js

return new ErrorConstructor(message);

which I guess is a bit of progress but still doesn't solve my issue obviously

EDIT#2: I got angular-route to work with the help of @artem by using the npm endpoint, for some reason the github endpoint did not work so I used jspm install npm:angular-route. Further investigation is needed as to why the github package did not work and the npm package did

EDIT#3: I have overriden the package configuration as you can see below, though that didn't help

"npm:angular-translate@2.11.1": {
        "format": "global",
        "dependencies": {
          "angular": ">=1.2.26"
        },
        "shim": {
          "angular-translate": {
            "deps": "angular"
          }
        }
      }
Robin-Hoodie
  • 4,886
  • 4
  • 30
  • 63
  • try to change your import to: import * as AngularRoute from 'angular-route' – artem Aug 23 '16 at 15:41
  • Hello, that syntax just imports everything from 'angular-route', which gives me an empty object as well – Robin-Hoodie Aug 23 '16 at 16:55
  • that index.js has `module.exports = 'ngRoute';` Taken as it is, it exports a string literal 'ngRoute'. I'm not sure SystemJS can handle that. The normal way to re-export in commonJS format would be `module.exports = require('./angular-route');` – artem Aug 23 '16 at 17:52
  • @artem Good point, I hadn't looked at the index.js of angular-route yet, I'll take a look if I can make it work with this knowledge – Robin-Hoodie Aug 23 '16 at 17:56
  • @artem I got it to work by using the angular-route npm endpoint instead of github by installing with `jspm install npm:angular-route`, I will take a look what's the difference between the two, the npm package also exports a string – Robin-Hoodie Aug 23 '16 at 18:08
  • I'd guess that the difference is that jspm modifies systemjs configuration when you use it to install modules, to make them work as intended – artem Aug 23 '16 at 18:18

2 Answers2

2

Here is not-so-minimal, not-really-self-contained example for angular-translate with systemjs:

npm install jspm
./node_modules/.bin/jspm install github:angular-translate/angular-translate

keep pressing <ENTER>, accepting all the default values

create file test.js

import AngularTranslate from 'angular-translate/angular-translate';

console.log(AngularTranslate);

create file index.html

<!doctype html>
<html>
<head>
    <script src="jspm_packages/system.src.js"></script>

    <script src="config.js"></script>
    <script>
        System.import('./test.js');
    </script>

</head>
<body>
</body>
</html>

open it in the browser:

Failed to load resource: the server responded with a status of 404 (File not found)
undefined:1 Uncaught (in promise) Error: (SystemJS) XHR error (404 File not found) loading 
http://localhost:8035/jspm_packages/github/angular-translate/angular-translate@2.11.1.js(…)

Why that file isn't there? It's supposed to be created by jspm, if you had installed angular-translate from npm it would have contained

module.exports = require("npm:angular-translate@2.11.1/dist/angular-translate.js");

which is just a redirect from symbolic package name (the name of that .js file) to that package main file, as specified in package.json:

"main": "dist/angular-translate.js",

But angular-translate is from github, there is no dist there. That's why jspm did not create the redirect file - there is nothing to redirect to.

No problem, just build it from the source we got from github:

cd jspm_packages/github/angular-translate/angular-translate@2.11.1/
npm install
npm run-script build
cd ../../../..

and fix mapping in config.js:

  map: {
      "angular-translate/angular-translate": "github:angular-translate/angular-translate@2.11.1/dist/angular-translate",

open index.html in the browser again:

system.src.js:122 Uncaught (in promise) Error: (SystemJS) angular is not defined(…)

No problem, angular is already installed as angular-translate dependency, just tell systemjs when and how to load it.

add to config.js:

  meta: {
    "angular-translate/angular-translate": {
        "deps": ["angular"]
      }
  },


  map: {
    "angular": "github:angular-translate/angular-translate@2.11.1/node_modules/angular/angular",

NOTE: You don't need to specify format for angular-translate. SystemJS auto-detects it correctly - it could be loaded as either 'amd' or 'cjs', but it will not work as 'global'. Also, you probably did not start by installing angular-translate, so you already have angular.js file and mapping in place somewhere.

Open index.html in the browser again. It prints in the console:

pascalprecht.translate

Yes angular-translate exports a string - seems to be typical for angular1 modules.

I have no experience with angular.js, so I declare it a success and stop here.

PS Why angular-route worked when you install it from npm, and did not work from github?

When installed from npm, jspm created a file named jspm_packages/npm/angular-route@1.5.8.js, containing

module.exports = require("npm:angular-route@1.5.8/index.js");

because package.json for angular-route has

  "main": "index.js",

which is correct and works for you.

When installed from github, jspm created similar file jspm_packages/github/angular/bower-angular-route@1.5.8.js, but this time it points to a different file

module.exports = require("github:angular/bower-angular-route@1.5.8/angular-route");

because someone put an override in jspm registry there at https://github.com/jspm/registry/blob/master/package-overrides/github/angular/bower-angular-route%401.3.0.json

because bower.json for bower-angular-route has

"main": "./angular-route.js",

Maybe it's an oversight, maybe it's correct and works for them - I don't know.

TL;DR It's not a good idea to use package manager for installing software, if the software was not packaged properly for that package manager.

artem
  • 46,476
  • 8
  • 74
  • 78
  • "You don't need to specify format for angular-translate. SystemJS auto- detects it correctly - and it's 'amd', not 'global'" Now I'm confused, on top of `angular-translate.js` file it reads `"format cjs"` – Robin-Hoodie Aug 24 '16 at 07:51
  • The one that I built from source does not have that string. It starts with boilerplate function that allows to load it as both amd and cjs. I updated the answer. – artem Aug 24 '16 at 15:27
2

I eventually fixed it by installing angular-translate as well as angular-route via their npm endpoints instead of the default (github) endpoints, using

jspm install npm:angular-route

&

jspm install npm:angular-translate -o '{dependencies: { angular: ">=1.2.26" } }'

The override for angular-translate was needed since jspm did not understand the original dependency syntax correctly which was angular: ">= 1.2.26 <=1.6" as described in this github issue

Robin-Hoodie
  • 4,886
  • 4
  • 30
  • 63