isolate-package 1.7.1 → 1.8.0-2

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 CHANGED
@@ -2,21 +2,18 @@
2
2
 
3
3
  <!-- TOC -->
4
4
 
5
+ - [TLDR](#tldr)
5
6
  - [Introduction](#introduction)
6
7
  - [Features](#features)
7
8
  - [Motivation](#motivation)
8
- - [Install](#install)
9
- - [Usage as binary](#usage-as-binary)
10
- - [Usage as function](#usage-as-function)
9
+ - [Installation](#installation)
10
+ - [Usage](#usage)
11
+ - [Troubleshooting](#troubleshooting)
11
12
  - [Prerequisites](#prerequisites)
12
13
  - [Define shared dependencies in the package manifest](#define-shared-dependencies-in-the-package-manifest)
13
14
  - [Define "version" field in each package manifest](#define-version-field-in-each-package-manifest)
14
15
  - [Define "files" field in each package manifest](#define-files-field-in-each-package-manifest)
15
16
  - [Use a flat structure inside your packages folders](#use-a-flat-structure-inside-your-packages-folders)
16
- - [Working with Firebase](#working-with-firebase)
17
- - [A Quick Start](#a-quick-start)
18
- - [Deploying from multiple packages](#deploying-from-multiple-packages)
19
- - [Deploying from the root](#deploying-from-the-root)
20
17
  - [Configuration Options](#configuration-options)
21
18
  - [buildDirName](#builddirname)
22
19
  - [excludeLockfile](#excludelockfile)
@@ -27,36 +24,38 @@
27
24
  - [tsconfigPath](#tsconfigpath)
28
25
  - [workspacePackages](#workspacepackages)
29
26
  - [workspaceRoot](#workspaceroot)
30
- - [Troubleshooting](#troubleshooting)
31
27
  - [Lockfiles](#lockfiles)
32
- - [NPM and PNPM](#npm-and-pnpm)
33
- - [Yarn](#yarn)
34
- - [A Partial Workaround](#a-partial-workaround)
35
- - [Different Package Managers](#different-package-managers)
36
- - [Using the Firebase Functions Emulator](#using-the-firebase-functions-emulator)
28
+ - [API](#api)
37
29
  - [The internal packages strategy](#the-internal-packages-strategy)
30
+ - [Working with Firebase](#working-with-firebase)
31
+ - [A Quick Start](#a-quick-start)
32
+ - [Deploying from multiple packages](#deploying-from-multiple-packages)
33
+ - [Deploying from the root](#deploying-from-the-root)
34
+ - [Using the Firebase Functions Emulator](#using-the-firebase-functions-emulator)
38
35
 
39
36
  <!-- /TOC -->
40
37
 
38
+ ## TLDR
39
+
40
+ Run `npx isolate-package isolate` from the monorepo package you would like to
41
+ isolate.
42
+
41
43
  ## Introduction
42
44
 
43
45
  Isolate a monorepo workspace package to form a self-contained deployable package
44
46
  that includes internal dependencies and a compatible lockfile. The internal
45
- packages structure is preserved, so dependencies are not bundled.
47
+ packages structure is preserved. Code is not bundled.
46
48
 
47
49
  ## Features
48
50
 
49
- - Isolate a monorepo package with its internal dependencies to form a
50
- self-contained installable package.
51
- - Deterministic deployment by generating an isolated lockfile based on the
52
- existing monorepo lockfile. Currently this feature is only supported for NPM
53
- and PNPM. See [lockfiles](#lockfiles) for more information.
51
+ - Isolates a monorepo package with its internal dependencies to form a
52
+ self-contained deployable directory.
53
+ - Generates an isolated / pruned lockfile based on the existing monorepo
54
+ lockfile. See [lockfiles](#lockfiles) for more information.
54
55
  - Zero-config for the vast majority of use-cases, with no manual steps involved.
55
56
  - Support for PNPM, NPM and Yarn.
56
- - Compatible with the Firebase tools CLI, incl 1st gen and 2nd gen Firebase
57
- functions deployments.
58
- - Uses a pack/unpack approach to isolate only those files that would have been
59
- part of a published NPM package.
57
+ - Compatible with the Firebase tools CLI, incl 1st and 2nd gen Firebase
58
+ functions.
60
59
  - Isolates internal workspace dependencies recursively. If package A depends on
61
60
  internal package B which depends on internal package C, all of them will be
62
61
  included.
@@ -65,7 +64,7 @@ packages structure is preserved, so dependencies are not bundled.
65
64
  ## Motivation
66
65
 
67
66
  This solution was born from a desire to deploy to
68
- [Firebase](https://firebase.google.com/) from a monorepo without requiring
67
+ [Firebase](https://firebase.google.com/) from a monorepo without resorting to
69
68
  custom shell scripts and other hacks. Here is
70
69
  [an article](https://thijs-koerselman.medium.com/deploy-to-firebase-without-the-hacks-e685de39025e)
71
70
  explaining the issue in more detail.
@@ -76,20 +75,19 @@ related to Firebase.
76
75
 
77
76
  > !! There is now
78
77
  > [a fork of firebase-tools](https://github.com/0x80/firebase-tools-with-isolate),
79
- > where isolate-package is integrated. It is preferred because it simplifies the
80
- > setup and allows the isolation to run only as part of the deploy process,
78
+ > where isolate-package is integrated. This is preferred because it simplifies
79
+ > the setup and allows the isolation to run only as part of the deploy process,
81
80
  > preserving live code updates when running the local Firebase emulators.
82
81
 
83
- ## Install
82
+ ## Installation
84
83
 
85
- Run `pnpm install isolate-package --dev` or the equivalent for `yarn` or `npm`.
84
+ Run `pnpm install isolate-package --dev` or the equivalent for `npm` or `yarn`.
86
85
 
87
86
  I recommend using `pnpm` for
88
- [a number of reasons](https://pnpm.io/feature-comparison). Also, at the time of
89
- writing it is the only package manager for which isolate-package can generate a
90
- lockfile. For more information see [lockfiles](#lockfiles).
87
+ [a number of reasons](https://pnpm.io/feature-comparison). In my experience it
88
+ is the best package manager, especially for monorepo setups.
91
89
 
92
- ## Usage as binary
90
+ ## Usage
93
91
 
94
92
  This package exposes a binary called `isolate`.
95
93
 
@@ -105,21 +103,18 @@ By default the isolated output will become available at `./isolate`.
105
103
  If you are here to simplify and improve your Firebase deployments check out the
106
104
  [Firebase quick start guide](#a-quick-start).
107
105
 
108
- ## Usage as function
106
+ ## Troubleshooting
109
107
 
110
- Alternatively, `isolate` can be integrated in other programs by importing it as
111
- a function. You optionally pass it a some user configuration and possibly a
112
- logger to handle any output messages should you need to write them to a
113
- different location as the standard `node:console`.
108
+ If something is not working as expected, add a `isolate.config.json` file, and
109
+ set `"logLevel"` to `"debug"`. This should give you detailed feedback in the
110
+ console.
114
111
 
115
- ```ts
116
- import { isolate } from "isolate-package";
112
+ In addition define an environment variable to debug the configuration being used
113
+ by setting `DEBUG_ISOLATE_CONFIG=true` before you execute `isolate`.
117
114
 
118
- await isolate({
119
- config: { logLevel: "debug" },
120
- logger: customLogger,
121
- });
122
- ```
115
+ When debugging Firebase deployment issues it might be convenient to trigger the
116
+ isolate process manually with `npx isolate` and possibly
117
+ `DEBUG_ISOLATE_CONFIG=true npx isolate`
123
118
 
124
119
  If you do not pass in any configuration, the function will try to read a
125
120
  `isolate.config.json` file from disk. You can set
@@ -163,10 +158,9 @@ generate part of the packed filename. A personal preference is to set it to
163
158
 
164
159
  ### Define "files" field in each package manifest
165
160
 
166
- > NOTE: This step is not required if you use the [internal packages > > > > > >
167
- >
168
- > > strategy](#the-internal-packages-strategy but you could set it to `["src"]`
169
- > > instead of `["dist"]`.
161
+ > NOTE: This step is not required if you use the
162
+ > [internal packages strategy](#the-internal-packages-strategy) but you could
163
+ > set it to `["src"]` instead of `["dist"]`.
170
164
 
171
165
  The isolate process uses (p)npm `pack` to extract files from package
172
166
  directories, just like publishing a package would.
@@ -207,112 +201,6 @@ You can, however, declare multiple workspace packages directories. Personally, I
207
201
  prefer to use `["packages/*", "apps/*", "services/*"]`. It is only the structure
208
202
  inside them that should be flat.
209
203
 
210
- ## Working with Firebase
211
-
212
- > !! There is now
213
- > [a fork of firebase-tools](https://github.com/0x80/firebase-tools-with-isolate),
214
- > where isolate-package is integrated. It is preferred because it simplifies the
215
- > setup and allows the isolation to run only as part of the deploy process,
216
- > preserving live code updates when running the local Firebase emulators.
217
-
218
- ### A Quick Start
219
-
220
- If you are not confident that your monorepo setup is solid, please check out my
221
- in-dept example at [mono-ts](https://github.com/0x80/mono-ts) where many
222
- different aspects are discussed and `isolate-package` is used to demonstrate
223
- Firebase deployments.
224
-
225
- This section describes the steps required for Firebase deployment, assuming:
226
-
227
- - You use a fairly typical monorepo setup
228
- - Your `firebase.json` config lives in the root of the package that you like to
229
- deploy to Firebase, hereafter referred to as the "target package".
230
-
231
- If your setup diverges from a traditional one, please continue reading the
232
- [Prerequisites](#prerequisites) section.
233
-
234
- 1. In the target package, install `isolate-package` and `firebase-tools` by
235
- running `pnpm add isolate-package firebase-tools -D` or the Yarn / NPM
236
- equivalent. I tend to install firebase-tools as a devDependency in every
237
- Firebase package, but you could also use a global install if you prefer that.
238
- 2. In the `firebase.json` config set `"source"` to `"./isolate"` and
239
- `"predeploy"` to `["turbo build", "isolate"]` or whatever suits your build
240
- tool. The important part here is that isolate is being executed after the
241
- build stage.
242
- 3. From the target package folder, you should now be able to deploy with
243
- `npx firebase deploy`.
244
-
245
- I recommend keeping a `firebase.json` file inside each Firebase package (as
246
- opposed to the monorepo root), because it allows you to deploy from multiple
247
- independent packages. It makes it easy to deploy 1st gen functions next to 2nd
248
- gen functions, deploy different node versions, and decrease the built output
249
- size and dependency lists for each package, improving deployment and cold-start
250
- times.
251
-
252
- ### Deploying from multiple packages
253
-
254
- You can deploy to Firebase from multiple packages in your monorepo, in which
255
- case you co-locate your `firebase.json` file with the source code, and not in
256
- the root of the monorepo. If you do want to keep the firebase config in the
257
- root, read the instructions for
258
- [deploying to Firebase from the root](#deploying-to-firebase-from-the-root).
259
-
260
- In order to deploy to Firebase, the `functions.source` setting in
261
- `firebase.json` needs to point to the isolated output folder, which would be
262
- `./isolate` when using the default configuration.
263
-
264
- The `predeploy` phase should first build and then isolate the output.
265
-
266
- Here's an example using [Turborepo](https://turbo.build/):
267
-
268
- ```cjson
269
- // firebase.json
270
- {
271
- "functions": {
272
- "source": "./isolate",
273
- "predeploy": ["turbo build", "isolate"]
274
- }
275
- }
276
- ```
277
-
278
- With this configuration you can then run `npx firebase deploy --only functions`
279
- from the package.
280
-
281
- If you like to deploy to Firebase Functions from multiple packages you will also
282
- need to configure a unique `codebase` identifier for each of them. For more
283
- information,
284
- [read this](https://firebase.google.com/docs/functions/beta/organize-functions).
285
-
286
- Make sure your Firebase package adheres to the things mentioned in
287
- [prerequisites](#prerequisites) and its package manifest contains the field
288
- `"main"`, or `"module"` if you set `"type": "module"`, so Firebase knows the
289
- entry point to your source code.
290
-
291
- ### Deploying from the root
292
-
293
- If, for some reason, you choose to keep the `firebase.json` file in the root of
294
- the monorepo you will have to place a configuration file called
295
- `isolate.config.json` in the root with the following content:
296
-
297
- ```cjson
298
- // isolate.config.json
299
- {
300
- "targetPackagePath": "./packages/your-firebase-package"
301
- }
302
- ```
303
-
304
- The Firebase configuration should then look something like this:
305
-
306
- ```cjson
307
- // firebase.json
308
- {
309
- "functions": {
310
- "source": "./packages/your-firebase-package/isolate",
311
- "predeploy": ["turbo build", "isolate"]
312
- }
313
- }
314
- ```
315
-
316
204
  ## Configuration Options
317
205
 
318
206
  For most users no configuration should be necessary.
@@ -338,13 +226,16 @@ setting to specify where the build output files are located.
338
226
 
339
227
  Type: `boolean`, default: Depends on package manager.
340
228
 
229
+ **Deprecated** This option exists from the time that lockfiles were not
230
+ supported for all package managers. You should not need this escape hatch
231
+ anymore.
232
+
341
233
  Sets the inclusion or exclusion of the lockfile as part of the deployment.
342
234
 
343
- Isolated NPM and PNPM lockfiles are generated based on the existing root
344
- lockfile, and they are included by default.
235
+ Isolated / pruned lockfiles are generated for NPM, PNPM and Yarn v1 (classic)
236
+ based on the existing root lockfile, and they are included by default.
345
237
 
346
- The lockfile for Yarn is excluded by default. For more information see
347
- [lockfiles](#lockfiles).
238
+ For more information see [lockfiles](#lockfiles).
348
239
 
349
240
  ### includeDevDependencies
350
241
 
@@ -430,83 +321,191 @@ services
430
321
 
431
322
  When you use the `targetPackagePath` option, this setting will be ignored.
432
323
 
433
- ## Troubleshooting
324
+ ## Lockfiles
434
325
 
435
- If something is not working as expected, add a `isolate.config.json` file, and
436
- set `"logLevel"` to `"debug"`. This should give you detailed feedback in the
437
- console.
326
+ A lockfile in a monorepo describes the dependencies of all packages, and does
327
+ not translate to the isolated output without altering it.
438
328
 
439
- In addition define an environment variable to debug the configuration being used
440
- by setting `DEBUG_ISOLATE_CONFIG=true` before you execute `isolate`.
329
+ If you copying the original lockfile and deploy it with the isolated code, a CI
330
+ environment will not accept the lockfile. It is also not possibly to generate a
331
+ brand new lockfile from the isolated code by mimicking a fresh install, because
332
+ versions would be able to diverge and thus negate the whole point of having a
333
+ lockfile in the first place.
441
334
 
442
- When debugging Firebase deployment issues it might be convenient to trigger the
443
- isolate process manually with `npx isolate` and possibly
444
- `DEBUG_ISOLATE_CONFIG=true npx isolate`
335
+ For this to work, we need to re-generate or prune the original lockfile to keep
336
+ the versions of the original but only describe the dependencies of the code in
337
+ the isolated output.
445
338
 
446
- ## Lockfiles
339
+ Since every package manager works completely different in this regard, this part
340
+ of the puzzle had to be solved in a different ways for each of them, and not all
341
+ are supported yet.
447
342
 
448
- A lockfile in a monorepo describes the dependencies of all packages, and does
449
- not necessarily translate to the isolated output without altering it. Different
450
- package managers use very different formats, and it might not be enough to do a
451
- find/replace on some paths.
343
+ At the moment lockfiles for the following package managers are supported:
452
344
 
453
- It is also not possibly to generate a brand new lockfile from the isolated code
454
- by mimicking a fresh install, because versions would be able to diverge and thus
455
- it would negate the whole point of having a lockfile in the first place.
345
+ - NPM
346
+ - PNPM
347
+ - Yarn Classic (v1)
456
348
 
457
- What we need is to re-generate a lockfile for the isolated output based on the
458
- versions that are currently installed and locked in the monorepo lockfile.
349
+ More detailed information on the implementation can be found in the
350
+ [additional docs](./docs/lockfiles.md).
459
351
 
460
- ### NPM and PNPM
352
+ ## API
461
353
 
462
- For NPM and PNPM a lockfile is generated and included in the isolated output.
354
+ Alternatively, `isolate` can be integrated in other programs by importing it as
355
+ a function. You optionally pass it a some user configuration and possibly a
356
+ logger to handle any output messages should you need to write them to a
357
+ different location as the standard `node:console`.
463
358
 
464
- @TODO write about how it works an how we got there.
359
+ ```ts
360
+ import { isolate } from "isolate-package";
465
361
 
466
- If you do somehow run into a problem related to the lockfile, you can opt-out of
467
- this by setting `excludeLockfile: true` in the `isolate.config.json`
468
- configuration file.
362
+ await isolate({
363
+ config: { logLevel: "debug" },
364
+ logger: customLogger,
365
+ });
366
+ ```
469
367
 
470
- ### Yarn
368
+ ## The internal packages strategy
369
+
370
+ An alternative approach to using internal dependencies in a Typescript monorepo
371
+ is
372
+ [the internal packages strategy](https://turbo.build/blog/you-might-not-need-typescript-project-references),
373
+ in which the package manifest entries point directly to Typescript source files,
374
+ to omit intermediate build steps. The approach is compatible with
375
+ isolate-package and showcased in
376
+ [my example monorepo setup](https://github.com/0x80/mono-ts)
377
+
378
+ In summary this is how it works:
471
379
 
472
- For now, Yarn lockfiles are simply copied over to the isolated output. I believe
473
- I have seen Firebase deployments work with it, but it is likely you will run
474
- into an error.
380
+ 1. The package to be deployed lists its internal dependencies as usual, but the
381
+ package manifests of those dependencies point directly to the Typescript
382
+ source (and types).
383
+ 2. You configure the bundler of your target package to include the source code
384
+ for those internal packages in its output bundle. In the case of TSUP for the
385
+ [API service in the mono-ts](https://github.com/0x80/mono-ts/blob/main/services/api/tsup.config.ts)
386
+ that configuration is: `noExternal: ["@mono/common"]`
387
+ 3. When `isolate` runs, it does the same thing as always. It detects the
388
+ internal packages, copies them to the isolate output folder and adjusts any
389
+ links.
390
+ 4. When deploying to Firebase, the cloud pipeline will treat the package
391
+ manifest as usual, which installs the listed dependencies and any
392
+ dependencies listed in the linked internal package manifests.
393
+
394
+ Steps 3 and 4 are no different from a traditional setup.
395
+
396
+ Note that the manifests for the internal packages in the output will still point
397
+ to the Typescript source files, but since the shared code was embedded in the
398
+ bundle, they will never be referenced via import statements. So the manifest the
399
+ entry declarations are never used. The reason the packages are included in the
400
+ isolated output is to instruct package manager to install their dependencies.
401
+
402
+ ## Working with Firebase
403
+
404
+ > !! There is now
405
+ > [a fork of firebase-tools](https://github.com/0x80/firebase-tools-with-isolate),
406
+ > where isolate-package is integrated. This is preferred because it simplifies
407
+ > the setup and allows the isolation to run only as part of the deploy process,
408
+ > preserving live code updates when running the local Firebase emulators.
475
409
 
476
- If you experience an issue, you can choose to exclude the lockfile from
477
- deployment by setting `"excludeLockfile": false` in your isolate.config.json
478
- file, or make the move to PNPM (recommended).
410
+ ### A Quick Start
479
411
 
480
- I am not aware of any code in the official Yarn repository for re-generating a
481
- lockfile, and I am reluctant to work on this feature based on user-land code.
412
+ If you are not confident that your monorepo setup is solid, please check out my
413
+ in-dept example at [mono-ts](https://github.com/0x80/mono-ts) where many
414
+ different aspects are discussed and `isolate-package` is used to demonstrate
415
+ Firebase deployments.
482
416
 
483
- Personally, I do not think Yarn is very relevant anymore in 2023 and I
484
- personally recommend switching to PNPM.
417
+ This section describes the steps required for Firebase deployment, assuming:
485
418
 
486
- ### A Partial Workaround
419
+ - You use a fairly typical monorepo setup
420
+ - Your `firebase.json` config lives in the root of the package that you like to
421
+ deploy to Firebase, hereafter referred to as the "target package".
487
422
 
488
- If you can not use a lockfile, because you depend on Yarn, a partial workaround
489
- would be to declare dependencies using exact versions in your package manifest.
490
- This doesn't prevent your dependencies-dependencies from installing newer
491
- versions, like a lockfile would, but at least you minimize the risk of things
492
- breaking.
423
+ If your setup diverges from a traditional one, please continue reading the
424
+ [Prerequisites](#prerequisites) section.
493
425
 
494
- ## Different Package Managers
426
+ 1. In the target package, install `isolate-package` and `firebase-tools` by
427
+ running `pnpm add isolate-package firebase-tools -D` or the Yarn / NPM
428
+ equivalent. I tend to install firebase-tools as a devDependency in every
429
+ Firebase package, but you could also use a global install if you prefer that.
430
+ 2. In the `firebase.json` config set `"source"` to `"./isolate"` and
431
+ `"predeploy"` to `["turbo build", "isolate"]` or whatever suits your build
432
+ tool. The important part here is that isolate is being executed after the
433
+ build stage.
434
+ 3. From the target package folder, you should now be able to deploy with
435
+ `npx firebase deploy`.
495
436
 
496
- Isolate package has been designed to work with all package managers, although
497
- [PNPM is recommended](https://pnpm.io/feature-comparison), especially for
498
- monorepo environments.
437
+ I recommend keeping a `firebase.json` file inside each Firebase package (as
438
+ opposed to the monorepo root), because it allows you to deploy from multiple
439
+ independent packages. It makes it easy to deploy 1st gen functions next to 2nd
440
+ gen functions, deploy different node versions, and decrease the built output
441
+ size and dependency lists for each package, improving deployment and cold-start
442
+ times.
499
443
 
500
- The isolation process will infer the package manager name and version from the
501
- type of lockfile found and the version that the OS reports for the installed
502
- executable. This information is then used to change some of its behavior. For
503
- example, the PNPM `pack` process is preferred over the default NPM `pack` if
504
- PNPM in used, simply because it seems to be much faster.
444
+ ### Deploying from multiple packages
505
445
 
506
- The Firebase cloud deploy pipeline will use the package manager that matches
507
- lockfile that was found in the deployed package.
446
+ You can deploy to Firebase from multiple packages in your monorepo, in which
447
+ case you co-locate your `firebase.json` file with the source code, and not in
448
+ the root of the monorepo. If you do want to keep the firebase config in the
449
+ root, read the instructions for
450
+ [deploying to Firebase from the root](#deploying-to-firebase-from-the-root).
508
451
 
509
- ## Using the Firebase Functions Emulator
452
+ In order to deploy to Firebase, the `functions.source` setting in
453
+ `firebase.json` needs to point to the isolated output folder, which would be
454
+ `./isolate` when using the default configuration.
455
+
456
+ The `predeploy` phase should first build and then isolate the output.
457
+
458
+ Here's an example using [Turborepo](https://turbo.build/):
459
+
460
+ ```cjson
461
+ // firebase.json
462
+ {
463
+ "functions": {
464
+ "source": "./isolate",
465
+ "predeploy": ["turbo build", "isolate"]
466
+ }
467
+ }
468
+ ```
469
+
470
+ With this configuration you can then run `npx firebase deploy --only functions`
471
+ from the package.
472
+
473
+ If you like to deploy to Firebase Functions from multiple packages you will also
474
+ need to configure a unique `codebase` identifier for each of them. For more
475
+ information,
476
+ [read this](https://firebase.google.com/docs/functions/beta/organize-functions).
477
+
478
+ Make sure your Firebase package adheres to the things mentioned in
479
+ [prerequisites](#prerequisites) and its package manifest contains the field
480
+ `"main"`, or `"module"` if you set `"type": "module"`, so Firebase knows the
481
+ entry point to your source code.
482
+
483
+ ### Deploying from the root
484
+
485
+ If, for some reason, you choose to keep the `firebase.json` file in the root of
486
+ the monorepo you will have to place a configuration file called
487
+ `isolate.config.json` in the root with the following content:
488
+
489
+ ```cjson
490
+ // isolate.config.json
491
+ {
492
+ "targetPackagePath": "./packages/your-firebase-package"
493
+ }
494
+ ```
495
+
496
+ The Firebase configuration should then look something like this:
497
+
498
+ ```cjson
499
+ // firebase.json
500
+ {
501
+ "functions": {
502
+ "source": "./packages/your-firebase-package/isolate",
503
+ "predeploy": ["turbo build", "isolate"]
504
+ }
505
+ }
506
+ ```
507
+
508
+ ### Using the Firebase Functions Emulator
510
509
 
511
510
  The Firebase functions emulator runs on the code that firebase.json `source`
512
511
  points to. Unfortunately, this is the same field as is used for declaring the
@@ -531,37 +530,3 @@ deployment process and the `source` property can still point to the original
531
530
  code.
532
531
 
533
532
  I plan to work on this once isolate-package is bit more mature.
534
-
535
- ## The internal packages strategy
536
-
537
- Recently I changed [my example monorepo setup](https://github.com/0x80/mono-ts)
538
- to include
539
- [the internal packages strategy](https://turbo.build/blog/you-might-not-need-typescript-project-references),
540
- (in which the package manifest entries point directly to TS source files, to
541
- omit the build step), and I was pleased to discover that the approach is
542
- compatible with `isolate-packages` with only a single change in configuration.
543
-
544
- In summary this is how it works:
545
-
546
- 1. The package to be deployed lists its internal dependencies as usual, but the
547
- package manifests of those dependencies point directly to the Typescript
548
- source (and types).
549
- 2. You configure the bundler of your target package to include the source code
550
- for those internal packages in its output bundle. In the case of TSUP for the
551
- [API service in the mono-ts](https://github.com/0x80/mono-ts/blob/main/services/api/tsup.config.ts)
552
- that configuration is: `noExternal: ["@mono/common"]`
553
- 3. When `isolate` runs, it does the exact same thing as always. It will detect
554
- the internal packages, copies them to the isolate output folder and adjusts
555
- any links.
556
- 4. When deploying to Firebase, the cloud pipeline will treat the package
557
- manifest as usual, which installs the listed dependencies and any
558
- dependencies listed in the linked internal package manifests.
559
-
560
- Steps 3 and 4 are no different from a traditional setup.
561
-
562
- Note that the manifests for the internal packages will still point to the
563
- Typescript source files, but since the shared code was embedded in the deployed
564
- bundle, they will never be referenced via import statements and as a result the
565
- entry points remain unused. The only reason the packages are included in the
566
- isolated output is so that the package manager knows what dependencies to
567
- install.