Code Monkey home page Code Monkey logo

addon-blueprint's People

Contributors

aklkv avatar bartocc avatar basz avatar bertdeblock avatar chancancode avatar dfreeman avatar ef4 avatar gossi avatar ignacemaes avatar ijlee2 avatar jelhan avatar levelbossmike avatar lolmaus avatar lukemelia avatar mansona avatar miguelcobain avatar nickschot avatar nullvoxpopuli avatar rwjblue avatar sergeastapov avatar simonihmig avatar void-malex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

addon-blueprint's Issues

Add new lints: publint and arethetypeswrong

I've been using publint and@arethetypeswrong/cli on a couple repos, and it's helpful for catching common footguns

these can be added to the concurrently` lint command in the addon package to help people double check that their package.json is configured correctly

publint works perfectly in my packages as is

arethetypeswrong, however, has some open issues:

Running ember-cli-update on generated v2 addon fails

Tried to update a v2 adodn created with the 1.3 version of this blueprint to the latest 1.4, using npx ember-cli-update. Which gave this error output:

Error creating new application. Removing generated directory `./ember-headless-form`
Cannot read properties of undefined (reading 'typescript')


Stack Trace and Error Report: /var/folders/w9/2p5cmdpn6sd1sbql4ynytzyr0000gn/T/error.dump.71fc2fa1a0a0e9ff14d25a835ccb7ce5.log
Error creating new application. Removing generated directory `./ember-headless-form`
Cannot read properties of undefined (reading 'typescript')


Stack Trace and Error Report: /var/folders/w9/2p5cmdpn6sd1sbql4ynytzyr0000gn/T/error.dump.f6618369a5f40caed8117658e0580f52.log
WARNING: Node v18.12.1 is not tested against Ember CLI on your platform. We recommend that you use the most-recent "Active LTS" version of Node.js. See https://git.io/v7S5n for details.
The option '--pnpm' is not registered with the 'new' command. Run `ember new --help` for a list of supported options.
The option '--ci-provider' is not registered with the 'new' command. Run `ember new --help` for a list of supported options.
The option '--typescript' is not registered with the 'new' command. Run `ember new --help` for a list of supported options.
WARNING: Node v18.12.1 is not tested against Ember CLI on your platform. We recommend that you use the most-recent "Active LTS" version of Node.js. See https://git.io/v7S5n for details.
The option '--pnpm' is not registered with the 'new' command. Run `ember new --help` for a list of supported options.
The option '--ci-provider' is not registered with the 'new' command. Run `ember new --help` for a list of supported options.
The option '--typescript' is not registered with the 'new' command. Run `ember new --help` for a list of supported options.
Error creating new application. Removing generated directory `./my-project`
Cannot read properties of undefined (reading 'typescript')


Stack Trace and Error Report: /var/folders/w9/2p5cmdpn6sd1sbql4ynytzyr0000gn/T/error.dump.4e3a1124bcb28256909920b53823657d.log
Error creating new application. Removing generated directory `./my-project`
Cannot read properties of undefined (reading 'typescript')


Stack Trace and Error Report: /var/folders/w9/2p5cmdpn6sd1sbql4ynytzyr0000gn/T/error.dump.a162f6e1bfdf06487bd6d1507d2c0912.log
Error: Command failed with exit code 1: npx [email protected] new my-project -sg -sn -sb -b @embroider/[email protected] --pnpm --ci-provider=github --typescript
WARNING: Node v18.12.1 is not tested against Ember CLI on your platform. We recommend that you use the most-recent "Active LTS" version of Node.js. See https://git.io/v7S5n for details.
The option '--pnpm' is not registered with the 'new' command. Run `ember new --help` for a list of supported options.
The option '--ci-provider' is not registered with the 'new' command. Run `ember new --help` for a list of supported options.
The option '--typescript' is not registered with the 'new' command. Run `ember new --help` for a list of supported options.
Error creating new application. Removing generated directory `./my-project`
    at makeError (/Users/sihmig/.npm/_npx/f4f35b2eda398bf9/node_modules/execa/lib/error.js:60:11)
    at handlePromise (/Users/sihmig/.npm/_npx/f4f35b2eda398bf9/node_modules/execa/index.js:118:26)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async __runEmber (/Users/sihmig/.npm/_npx/f4f35b2eda398bf9/node_modules/ember-cli-update/src/get-start-and-end-commands.js:214:11)
    at async _runEmber (/Users/sihmig/.npm/_npx/f4f35b2eda398bf9/node_modules/ember-cli-update/src/get-start-and-end-commands.js:230:11)
    at async createProject (/Users/sihmig/.npm/_npx/f4f35b2eda398bf9/node_modules/ember-cli-update/src/get-start-and-end-commands.js:245:9)
    at async _prepareCommand (/Users/sihmig/.npm/_npx/f4f35b2eda398bf9/node_modules/boilerplate-update/src/get-start-and-end-commands.js:54:17)
    at async AsyncFunction.prepareCommandUsingRemote (/Users/sihmig/.npm/_npx/f4f35b2eda398bf9/node_modules/boilerplate-update/src/get-start-and-end-commands.js:110:10)
    at async AsyncFunction.prepareCommand (/Users/sihmig/.npm/_npx/f4f35b2eda398bf9/node_modules/boilerplate-update/src/get-start-and-end-commands.js:193:10)
    at async Promise.all (index 0) {
  shortMessage: 'Command failed with exit code 1: npx [email protected] new my-project -sg -sn -sb -b @embroider/[email protected] --pnpm --ci-provider=github --typescript',
  command: 'npx [email protected] new my-project -sg -sn -sb -b @embroider/[email protected] --pnpm --ci-provider=github --typescript',
  escapedCommand: 'npx "[email protected]" new my-project -sg -sn -sb -b "@embroider/[email protected]" --pnpm "--ci-provider=github" --typescript',
  exitCode: 1,
  signal: undefined,
  signalDescription: undefined,
  stdout: 'WARNING: Node v18.12.1 is not tested against Ember CLI on your platform. We recommend that you use the most-recent "Active LTS" version of Node.js. See https://git.io/v7S5n for details.\n' +
    "The option '--pnpm' is not registered with the 'new' command. Run `ember new --help` for a list of supported options.\n" +
    "The option '--ci-provider' is not registered with the 'new' command. Run `ember new --help` for a list of supported options.\n" +
    "The option '--typescript' is not registered with the 'new' command. Run `ember new --help` for a list of supported options.\n" +
    'Error creating new application. Removing generated directory `./my-project`',
  stderr: undefined,
  failed: true,
  timedOut: false,
  isCanceled: false,
  killed: false
}

The exact reason why this blueprint fails is not as interesting as the fact that ecu runs it with an old version of EmberCLI 3.16! ๐Ÿค” One that apparently the blueprint does not work with, but that's ok IMHO, we can require to run it only with recent versions, not? (e.g. the --typescript flag in EmberCLI is only properly supported (for our use case) with 4.10.0 (currently beta)...

Which ECMAScript version to target?

According to the RFC, it should be 2019. See #1 (comment)

So should we

  • Set ESLint to 2019, to guard against publishing using later versions of the spec? Which means you also cannot author using newer features.
  • Set ESLint to latest, and add a babel transformations to our rollup config for 202x -> 2019?
  • Or was that target of 2019 the latest at the time the RFC was written, and we can actually author and publish with latest features? (relying on the app to eventually transpile)

Creating addon fails on undefined property

When trying to create a v2 addon, the script fails (regardless of any flags provided or omitted, including --typescript) with the following error:

Cannot read properties of undefined (reading 'typescript')

Full stacktrace and error report:

`=================================================================================

