olov / ng-annotate

Add, remove and rebuild AngularJS dependency injection annotations
MIT License
2.03k stars 150 forks source link

ngInject in directive class doesn't work (webpack, babel) #252

Closed 0x00000001A closed 8 years ago

0x00000001A commented 8 years ago

I have this configuration:

package.json:

{
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "angular-mocks": "^1.5.8",
    "babel-core": "^6.16.0",
    "babel-loader": "^6.2.5",
    "babel-plugin-syntax-decorators": "^6.13.0",
    "babel-preset-es2015": "^6.16.0",
    "browser-sync": "^2.16.1",
    "connect-history-api-fallback": "^1.3.0",
    "css-loader": "^0.25.0",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.9.0",
    "gulp": "^3.9.1",
    "gulp-util": "^3.0.7",
    "html-webpack-harddisk-plugin": "0.0.2",
    "html-webpack-plugin": "^2.22.0",
    "ng-annotate": "^1.2.1",
    "ng-annotate-loader": "^0.2.0",
    "node-sass": "^3.10.1",
    "path": "^0.12.7",
    "pug-html-loader": "^1.0.8",
    "raw-loader": "^0.5.1",
    "sass-loader": "^4.0.2",
    "style-loader": "^0.13.1",
    "supports-color": "^3.1.2",
    "url-loader": "^0.5.7",
    "webpack": "^1.13.2",
    "webpack-dev-middleware": "^1.8.3",
    "webpack-hot-middleware": "^2.12.2"
  },
  "dependencies": {
    "angular": "^1.5.8",
    "angular-ui-router": "^1.0.0-beta.1",
    "breakpoint-sass": "^2.7.0",
    "susy": "^2.2.12"
  }
}

.babelrc

{
  "presets": ["es2015"],
  "plugins": ["syntax-decorators"]
}

webpack.config.js

'use strict';

var webpack = require('webpack');

var path = require('path');
var extractTextPlugin = require('extract-text-webpack-plugin');
var htmlWebpackPlugin = require('html-webpack-plugin');
var commonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
var htmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');

module.exports = {
  devtool: 'source-map',
  target: 'web',

  entry: {
    app: [
      './src/app.js',
      'webpack-hot-middleware/client?reload=true'
    ],
    vendor: [
      'angular',
      'angular-ui-router'
    ]
  },

  output: {
    // Absolute output directory
    path: path.join(__dirname, '/.tmp/'),

    // Output path from the view of the page
    publicPath: '/',

    // Filename for entry points
    filename: '[name].bundle.js',

    // Filename for non-entry points
    chunkFilename: '[name].bundle.js'
  },

  // Sass loader configuration
  sassLoader: {
    outputStyle: 'compressed',
    precision: 10,
    sourceComments: false
  },

  // Babel loader configuration
  // babel: {
  //   // keep /*@ngInject*/ comment
  //   shouldPrintComment(comment) {
  //     return /@ngInject/.test(comment);
  //   }
  // },

  module: {
    loaders: [{
      // JS loader
      test: /\.js$/,
      include: [
          path.resolve(__dirname, 'src/')
      ],
      loader: 'ng-annotate!babel'
    }, {
      // Pug loader
      test: /\.pug$/,
      loader: 'pug-html?doctype=html'
    }, {
      // Assets loader
      test: /\.(png|jpg|jpeg|gif|ico)$/,
      loader: 'file'
    }, {
      // Fonts loader
      test: /\.(woff|woff2|eot|ttf|svg)$/,
      loader: 'url'
    }, {
      // Sass loader
      test: /\.(scss|sass)$/,
      loaders: ['style', 'css', 'sass'],
      include: [
        path.resolve(__dirname, 'src/assets/styles/main.scss')
      ]
    }]
  },

  plugins: [
    new extractTextPlugin('[name].[hash].css', {
      disable: false
    }),

    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: Infinity
    }),

    new htmlWebpackPlugin({
      template: 'src/index.pug',
      inject: 'body',
      hash: true
    }),

    new webpack.HotModuleReplacementPlugin()
  ]
};

gulp task

gulp.task('serve', () => {
    const config = require('./webpack.config');
    let compiler = webpack(config);

    browserSync({
        port: 3000,
        open: false,
        baseDir: 'src',
        middleware: [
            historyApiFallback(),
            webpackDevMiddleware(compiler, {
              stats: {
                colors: colorsSupported,
                chunks: false,
                modules: false
              },
              publicPath: '/'
            }),
            webpackHotMiddleware(compiler)
        ]
    });
});

I have next directive:

export default class uiDropdownDirective {
  constructor($document, $interval) {
    "ngInject";
    this.restrict = 'A';
    this.$document = $document;
  }

  link($t, $element, $a) {
    console.log(angular.element(document), this.$document, this.$interval);
    setTimeout(function() {
      console.log(angular.element(document), this.$document, this.$interval);
    }, 1000);
    $element.on('click', e => {
      e.preventDefault();

      $element.toggleClass('expanded');
    });
  }
}

Here is how i include directive:

import angular from 'angular';

import uiDropdown from './ui-dropdown/ui-dropdown.directive';

let uiModule = angular.module('ui', [])
  .directive('uiDropdown', () => new uiDropdown)
  .name;

export default uiModule;

And console.log gives next output:

[document] undefined undefined
[document] undefined undefined

But this example will work properly:

import angular from 'angular';

// import uiDropdown from './ui-dropdown/ui-dropdown.directive';

let uiModule = angular.module('ui', []).directive('uiDropdown', () => {
   return {
      restrict: 'A',
      controller: ($http) => {
        'ngInject';
        console.log($http);
      }
   };
})
.name;

export default uiModule;
0x00000001A commented 8 years ago

My fault, sorry pls

Here is how need include controller properly:

let uiModule = angular.module('ui', [])
  .directive('uiDropdown', ($document) => {
    "ngInject";
    return new uiDropdown($document);
  })
  .name;

or

let uiModule = angular.module('ui', [])
  .directive('uiDropdown', /*@ngInject*/ ($document) => new uiDropdown($document))
  .name;

as you like