Skip to content

Blueprint - TypeScript files from transitively installed addons are transpiled #10962

@TSenter

Description

@TSenter

I know the title is a bit confusing, so take this example:

What's Wrong

I have an app with the isTypeScriptProject flag in .ember-cli set to true. I install addon-a. The install blueprint for addon-a installs addon-b via addAddonToProject, like so:

await this.addAddonToProject({
  name: 'addon-b',
  target: 'latest',
});

Both addon-a and addon-b have files provided by the install blueprint in TypeScript (e.g., app/app.ts, app/routes/application.ts, etc.). Both addons also have shouldTransformTypeScript set to true. However, when the install blueprint for addon-a finishes, any TypeScript files provided by addon-b are actually created as transpiled JavaScript (e.g., app/app.js, app/routes/application.js, etc.). This usually results in new, conflicting files being created, since the project is configured for TypeScript already.

Trace

I've been able to trace the cause of this, so here are (most) of the steps taken, and why this happens:

  1. My addon's blueprint calls this.addAddonToProject(...)
  2. In lib/models/blueprint.js, the taskOptions.blueprintOptions defaults to an empty object (source)
  3. The addon-install task is looked up and run with the empty blueprintOptions (source)
  4. The addon-install task calls its own installBlueprint method with the empty blueprintOptions (source)
  5. The installBlueprint method merges the empty options before running the generate-from-blueprint task (source)
  6. Since this._processOptions in models/blueprint.js (called from the install hook) just copies values, the install hook just passes those options directly to the addon blueprint's beforeInstall, processFiles, and afterInstall hooks (source)
  7. Eventually, the processFiles hook uses this.shouldConvertToJS and this.convertToJS to transpile the files (source)
  8. shouldConvertToJS checks the typescript and isTypeScriptProject properties on the options object to determine whether or not to transpile the TS files (source)
  9. Since the options passed in don't include either property, the files are always transpiled

Potential Solution

I'm not sure if this is the best place for this to go, but I believe the blueprint model should be modified to not use an empty object for the default value of blueprintOptions (source). Either that, or the addon-install task should provide better defaults for its options that should be merged with the given options.

Current Workaround

From the snippet above, this issue can be remediated by addon-a by manually providing the isTypeScriptProject (or typescript) option(s):

 await this.addAddonToProject({
   name: 'addon-b',
   target: 'latest',
+  blueprintOptions: {
+    isTypeScriptProject: options.isTypeScriptProject,
+    typescript: options.typescript,
+  }, 
 });

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions