preboot/angularjs-webpack

Problems with deploying to S3

jswiss opened this issue · 7 comments

Hi there,

I'm trying to deploy to AWS S3 and am running into some issues. Anytime I try to switch states, I get an Unknown provider error, like below:

Error: [$injector:unpr] Unknown provider: eProvider <- e <- dataSources

In the above, dataSources is a service I've injected into the 'dashboard' route. Everything works fine when running locally, but it crashes after running the build.

To be honest, I'm a complete deployment n00b. I ran npm run build, then uploaded the resulting dist directory to S3. I suspect my project's directory structure and/or the way I've injected dependencies may be at fault. Using dataSources as an example:

The dataSources service is exported

dataSources.service.js

import angular from 'angular';

class dataSources {
 // ...code here
}

export default angular.module('services.dataSources', [])
  .service('dataSources', dataSources)
  .name;

Which is imported into index.js

import angular from 'angular';
import uirouter from 'angular-ui-router';

import './dash.css';

import routing from './dash.routes';
import DashboardController from './dash.controller';
import dataSources from './dataSources.service';

export default angular.module('app.dash', [ uirouter, dataSources ])
  .config(routing)
  .controller('DashboardController', DashboardController)
  .name;

And is then injected into the dashboard controller
dash.controller.js

import facilityTypeCount from './chart-facility-type-count';

export default class DashboardController {
  constructor(dataSources) {

    const self = this;

    dataSources.doStuff()

}

DashboardController.$inject = [ 'dataSources' ];

Finally, everything is brought into app.js

import angular from 'angular';
import uirouter from 'angular-ui-router';

// import config file and modules here
import routing from './app.config';
import home from './features/home';
import dashboard from './features/dashboard';

angular.module('app', [ uirouter, routing, home, dashboard ])
  .config(routing);

Like I said, this all works locally. I don't know whether I need to reconfig Webpack, or if I'm not injecting something properly, or something else entirely. Any help would be much appreciated.

phra commented

@jswiss if you can post an example project i can look into it. imho some of your components are missing the inject metadata for safe minification.

@phra very kind of you. I just noticed I didn't format properly, so I fixed that. My repo is available
here
I tried playing around with how I injected services, but so far no luck. I'll totally send beer money if you can help sort this!

Thanks @phra . I've actually never had to inject metadata into an Angular app; this is the first one I've worked on that wasn't already in production. I found this article talking about it, is it what you are referring to?

I've read before that minification/uglification messes with metadata, but I didn't know it causes an error that breaks all interpolated code.

That's what he meant: https://docs.angularjs.org/guide/di

To minify Angular code, you have to use array syntax, $inject property or ng-annotate.

@preboot seems to recommend $inject: #12 (comment)

Ah, cool, thanks a million @apihlaja

For now I just commented out Uglify in Webpack (needed to get something live quick), but I'll clean up my dependency injection later.

Thanks again!

phra commented

@jswiss you can use the webpack loader version -> https://www.npmjs.com/package/ng-annotate-loader
just keep in mind that i have to explicitly add "ngInject"; as first line of the constructor of every ES6 classes otherwise the loader will not know to annotate the transplied version of the class.

i close the ticket. feel free to reopen.