ENV Summary:

TIME: Thu Feb 09 2023 16:31:06 GMT-0600 (Central Standard Time)
TITLE: ember
ARGV:

  • /Users/user/.nvm/versions/node/v16.18.0/bin/node
  • /Users/user/.nvm/versions/node/v18.7.0/bin/ember
  • addon
  • vault-common
  • -b
  • @embroider/addon-blueprint
  • --yarn
  • --skip-git
  • --skip-npm
  • --test-app-name=vault-common-test-app
  • --test-app-location=addons/vault-common/test-app
  • --addon-location=addons/vault-common/package
  • --typescript
    EXEC_PATH: /Users/user/.nvm/versions/node/v16.18.0/bin/node
    TMPDIR: /var/folders/tk/b6pwmbm56bqf_fhqgx_45_hh0000gp/T
    SHELL: /bin/zsh
    PATH:
  • /Users/user/.nvm/versions/node/v16.18.0/bin
  • /Users/user/.nvm/versions/node/v18.7.0/bin
  • /usr/local/opt/[email protected]/bin
  • /opt/homebrew/bin
  • /opt/homebrew/sbin
  • /usr/local/bin
  • /System/Cryptexes/App/usr/bin
  • /usr/bin
  • /bin
  • /usr/sbin
  • /sbin
  • /usr/local/go/bin
  • /Users/user/.nvm/versions/node/v18.7.0/bin
  • /usr/local/opt/[email protected]/bin
  • /opt/homebrew/bin
  • /opt/homebrew/sbin
    PLATFORM: darwin arm64
    FREEMEM: 3779903488
    TOTALMEM: 34359738368
    UPTIME: 87986
    LOADAVG: 7.1728515625,8.90380859375,9.37451171875
    CPUS:
  • Apple M1 Max - 24
  • Apple M1 Max - 24
  • Apple M1 Max - 24
  • Apple M1 Max - 24
  • Apple M1 Max - 24
  • Apple M1 Max - 24
  • Apple M1 Max - 24
  • Apple M1 Max - 24
  • Apple M1 Max - 24
  • Apple M1 Max - 24
    ENDIANNESS: LE
    VERSIONS:
  • ares: 1.18.1
  • brotli: 1.0.9
  • cldr: 41.0
  • icu: 71.1
  • llhttp: 6.0.10
  • modules: 93
  • napi: 8
  • nghttp2: 1.47.0
  • nghttp3: 0.7.0
  • ngtcp2: 0.8.1
  • node: 16.18.0
  • openssl: 1.1.1q+quic
  • tz: 2022b
  • unicode: 14.0
  • uv: 1.43.0
  • v8: 9.4.146.26-node.22
  • zlib: 1.2.11

ERROR Summary:

  • broccoliBuilderErrorStack: [undefined]
  • code: [undefined]
  • codeFrame: [undefined]
  • errorMessage: Cannot read properties of undefined (reading 'typescript')
  • errorType: [undefined]
  • location:
    • column: [undefined]
    • file: [undefined]
    • line: [undefined]
  • message: Cannot read properties of undefined (reading 'typescript')
  • name: TypeError
  • nodeAnnotation: [undefined]
  • nodeName: [undefined]
  • originalErrorMessage: [undefined]
  • stack: TypeError: Cannot read properties of undefined (reading 'typescript')
    at Class.files (/private/var/folders/tk/b6pwmbm56bqf_fhqgx_45_hh0000gp/T/ember-cli202319-32893-z6kpe5.bycl/node_modules/@embroider/addon-blueprint/index.js:268:17)
    at Class.superWrapper [as files] (/Users/user/projects/cloud-ui/node_modules/core-object/lib/assign-properties.js:34:20)
    at Class.install (/Users/user/projects/cloud-ui/node_modules/ember-cli/lib/models/blueprint.js:449:43)
    at Class.install (/private/var/folders/tk/b6pwmbm56bqf_fhqgx_45_hh0000gp/T/ember-cli202319-32893-z6kpe5.bycl/node_modules/@embroider/addon-blueprint/index.js:45:32)
    at Class.superWrapper [as install] (/Users/user/projects/cloud-ui/node_modules/core-object/lib/assign-properties.js:34:20)
    at InstallBlueprintTask.run (/Users/user/projects/cloud-ui/node_modules/ember-cli/lib/tasks/install-blueprint.js:49:21)
    at async Class.run (/Users/user/projects/cloud-ui/node_modules/ember-cli/lib/commands/init.js:93:5)
    at async Class.run (/Users/user/projects/cloud-ui/node_modules/ember-cli/lib/commands/new.js:93:22)
    at async /Users/user/projects/cloud-ui/node_modules/ember-cli/lib/cli/cli.js:204:32
    at async CLI.run (/Users/user/projects/cloud-ui/node_modules/ember-cli/lib/cli/cli.js:251:14)

