feat(webpack): angular12 support & looser dependencies (#9441)

* chore: dep scoping

* chore: carrots for all dep major versions

* chore: dev.1

* chore: use at least min of 5.34 on webpack

* chore: ignore angular warnings

* feat: add hmr support for angular 12

* feat: custom hmr dispose logic for angular 12

* chore: dev.3

* chore: ignore warnings

* chore: dev.4

* chore: ignore ivy compiled warnings

* chore: dev.5

Co-authored-by: Eduardo Speroni <edusperoni@gmail.com>
This commit is contained in:
Nathan Walker
2021-06-08 11:35:21 -07:00
committed by GitHub
parent dea18978d5
commit 93843b7b4e
5 changed files with 215 additions and 38 deletions

View File

@@ -21,7 +21,13 @@ exports[`angular configuration for android 1`] = `
ignoreWarnings: [
/System.import\\\\(\\\\) is deprecated/,
/Zone\\\\.js does not support native async\\\\/await/,
/environment(\\\\.(\\\\w+))?\\\\.ts is part of the TypeScript compilation but it's unused/
/environment(\\\\.(\\\\w+))?\\\\.ts is part of the TypeScript compilation but it's unused/,
{
module: /@angular\\\\/core\\\\/(__ivy_ngcc__\\\\/)?fesm2015\\\\/core.js/,
message: /Critical dependency: the request of a dependency is an expression/
},
/core\\\\/profiling/,
/core\\\\/ui\\\\/styling/
],
output: {
path: '__jest__/platforms/android/app/src/main/assets/app',
@@ -388,7 +394,13 @@ exports[`angular configuration for ios 1`] = `
ignoreWarnings: [
/System.import\\\\(\\\\) is deprecated/,
/Zone\\\\.js does not support native async\\\\/await/,
/environment(\\\\.(\\\\w+))?\\\\.ts is part of the TypeScript compilation but it's unused/
/environment(\\\\.(\\\\w+))?\\\\.ts is part of the TypeScript compilation but it's unused/,
{
module: /@angular\\\\/core\\\\/(__ivy_ngcc__\\\\/)?fesm2015\\\\/core.js/,
message: /Critical dependency: the request of a dependency is an expression/
},
/core\\\\/profiling/,
/core\\\\/ui\\\\/styling/
],
output: {
path: '__jest__/platforms/ios/jest/app',

View File

@@ -1,6 +1,6 @@
{
"name": "@nativescript/webpack",
"version": "5.0.0-beta.13",
"version": "5.0.0-dev.5",
"private": false,
"main": "dist/index.js",
"files": [
@@ -14,44 +14,44 @@
"build": "tsc --project tsconfig.build.json",
"test": "jest",
"copy-stubs": "mkdirp dist/stubs && cp -R src/stubs/* dist/stubs",
"prepack": "npm test && npm run build && npm run copy-stubs && chmod +x dist/bin/index.js"
"prepack": "npm run test && npm run build && npm run copy-stubs && chmod +x dist/bin/index.js"
},
"dependencies": {
"@babel/core": "7.14.3",
"@pmmmwh/react-refresh-webpack-plugin": "0.4.3",
"acorn": "^8.3.0",
"@babel/core": "^7.0.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.0",
"acorn": "^8.0.0",
"acorn-stage3": "^4.0.0",
"babel-loader": "8.2.2",
"chalk": "4.1.1",
"cli-highlight": "2.1.11",
"commander": "7.2.0",
"copy-webpack-plugin": "9.0.0",
"css": "3.0.0",
"css-loader": "5.2.6",
"dotenv-webpack": "7.0.2",
"fork-ts-checker-webpack-plugin": "6.2.10",
"loader-utils": "2.0.0",
"lodash.get": "4.4.2",
"micromatch": "4.0.4",
"postcss": "8.3.0",
"postcss-import": "14.0.2",
"postcss-loader": "5.3.0",
"raw-loader": "4.0.2",
"react-refresh": "0.10.0",
"sass": "1.34.0",
"sass-loader": "12.0.0",
"sax": "1.2.4",
"source-map": "0.7.3",
"terser-webpack-plugin": "5.1.3",
"ts-dedent": "2.1.1",
"ts-loader": "9.2.2",
"vue-loader": "15.9.7",
"webpack": "^5.0.0",
"webpack-bundle-analyzer": "4.4.2",
"webpack-chain": "6.5.1",
"webpack-cli": "^4.7.0",
"webpack-merge": "5.7.3",
"webpack-virtual-modules": "0.4.3"
"babel-loader": "^8.0.0",
"chalk": "^4.0.0",
"cli-highlight": "^2.0.0",
"commander": "^7.0.0",
"copy-webpack-plugin": "^9.0.0",
"css": "^3.0.0",
"css-loader": "^5.0.0",
"dotenv-webpack": "^7.0.0",
"fork-ts-checker-webpack-plugin": "^6.0.0",
"loader-utils": "^2.0.0",
"lodash.get": "^4.0.0",
"micromatch": "^4.0.0",
"postcss": "^8.0.0",
"postcss-import": "^14.0.0",
"postcss-loader": "^5.0.0",
"raw-loader": "^4.0.0",
"react-refresh": "^0.10.0",
"sass": "^1.0.0",
"sass-loader": "^12.0.0",
"sax": "^1.0.0",
"source-map": "^0.7.0",
"terser-webpack-plugin": "^5.0.0",
"ts-dedent": "^2.0.0",
"ts-loader": "^9.0.0",
"vue-loader": "^15.0.0",
"webpack": "^5.34.0",
"webpack-bundle-analyzer": "^4.0.0",
"webpack-chain": "^6.0.0",
"webpack-cli": "^4.0.0",
"webpack-merge": "^5.0.0",
"webpack-virtual-modules": "^0.4.0"
},
"devDependencies": {
"@types/css": "0.0.31",

View File

@@ -146,6 +146,15 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
tsconfig: tsConfigPath,
},
]);
config.when(env.hmr, (config) => {
config.module
.rule('angular-hmr')
.enforce('post')
.test(getEntryPath())
.use('angular-hmr-loader')
.loader('angular-hmr-loader');
});
}
// look for platform specific polyfills first
@@ -192,6 +201,15 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
* +-----------------------------------------------------------------------------------------+
*/
/environment(\.(\w+))?\.ts is part of the TypeScript compilation but it's unused/,
/**
* This rule hides
*/
{
module: /@angular\/core\/(__ivy_ngcc__\/)?fesm2015\/core.js/,
message: /Critical dependency: the request of a dependency is an expression/,
},
/core\/profiling/,
/core\/ui\/styling/,
])
);

