2

I'm working on an Angular.js project written with TypeScript. We're trying to evaluate whether to upgrade to Angular 8 and we're stuck with how to use ng-annotate with angular-cli's webpack configuration.

I believe that this can be achieved either by using the @angular-builders/custom-webpack tool or by using ngx-build-plus tool but I had not succeeded with neither of them.

My current attempt includes a partial webpack file for ngx-build-plus with the following configuration :

  module: {
    rules: [
      {
        test: /\.ts$/,
        loaders: ['ng-annotate-loader?ngAnnotate=ng-annotate-patched'],
      },
      {
        test: /\.tpl\.html$/,
        loader: 'ng-cache-loader?-url&module=templates&prefix=src:./**/'
      }
    ]
  },
};

Having this, when I run ng serve --extra-webpack-config webpack.partial.js -o I get the following error : NonErrorEmittedError: (Emitted value instead of an instance of Error) error: couldn't process source due to parse error,Unexpected token

The token to which it refers, is simply the type declaration for a method parameter. So I'm guessing that there is some conflict with the loader that angular-cli already uses for TypeScript files but I don't know how to resolve this.

Is there any input on how to solve this either using one of the two tools or something else?

Nick Tsitlakidis
  • 2,269
  • 3
  • 22
  • 26

2 Answers2

2

So, the way to do this is by using webpack-merge and custom-webpack.

This is the configuration to run ng-annotate with Typescript files :



module.exports = (config, options) => {
  const customConfig = {
    module: {
      rules: [
        {
          test: /\.ts$/,
          loaders: ['ng-annotate-loader?ngAnnotate=ng-annotate-patched'],
        },
        {
          test: /\.tpl\.html$/,
          loader: 'ng-cache-loader?-url&module=templates&prefix=src:./**/'
        }
      ]
    }
  };

    return merge.strategy({
      'module.rules': 'prepend'
    })(config, customConfig)
  };

The key part is the merge.strategy call which will make sure that the loaders of the custom configuration will be prepended to the ones that angular-cli already sets up.

Nick Tsitlakidis
  • 2,269
  • 3
  • 22
  • 26
1

After several hours of looking at alternatives, the solution that worked the best for me was using babel-plugin-angularjs-annotate by:

  • Creating a new project
  • Installing babel and babel-plugin-angularjs-annotate
  • Executing babel, which takes the files from src, adds the annotations, and puts the result in the folder output.

For others needing the complete solution, this is what I executed:

  • mkdir babel-project && cd babel-project
  • npm init -y
  • npm install -D babel-cli babel-plugin-angularjs-annotate
  • Create .babelrc and add this:
{
  "presets": [],
  "plugins": [ "angularjs-annotate" ]
}
  • Finally execute babel: npx babel src -d build --extensions .ts

This takes files like:

import * as _ from "underscore";
import "@app2/hello/chao"

const greeting = () => "Hello World"

angular.module("MyMod")
    .controller("MyCtrl", ($scope, HelloClient) => {
        HelloClient.add($scope, greeting);
    });

And turns them into:

import * as _ from "underscore";
import "@app2/hello/chao";

const greeting = () => "Hello World";

angular.module("MyMod").controller("MyCtrl", ["$scope", "HelloClient", ($scope, HelloClient) => {
    HelloClient.add($scope, greeting);
}]);

Update

Using babel-plugin-angularjs-annotate messed a lot with my formatting, so I ended up copying&pasting just the relevant parts of the Babel output, which took some hours.

Daniel
  • 21,933
  • 14
  • 72
  • 101