Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get webpack to find angular modules?

I'm trying to setup a bare-bones application with Angular 1 + Typescript 2 and Webpack. The app works fine until I try to use an external module, ex: angular-ui-router.

It always complains that it can't find the dependency:

ERROR in ./src/app.ts Module not found: Error: Cannot resolve module 'angular-ui-router' in ./src/app.ts 3:26-54

Demo showing problem: https://github.com/jxc876/angular-ts

I suspect I'm not importing the routing dependency correctly, tried:

  • import uiRouter from 'angular-ui-router';
  • import * as uiRouter from 'angular-ui-router'

Tried with angular-route and also ui-router but neither works. Tried ts-loader and awesome-typescript-loader.

App

import * as angular from 'angular';
import uiRouter from 'angular-ui-router';

let myApp = angular.module('myApp', [uiRouter]);

myApp.config(function($stateProvider) {
  let homeState = {
    name: 'home',
    url: '/home',
    template: '<div>It works !!!</div>'
  }

  $stateProvider.state(homeState);
});

Config

package.json

{
  "name": "ts-demo",
  "scripts": {
    "start": "webpack-dev-server --content-base ./src"
  },
  ...
  "devDependencies": {
    "@types/angular": "^1.5.16",
    "@types/angular-ui-router": "^1.1.34",
    "awesome-typescript-loader": "^3.0.0-beta.3",
    "typescript": "^2.0.9",
    "webpack": "^1.13.3",
    "webpack-dev-server": "^1.16.2"
  },
  "dependencies": {
    "angular": "^1.5.8",
    "angular-ui-router": "^0.3.1",
    "enhanced-resolve": "^2.3.0"
  }
}

webpack.config.js

module.exports = {
  entry: './src/app',
  output: {
    filename: './dist/bundle.js'
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx']
  },
  devtool: 'source-map',
  module: {
    loaders: [
      {
        test: /\.ts$/,
        loader: 'awesome-typescript-loader'
      }
    ]
  }
};

tsconfig.json

{
    "compilerOptions": {
        "outDir": "./dist/",
        "allowJs": true,
        "target": "es5",
        "module": "commonjs",
        "moduleResolution": "node",
        "strictNullChecks": true,
        "listFiles": true
    },
    "include": [
        "./src/**/*"
    ],
      "exclude": [
        "node_modules"
    ]
}
like image 653
Mike R Avatar asked Nov 25 '16 18:11

Mike R


People also ask

Is webpack needed for Angular?

No. It means it uses standard TypeScript / EcmaScript imports. The Angular CLI does use Webpack, though. There is none.

How do I add a webpack to an existing Angular project?

In order to use a custom webpack config, you will need to add @angular-builders/custom-webpack and @angular-builders/dev-server to your project as devDependency packages: npm install --save-dev @angular-builders/custom-webpack @10.0. 1.

What is Webpack in angular?

Webpack is a module bundler for the web. It is incredibly powerful and enables modularity in angular applications. This is the first of several lessons to get you up and going with webpack in Angular applications. [00:00] The first thing that we're going to want to do, obviously, is install Webpack.

How do I run a Webpack-bundle-analyzer on an angular app?

First, you’ll want to install webpack-bundle-analyzer in your project as a dev dependency: Then, build your app for production using the Angular CLI and specify the --stats-json so that the webpack stats data gets exported to the dist folder: Now, run the local webpack-bundle-analyzer against the stats.json file using npx:

Why can't I find the Webpack module in my project?

This error mostly occurs because of old dependencies, if at all are not upgraded then it can be deleted manually by deleting the node_modules Folder and also the package-lock.json file An unhandled exception occurred: Cannot find module 'webpack' Simply means there is no webpack in your project.

What is Webpack and why should you learn it?

Learning about webpack is one of the major hurdles to getting up and running with modern JavaScript frameworks like React and Angular. The nice folks on the Angular team wanted to make it easier for people to start using Angular. They did this by embedding webpack in the Angular CLI.


Video Answer


3 Answers

I suppose that since I'm using UI-Router for AngularJS (1.x), I had to use...

import '@uirouter/angularjs'

...instead of...

import 'angular-ui-router'

like image 136
thargenediad Avatar answered Oct 26 '22 22:10

thargenediad


This one should do the job:

import * as angular from 'angular';
import * as uiRouter from 'angular-ui-router';

let myApp = angular.module('myApp', ['ui.router']);

Notice, that import is just importing router code and in application module you need to inject 'ui.router' string.

like image 38
yarl Avatar answered Oct 27 '22 00:10

yarl


Finally figured this out.

First issue is that the typescript compiler removes import statements that are not used.

The compiler detects whether each module is used in the emitted JavaScript. If a module identifier is only ever used in type annotations and never as an expression then no require call is emitted for that module. This culling of unused references is a good performance optimization, and also allows for optional loading of those modules.

source: https://github.com/Microsoft/TypeScript/issues/4717

I assigned the imported value to a dummy array and it seems to fix this. Logging the value out to the console also works. (See my final note on why I couldn't simply pass it into the dependency array).

EDIT: Better solution is to use import "module"; syntax since that is always emitted based on the github above, ex: import 'angular-ui-router';


Second, my webpack file was missing an empty string in the resolve array:

resolve { extensions: ['', '.ts', '.js'] }

Without this it couldn't pull in the file for ui router.

A few things I noticed while working on this: webpack --display-error-details is super useful. For some reason it was looking for double .js.js extensions inside node_modules/angular-ui-router/release:

resolve file
  /Users/mich2264/projects/angular-ts/node_modules/angular-ui-router/release/angular-ui-router.js.ts doesn't exist
  /Users/mich2264/projects/angular-ts/node_modules/angular-ui-router/release/angular-ui-router.js.js doesn't exist

--traceResolution is equally useful for typescript.

EDIT: Appears to be a awesome-typescript-loader loader bug: https://github.com/s-panferov/awesome-typescript-loader/pull/264


Finally, I'm not sure why but when I import the default value from angular-ui-router and I log it or set a breakpoint it shows up correctly as ui.router, but if I attempt to pass it into the dependency array it becomes undefined.

@types/angular-ui-router defines the following export inside their type file : export default "ui.router";

like image 44
Mike R Avatar answered Oct 26 '22 22:10

Mike R