Может ли @ngtools/webpack AngularWebpackPlugin связывать частично скомпилированные библиотеки ivy?
У меня есть несколько старое веб-приложение Angular, которое было обновлено с Angular 6 до Angular 12, однако Angular CLI не используется для его создания, вместо этого он полагается на Webpack 5, его загрузчики и AngularWebpackPlugin из @ngtools/webpack.
Недавно мне нужно было перейти на последнюю версию библиотеки, которую я использовал, и после производственной сборки я получил следующее предупреждение:
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.
После удаления минимизатора и более подробного просмотра трассировки стека ошибок, похоже, проблема связана именно с этой новой библиотекой.
Теперь я немного покопался и обнаружил, что, начиная с Angular 11.1, библиотеки теперь могут быть частично скомпилированы для Ivy и отправлены в NPM таким образом, не требуя ngcc. И, как и ожидалось, исходный код этой библиотеки указывает на то, что действительно основное различие между старой версией, которую я использовал, и новой, которую я пытаюсь использовать, заключается в том, что более новая версия частично скомпилирована.
Теперь конфигурация веб-пакета моего приложения выглядит следующим образом (я оставил только настройки, которые считаю актуальными, при необходимости я могу предоставить весь файл конфигурации):
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: [...]
})
]
};
Мой вопрос: я пропустил здесь шаг? Есть ли какой-то плагин, который мне нужно использовать для «связывания» частично скомпилированных библиотек, чтобы избежать этой проблемы? Можно ли таким образом скомпилировать приложение Angular для производства с использованием Webpack? Я пробовал кучу вещей, но все указывает на то, что я пропустил какой-то шаг во всем этом процессе. Кроме того, я создал тестовое приложение с помощью Angular CLI и использовал его для установки библиотеки и компиляции в производственном режиме, и все это работает как шарм, поэтому я могу исключить идею о том, что это ошибка создателя библиотеки.
Зависимости приложений следующие:
"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"
}
1 ответ
Есть ли какой-то плагин, который мне нужно использовать для «связывания» частично скомпилированных библиотек, чтобы избежать этой проблемы?
Да! Вам необходимо добавить Angular Linker для обработки проблемного плагина. В настоящее время он доступен только как плагин Babel:
@angular/compiler-cli/linker/babel
Короче говоря, добавьте это в конфигурацию Webpack и замените
ng-click-outside
с вашим собственным плагином:
rules: [
{
// Explicit rule to run the linker over partial libraries
test: /.*\.(js|ts)$/,
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: /.*\.(js|ts)$/,
exclude: /node_modules/,
use: [
{loader: 'babel-loader'}, // Optional
{loader: '@ngtools/webpack'}, // Required
{loader: '@angular-devkit/build-optimizer/webpack-loader'}, // Optional
]
},
Также вам следует удалить старые
@ngtools/webpack
правило. Вам больше не нужно обрабатывать файлы ngfactory или ngstyle в Angular 12.
Для получения дополнительной информации см. Мой другой ответ SO здесь . Авторство оригинального решения принадлежит Роберту ван Хузелю из этого выпуска Github .