View File

@@ -0,0 +1,117 @@
import {
isDevMode,
ɵresetCompiledComponents,
// @ts-ignore
} from '@angular/core';
declare const __webpack_require__: any;
declare const ng: any;
export default function (mod: any): void {
if (!mod['hot']) {
return;
}
if (!isDevMode()) {
console.error(
`[NG HMR] Cannot use HMR when Angular is running in production mode. To prevent production mode, do not call 'enableProdMode()'.`
);
return;
}
mod['hot'].accept();
mod['hot'].dispose(() => {
if (typeof ng === 'undefined') {
console.warn(
`[NG HMR] Cannot find global 'ng'. Likely this is caused because scripts optimization is enabled.`
);
return;
}
if (!ng.getInjector) {
// View Engine
return;
}
// Reset JIT compiled components cache
ɵresetCompiledComponents();
try {
if (global['__cleanup_ng_hot__']) global['__cleanup_ng_hot__']();
} catch (e) {
console.error('[NG HMR] Error disposing previous module');
console.error(e, e?.stack);
// HMR breaks when rejecting the main module dispose, so we manually trigger an HMR restart
const hash = __webpack_require__.h();
console.log(`[HMR][${hash}] failure | Error disposing previous module`);
throw e;
}
});
}
// TODO: maybe restore form values!
// function restoreFormValues(oldInputs: any[], oldOptions: any[]): void {
// // Restore input that are not hidden
// const newInputs = document.querySelectorAll('input:not([type="hidden"]), textarea');
// if (newInputs.length && newInputs.length === oldInputs.length) {
// console.log('[NG HMR] Restoring input/textarea values.');
// for (let index = 0; index < newInputs.length; index++) {
// const newElement = newInputs[index];
// const oldElement = oldInputs[index];
// switch (oldElement.type) {
// case 'button':
// case 'image':
// case 'submit':
// case 'reset':
// // These types don't need any value change.
// continue;
// case 'radio':
// case 'checkbox':
// newElement.checked = oldElement.checked;
// break;
// case 'color':
// case 'date':
// case 'datetime-local':
// case 'email':
// case 'file':
// case 'hidden':
// case 'month':
// case 'number':
// case 'password':
// case 'range':
// case 'search':
// case 'tel':
// case 'text':
// case 'textarea':
// case 'time':
// case 'url':
// case 'week':
// newElement.value = oldElement.value;
// break;
// default:
// console.warn('[NG HMR] Unknown input type ' + oldElement.type + '.');
// continue;
// }
// dispatchEvents(newElement);
// }
// } else if (oldInputs.length) {
// console.warn('[NG HMR] Cannot restore input/textarea values.');
// }
// // Restore option
// const newOptions = document.querySelectorAll('option');
// if (newOptions.length && newOptions.length === oldOptions.length) {
// console.log('[NG HMR] Restoring selected options.');
// for (let index = 0; index < newOptions.length; index++) {
// const newElement = newOptions[index];
// newElement.selected = oldOptions[index].selected;
// dispatchEvents(newElement);
// }
// } else if (oldOptions.length) {
// console.warn('[NG HMR] Cannot restore selected options.');
// }
// }

View File

@@ -0,0 +1,30 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { join } from 'path';
export const HmrLoader = __filename;
const hmrAcceptPath = join(__dirname, './hmr-accept.js').replace(/\\/g, '/');
export default function (
this: any,
content: string,
// Source map types are broken in the webpack type definitions
map: any
): void {
const source = `${content}
// HMR Accept Code
import ngHmrAccept from '${hmrAcceptPath}';
ngHmrAccept(module);
`;
this.callback(null, source, map);
return;
}