@blotch/rsbuild-plugin-angular-lynx 22.2.1 → 22.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -3
- package/dist/544.js +21 -0
- package/dist/angular-cli-context.d.ts +34 -0
- package/dist/angular-diagnostics.d.ts +58 -0
- package/dist/angular-diagnostics.test.d.ts +1 -0
- package/dist/angular-rebuild-coordinator.d.ts +1 -1
- package/dist/angular.d.ts +5 -3
- package/dist/background-entry.d.ts +96 -0
- package/dist/background-entry.test.d.ts +1 -0
- package/dist/budgets-plugin.d.ts +64 -0
- package/dist/budgets-plugin.test.d.ts +1 -0
- package/dist/client/background-hot-updates.d.ts +50 -0
- package/dist/client/background-hot-updates.js +77 -0
- package/dist/client/background-hot-updates.test.d.ts +1 -0
- package/dist/client/css-hot-update.cjs +9 -0
- package/dist/client/css-hot-update.d.ts +44 -0
- package/dist/client/css-hot-update.js +42 -0
- package/dist/client/css-hot-update.test.d.ts +1 -0
- package/dist/client/hmr-background.js +16 -0
- package/dist/client/hmr-main-thread.js +9 -0
- package/dist/client/hmr-protocol.d.ts +74 -0
- package/dist/client/main-thread-hot-updates.d.ts +40 -0
- package/dist/client/main-thread-hot-updates.js +78 -0
- package/dist/client/main-thread-hot-updates.test.d.ts +1 -0
- package/dist/client/testing/test-context.d.ts +16 -0
- package/dist/component-styles-cache.d.ts +13 -31
- package/dist/component-styles.d.ts +73 -0
- package/dist/component-styles.test.d.ts +1 -0
- package/dist/cross-thread-transform.d.ts +38 -0
- package/dist/cross-thread-transform.test.d.ts +1 -0
- package/dist/css.d.ts +2 -2
- package/dist/entry.d.ts +28 -2
- package/dist/hot-updates.d.ts +67 -0
- package/dist/hot-updates.test.d.ts +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1494 -638
- package/dist/layers.d.ts +6 -4
- package/dist/logger/dev-logger-middleware.d.ts +13 -7
- package/dist/logger/dev-logger.d.ts +13 -0
- package/dist/polyfills.js +56 -0
- package/dist/polyfills.test.d.ts +1 -0
- package/dist/pure-classes.d.ts +27 -0
- package/dist/pure-classes.test.d.ts +1 -0
- package/dist/resolve.d.ts +19 -0
- package/dist/resolve.test.d.ts +1 -0
- package/dist/split-chunks.d.ts +2 -2
- package/dist/styles/blur-view.css +16 -0
- package/dist/transform-module.d.ts +43 -17
- package/dist/utils/angular/budgets.d.ts +72 -0
- package/dist/utils/angular/budgets.test.d.ts +1 -0
- package/dist/utils/angular/build-internals.d.ts +14 -0
- package/dist/utils/angular/component-scope-id.d.ts +5 -3
- package/dist/utils/angular/component-style-bundler.d.ts +1 -1
- package/dist/utils/angular/options.d.ts +80 -2
- package/dist/utils/angular/read-workspace.d.ts +5 -1
- package/dist/utils/angular/resolve-primary-build.d.ts +26 -0
- package/dist/utils/angular/resolve-primary-build.test.d.ts +1 -0
- package/dist/utils/options.d.ts +40 -1
- package/package.json +13 -8
- package/dist/loaders/thread-globals-loader.d.ts +0 -8
- package/dist/loaders/thread-globals-loader.js +0 -6
- package/patch/patch-angular-build.cjs +0 -27
- /package/dist/{loaders/thread-globals-loader.test.d.ts → angular-cli-context.test.d.ts} +0 -0
package/dist/layers.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { RsbuildPluginAPI } from '@lynx-js/rspeedy';
|
|
2
2
|
/**
|
|
3
|
-
* Webpack layer names for the dual-thread build. Each entry is
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* Webpack layer names for the dual-thread build. Each entry is split into two
|
|
4
|
+
* webpack entries with different layers (entry.ts), and every module an entry
|
|
5
|
+
* reaches stays in its layer. The layer determines which SWC target (ES2015 vs
|
|
6
|
+
* ES2019), which `__MAIN_THREAD__` value and which thread-specific
|
|
7
|
+
* configuration (CSS extraction vs ignore, AMD wrapping vs plain) applies to
|
|
8
|
+
* the module.
|
|
7
9
|
*/
|
|
8
10
|
export declare const LAYERS: {
|
|
9
11
|
BACKGROUND: string;
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
export declare const formatArg: (arg: unknown) => string;
|
|
3
|
-
export declare const getLogFilePath: () => string;
|
|
4
2
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* Connect-style middleware that receives log batches from on-device and
|
|
4
|
+
* writes them to a log file. Rspeedy's TUI uses the alternate screen buffer,
|
|
5
|
+
* so stdout writes are hidden — a file + `tail -f` is more reliable.
|
|
7
6
|
*/
|
|
7
|
+
/** The dev server path the app posts its log entries to. */
|
|
8
|
+
export declare const DEV_LOGS_PATH = "/__dev_logs";
|
|
9
|
+
export declare const formatArg: (arg: unknown) => string;
|
|
8
10
|
/**
|
|
9
|
-
* Creates a connect-style middleware that handles POST /__dev_logs
|
|
10
|
-
* Other requests are passed through to the next
|
|
11
|
+
* Creates a connect-style middleware that handles POST /__dev_logs and writes
|
|
12
|
+
* the entries to `logFilePath`. Other requests are passed through to the next
|
|
13
|
+
* middleware.
|
|
14
|
+
*
|
|
15
|
+
* The file is created, or emptied, right away: each dev server start begins a
|
|
16
|
+
* fresh log, and `tail -f` can follow it before the first entry arrives.
|
|
11
17
|
*/
|
|
12
|
-
export declare const createDevLoggerMiddleware: () => ((req: IncomingMessage, res: ServerResponse, next: () => void) => void);
|
|
18
|
+
export declare const createDevLoggerMiddleware: (logFilePath: string) => ((req: IncomingMessage, res: ServerResponse, next: () => void) => void);
|
|
@@ -1,2 +1,15 @@
|
|
|
1
1
|
import type { RsbuildPluginAPI } from '@lynx-js/rspeedy';
|
|
2
|
+
/**
|
|
3
|
+
* Receives `LynxLogger` entries from the app on the dev server itself, and
|
|
4
|
+
* writes them to `.dev-logs`. Also injects __DEV_LOG_URL__ at compile time so
|
|
5
|
+
* the runtime knows where to POST logs (rspack's __webpack_public_path__ isn't
|
|
6
|
+
* accessible as a globalThis property in Lynx's JS environment).
|
|
7
|
+
*
|
|
8
|
+
* The endpoint is a middleware on the dev server, at the origin the app loads
|
|
9
|
+
* its bundle from, rather than a server of its own on a port next to it. The
|
|
10
|
+
* phone can already reach that origin, and its port is the one rspeedy
|
|
11
|
+
* resolved: a second server had to guess its port when the bundle was
|
|
12
|
+
* compiled, and when that port was taken it moved to another one while the
|
|
13
|
+
* app kept posting to the first, so the logs were lost.
|
|
14
|
+
*/
|
|
2
15
|
export declare const applyDevLogger: (api: RsbuildPluginAPI) => void;
|
package/dist/polyfills.js
CHANGED
|
@@ -40,6 +40,62 @@ if ("u" < typeof AbortController) {
|
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
if ('function' != typeof Object.hasOwn) Object.hasOwn = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
43
|
+
const definePolyfillOverride = (proto, name, value)=>{
|
|
44
|
+
Object.defineProperty(proto, name, {
|
|
45
|
+
value,
|
|
46
|
+
writable: true,
|
|
47
|
+
configurable: true,
|
|
48
|
+
enumerable: false
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
const definePolyfill = (proto, name, value)=>{
|
|
52
|
+
if (proto && 'function' != typeof proto[name]) definePolyfillOverride(proto, name, value);
|
|
53
|
+
};
|
|
54
|
+
const relativeIndex = function(index) {
|
|
55
|
+
const length = this.length;
|
|
56
|
+
let n = Math.trunc(Number(index)) || 0;
|
|
57
|
+
if (n < 0) n += length;
|
|
58
|
+
if (n < 0 || n >= length) return;
|
|
59
|
+
return 'string' == typeof this ? this.charAt(n) : this[n];
|
|
60
|
+
};
|
|
61
|
+
definePolyfill(Array.prototype, 'at', relativeIndex);
|
|
62
|
+
definePolyfill(String.prototype, 'at', function(index) {
|
|
63
|
+
return relativeIndex.call(String(this), index);
|
|
64
|
+
});
|
|
65
|
+
if ('function' == typeof Int8Array) definePolyfill(Object.getPrototypeOf(Int8Array.prototype), 'at', relativeIndex);
|
|
66
|
+
definePolyfill(Array.prototype, 'findLastIndex', function(predicate, thisArg) {
|
|
67
|
+
for(let i = this.length - 1; i >= 0; i--)if (predicate.call(thisArg, this[i], i, this)) return i;
|
|
68
|
+
return -1;
|
|
69
|
+
});
|
|
70
|
+
definePolyfill(Array.prototype, 'findLast', function(predicate, thisArg) {
|
|
71
|
+
for(let i = this.length - 1; i >= 0; i--)if (predicate.call(thisArg, this[i], i, this)) return this[i];
|
|
72
|
+
});
|
|
73
|
+
definePolyfill(String.prototype, 'replaceAll', function(search, replacement) {
|
|
74
|
+
const subject = String(this);
|
|
75
|
+
if (search instanceof RegExp) {
|
|
76
|
+
if (!search.global) throw new TypeError('replaceAll must be called with a global RegExp');
|
|
77
|
+
return subject.replace(search, replacement);
|
|
78
|
+
}
|
|
79
|
+
const needle = String(search);
|
|
80
|
+
const pattern = new RegExp(needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g');
|
|
81
|
+
return subject.replace(pattern, replacement);
|
|
82
|
+
});
|
|
83
|
+
if ("u" < typeof Intl) definePolyfillOverride(Number.prototype, 'toLocaleString', function(_locales, options) {
|
|
84
|
+
const value = Number(this);
|
|
85
|
+
if (Number.isNaN(value)) return 'NaN';
|
|
86
|
+
if (!Number.isFinite(value)) return value > 0 ? '∞' : '-∞';
|
|
87
|
+
const opts = options || {};
|
|
88
|
+
const min = opts.minimumFractionDigits ?? 0;
|
|
89
|
+
const max = Math.max(min, opts.maximumFractionDigits ?? Math.max(min, 3));
|
|
90
|
+
const fixed = Math.abs(value).toFixed(max);
|
|
91
|
+
const dot = fixed.indexOf('.');
|
|
92
|
+
let integer = dot < 0 ? fixed : fixed.slice(0, dot);
|
|
93
|
+
let fraction = dot < 0 ? '' : fixed.slice(dot + 1).replace(/0+$/, '');
|
|
94
|
+
while(fraction.length < min)fraction += '0';
|
|
95
|
+
if (false !== opts.useGrouping) integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
96
|
+
const sign = value < 0 && 0 !== Number(fixed) ? '-' : '';
|
|
97
|
+
return sign + integer + (fraction ? `.${fraction}` : '');
|
|
98
|
+
});
|
|
43
99
|
if ('function' != typeof Promise.allSettled) Promise.allSettled = (promises)=>Promise.all(Array.from(promises, (p)=>Promise.resolve(p).then((value)=>({
|
|
44
100
|
status: 'fulfilled',
|
|
45
101
|
value
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps each top-level class with private or static members in a pure IIFE,
|
|
3
|
+
* so a bundler can drop the classes nothing uses.
|
|
4
|
+
*
|
|
5
|
+
* The background layer compiles to ES2015 (layers.ts), so SWC lowers private
|
|
6
|
+
* and static class fields. A class declaration keeps its own statement, but the
|
|
7
|
+
* class expressions that bundled libraries are written in (`var X = class
|
|
8
|
+
* {…}`) become a sequence that assigns each private field's `WeakMap` to an
|
|
9
|
+
* outer variable: `var X = (_a = new WeakMap(), class {…})`. The assignment
|
|
10
|
+
* counts as a side effect, so rspack keeps every such class, and every import
|
|
11
|
+
* it uses, even when nothing uses the class. The runtime's own classes are
|
|
12
|
+
* like that (it uses `#private` fields throughout), which kept Angular's
|
|
13
|
+
* renderer and change detection in the background bundle.
|
|
14
|
+
*
|
|
15
|
+
* Angular's build already wraps a class whose static members are Angular's
|
|
16
|
+
* own (`ɵcmp`, `ɵfac` and so on) in `/*#__PURE__*\/ (() => {…})()`; this does
|
|
17
|
+
* the same for the rest. Inside the IIFE, the lowering's assignments are local
|
|
18
|
+
* and the call is marked pure. A class whose static members could have side
|
|
19
|
+
* effects of their own (anything but literals, functions and new collections)
|
|
20
|
+
* is left alone.
|
|
21
|
+
*
|
|
22
|
+
* @param code - The module's code, before SWC lowers it (and, for a `.ts`
|
|
23
|
+
* file, strips its types).
|
|
24
|
+
* @param filename - The module's path, for the parser.
|
|
25
|
+
* @returns The transformed code, or `code` itself when nothing applies.
|
|
26
|
+
*/
|
|
27
|
+
export declare const wrapPureClasses: (code: string, filename: string) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { RsbuildPluginAPI } from '@lynx-js/rspeedy';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves `import`s to a package's ES module build.
|
|
4
|
+
*
|
|
5
|
+
* The Lynx build engine resolves every request with the conditions `lynx`,
|
|
6
|
+
* `import`, `require` and `browser`, whether it comes from an `import` or a
|
|
7
|
+
* `require()`. A package whose `exports` list `require` before any of the
|
|
8
|
+
* others then resolves to its CommonJS build even from an `import`. rxjs is
|
|
9
|
+
* one (`types`, `node`, `require`, `es2015`, `default`), and Angular and the
|
|
10
|
+
* runtime import it everywhere. CommonJS can't be tree-shaken, so every app
|
|
11
|
+
* carried all of rxjs on both threads, about 130 kB of each bundle, when the
|
|
12
|
+
* background thread uses `Subject` alone.
|
|
13
|
+
*
|
|
14
|
+
* So `import`s get the engine's conditions without `require`, and with
|
|
15
|
+
* `module` after `import`, as webpack's defaults have them (tslib's ES module
|
|
16
|
+
* build is behind `module`). A `require()` still resolves with all of the
|
|
17
|
+
* engine's conditions.
|
|
18
|
+
*/
|
|
19
|
+
export declare const applyResolve: (api: RsbuildPluginAPI) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/split-chunks.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { RsbuildPluginAPI } from '@lynx-js/rspeedy';
|
|
2
|
-
import type {
|
|
3
|
-
export declare const applySplitChunksRule: (api: RsbuildPluginAPI, options:
|
|
2
|
+
import type { NormalizedPluginAngularLynxOptions } from './utils/options.js';
|
|
3
|
+
export declare const applySplitChunksRule: (api: RsbuildPluginAPI, options: NormalizedPluginAngularLynxOptions) => void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The look of iOS's blur-view materials on Android, where Lynx's blur-view
|
|
3
|
+
* only blurs. On Android the runtime sets these variables inline on every
|
|
4
|
+
* blur-view (see android-blur-material.ts in @blotch/angular-lynx); iOS leaves
|
|
5
|
+
* them unset, so the fallbacks apply there and change nothing.
|
|
6
|
+
*
|
|
7
|
+
* The type selector is what lets the app restyle a blur-view: it loses to any
|
|
8
|
+
* class, id or inline style, so `bg-white/30` or `shadow-none` still wins.
|
|
9
|
+
* The build adds this file to the native bundle first, so an app's own
|
|
10
|
+
* `blur-view` rule comes later and wins too. Web draws its materials itself.
|
|
11
|
+
*/
|
|
12
|
+
blur-view {
|
|
13
|
+
background-color: var(--angular-lynx-blur-background, transparent);
|
|
14
|
+
background-image: var(--angular-lynx-blur-background-image, none);
|
|
15
|
+
box-shadow: var(--angular-lynx-blur-box-shadow, none);
|
|
16
|
+
}
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The stylesheets extracted from one module's components (see
|
|
3
|
+
* component-styles.ts), written as CSS files.
|
|
4
|
+
*/
|
|
5
|
+
export type ModuleStylesheets = {
|
|
6
|
+
/** The CSS files, in the order the module's components declare them. */
|
|
7
|
+
imports: string[];
|
|
8
|
+
/** Each Emulated component's class name and the scope ID its CSS uses. */
|
|
9
|
+
scopes: Array<{
|
|
10
|
+
className: string;
|
|
11
|
+
scopeId: string;
|
|
12
|
+
}>;
|
|
13
|
+
};
|
|
2
14
|
/**
|
|
3
15
|
* Transforms the Angular-compiled JS for a single component module before rspack
|
|
4
16
|
* bundles it. This is the per-module half of the AngularLynx pipeline, extracted
|
|
@@ -6,26 +18,40 @@ import type { ComponentScopeInfo, ComponentStylesEntry } from './component-style
|
|
|
6
18
|
* string→string function (no rspack loader context, no compilation cache).
|
|
7
19
|
*
|
|
8
20
|
* It applies, in order:
|
|
9
|
-
* 1. Prepends `import "<
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
21
|
+
* 1. Prepends `import "<component.css>"` statements for the stylesheets
|
|
22
|
+
* extracted from the module's components (resolved relative to the
|
|
23
|
+
* component file).
|
|
24
|
+
* 2. Appends a `Component.ɵcmp.id = '<scopeId>'` assignment for each
|
|
25
|
+
* Emulated component, which ties its scoped CSS to its renderer.
|
|
13
26
|
* 3. Runs the worklet ("main thread" directive) transform over the result.
|
|
27
|
+
* 4. Runs the cross-thread transform (cross-thread-transform.ts), which gives
|
|
28
|
+
* module-level background functions and refs IDs that match on both
|
|
29
|
+
* threads.
|
|
30
|
+
* 5. In a development build with hot updates (`hot` is set), makes the
|
|
31
|
+
* module take them (hot-updates.ts): an entry module re-bootstraps the
|
|
32
|
+
* app, and a module that defines components updates them in place when
|
|
33
|
+
* only their templates or styles changed. Other modules pass their
|
|
34
|
+
* updates on to the modules that import them.
|
|
14
35
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* and re-bootstrap its own copy of the app, so HMR reported success and the
|
|
21
|
-
* main thread kept rendering the old code until a manual reload. With no
|
|
22
|
-
* module accepting, the update aborts and the Lynx HMR client
|
|
23
|
-
* (`@lynx-js/webpack-dev-transport`) falls back to a full `Page.reload`, which
|
|
24
|
-
* re-runs both threads with the new bundle.
|
|
36
|
+
* The hot update clients apply each update on both threads (see client/).
|
|
37
|
+
* Before they did, only the background thread took hot updates, so a
|
|
38
|
+
* self-accepting entry (which an earlier version had) re-bootstrapped the
|
|
39
|
+
* background thread's copy of the app while the main thread, which draws the
|
|
40
|
+
* screen, kept running the old code.
|
|
25
41
|
*/
|
|
26
42
|
export declare const buildTransformedCode: (params: {
|
|
27
43
|
code: string;
|
|
28
44
|
resourcePath: string;
|
|
29
|
-
|
|
30
|
-
|
|
45
|
+
stylesheets: ModuleStylesheets | undefined;
|
|
46
|
+
/** The project root, which cross-thread IDs are relative to. */
|
|
47
|
+
root: string;
|
|
48
|
+
/**
|
|
49
|
+
* Set in a development build with hot updates. `entry` says whether the
|
|
50
|
+
* module is one of the app's entries, and `source` reads its TypeScript
|
|
51
|
+
* source.
|
|
52
|
+
*/
|
|
53
|
+
hot?: {
|
|
54
|
+
entry: boolean;
|
|
55
|
+
source: () => string;
|
|
56
|
+
};
|
|
31
57
|
}) => string;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { Budget } from './options.js';
|
|
2
|
+
/**
|
|
3
|
+
* Checks angular.json `budgets` against a Lynx build's output.
|
|
4
|
+
*
|
|
5
|
+
* The size parsing, the thresholds and the messages are ported from
|
|
6
|
+
* `@angular/build`'s bundle calculator (`src/utils/bundle-calculator.js` and
|
|
7
|
+
* `src/utils/format-bytes.js`), so a Lynx app reports budgets exactly as
|
|
8
|
+
* `ng build` does for a web app: the same units (1 kB = 1000 bytes), the
|
|
9
|
+
* same baseline arithmetic and the same wording. It's copied because those
|
|
10
|
+
* modules are internal to `@angular/build`, not in its package `exports`.
|
|
11
|
+
*
|
|
12
|
+
* What each budget type measures differs from the web, because a Lynx app
|
|
13
|
+
* ships as `.bundle` files rather than separate scripts and stylesheets:
|
|
14
|
+
*
|
|
15
|
+
* - `initial`: each entry's bundle, on its own. A Lynx page loads one bundle,
|
|
16
|
+
* so a multi-page app's pages are checked separately rather than summed.
|
|
17
|
+
* - `bundle`: the bundle of the entry named by the budget's `name`.
|
|
18
|
+
* - `all` / `any`: every bundle and script the `lynx` environment emits,
|
|
19
|
+
* together / each. Media and fonts aren't counted, as on the web.
|
|
20
|
+
* - `allScript` / `anyScript`: the same files as `all` / `any`. A Lynx
|
|
21
|
+
* bundle carries the app's scripts (and its styles, encoded together), so
|
|
22
|
+
* there is no script-only file to measure.
|
|
23
|
+
* - `anyComponentStyle`: each component stylesheet, compiled.
|
|
24
|
+
*/
|
|
25
|
+
/** Angular's unit for `kB`, `MB` and `GB`: decimal, not 1024. */
|
|
26
|
+
export declare const BYTES_IN_KILOBYTE = 1000;
|
|
27
|
+
export type BudgetSeverity = 'warning' | 'error';
|
|
28
|
+
export type BudgetThreshold = {
|
|
29
|
+
readonly limit: number;
|
|
30
|
+
readonly type: 'maximum' | 'minimum';
|
|
31
|
+
readonly severity: BudgetSeverity;
|
|
32
|
+
};
|
|
33
|
+
export type BudgetFailure = {
|
|
34
|
+
readonly severity: BudgetSeverity;
|
|
35
|
+
readonly label: string;
|
|
36
|
+
readonly message: string;
|
|
37
|
+
};
|
|
38
|
+
/** A file the `lynx` environment emits that budgets count. */
|
|
39
|
+
export type BudgetAsset = {
|
|
40
|
+
readonly name: string;
|
|
41
|
+
readonly size: number;
|
|
42
|
+
/** Set for an entry's own bundle: the entry (page) it was built from. */
|
|
43
|
+
readonly entryName?: string;
|
|
44
|
+
};
|
|
45
|
+
/** The compiled size of one component stylesheet. */
|
|
46
|
+
export type ComponentStyleSize = {
|
|
47
|
+
/** The stylesheet, or for inline styles the component, relative to the workspace. */
|
|
48
|
+
readonly label: string;
|
|
49
|
+
readonly size: number;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Parses a budget size (`'500kB'`, `'1.5mb'`, `'2048'`, `'10%'`) into bytes.
|
|
53
|
+
* A percentage is of `baseline`; with a baseline, the result is the baseline
|
|
54
|
+
* moved by the value, up (`factor` 1) or down (`factor` -1). Input it
|
|
55
|
+
* can't parse gives NaN, which no size crosses, as in Angular.
|
|
56
|
+
*/
|
|
57
|
+
export declare const calculateBytes: (input: string, baseline?: string, factor?: 1 | -1) => number;
|
|
58
|
+
/**
|
|
59
|
+
* The limits a budget sets, in the order Angular checks them. `warning` and
|
|
60
|
+
* `error` are relative to the baseline in both directions, so each gives a
|
|
61
|
+
* minimum and a maximum.
|
|
62
|
+
*/
|
|
63
|
+
export declare const calculateThresholds: (budget: Budget) => BudgetThreshold[];
|
|
64
|
+
/** Formats a byte count the way `ng build`'s budget messages do: `1.23 kB`. */
|
|
65
|
+
export declare const formatSize: (size: number) => string;
|
|
66
|
+
/** The failures of one measured size against a budget's thresholds. */
|
|
67
|
+
export declare const checkThresholds: (thresholds: readonly BudgetThreshold[], size: number, label: string) => BudgetFailure[];
|
|
68
|
+
/** Checks every budget against a build's output. */
|
|
69
|
+
export declare const checkBudgets: (budgets: readonly Budget[], output: {
|
|
70
|
+
readonly assets: readonly BudgetAsset[];
|
|
71
|
+
readonly componentStyles: readonly ComponentStyleSize[];
|
|
72
|
+
}) => BudgetFailure[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type * as AngularCompilationModule from '@angular/build/src/tools/angular/compilation';
|
|
2
|
+
import type * as ComponentStylesheetsModule from '@angular/build/src/tools/esbuild/angular/component-stylesheets';
|
|
3
|
+
import type * as JavaScriptTransformerModule from '@angular/build/src/tools/javascript-transformer';
|
|
4
|
+
/** Absolute path of the installed `@angular/build` package root. */
|
|
5
|
+
export declare const angularBuildRoot: string;
|
|
6
|
+
/**
|
|
7
|
+
* Loads a module from inside `@angular/build` by its path relative to the
|
|
8
|
+
* package root, bypassing the `exports` map.
|
|
9
|
+
*/
|
|
10
|
+
export declare const loadAngularBuildInternal: <T>(subpath: string) => T;
|
|
11
|
+
export declare const createAngularCompilation: typeof AngularCompilationModule.createAngularCompilation, DiagnosticModes: typeof AngularCompilationModule.DiagnosticModes;
|
|
12
|
+
export declare const JavaScriptTransformer: typeof JavaScriptTransformerModule.JavaScriptTransformer;
|
|
13
|
+
export declare const ComponentStylesheetBundler: typeof ComponentStylesheetsModule.ComponentStylesheetBundler;
|
|
14
|
+
export type ComponentStylesheetBundler = ComponentStylesheetsModule.ComponentStylesheetBundler;
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
* (for "Lynx") differentiates these from Angular's default 'ng' prefix IDs,
|
|
6
6
|
* preventing collisions if browser-Angular scope IDs leak into shared code.
|
|
7
7
|
* This ID appears in:
|
|
8
|
-
* - CSS
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
8
|
+
* - the component's compiled CSS: `.title._ngcontent-l<hash>`,
|
|
9
|
+
* `._nghost-l<hash>` (see component-styles.ts)
|
|
10
|
+
* - ɵcmp.id: set by the loader (see transform-module.ts)
|
|
11
|
+
* - the `_ngcontent-l<hash>` and `_nghost-l<hash>` classes that
|
|
12
|
+
* EmulatedLynxRenderer adds to the component's elements
|
|
11
13
|
*/
|
|
12
14
|
export declare const generateComponentScopeId: (className: string, containingFile: string) => string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentStylesheetBundler } from '
|
|
1
|
+
import { ComponentStylesheetBundler } from './build-internals.js';
|
|
2
2
|
import type { NormalizedOptions } from './options.js';
|
|
3
3
|
/**
|
|
4
4
|
* Creates an Angular `ComponentStylesheetBundler` configured for the current workspace.
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { OutputHashing } from '@angular-devkit/build-angular';
|
|
2
1
|
import type { workspaces } from '@angular-devkit/core';
|
|
3
2
|
import type { TargetDefinition } from '@angular-devkit/core/src/workspace/definitions';
|
|
4
3
|
import { type NormalizedCachedOptions } from './normalize-cache.js';
|
|
@@ -40,6 +39,53 @@ export type NormalizedI18nOptions = {
|
|
|
40
39
|
sourceLocale: string;
|
|
41
40
|
hasDefinedSourceLocale: boolean;
|
|
42
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* The values of angular.json's `outputHashing` build option: which emitted
|
|
44
|
+
* file names get a content hash.
|
|
45
|
+
*
|
|
46
|
+
* Copied from the `OutputHashing` enum that Angular's builder schemas
|
|
47
|
+
* generate, as a string union because angular.json holds plain strings.
|
|
48
|
+
* Keep it in step with them when Angular adds a value.
|
|
49
|
+
*
|
|
50
|
+
* It used to be imported from `@angular-devkit/build-angular`, which made
|
|
51
|
+
* that package a peer dependency of this plugin. That package is Angular's
|
|
52
|
+
* legacy webpack-based builder: apps from a current `ng new` don't have it,
|
|
53
|
+
* and npm installs missing peer dependencies, so every AngularLynx app got it
|
|
54
|
+
* and its webpack toolchain (about 300 packages) for this one type.
|
|
55
|
+
*
|
|
56
|
+
* @see `OutputHashing` in `@angular/build/src/builders/application/schema.d.ts`
|
|
57
|
+
* @see `OutputHashing` in `@angular-devkit/build-angular/src/builders/browser/schema.d.ts`
|
|
58
|
+
*/
|
|
59
|
+
export type OutputHashing = 'all' | 'bundles' | 'media' | 'none';
|
|
60
|
+
/**
|
|
61
|
+
* One entry of angular.json's `budgets` build option: a size limit on part
|
|
62
|
+
* of the build output, which `ng build` reports as a warning or an error
|
|
63
|
+
* when the output crosses it. See budgets.ts for what each `type` measures
|
|
64
|
+
* in a Lynx build.
|
|
65
|
+
*
|
|
66
|
+
* Copied from the `Budget` type (and its `Type` enum, as a string union) that
|
|
67
|
+
* Angular's application builder schema generates, for the same reason as
|
|
68
|
+
* {@link OutputHashing}: importing it would make an Angular builder package a
|
|
69
|
+
* dependency of this plugin for one type. Keep it in step with Angular's
|
|
70
|
+
* schema when Angular adds a field or a budget type.
|
|
71
|
+
*
|
|
72
|
+
* @see `Budget` in `@angular/build/src/builders/application/schema.d.ts`
|
|
73
|
+
*/
|
|
74
|
+
export type Budget = {
|
|
75
|
+
readonly type: 'all' | 'allScript' | 'any' | 'anyComponentStyle' | 'anyScript' | 'bundle' | 'initial';
|
|
76
|
+
/** The bundle a `bundle` budget measures: an entry name. */
|
|
77
|
+
readonly name?: string;
|
|
78
|
+
/** The size that the relative thresholds below are relative to. */
|
|
79
|
+
readonly baseline?: string;
|
|
80
|
+
readonly maximumWarning?: string;
|
|
81
|
+
readonly maximumError?: string;
|
|
82
|
+
readonly minimumWarning?: string;
|
|
83
|
+
readonly minimumError?: string;
|
|
84
|
+
/** A threshold in both directions from `baseline`. */
|
|
85
|
+
readonly warning?: string;
|
|
86
|
+
/** A threshold in both directions from `baseline`. */
|
|
87
|
+
readonly error?: string;
|
|
88
|
+
};
|
|
43
89
|
export type NormalizedOptions = {
|
|
44
90
|
tsconfig: string;
|
|
45
91
|
aot: boolean;
|
|
@@ -56,7 +102,7 @@ export type NormalizedOptions = {
|
|
|
56
102
|
};
|
|
57
103
|
fileReplacements: Record<string, string> | undefined;
|
|
58
104
|
polyfills?: string[];
|
|
59
|
-
index: string;
|
|
105
|
+
index: string | undefined;
|
|
60
106
|
browser: string;
|
|
61
107
|
advancedOptimizations: boolean;
|
|
62
108
|
outputPath: string | undefined;
|
|
@@ -71,9 +117,41 @@ export type NormalizedOptions = {
|
|
|
71
117
|
styles: string[];
|
|
72
118
|
i18n: NormalizedI18nOptions;
|
|
73
119
|
i18nMissingTranslation: 'error' | 'warning' | 'ignore';
|
|
120
|
+
budgets: readonly Budget[];
|
|
74
121
|
};
|
|
75
122
|
export declare const readTarget: (project: workspaces.ProjectDefinition, target?: string) => TargetDefinition | undefined;
|
|
123
|
+
/**
|
|
124
|
+
* Resolves angular.json's `index` option to an absolute path the way
|
|
125
|
+
* `@angular/build`'s application builder does. Projects from recent `ng new`
|
|
126
|
+
* omit it and rely on the builder's default of `<sourceRoot>/index.html`, so
|
|
127
|
+
* assuming a string here crashed on every freshly generated app. It may also be
|
|
128
|
+
* an `{ input, output }` object, or a boolean to build without an index page.
|
|
129
|
+
*/
|
|
130
|
+
export declare const resolveIndexPath: (index: unknown, project: workspaces.ProjectDefinition, workspaceRoot: string) => string | undefined;
|
|
131
|
+
/**
|
|
132
|
+
* Resolves angular.json's `outputPath`, which may be a string or a
|
|
133
|
+
* `{ base, browser, ... }` object. Recent `ng new` omits it; returning
|
|
134
|
+
* `undefined` then keeps rspeedy's own `dist` directory (see
|
|
135
|
+
* `applyAngularConfig`) rather than crashing on `path.join(root, undefined)`.
|
|
136
|
+
*/
|
|
137
|
+
export declare const resolveOutputPath: (outputPath: unknown, workspaceRoot: string) => string | undefined;
|
|
138
|
+
/**
|
|
139
|
+
* Reads the build target's options from angular.json, merged the way Angular
|
|
140
|
+
* CLI merges them: the selected configuration's keys (by default the
|
|
141
|
+
* target's `defaultConfiguration`) over the base options, leaving the keys it
|
|
142
|
+
* doesn't mention at their base values.
|
|
143
|
+
*
|
|
144
|
+
* Only for plain rspeedy runs. Under `ng build` / `ng serve`, Angular CLI has
|
|
145
|
+
* already merged them, `-c` and command-line overrides included, and the
|
|
146
|
+
* builders pass them in (see angular-cli-context.ts).
|
|
147
|
+
*/
|
|
148
|
+
export declare const readBuildTargetOptions: (project: workspaces.ProjectDefinition, configurationName?: string) => Record<string, unknown>;
|
|
76
149
|
export declare const readBuildOptions: (project: workspaces.ProjectDefinition, basePath: string, configurationName?: string) => Promise<NormalizedOptions>;
|
|
150
|
+
/**
|
|
151
|
+
* Turns a build target's options into the shape the compile pipeline uses:
|
|
152
|
+
* absolute paths, and the expanded forms of Angular's shorthand options.
|
|
153
|
+
*/
|
|
154
|
+
export declare const normalizeBuildOptions: (buildOptions: Readonly<Record<string, unknown>>, project: workspaces.ProjectDefinition, basePath: string) => Promise<NormalizedOptions>;
|
|
77
155
|
/**
|
|
78
156
|
* Normalizes the `i18n` section from angular.json's project definition.
|
|
79
157
|
* Angular supports `sourceLocale` as either a string ('en-US') or an object
|
|
@@ -3,5 +3,9 @@ export type AngularWorkspace = {
|
|
|
3
3
|
workspace: workspaces.WorkspaceDefinition;
|
|
4
4
|
basePath: string;
|
|
5
5
|
};
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Reads the angular.json found by searching up from `from`: the workspace
|
|
8
|
+
* root Angular CLI passed in, or the working directory under plain rspeedy.
|
|
9
|
+
*/
|
|
10
|
+
export declare const getAngularWorkspace: (from?: string) => Promise<AngularWorkspace>;
|
|
7
11
|
export declare const getProjectByCwd: (workspace: workspaces.WorkspaceDefinition, basePath: string) => string | null;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { workspaces } from '@angular-devkit/core';
|
|
2
|
+
import type { AngularCliContext } from '../../angular-cli-context.js';
|
|
3
|
+
import { type NormalizedOptions } from './options.js';
|
|
4
|
+
/**
|
|
5
|
+
* Picks the project whose build target configures the compile (tsconfig,
|
|
6
|
+
* polyfills, global styles, output path), and normalizes its options.
|
|
7
|
+
*
|
|
8
|
+
* The project is the one Angular CLI is building, when there is one: one of
|
|
9
|
+
* the `pages` if the plugin builds several, otherwise any. Without Angular
|
|
10
|
+
* CLI it is the first of the `pages`, or the project the working directory
|
|
11
|
+
* is in.
|
|
12
|
+
*
|
|
13
|
+
* The options are the ones Angular CLI resolved for that project (with `-c`
|
|
14
|
+
* and command-line overrides applied) when it is the one being built, and
|
|
15
|
+
* otherwise the target's options in angular.json under its default
|
|
16
|
+
* configuration.
|
|
17
|
+
*/
|
|
18
|
+
export declare const resolvePrimaryBuild: ({ workspace, basePath, pages, cli, }: {
|
|
19
|
+
workspace: workspaces.WorkspaceDefinition;
|
|
20
|
+
basePath: string;
|
|
21
|
+
pages: string[] | "all" | undefined;
|
|
22
|
+
cli: AngularCliContext | undefined;
|
|
23
|
+
}) => Promise<{
|
|
24
|
+
projectName: string;
|
|
25
|
+
buildOptions: NormalizedOptions;
|
|
26
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/utils/options.d.ts
CHANGED
|
@@ -2,14 +2,29 @@ export type PluginAngularLynxOptions = {
|
|
|
2
2
|
customCSSInheritanceList?: string[] | undefined;
|
|
3
3
|
debugInfoOutside?: boolean;
|
|
4
4
|
defaultDisplayLinear?: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Make `overflow: visible` the default for every element, as on the web.
|
|
7
|
+
* With `false`, elements clip their children unless they set `overflow`,
|
|
8
|
+
* Lynx's older default.
|
|
9
|
+
*/
|
|
5
10
|
defaultOverflowVisible?: boolean;
|
|
6
11
|
enableA11y?: boolean;
|
|
7
12
|
enableAccessibilityElement?: boolean;
|
|
8
13
|
enableCSSInheritance?: boolean;
|
|
9
14
|
enableCSSInvalidation?: boolean;
|
|
10
15
|
enableCSSSelector?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated Has no effect, and never did: it was never passed to Lynx.
|
|
18
|
+
* Lynx's template plugin and React Lynx dropped it too. Will be removed in
|
|
19
|
+
* a future release.
|
|
20
|
+
*/
|
|
11
21
|
enableICU?: boolean;
|
|
12
22
|
enableNewGesture?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* @deprecated Has no effect, and never did: it was never passed to Lynx.
|
|
25
|
+
* Lynx's template plugin and React Lynx dropped it too. Will be removed in
|
|
26
|
+
* a future release.
|
|
27
|
+
*/
|
|
13
28
|
enableParallelElement?: boolean;
|
|
14
29
|
enableRemoveCSSScope?: boolean;
|
|
15
30
|
enableSSR?: boolean;
|
|
@@ -23,9 +38,33 @@ export type PluginAngularLynxOptions = {
|
|
|
23
38
|
* When omitted, uses `source.entry` from lynx.config.ts (single or multi-entry).
|
|
24
39
|
*/
|
|
25
40
|
pages?: string[] | 'all' | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated Has no effect, and never did: it was never passed to Lynx.
|
|
43
|
+
* Lynx's template plugin and React Lynx dropped it too. Will be removed in
|
|
44
|
+
* a future release.
|
|
45
|
+
*/
|
|
26
46
|
pipelineSchedulerConfig?: number;
|
|
27
47
|
removeDescendantSelectorScope?: boolean;
|
|
28
48
|
targetSdkVersion?: string;
|
|
29
49
|
experimental_isLazyBundle?: boolean;
|
|
30
50
|
};
|
|
31
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Options the plugin still accepts, so existing `lynx.config.ts` files keep
|
|
53
|
+
* type-checking, but ignores. They were declared and given defaults but never
|
|
54
|
+
* passed to Lynx, and `@lynx-js/template-webpack-plugin` 0.9 removed them
|
|
55
|
+
* (lynx-family/lynx-stack#1705, #1800), so there's nothing to pass them to:
|
|
56
|
+
*
|
|
57
|
+
* - `enableParallelElement` and `pipelineSchedulerConfig` turn on Lynx's
|
|
58
|
+
* experimental parallel element resolution, which React Lynx turned off for
|
|
59
|
+
* stability.
|
|
60
|
+
* - `enableICU` binds a host-provided ICU service (`LynxServiceI18nProtocol`
|
|
61
|
+
* on iOS, `ICURegister` on Android) into the JS context. Lynx Explorer and
|
|
62
|
+
* the apps `ng build --platform` makes don't provide one.
|
|
63
|
+
*/
|
|
64
|
+
export declare const DEPRECATED_OPTIONS: readonly ["enableICU", "enableParallelElement", "pipelineSchedulerConfig"];
|
|
65
|
+
type DeprecatedOption = (typeof DEPRECATED_OPTIONS)[number];
|
|
66
|
+
export type NormalizedPluginAngularLynxOptions = Required<Omit<PluginAngularLynxOptions, DeprecatedOption>>;
|
|
67
|
+
/** The deprecated options `options` sets, to warn about. */
|
|
68
|
+
export declare const deprecatedOptionsIn: (options?: Partial<PluginAngularLynxOptions>) => DeprecatedOption[];
|
|
69
|
+
export declare const normalizeOptions: (options?: Partial<PluginAngularLynxOptions>) => NormalizedPluginAngularLynxOptions;
|
|
70
|
+
export {};
|