=================================================================================
`

Make release-it setup opt-in/-out

I'd prefer to see something like this be opt-in (or at least opt-out-able ๐Ÿ™‚)

I'm a happy user of release-it in OSS projects in general, but at work we have a whole set of internal infrastructure that manages package releases, and if possible I'd like to avoid having to document that folks need to manually undo the results of running rwjblue-release-it-setup in freshly-generated addons.

Originally posted by @dfreeman in #4 (comment)

Should the addon declare a node dependency?

Currently the v2 addon here in the blueprint, but also other v2 addons in the wild (e.g. ember-page-title), have an engines.node declaration in their package.json. While they have some dependencies (at least @embroider/addon-shim) that run in node (which express their node dependency on their own), the addon itself is supposed to be static browser-based/idiomatic JavaScript.

So it seems to me we should remove the declaration?

Typescript declarations break build

Reproduction:

  1. Make a new addon using the --typescript flag.

  2. Paste this code into the addon's index.ts:

    export class Example {
      declare myField: string;
    }
  3. Run the addon's build. You get this error:

SyntaxError: /Users/edward/hacking/v2-example/v2-example/src/index.ts: TypeScript 'declare' fields must first be transformed by @babel/plugin-transform-typescript.
If you have already enabled that plugin (or '@babel/preset-typescript'), make sure that it runs before any plugin related to additional class features:
 - @babel/plugin-proposal-class-properties
 - @babel/plugin-proposal-private-methods
 - @babel/plugin-proposal-decorators
  1 | export class Example {
> 2 |   declare myField: string;
    |   ^^^^^^^^^^^^^^^^^^^^^^^^
  3 | }
  4 |

I'm not sure exactly how to fix this while still using the typescript preset, because you can't interleave presets and plugins. As far as I know, the plugins always run before the presets.

Yarn does not allow duplicate workspace names

Got this error on 1.5

โฏ npx ember-cli addon ember-qunit -b @embroider/addon-blueprint
Command failed with exit code 1: yarn install
Internal Error: Duplicate workspace name ember-qunit: Development/tmp/ember-qunit/ember-qunit conflicts with Development/tmp/ember-qunit

Setup CI for latest node version?

It seems rollup-plugin-ts dropped node 14 support without a new major.

The blueprint emits a Github workflow using node 14, which will make a TS addon fail with the new version, and when running with our ootb floating dependencies scenario. But given that v2 addons actually don't have a dependency on node, it's just used for our prepublish rollup build, should we then switch to running the latest node in CI instead?

Build fails immediately after creating addon

It seems once you create the addon the build fails immediately due to there being no hbs files to lint. I think we should either A) add a hbs file so it passes or B) remove the hbs linting step and let the user add it in

Add better test coverage

  • smoke tests that assert that the generated addon passes linting and tests
  • fixture-based tests that assert for specific content of generated files (especially including those not covered by smoke tests above, like generated .md, ci.yml etc.). Related:

Move `.md` files to published package

Suggest to move README.md, LICENSE.md and CHANGELOG.md from the repository root into the ./packages/__name__ directory.

In doing so, the three files will be picked up by npm pack and npm publish respectively, so that the npmjs.com listing shows
the proper README.md instead of an error message about missing readme, and so that these files are also available in the users node_modules.

We should also add symlinks from the old location to the new location (I wonder if blueprints can contain symlinks), so that GitHub still renders the repository overview correctly. It's important, that the files are physically moved instead of just symlinked into the package, as npm pack doesn't follow symlinks.

CONTRIBUTING.md should not be moved, as it's only relevant in the context of the repository.

Remove yarn as default

when using default options with this blueprint in particular, the package manager is switched to yarn.

when using --addon-only it's npm.

Let's remove the logic for setting up yarn by default to align with everything else and npm is default anyway

Info: dependenciesMeta.*.injected

When using dependenciesMeta.*.injected (ie: the most correct way to manage in-repo dependencies, as it simulates what would happen when installed from npm), you need a too like this: https://github.com/NullVoxPopuli/pnpm-sync-dependencies-meta-injected

however buying in to that tool, and using turbo to manage it, is def out of scoped for a blueprint project.

so, I'm planning on making another blueprint that applies recommended turbo + pnpm configurations (for at least my projects anyway) -- NullVoxPopuli/ember-apply#463

Goals:

  • run prettier after eslint, but still together in the "Lint" task
  • publint
  • arethetypeswrong
  • depMeta*injected syncing
  • turbo
  • tool for skipping whole CI jobs based on turbo's cache queries

Incorrect peer setup (revealed with pnpm, npm8)

in an addon,

.
โ”œโ”€โ”ฌ @glint/environment-ember-loose 0.9.7
โ”‚ โ”œโ”€โ”€ โœ• missing peer @glimmer/component@^1.1.2
โ”‚ โ”œโ”€โ”€ โœ• missing peer ember-cli-htmlbars@^6.0.1
โ”‚ โ””โ”€โ”ฌ @glint/template 0.9.7
โ”‚   โ””โ”€โ”€ โœ• missing peer @glimmer/component@^1.1.2
โ”œโ”€โ”ฌ ember-template-lint 4.18.2
โ”‚ โ””โ”€โ”ฌ ember-template-imports 3.4.0
โ”‚   โ””โ”€โ”€ โœ• missing peer ember-cli-htmlbars@^6.0.0
โ””โ”€โ”ฌ @types/ember__test-helpers 2.9.1
  โ””โ”€โ”ฌ @ember/test-helpers 2.9.3
    โ”œโ”€โ”€ โœ• missing peer ember-source@>=3.8.0
    โ””โ”€โ”ฌ @embroider/util 1.9.0
      โ””โ”€โ”€ โœ• missing peer ember-source@"*"
Peer dependencies that should be installed:
  @glimmer/component@">=1.1.2 <2.0.0"
  ember-cli-htmlbars@">=6.0.1 <7.0.0"
  ember-source@>=3.8.0

So we need to add the 3 recommended dependencies to the peer list, because we ship glint by default"

ember-cli-htmlbars is a bit silly though, so I'm going to add a pnpm.ignore entry for that (idk how to do the equiv for npm)

Support TypeScript

When RFC800 has landed, especially the --typescript flag for ember addon (see https://emberjs.github.io/rfcs/0800-ts-adoption-plan.html#cli-integration), we should support that here as well. Especially as we need to compile TypeScript in rollup, so support in addons is not as trivial as for v1 addons (ember install ember-cli-typescript).

Some prior art:

NVP's future plans for the v2 addon blueprint

To make things "easiest by default", while still also allowing for the correctness for power-users today, I'd like to propose we (eventually):

  • make the blueprint output a uni-repo by default
    • this will only be possible once the vite work is finished in the embroider repo
    • Vite will manage the development environment
    • tests folder in the addon (but no evidence of an ember app anywhere (as we have with the dummy app in v1 addons)
    • The details of the test app are wholly within a vite plugin provided by @embroider/addon-dev
    • same or better browser / CLI ergonomics as in v1 addons (this is prototyped in the glimmer-vm repo)
    • this would be the only way we can have ember-cli support blueprints / ember g today -- unless we somehow have a way to tell ember-cli about monorepo layouts -- e.g.: generate component in workspace A, and test in workspace B, etc.
  • make existing flags require the use of a --monorepo flag
    This is pretty much the inverse of --addon-only today, but we'd add some assertions so folks are not able to mix and match and potentially observe unexpected behavior (for example, --addon-only with --test-app* doesn't make sense).
    Supporting monorepo is still important because it greatly increases the liklihood that an addon is built successfully and is ensured to work once published to npm. Additionally, for testing multiple-dependency scenarios without tons of build macros requires additional test-apps (unless folks like lots of build time conditionals in their test code)
    These args would be gated behind --monorepo
    • --addon-location
    • --test-app-location
    • --test-app-name

Obvious caveats:

  • my plan
  • i've barely talked about it with folks
  • lots to do before work here can even start

Add `type-tests` folder to addon folder when `--typescript` is enabled

Library for testing types: expect-type (what ember-source uses).

Example:

Will require that we update the eslint configs (I had to do that for my own stuff here)


Open questions:

  • ember.js has a separate tsconfig.json for the type tests -- do we need this? I did not find that I needed it for ember-resources

    answer: we do need this -- ember-resources' types are generated through rollup, rather than tsc/glint

Provide documentation for advanced monorepo layouts

Provide recommendations and instructions for how to structure the monorepo (see #2) for advanced use cases:

  • multiple addons
  • multiple test-apps
  • docs app (it's conceptionally supported by the default blueprint, but the blueprint does not set this up by default)

Automate publishing with `release-it`?

Should we run or add the output of yarn create rwjblue-release-it-setup to the blueprint?

I found this to be super useful. However the v1 blueprint does not have this, so maybe adding this becomes controversial when backporting this to the main ember-cli repo?

On the other hand, it makes publishing so much easier, especially in a monorepo with potentially multiple public packages, or just that it automates the internal cross-references (addon being a dependency of test-app).

Document addon release process

Releasing v2 addon is not entirely trivial, so would be good to have a way to tell folks how to do this.

cd my-addon-git-repo
cd my-addon # because v2 folder nesting
yarn version && yarn publish

Given that people might prefer variety of tools (yarn / npm / ...) it might be a good idea to document this in *.md file, so that people can follow & adapt.

Proposal:

  • Add RELEASE.md file
  • This file will have a way to release npm package

Planning --pnpm support, questions about yarn / npm workspaces

So, in my v2 addon projects, I have this for scripts:

  "scripts": {
    "dev": "concurrently 'npm:dev:*' --restart-after 5000 --prefix-colors cyan,white,yellow",
    "dev:ember": "pnpm run --filter ember-app start",
    "dev:addon": "pnpm run --filter ember-resources start --no-watch.clearScreen",
    "dev:docs": "pnpm run --filter docs docs:watch --preserveWatchOutput",
    "ci:update": "npx ember-ci-update",
    "build": "pnpm run --filter ember-resources build",
    "lint": "pnpm run --filter '*' lint:js --fix"
  },

Some notes aand key differences between this and what is currently in the blueprints

  • concurrently instead of npm-run-all
    • concurrently is actively maintained, less vebose, better log output, etc
  • I'm mixing terms, "dev" and "start" -- I think unifying on "start" is probably good to keep for us
  • --restart-after 5000 is because ember-cli constantly crashes when addons' dist files are changed and you have a browser trying to load the app. See: ember-cli/ember-cli#9584 (and all related links / refs -- big problem, and it's kind of embarassing no one has fixed it ๐Ÿ˜… (and I'm also to blame for why it hasn't been fixed))

Questions:

  • I saw that @bertdeblock proposed --package-manager -- ember-cli/ember-cli#9879 -- maybe we use this instead of --pnpm
  • does yarn have something like --filter "*" this greatly reduces boilerplate, as we can have "test": "pnpm run --filter '*' test" as well.
  • is npm even worth supporting?

Move/copy config/ignore entries for monorepo root to addon-workspace

Not to say we shouldn't keep the files in the root directory, we just need to change what's in them.

This includes (some of these are already in the addon directory, but are missing info)

  • .gitignore
  • .eslintignore
  • .prettierignore
  • .prettierrc.cjs
  • .eslintrc.cjs

every other blueprint in the ember ecosystem has atomic workspaces

  • contains its own ignore files
  • can by "drag'n'drop refactored"

The top-level ignore files are still helpful, because editors are what run prettier / etc outside of workspaces.

Additionally, our blueprint doesn't even run prettier from the root directory.

This would also allow the --addon-only flag to "just work" without having additional logic (like we have now (? (need to check)) for moving files that would be in the root to the addon workspace (because it's the only workspace with --addon-only)

TypeScript: let's discuss options, rollup-plugin-ts isn't working for us (as in: it's too much trouble)

A few of us have had a number of problems with rollup-plugin-ts over time.
Most recently, a removal here: embroider-build/embroider#1510

One strategy that I've done is to compile everything with babel, and compile types in a separate process.
For folks that don't have gjs/gts they can use @rollup/plugin-typescript and have that plugin generate the types for them.
@rollup/plugin-typescript provides transformer options -- but because we transform gjs/gts files via a pre-parse-transformer (provided by ember-template-imports for the most part), we don't (yet?) have a way to use @rollup/plugin-typescript (it errors on gts imports, which you'd normally solve by adding @rollup/plugin-node-resolve, but tsc doesn't respect that plugin (it also wouldn't solve the transform of <template> issue).

So, what I've found that works is:

  • one process for transpile
  • one process for types

which, alone isn't sufficient, because we remove the dist folder via addon.clean().
but, we can make inline plugins, so I've done this for my latest rollup config:

import copy from 'rollup-plugin-copy';
import { babel } from '@rollup/plugin-babel';
import { Addon } from '@embroider/addon-dev/rollup';
import { glimmerTemplateTag } from 'rollup-plugin-glimmer-template-tag';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import { execa } from 'execa';

const addon = new Addon({
  srcDir: 'src',
  destDir: 'dist',
});

const extensions = ['.js', '.ts', '.gts', '.gjs', '.hbs', '.json'];

export default {
  output: addon.output(),
  plugins: [
    addon.publicEntrypoints(['**/*.js']),
    addon.appReexports(['components/*.js', 'helpers/**/*.js']),
    addon.dependencies(),
    addon.hbs(),
    glimmerTemplateTag(),
    nodeResolve({ extensions }),
    babel({ extensions, babelHelpers: 'inline' }),
    addon.keepAssets(['**/*.css']),
    {
      name: 'generate type declarations',
      async writeBundle() {
        await execa('glint', ['--build']);
      },
    },
    addon.clean(),
    copy({
      targets: [
        { src: '../README.md', dest: '.' },
        { src: '../LICENSE.md', dest: '.' },
      ],
    }),
  ],
};

and for my tsconfig.json:

{
  "extends": "@tsconfig/ember/tsconfig.json",
  "include": ["src/**/*", "unpublished-development-types/**/*"],
  "glint": {
    "environment": ["ember-loose", "ember-template-imports"]
  },
  "compilerOptions": {
    "declarationDir": "dist",
    "emitDeclarationOnly": true,
    "noEmit": false
  }
}

and for my babel:

'use strict';

module.exports = {
  presets: ['@babel/preset-typescript'],
  plugins: [
    ['@babel/plugin-transform-typescript', { allowDeclareFields: true }],
    'ember-template-imports/src/babel-plugin',
    '@embroider/addon-dev/template-colocation-plugin',
    ['@babel/plugin-proposal-decorators', { legacy: true }],
    '@babel/plugin-proposal-class-properties',
  ],
};

So... this works, but it's obviously not as performant as we'd like. At the end of each build, we boot up a whole typescript/glint compile -- thankfully tsc/glint has a cache, but we still pay boot/parse/cache-check time that we otherwise wouldn't pay if we had a native watch integration with rollup.

Automatically disable prototype extensions in test app?

To make sure addons don't accidentally depend on prototype extensions, as they could be disabled in the host app.
The easiest solution would probably be to add ember-disable-prototype-extensions to the test app's package file?

Support operation within existing monorepo

The current blueprint does not allow creating new v2 addon within an existing monorepo easily, unlike what the Readme says. Although we have customization options like --addon-location, these only allow creating the addon structure in a temporary path and then copying things over to the actual monorepo. But ideally we would be able to do...

cd existing-repo
ember addon my-addon -b @embroider/addon-blueprint --addon-location=packages/my-addon/addon --test-app-location=packages/my-addon/test-app --test-app-name=my-addon-test-app --skip-git

This would:

  • omit all root files, especially package.json
  • put README.md et al directly into the adodn folder, and not copy-on-build

This fails though:

  • ember addon forcefully creates a new my-addon directory here, so we would end up with the addon being in existing-repo/my-addon/packages/my-addon/addon instead of existing-repo/packages/my-addon/addon. EmberCLI does not seems to have a way to prevent that.
  • another approach would be to use the simpler generate command, which does not have this behaviour, as e.g. ember g in-repo-addon my-addon -b @embroider/addon-blueprint ..., but this also fails due to
    • the generate command expecting to be run inside an EmberCLI project, which existing-repo is not
    • the custom blueprint option -b not being supported here

How can we solve this?

  • copy stuff from existing-repo/my-addon/* to .. on afterInstall? ๐Ÿคจ
  • Create the missing functionality in EmberCLI? Would require all users to use that version of EmberCLI...
  • Use our own blueprint infrastructure not related to EmberCLI (or something of the shelve from npm)

dist branch: Yarn complains that rollup is not found when consuming the addon

When adding the addon created via the blueprint as a dependency in the package.json file using the form:
"addon-name": "https://github.com/name/repo-name#dist
Yarn complains with the following error:

Packing addon-name@https://github.com/name/repo.git#commit=commitSha from sources
No package manager configuration detected; defaulting to Yarn
yarn pack v1.22.19
$ rollup --config
/bin/sh: rollup: command not found
error Command failed with exit code 127.
info Visit https://yarnpkg.com/en/docs/cli/pack for documentation about this command.

The one lint config to rule them all (also how to get gjs/gts linting going)

A proposal in brief:

Covers:

  • app
  • addon
  • v2 addon
  • JS / gjs
  • TS / gts
  • all node files added to the root directory of any project
  • easy to change
  • conditional typescript -- based on the inclusion of typsecript as a resolveable module -- cc @chriskrycho
  • I want to recommend this for the default blueprint for apps/addons in ember-cli as well

Thoughts?:

sample repo if cloning is easier: https://github.com/NullVoxPopuli/ember-lint-demonstrate-overrides-based-config

But also trying this out on a real project: NullVoxPopuli/limber#545

'use strict';

function hasDep(depName) {
  try {
    return Boolean(require.resolve(depName));
  } catch (e) {
    if (e.message.startsWith(`Cannot find module '${depName}'`)) return false;

    throw e;
  }
}

function proposedEmberDefault(personalPreferences) {
  let hasTypeScript = hasDep('typescript');

  const configBuilder = {
    modules: {
      browser: {
        get js() {
          return {
            files: [
              '{src,app,addon,addon-test-support,tests}/**/*.{gjs,js}',
              'tests/dummy/config/deprecation-workflow.js',
              'config/deprecation-workflow.js',
            ],
            parser: 'babel-eslint',
            parserOptions: {
              ecmaVersion: 2022,
              sourceType: 'module',
              ecmaFeatures: {
                legacyDecorators: true,
              },
            },
            plugins: ['ember'],
            extends: [
              'eslint:recommended',
              'plugin:ember/recommended',
              'plugin:prettier/recommended',
            ],
            env: {
              browser: true,
            },
            rules: {
              ...personalPreferences.rules,
            },
          }
        },
        get ts() {
          if (!hasTypeScript) return;

          return {
            files: ['{src,app,addon,addon-test-support,tests,types}/**/*.{gts,ts}'],
            parser: '@typescript-eslint/parser',
            plugins: ['ember'],
            extends: [
              'eslint:recommended',
              'plugin:ember/recommended',
              'plugin:prettier/recommended',
              'plugin:@typescript-eslint/recommended',
            ],
            env: {
              browser: true,
            },
            rules: {
              // type imports are removed in builds
              '@typescript-eslint/consistent-type-imports': 'error',

              // prefer inference, but it is recommended to declare
              // return types around public API
              '@typescript-eslint/explicit-function-return-type': 'off',
              '@typescript-eslint/explicit-module-boundary-types': 'off',

              // Allows placeholder args to still be defined for
              // documentation or "for later" purposes
              '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
              ...personalPreferences.rules,
            },
          }
        },
        get declarations() {
          if (!hasTypeScript) return;

          return {
            files: ['**/*.d.ts'],
            extends: [
              'eslint:recommended',
              'plugin:prettier/recommended',
              'plugin:@typescript-eslint/recommended',
            ],
            env: {
              browser: true,
            },
            rules: {
              '@typescript-eslint/no-empty-interface': 'off'
            }
          }
        }
      },
      tests: {
        get js() {
          let browserJS = configBuilder.modules.browser.js;
          return {
            ...browserJS,
            files: ['tests/**/*-test.{gjs,js}'],
            extends: [...browserJS.extends, 'plugin:qunit/recommended'],
          }
        },
        get ts() {
          if (!hasTypeScript) return;

          let browserTS = configBuilder.modules.browser.ts;

          return {
            ...browserTS,
            files: ['tests/**/*-test.{gts,ts}'],
            extends: [...browserTS.extends, 'plugin:qunit/recommended'],
          }
        },
      }
    },
    commonjs: {
      node: {
        get js() {
          return {
            files: [
              './*.{cjs,js}',
              './config/**/*.js',
              './lib/*/index.js',
              './server/**/*.js',
              './blueprints/*/index.js',
            ],
            parserOptions: {
              sourceType: 'script',
            },
            env: {
              browser: false,
              node: true,
            },
            plugins: ['node'],
            extends: ['plugin:node/recommended'],
            rules: {
              ...personalPreferences.rules,
              // this can be removed once the following is fixed
              // https://github.com/mysticatea/eslint-plugin-node/issues/77
              'node/no-unpublished-require': 'off',
            },
          }
        }
      }
    }
  }

  return configBuilder;
}


const personalPreferences = {
  rules: {
    // const has misleading safety implications
    // look in to "liberal let"
    'prefer-const': 'off',

    // people should know that no return is undefined in JS
    'getter-return': ['error', { allowImplicit: true }],

    'padding-line-between-statements': [
      'error',
      { blankLine: 'always', prev: '*', next: 'return' },
      { blankLine: 'always', prev: '*', next: 'break' },
      { blankLine: 'always', prev: '*', next: 'block-like' },
      { blankLine: 'always', prev: 'block-like', next: '*' },
      { blankLine: 'always', prev: ['const', 'let'], next: '*' },
      { blankLine: 'always', prev: '*', next: ['const', 'let'] },
      { blankLine: 'any', prev: ['const', 'let'], next: ['const', 'let'] },
      { blankLine: 'any', prev: ['*'], next: ['case'] },
    ],
  },
}

const config = proposedEmberDefault(personalPreferences);

module.exports = {
  root: true,
  /**
   * No root rules needed, because we define everything with overrides
   * so that understanding what set of rules is applied to what files
   * is easier to understand.
   *
   * This can be debugged with
   *
   * eslint --print-config ./path/to/file
   */
  rules: {},
  overrides: [
    config.commonjs.node.js,
    config.modules.browser.js,
    config.modules.browser.ts,
    config.modules.browser.declarations,
    config.modules.tests.js,
    config.modules.tests.ts,
  ].filter(Boolean),
};

release-it stuff errors, preventing addon generation

having a flag like #9 would be really good.

Here is the error I got:

 ember addon my-addon -b ../NullVoxPopuli/addon-blueprint/
# ....
Error creating new application. Removing generated directory `./my-addon`
Command failed with ENOENT: create-rwjblue-release-it-setup --no-install
spawn create-rwjblue-release-it-setup ENOENT


Stack Trace and Error Report: /tmp/error.dump.db9873fe8c3dfb583cc98606cb31108f.log

when this error occurs, the addon directory is removed.

Pros & Cons of workspace layouts

This tries to summarizes the pros & cons of the different possible directory layouts for organizing the different packages of a v2 addon in a monorepo:

/packages/* /packages/* + /test-apps/* + /docs /addon + /test-app + /docs /addon + /test-apps/* + /docs /<addon-name> + /test-app + /docs
Where to put addon /packages/my-addon /packages/my-addon /addon /addon /<addon-name>
Where to put test-app /packages/test-app /test-apps/default ? /test-app /test-apps/default ? /test-app
Where to put docs-app /packages/docs /docs /docs /docs /docs
Fosters monorepo discoverability 1 โœ… โœ… โŒ โญ•๏ธ โœ…
Supports multiple addons โœ… โœ… โŒ โŒ โœ…
Supports multiple test-apps โœ… โœ… โŒ โœ… โญ•๏ธ
Easy to understand โญ•๏ธ โญ•๏ธ โœ… โœ… โœ…
Good for few packages โœ… โญ•๏ธ โœ… โœ… โœ…
Good for many packages โญ•๏ธ โœ… โŒ โŒ โญ•๏ธ
Used by ember-stargate similar to Embroider ember-page-title ember-resources

โœ… = well supported
โญ•๏ธ = so-so
โŒ = not supported

1 - easy to grasp that existing packages are not static, but can be extended at any time

Does the README usage section work?

When I try:

โฏ ember addon my-addon -b @embroider/addon-blueprint --yarn

I get:

Error creating new application. Removing generated directory `./my-addon`
Command failed with exit code 1: npm install --no-package-lock --save @embroider/addon-blueprint
npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@embroider%2faddon-blueprint - Not found
npm ERR! 404
npm ERR! 404  '@embroider/addon-blueprint@*' is not in this registry.
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/michal/.npm/_logs/2022-06-25T18_12_15_560Z-debug-0.log


Stack Trace and Error Report: /var/folders/8q/yrjx_8s115q43r8w5qd90_m00000gn/T/error.dump.8997ea6d390387a3e22356075c7a9c29.log

pnpm flag still runs yarn

Using the --pnpm flag correctly produces a ppm-workspace.yaml file, but the actual package install runs yarn.

I ran:

ember addon glimmer-scoped-css -b @embroider/addon-blueprint --pnpm --typescript

Using

ember-cli: 4.10.0
node: 16.19.0
os: darwin arm64

The output shows yarn running and produces a yarn.lock file and not a pnpm lock file.

Error when passing `--release-it`

Currently running:

ember addon ember-new-v2-addon-testr -b @embroider/addon-blueprint --pnpm --skip-npm --typescript --release-it

and getting:

Error creating new application. Removing generated directory `./ember-new-v2-addon-test`
Command failed with exit code 1: create-rwjblue-release-it-setup --no-install
[HttpError: Not Found] {
  statusCode: 404,
  headers: {
    server: 'GitHub.com',
    date: 'Wed, 22 Mar 2023 02:37:06 GMT',
    'content-type': 'application/json; charset=utf-8',
    'content-length': '106',
    'x-github-media-type': 'github.v3; param=symmetra-preview; format=json',
    'x-github-api-version-selected': '2022-11-28',
    'x-ratelimit-limit': '60',
    'x-ratelimit-remaining': '48',
    'x-ratelimit-reset': '1679456172',
    'x-ratelimit-used': '12',
    'x-ratelimit-resource': 'core',
    'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset',
    'access-control-allow-origin': '*',
    'strict-transport-security': 'max-age=31536000; includeSubdomains; preload',
    'x-frame-options': 'deny',
    'x-content-type-options': 'nosniff',
    'x-xss-protection': '0',
    'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin',
    'content-security-policy': "default-src 'none'",
    vary: 'Accept-Encoding, Accept, X-Requested-With',
    'x-github-request-id': 'E2D8:2E7B:5B89B1:BC9C65:641A69D2',
    connection: 'close'
  },
  body: {
    message: 'Not Found',
    documentation_url: 'https://docs.github.com/rest/reference/issues#create-a-label'
  },
  method: 'POST',
  endpoint: '/repos/esbanarango/ember-new-v2-addon-test/labels'
}
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Error: Not Found".] {
  code: 'ERR_UNHANDLED_REJECTION'
}

Node.js v18.14.2


Stack Trace and Error Report: /var/folders/jq/k7tk0_dx5yvc0cxl4q3ll7680000gp/T/error.dump.581f5380f88e7166d5a81988b66fa7e3.log

Confusing package.json script interactions

Out of the box, yarn test at the top-level emits a confusing warning because it runs the test script in every package and the test script in the addon just echos a warning.

Also, the current setup runs linting in CI twice, because it runs both yarn lint as a dedicated step, but also includes linting in the test-app's test script.

Inconstistent prettier config

My IDE (with prettier on-save enabled) keeps on formatting the any file (as expected), but this causes eslint errors to pop up, related to prettier-eslint integration. So it seems eslint uses a different prettier config than what is configured in our .prettierrc.js. And indeed these configs are hardcoded here: https://github.com/NullVoxPopuli/eslint-configs/blob/main/configs/base.js#L97.

At the very least we should make our .prettierrc.js match these settings. But I think actually the eslint plugin should just take whatever prettier config the project has!?

cc @NullVoxPopuli

Cannot generate addon with typescript

ember -v
ember-cli: 4.9.2
node: 18.12.1
os: darwin arm64

Executing ember addon demo -b @embroider/addon-blueprint --typescript results in

  create tests/integration/.gitkeep
  create tests/test-helper.ts
  create tests/unit/.gitkeep
  install addon ember-cli-typescript

๐Ÿšง  Installing packages... This might take a couple of minutes.
Error creating new application. Removing generated directory `./demo`
Command failed with exit code 1: yarn add --dev ember-cli-typescript --non-interactive
error Running this command will add the dependency to the workspace root rather than the workspace itself, which might not be what you want - if you really meant it, make it explicit by running this command again with the -W flag (or --ignore-workspace-root-check).
yarn add v1.22.19

Running ember addon demo -b @embroider/addon-blueprint --typescript -W results in the same issue

Running ember addon v2-demo -b @embroider/addon-blueprint --typescript --ignore-workspace-root-check also has the same error

Cannot find module '@babel/plugin-proposal-object-rest-spread'

Seen this in one of my addons, but also happening here in CI.

This is happening because of some sloppy dependency handling in plugin-rollup-ts, as it tries to resolve these babel blugins without actually declaring any dependency whatsoever on them. I guess this accidentally worked because of some looseness of package managers, where some other dependency brought those in. Strangely enough that was even the case for pnpm!

This was only popping up now (when ignoring the lockfile!), presumably because those other dependencies changed something to not make those plugins resolvable anymore..

As already reported in wessberg/rollup-plugin-ts#189 long time ago, using these plugins shouldn't actually happen at all. So I hope landing this PR will actually fix both issues.

Also reported upstream here, posting here for visibility.

build:types script doesn't work

The build:types script from #136 (i.e. glint --declaration) did not work for ember-container-query. I noticed that the declarations folder is missing entirely.

I looked into what the scripts should be, so that they work for both tsc and glint cases:

/* package.json for projects with Glint */
"scripts": {
  "build:types": "glint --build",
  "lint:types": "glint --project tsconfig.development.json",
  "start:types": "glint --declaration --watch",  // ideally, we can run just `glint --watch`
}
/* package.json for projects without Glint */
"scripts": {
  "build:types": "tsc --build",
  "lint:types": "tsc --project tsconfig.development.json",
  "start:types": "tsc --watch"
}
/* tsconfig.json */
{
  "extends": "@tsconfig/ember/tsconfig.json",
  "compilerOptions": {
    "declaration": true,
    "declarationDir": "declarations",
    "emitDeclarationOnly": true,
    "noEmit": false
  },
  "include": [
    "src/**/*",
    "unpublished-development-types/**/*"
  ]
}
/* tsconfig.development.json */
{
  "extends": "@tsconfig/ember/tsconfig.json",
  "compilerOptions": {
    "declaration": true,
    "declarationDir": "declarations"
  },
  "include": [
    "src/**/*",
    "unpublished-development-types/**/*"
  ]
}

Command failed with ENOENT: create-rwjblue-release-it-setup --no-install

When I try to run this blueprint directly from the git repo like this:

npx ember-cli new my-shiny-new-addon -b embroider-build/addon-blueprint

I see the following error:

Error creating new application. Removing generated directory `./my-shiny-new-addon`
Command failed with ENOENT: create-rwjblue-release-it-setup --no-install
spawn create-rwjblue-release-it-setup ENOENT
Full output
installing ember-v2-addon-blueprint
  create .editorconfig
  create .github/workflows/ci.yml
  create .prettierignore
  create .prettierrc.js
  create CONTRIBUTING.md
  create LICENSE.md
  create README.md
  create .gitignore
  create package.json
  create packages/my-shiny-new-addon/.eslintignore
  create packages/my-shiny-new-addon/.eslintrc.js
  create packages/my-shiny-new-addon/.template-lintrc.js
  create packages/my-shiny-new-addon/addon-main.js
  create packages/my-shiny-new-addon/babel.config.json
  create packages/my-shiny-new-addon/package.json
  create packages/my-shiny-new-addon/rollup.config.js
  create packages/my-shiny-new-addon/src/index.js
  create test-app-overrides/config/ember-try.js
  create test-app-overrides/ember-cli-build.js
installing app
Ember CLI v4.3.0

โœจ  Creating a new Ember app in /Users/dfreeman/Desktop/Scratch/my-shiny-new-addon:
  create .editorconfig
  create .ember-cli
  create .eslintignore
  create .eslintrc.js
  create .prettierignore
  create .prettierrc.js
  create .template-lintrc.js
  create .travis.yml
  create .watchmanconfig
  create README.md
  create app/app.js
  create app/components/.gitkeep
  create app/controllers/.gitkeep
  create app/helpers/.gitkeep
  create app/index.html
  create app/models/.gitkeep
  create app/router.js
  create app/routes/.gitkeep
  create app/styles/app.css
  create app/templates/application.hbs
  create config/ember-cli-update.json
  create config/environment.js
  create config/optional-features.json
  create config/targets.js
  create ember-cli-build.js
  create .gitignore
  create package.json
  create public/robots.txt
  create testem.js
  create tests/helpers/index.js
  create tests/index.html
  create tests/integration/.gitkeep
  create tests/test-helper.js
  create tests/unit/.gitkeep
  create vendor/.gitkeep
Error creating new application. Removing generated directory `./my-shiny-new-addon`
Command failed with ENOENT: create-rwjblue-release-it-setup --no-install
spawn create-rwjblue-release-it-setup ENOENT


Stack Trace and Error Report: /var/folders/6w/fd1g7pqj4vj0n3w28l2fql940000gn/T/error.dump.80a9ca3c7f0b2b198a802f12adbd91a2.log

(The log file doesn't contain any additional info, just a shallow processTicksAndRejections backtrace)

Rollup clean plugin causes noisy build errors

I think that the clean we have in the rollup config causes transient-but-noisy build errors in the test-app. Because it starts the build by removing everything in dist, the test-app can rebuild and find things missing and get build and/or type errors.

This seems better if you remove clean. The downside is that there is no automatic removal of build artifacts if you really do delete something from your source.

--volta flag?

Volta is a common tool used amongst addon authors -- would it make sense to have a --volta flag to pre-configure the volta entries?

root package.json

volta: {
  node: "{whatever current is}",
}

and for each generated workspace:

volta: {
  extends: path.relative(here, wherever the root is)
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.