Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions docs/initialize.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
Install the CLI and wire `addIcons`. See also [Usage](./usage.md).
Install the CLI and wire icon registration. See also [Usage](./usage.md).

```bash
npm install @rdlabo/ionic-angular-collect-icons --save-dev
npm install --save-dev @rdlabo/ionic-angular-collect-icons
```

The generated application code imports the package's browser runtime, so build
environments must install development dependencies before compiling the
application. The runtime is then bundled into the application output.

### 🤖 Automatic Configuration

```bash
Expand All @@ -23,17 +27,27 @@ This will generate `src/use-icons.ts`.
#### 2. Import the generated file in your `main.ts` ( or `app.config.ts` ) file:

```diff
+ import { addIcons } from 'ionicons';
+ import * as allIcons from 'ionicons/icons';
+ import { initializeIonicons } from '@rdlabo/ionic-angular-collect-icons/runtime';
+ import * as useIcons from './use-icons';

if (environment.production) {
enableProdMode();
}

+ addIcons(environment.production ? useIcons : allIcons);
+ void initializeIonicons(useIcons);
```

`initializeIonicons` registers the collected icons synchronously. In Angular
development builds it then loads the complete Ionicons catalog; Angular removes
that development-only import from optimized production builds.

When an interactive collector run detects the ternary initializer emitted by
older releases, it asks whether to migrate it. The default answer is **Yes**.
Selecting **No** leaves the initializer unchanged. Existing custom
`addIcons(...)` calls are also left unchanged. See
[Migration](./migration.md#upgrade-the-icon-initializer) for preview,
non-interactive, and matching details.

#### 3. Remove other `addIcons` calls in class constructor

```diff
Expand Down
92 changes: 92 additions & 0 deletions docs/migration.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,97 @@
# Migration Guide

## Upgrade the icon initializer

This section applies when upgrading from 3.0.1 or earlier to a release that
provides `initializeIonicons`.

Older releases generated a namespace import for the complete Ionicons catalog:

```ts
import { addIcons } from "ionicons";
import * as allIcons from "ionicons/icons";
import * as useIcons from "./use-icons";

addIcons(environment.production ? useIcons : allIcons);
```

Although the production branch selected `useIcons` at runtime, the namespace
import could still retain the complete catalog in optimized application
bundles. The package now provides a browser runtime that keeps the production
dependency graph tree-shakeable.

First update the package, then run the collector in an interactive terminal:

```bash
npm install --save-dev @rdlabo/ionic-angular-collect-icons@latest
npx @rdlabo/ionic-angular-collect-icons
```

Build environments must install development dependencies because the generated
application code imports the browser runtime while compiling. The runtime is
then bundled into the application output.

When it detects this generated initializer, the CLI asks whether to migrate it.
**Yes** is selected by default. Selecting **No** leaves the initializer
unchanged and continues normal icon collection.

To preview the source diff first, select **No** and run:

```bash
npx @rdlabo/ionic-angular-collect-icons --migrate true --dry-run true
```

For CI or another non-interactive environment, explicitly approve the migration
with `--migrate true`. Without that flag, the initializer is left
unchanged. The resulting code after approval is:

```ts
import { initializeIonicons } from "@rdlabo/ionic-angular-collect-icons/runtime";
import * as useIcons from "./use-icons";

void initializeIonicons(useIcons);
```

`initializeIonicons` registers the collected icons synchronously. Development
builds then load and register the complete catalog asynchronously. Angular's
production optimizer removes that development-only import.

The confirmed migration only rewrites the ternary initializer generated by
older releases:

```ts
addIcons(environment.production ? useIcons : allIcons);
```

The import bindings must also match the known generated structure. Other
`addIcons(...)` calls and imports used by custom application code are preserved.
The migrator recognizes both the legacy bare generated path such as
`"use-icons"` and its canonical relative form `"./use-icons"`, and writes the
canonical form after migration.
When `--migrate true` is explicitly requested, the conventional
`addIcons(useIcons)` form is also upgraded only when `useIcons` is the namespace
import for the configured generated icon file. If the initializer was
customized, apply the import and call replacement manually and keep custom
registrations separately.

