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
.
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);
});
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"
]
}
No. It means it uses standard TypeScript / EcmaScript imports. The Angular CLI does use Webpack, though. There is none.
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.
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.
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:
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.
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.
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'
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.
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";
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With