mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
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:
@@ -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',
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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/,
|
||||
])
|
||||
);
|
||||
|
||||
|
||||
117
packages/webpack5/src/loaders/angular-hmr-loader/hmr-accept.ts
Normal file
117
packages/webpack5/src/loaders/angular-hmr-loader/hmr-accept.ts
Normal 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.');
|
||||
// }
|
||||
// }
|
||||
30
packages/webpack5/src/loaders/angular-hmr-loader/index.ts
Normal file
30
packages/webpack5/src/loaders/angular-hmr-loader/index.ts
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user