To roll back the runtime integration while keeping production bundles
tree-shakeable, replace its import and call with:

```ts
import { addIcons } from "ionicons";
import * as useIcons from "./use-icons";

addIcons(useIcons);
```

This rollback does not register the complete catalog during development. Do not
restore the old `allIcons` namespace import, because that is the source of the
production bundle regression.

After migrating, run the consuming application's tests and an optimized
production build. Bundle statistics should contain only the icons exported by
`use-icons.ts`, not a separate chunk containing the complete Ionicons catalog.

## Migrating to Ionic Angular 9

This version targets Ionic Angular 9 and follows the
Expand Down
32 changes: 28 additions & 4 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,25 @@ npx @rdlabo/ionic-angular-collect-icons --interactive true

### --initialize [boolean]

If you want to initialize `addIcons` automatically, you can use the `--initialize` flag. The default is `false`. The CLI add lines:
If you want to initialize icon registration automatically, you can use the `--initialize` flag. The default is `false`. The CLI adds these lines:

```diff
+ import { addIcons } from 'ionicons';
+ import * as allIcons from 'ionicons/icons';
+ import { initializeIonicons } from '@rdlabo/ionic-angular-collect-icons/runtime';
+ import * as useIcons from './use-icons';

if (environment.production) {
enableProdMode();
}

+ addIcons(environment.production ? useIcons : allIcons);
+ void initializeIonicons(useIcons);
```

the CLI will add lines at the file that has `enableProdMode()`. Of course, it can also be set manually.

`--initialize` is only required when adding the initializer to a project that
does not have one. Migration of an existing initializer requires a separate
confirmation.

And remove other `addIcons` calls in class constructor.

```diff
Expand All @@ -50,6 +53,27 @@ And remove other `addIcons` calls in class constructor.
npx @rdlabo/ionic-angular-collect-icons --initialize true
```

### --migrate [boolean]

In an interactive terminal, the collector asks before applying each recognized
source migration. **Yes** is selected by default; **No** leaves that migration's
target unchanged.

Use this option to answer explicitly, such as in CI or another non-interactive
environment:

```bash
npx @rdlabo/ionic-angular-collect-icons --migrate true
```

Preview the generated diff without writing files:

```bash
npx @rdlabo/ionic-angular-collect-icons --migrate true --dry-run true
```

The option is unset by default so an interactive run can ask for confirmation.

### --project-path [string]

If you want to specify the path to the project, you can use the `--project-path` flag. The default is the current directory.
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 28 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,40 @@
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./runtime": {
"types": "./dist/runtime.d.ts",
"import": "./dist/runtime.mjs",
"require": "./dist/runtime.js"
},
"./dist/index": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./dist/runtime": {
"types": "./dist/runtime.d.ts",
"import": "./dist/runtime.mjs",
"require": "./dist/runtime.js"
},
"./dist/*": "./dist/*",
"./docs/*": "./docs/*",
"./package.json": "./package.json"
},
"bin": "./dist/index.js",
"files": [
"dist",
"docs"
],
"scripts": {
"start": "jiti ./src/index.ts",
"build": "tsup src/index.ts --format cjs,esm --dts --target node22",
"dev": "npm run build --watch",
"build": "tsup",
"dev": "tsup --watch",
"test": "vitest run",
"test:watch": "vitest",
"coverage": "vitest run --coverage",
Expand All @@ -45,6 +70,7 @@
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"@vitest/coverage-v8": "^0.34.6",
"esbuild": "0.24.2",
"eslint": "^8.57.0",
"jiti": "^1.21.0",
"np": "^10.2.0",
Expand Down
9 changes: 9 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ async function main() {
cliOptions: cli,
dir: cli.projectPath,
spinner: s,
confirmInitializerMigration:
TERMINAL_INFO.tty && !TERMINAL_INFO.ci
? async () =>
(await confirm({
message:
"A legacy generated Ionicons initializer was found. Migrate it now?",
initialValue: true,
})) === true
: undefined,
});
} catch (e: any) {
s.stop("An error occurred during the migration.", 1);
Expand Down
Loading
Loading