@ngtools/webpack AngularWebpackPlugin link 可以部分编译常春藤库吗?
Can @ngtools/webpack AngularWebpackPlugin link partially compiled ivy libraries?
我有这个有点旧的 Angular Web 应用程序,它已从 Angular 6 更新到 Angular 12,但是,Angular CLI 未用于构建它,而不是它依赖于 Webpack 5,它的加载器和来自 @ngtools/webpack.
的 AngularWebpackPlugin
最近,我需要升级到我正在使用的库的最新版本,并且在我的生产构建后收到以下警告:
Uncaught Error: The injectable 'j' needs to be compiled using the JIT compiler, but '@angular/compiler' is not available.
The injectable is part of a library that has been partially compiled.
However, the Angular Linker has not processed the library such that JIT compilation is used as fallback.
Ideally, the library is processed using the Angular Linker to become fully AOT compiled.
Alternatively, the JIT compiler should be loaded by bootstrapping using '@angular/platform-browser-dynamic' or '@angular/platform-server',
or manually provide the compiler with 'import "@angular/compiler";' before bootstrapping.
删除最小化器并更详细地查看错误堆栈跟踪后,这似乎是新库的问题,特别是。
现在,我做了一些 digging 并发现,自 Angular 11.1 以来,现在可以为 Ivy 部分编译库并以这种方式传送到 NPM,而不需要 ngcc。而且,正如预期的那样,该库的源代码表明,事实上,我使用的旧版本与我尝试使用的新版本之间的主要区别在于,新版本是部分编译的。
现在,我的应用的webpack配置如下(我只留下了我认为相关的设置,如果需要我可以提供整个配置文件):
module.exports = {
...
module: {
rules: [
{
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
loader: '@ngtools/webpack'
}
],
},
...
plugins: [
new CleanWebpackPlugin(),
new AngularWebpackPlugin({
tsconfig: './tsconfig-aot.json'
}),
new HtmlWebpackPlugin({
...
}),
new CopyWebpackPlugin({
patterns: [...]
})
]
};
我的问题是我在这里漏掉了一步吗?我需要使用某个插件来“link”部分编译的库以便避免这个问题吗?是否有可能以这种方式使用 Webpack 编译 Angular 应用程序用于生产?
我尝试了很多东西,但一切都表明我在整个过程中错过了一个步骤。
此外,我使用 Angular CLI 创建了一个测试应用程序,并用它来安装库并使用生产模式编译它,这一切都非常有效,所以我可以排除它是库创建者的错的想法。
App依赖如下:
"dependencies": {
"@angular/animations": "12.2.0",
"@angular/cdk": "^12.2.0",
"@angular/common": "12.2.0",
"@angular/compiler": "12.2.0",
"@angular/core": "12.2.0",
"@angular/forms": "12.2.0",
"@angular/platform-browser": "12.2.0",
"@angular/platform-browser-dynamic": "12.2.0",
"@angular/platform-server": "12.2.0",
"@angular/router": "12.2.0",
"@angular/upgrade": "12.2.0",
"@fullcalendar/core": "^5.9.0",
"angular-auth-oidc-client": "^12.0.2",
"angular-google-tag-manager": "^1.4.2",
"angular2-ladda": "^2.0.0",
"angular2-uuid": "1.1.1",
"core-js": "^3.16.1",
"headroom.js": "^0.12.0",
"ngx-google-places-autocomplete": "^2.0.5",
"ngx-headroom": "^1.0.6",
"primeicons": "^4.1.0",
"primeng": "^11.4.5",
"protractor": "^7.0.0",
"rxjs": "^6.6.7",
"tslib": "^2.3.0",
"zone.js": "0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "^12.2.0",
"@angular/cli": "12.2.0",
"@angular/compiler-cli": "^12.2.2",
"@ngtools/webpack": "^12.2.2",
"@types/core-js": "^2.5.5",
"@types/google.maps": "^3.45.6",
"@types/jasmine": "^3.8.2",
"@types/node": "10.11.7",
"angular-router-loader": "0.8.5",
"angular2-template-loader": "0.6.2",
"autoprefixer": "^9.8.6",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^6.4.1",
"css-loader": "^1.0.0",
"file-loader": "2.0.0",
"html-webpack-plugin": "^5.3.2",
"istanbul-instrumenter-loader": "^3.0.1",
"jasmine": "^3.8.0",
"jasmine-spec-reporter": "^5.0.2",
"jasmine-ts": "^0.4.0",
"karma": "^6.3.4",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage": "^2.0.3",
"karma-coverage-istanbul-reporter": "^3.0.3",
"karma-jasmine": "^4.0.1",
"karma-jasmine-html-reporter": "^1.7.0",
"karma-webpack": "^5.0.0",
"postcss-loader": "3.0.0",
"raw-loader": "0.5.1",
"rxjs-tslint": "^0.1.8",
"sass": "^1.37.5",
"sass-loader": "^10.2.0",
"source-map-loader": "^0.2.4",
"style-loader": "0.23.1",
"terser-webpack-plugin": "^4.2.3",
"ts-loader": "^8.3.0",
"ts-node": "^8.10.2",
"tslint": "^6.1.3",
"tslint-loader": "3.5.4",
"typescript": "^4.3.5",
"webpack": "^5.51.0",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.0.0"
}
Is there a certain plugin i need to use to "link" the partially compiled libraries so I avoid this issue?
是的!您需要添加 Angular Linker 来处理有问题的插件。目前只能作为 Babel 插件使用:@angular/compiler-cli/linker/babel
简而言之,将其添加到您的 Webpack 配置中,并将 ng-click-outside
替换为您的插件:
rules: [
{
// Explicit rule to run the linker over partial libraries
test: /.*\.js$/,
include: /node_modules\/ng-click-outside/,
use: [
{
loader: 'babel-loader',
options: {
configFile: false,
plugins: ['@angular/compiler-cli/linker/babel'], // Required!
}
}
]
},
{
// Regular rule for all non-library files
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: [
{loader: 'babel-loader'}, // Optional
{
loader: '@ngtools/webpack', // Required
options: {
directTemplateLoading: false, // See https://www.npmjs.com/package/@ngtools/webpack
}
},
{loader: '@angular-devkit/build-optimizer/webpack-loader'}, // Optional
]
},
此外,您应该删除旧的 @ngtools/webpack
规则。您不再需要处理 'ngfactory' 或 'ngstyle' 中的文件 Angular 12.
有关详细信息,请参阅我的其他 SO 回答 here. Credit for the webpack config goes to Robert van Hoesel from this Github issue。
我有这个有点旧的 Angular Web 应用程序,它已从 Angular 6 更新到 Angular 12,但是,Angular CLI 未用于构建它,而不是它依赖于 Webpack 5,它的加载器和来自 @ngtools/webpack.
的 AngularWebpackPlugin最近,我需要升级到我正在使用的库的最新版本,并且在我的生产构建后收到以下警告:
Uncaught Error: The injectable 'j' needs to be compiled using the JIT compiler, but '@angular/compiler' is not available.
The injectable is part of a library that has been partially compiled.
However, the Angular Linker has not processed the library such that JIT compilation is used as fallback.
Ideally, the library is processed using the Angular Linker to become fully AOT compiled.
Alternatively, the JIT compiler should be loaded by bootstrapping using '@angular/platform-browser-dynamic' or '@angular/platform-server',
or manually provide the compiler with 'import "@angular/compiler";' before bootstrapping.
删除最小化器并更详细地查看错误堆栈跟踪后,这似乎是新库的问题,特别是。
现在,我做了一些 digging 并发现,自 Angular 11.1 以来,现在可以为 Ivy 部分编译库并以这种方式传送到 NPM,而不需要 ngcc。而且,正如预期的那样,该库的源代码表明,事实上,我使用的旧版本与我尝试使用的新版本之间的主要区别在于,新版本是部分编译的。
现在,我的应用的webpack配置如下(我只留下了我认为相关的设置,如果需要我可以提供整个配置文件):
module.exports = {
...
module: {
rules: [
{
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
loader: '@ngtools/webpack'
}
],
},
...
plugins: [
new CleanWebpackPlugin(),
new AngularWebpackPlugin({
tsconfig: './tsconfig-aot.json'
}),
new HtmlWebpackPlugin({
...
}),
new CopyWebpackPlugin({
patterns: [...]
})
]
};
我的问题是我在这里漏掉了一步吗?我需要使用某个插件来“link”部分编译的库以便避免这个问题吗?是否有可能以这种方式使用 Webpack 编译 Angular 应用程序用于生产? 我尝试了很多东西,但一切都表明我在整个过程中错过了一个步骤。 此外,我使用 Angular CLI 创建了一个测试应用程序,并用它来安装库并使用生产模式编译它,这一切都非常有效,所以我可以排除它是库创建者的错的想法。
App依赖如下:
"dependencies": {
"@angular/animations": "12.2.0",
"@angular/cdk": "^12.2.0",
"@angular/common": "12.2.0",
"@angular/compiler": "12.2.0",
"@angular/core": "12.2.0",
"@angular/forms": "12.2.0",
"@angular/platform-browser": "12.2.0",
"@angular/platform-browser-dynamic": "12.2.0",
"@angular/platform-server": "12.2.0",
"@angular/router": "12.2.0",
"@angular/upgrade": "12.2.0",
"@fullcalendar/core": "^5.9.0",
"angular-auth-oidc-client": "^12.0.2",
"angular-google-tag-manager": "^1.4.2",
"angular2-ladda": "^2.0.0",
"angular2-uuid": "1.1.1",
"core-js": "^3.16.1",
"headroom.js": "^0.12.0",
"ngx-google-places-autocomplete": "^2.0.5",
"ngx-headroom": "^1.0.6",
"primeicons": "^4.1.0",
"primeng": "^11.4.5",
"protractor": "^7.0.0",
"rxjs": "^6.6.7",
"tslib": "^2.3.0",
"zone.js": "0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "^12.2.0",
"@angular/cli": "12.2.0",
"@angular/compiler-cli": "^12.2.2",
"@ngtools/webpack": "^12.2.2",
"@types/core-js": "^2.5.5",
"@types/google.maps": "^3.45.6",
"@types/jasmine": "^3.8.2",
"@types/node": "10.11.7",
"angular-router-loader": "0.8.5",
"angular2-template-loader": "0.6.2",
"autoprefixer": "^9.8.6",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^6.4.1",
"css-loader": "^1.0.0",
"file-loader": "2.0.0",
"html-webpack-plugin": "^5.3.2",
"istanbul-instrumenter-loader": "^3.0.1",
"jasmine": "^3.8.0",
"jasmine-spec-reporter": "^5.0.2",
"jasmine-ts": "^0.4.0",
"karma": "^6.3.4",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage": "^2.0.3",
"karma-coverage-istanbul-reporter": "^3.0.3",
"karma-jasmine": "^4.0.1",
"karma-jasmine-html-reporter": "^1.7.0",
"karma-webpack": "^5.0.0",
"postcss-loader": "3.0.0",
"raw-loader": "0.5.1",
"rxjs-tslint": "^0.1.8",
"sass": "^1.37.5",
"sass-loader": "^10.2.0",
"source-map-loader": "^0.2.4",
"style-loader": "0.23.1",
"terser-webpack-plugin": "^4.2.3",
"ts-loader": "^8.3.0",
"ts-node": "^8.10.2",
"tslint": "^6.1.3",
"tslint-loader": "3.5.4",
"typescript": "^4.3.5",
"webpack": "^5.51.0",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.0.0"
}
Is there a certain plugin i need to use to "link" the partially compiled libraries so I avoid this issue?
是的!您需要添加 Angular Linker 来处理有问题的插件。目前只能作为 Babel 插件使用:@angular/compiler-cli/linker/babel
简而言之,将其添加到您的 Webpack 配置中,并将 ng-click-outside
替换为您的插件:
rules: [
{
// Explicit rule to run the linker over partial libraries
test: /.*\.js$/,
include: /node_modules\/ng-click-outside/,
use: [
{
loader: 'babel-loader',
options: {
configFile: false,
plugins: ['@angular/compiler-cli/linker/babel'], // Required!
}
}
]
},
{
// Regular rule for all non-library files
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: [
{loader: 'babel-loader'}, // Optional
{
loader: '@ngtools/webpack', // Required
options: {
directTemplateLoading: false, // See https://www.npmjs.com/package/@ngtools/webpack
}
},
{loader: '@angular-devkit/build-optimizer/webpack-loader'}, // Optional
]
},
此外,您应该删除旧的 @ngtools/webpack
规则。您不再需要处理 'ngfactory' 或 'ngstyle' 中的文件 Angular 12.
有关详细信息,请参阅我的其他 SO 回答 here. Credit for the webpack config goes to Robert van Hoesel from this Github issue。