Reputation: 95
I have build a small example app to show off this issue. It seems when importing modules in the module declaration it does import the modules declarations. For example when I import the browser module it does not import NgIf, NgFor etc etc and when I import NgSelect it does not import any of its Schema or components. I am building the app without using angular-cli as I am currently migrating an app from angularjs to angular and moving it to use angular-cli would be an issue.
I have set up the webpack config like
const path = require('path'),
AngularWebpackPlugin = require('@ngtools/webpack'),
webpack = require('webpack'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
WebpackDevServer = require('webpack-dev-server');
module.exports = {
entry: {
'test': { import: "./app/app.module.ts", filename: 'js/[name].bundle.min.js' },
},
mode: 'none',
output: {
path: path.resolve(__dirname, "dist"),
clean: true
},
resolve: {
//extensions: ['.ts', '...'],
extensions: ['.tsx', '.ts', '.js', '.mjs', '.json']
},
optimization: {
},
plugins: [
new webpack.ProvidePlugin({
moment: 'moment'
}),
new HtmlWebpackPlugin({
title: 'Test',
template: './app/index.hbs',
cache: false,
hash: true,
inject: false
}),
new AngularWebpackPlugin.AngularWebpackPlugin({
'tsconfig': 'tsconfig.json',
//"compilerOptions": {},
"sourceMap": true,
'jitMode': true
})
],
module: {
rules:
[
{
test: /\.hbs$/i,
use: "handlebars-loader",
exclude: /node_modules/,
},
{
test: /\.[jt]sx?$/,
loader: '@ngtools/webpack',
include: /app[\\/]/,
exclude: [ /node_modules/ ]
},
{
test: /\.[cm]?js$/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
compact: false,
plugins: ['@angular/compiler-cli/linker/babel'],
},
},
},
{
test: /\.template\.html$/,
exclude: /node_modules/,
use:
[
{
loader: 'raw-loader',
options:
{
esModule: false,
},
}
],
},
{
test: /\.css$/i,
exclude: /node_modules/,
use:
[
{
loader: 'css-loader',
options: {
import: false,
url: false,
modules: false
}
}
]
}
],
},
devServer: {
static: {
directory: path.join(__dirname, 'dist'),
watch: true
},
host: "localhost",
compress: true,
port: 5000,
server: 'https',
open: true,
liveReload: false,
hot: true,
client: {
overlay: true,
progress: true,
}
}
}
and the angular test app is
app.module.ts
import 'zone.js';
import { NgSelectModule } from '@ng-select/ng-select';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
NgSelectModule,
],
providers: [
],
bootstrap: [AppComponent]
})
export class AppModule {
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
app.component.ts
import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-root',
template: require('./app.template.html'),
})
export class AppComponent implements OnInit {
public source = [ { id: 1, name: "moo" }]
public selected = null;
ngOnInit(): void {
console.log("YAY!");
}
}
app.template.html
<!DOCTYPE html>
<html lang="en">
<head>
<title ng-bind="title">T.I.E.R</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta content="IE=edge, chrome=1" http-equiv="X-UA-Compatible" />
</head>
<body>
<app-root></app-root>
<script defer src="js/test.bundle.min.js?904b25da0a6807f141ae"></script>
</body></html>
and my tsconfig is:
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"resolveJsonModule": true,
"forceConsistentCasingInFileNames": true,
"strict": false,
"noImplicitOverride": false,
"noPropertyAccessFromIndexSignature": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": true,
"emitDecoratorMetadata": true,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "Node",
"importHelpers": true,
"target": "ES2022",
"module": "ES2022",
"useDefineForClassFields": false,
"lib": [
"ES2022",
"dom"
]
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true,
"compilationMode": "partial"
}
}
As far as I can tell I am building the Ivy partials but I am getting the errors:
NG0304: 'ng-select' is not a known element (used in the 'AppComponent' component template):
and
NG0303: Can't bind to 'ngModel' since it isn't a known property of 'ng-select' (used in the 'AppComponent' component template).
as if it is not imported. Apart from that angular is working fine. If I put NgIf in imports I can use it but it should be imported from BrowserModule or CommonModule.
Anyone have any ideas because I have spent 3 days on this and am about to stab my monitor?
Upvotes: 3
Views: 604
Reputation: 21
You need to import the CommonModule from @angular/common in the module where your component is used. The CommonModule provides directives like *ngIf and *ngFor.
Open the module file where your component is declared, usually app.module.ts or a feature module.
Add CommonModule to the imports array if it isn't already imported.
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; // Import this to use *ngIf, *ngFor
import { YourComponent } from './your-component.component';
@NgModule({
declarations: [
YourComponent
],
imports: [
CommonModule // Add this to ensure *ngIf and *ngFor work
]
})
export class YourModule { }
If you are using
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
...
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
as LidiyaParshina suggested then try to set your jitMode to @angular/compiler in webpack.config.ts like this:
new AngularWebpackPlugin.AngularWebpackPlugin({
'tsconfig': 'tsconfig.json',
//"compilerOptions": {},
"sourceMap": true,
// 'jitMode': true
'jitMode': '@angular/compiler'
})
Otherwise you could have a problems.
For pipe translations in your app.module.ts you should put:
...
import { CommonModule } from '@angular/common'; // Import this to use *ngIf, *ngFor
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
...
function HttpLoaderFactory(http: HttpClient):TranslateHttpLoader {
return new TranslateHttpLoader(http, '../i18n/', '.json');
}
...
@NgModule({
imports: [
BrowserModule,
NgbModule,
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
},
}),
...
],
...
})
export class IsbAppModule {}
and in your feature modules you should use:
...
import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
import { NgSelectModule } from '@ng-select/ng-select';
import { TranslateModule } from '@ngx-translate/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
...
@NgModule({
imports: [
CommonModule,
NgbNavModule,
NgSelectModule,
NgbModule,
TranslateModule.forChild(), <--- Put this line
...
],
...
})
export class IsbCompanyModule {}
Hope it helps!
Upvotes: 0
Reputation: 324
Try to add to your module app.module.ts schemas: [CUSTOM_ELEMENTS_SCHEMA]
import 'zone.js';
import { NgSelectModule } from '@ng-select/ng-select';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
NgSelectModule,
],
providers: [
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
bootstrap: [AppComponent]
})
export class AppModule {
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
Upvotes: 0