Skip to content

Add support for CommonJS #3031

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
slavafomin opened this issue Sep 22, 2016 · 7 comments
Closed

Add support for CommonJS #3031

slavafomin opened this issue Sep 22, 2016 · 7 comments

Comments

@slavafomin
Copy link

slavafomin commented Sep 22, 2016

Hello!

Thank you for this great library!

However, right now, when this module is used in CommonJS it leads to errors, because the module returns the factory function instead of the Angular.js module's name.

Please see how this is implemented for native Angular.js router:
https://github.com/angular/bower-angular-route/blob/master/index.js

Notice how module's name is returned to the caller of require().

Usage example

const app = angular.module('app', [
  require('angular-ui-router'),
  require('angular-ui-router.statehelper'),
  require('./config'),
  require('./index-controller'),
]);

Workaround

Right now, I have to use it this way, which is cumbersome:

// Making sure modules are added to the bundle by Webpack.
require('angular-ui-router');
require('angular-ui-router.statehelper')

const app = angular.module('app', [

  // Manually specifying modules names.
  'ui.router',
  'ui.router.stateHelper',

  require('./config'),
  require('./index-controller'),
]);

Thanks!

@christopherthielen
Copy link
Contributor

christopherthielen commented Sep 22, 2016

What version of ui-router are you using? The legacy versions should be returning "ui.router" when require('angular-ui-router') is used.

In 1.0, you should use require('angular-ui-router').default or import uiRouter from "angular-ui-router"

Please see https://ui-router.github.io/guide/ng1/migrate-to-1_0#commonjs-module-name
and microsoft/TypeScript#2719
and #2506
and http://stackoverflow.com/questions/33505992/babel-6-changes-how-it-exports-default

@slavafomin
Copy link
Author

Thank you @christopherthielen for a comprehensive explanation. I will look into it.

Maybe it is possible to use the index.js: export { default } from "./components/MyComponent"; workaround mentioned on SO?

@christopherthielen
Copy link
Contributor

I think the workaround (changing the index to exports.default = 'ui.router') could create issues with the other exports (from ui-router-core). I believe ES6 modules are the future and that the existing workaround (adding require('angular-ui-router').default) seems like a simple enough workaround to allow interop with commonjs.

Because of that, I personally think the existing setup is "good enough".

I'm closing this issue, but I'm open to hearing about other possible approaches, if it can be shown that they won't cause problems with other module setups.

@slavafomin
Copy link
Author

I'm not sure I understand how the offered workaround could create issues, could you please elaborate on this?

The require('angular-ui-router').default approach is counter-intuitive, because most of the Angular.js modules (including official module by Angular team) are working with just a simple require(). I think it's great to use new ES6 features, but it shouldn't break the interface for older code.

@christopherthielen
Copy link
Contributor

I'm not sure I understand how the offered workaround could create issues, could you please elaborate on this?

CommonJS supports either a single default export or multiple named exports, but they are mutually exclusive (as far as I know). There are many other symbols exported from ui-router that people can currently import, e.g., import { trace } from "angular-ui-router"; trace.enable();

because most of the Angular.js modules (including official module by Angular team)

This problem is a ES6->CJS interop issue and those modules aren't authored in ES6.

@slavafomin
Copy link
Author

Hmm. Do we really need to import something from the module directly? Isn't it a best practice to use configuration providers and services to interact with the module?

angular.module('app', [
  require('angular-ui-router')
])
  .config(function (traceProvider) {
    traceProvider.enable();
  })

Actually, I'm not seeing something being imported from the module directly in the documentation or in the examples (at first glance). Could you give me a link where this use case is documented?

@christopherthielen
Copy link
Contributor

All you have to do is add .default to your app's module deps in one place. This is documented in the 1.0 migration guide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants