diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 53f377618..3eb875667 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -48,7 +48,7 @@ Note: The fact that the synthesized module is _not_ persisted to disk means that **Invariants:** -- The core **template DSL** has no knowledge of semantics that are particular to a given environment (e.g. GlimmerX's functions-as-modifiers), nor of any built-in globals or keywords.[^dsl-invariants] +- The core **template DSL** has no knowledge of semantics that are particular to a given environment, nor of any built-in globals or keywords.[^dsl-invariants] - Code emitted by the **transform** layer never directly references `@glint/template`. Rather, **environment** packages re-export the contents of `@glint/template` with tweaks or additions to the types that reflect their runtime behavior. This typically includes declaring the set of available `Globals` and defining appropriate semantics for `resolve`. [^dsl-invariants]: It does have _definitions_ for a small number of keywords that are core to the VM, but it's still up to individual environments to expose them. @@ -124,4 +124,4 @@ This relationship looks roughly like this: [matklad]: https://matklad.github.io/2021/02/06/ARCHITECTURE.md.html -[^env]: Each environment is specific to a single context (“environment”) like Ember, GlimmerX, etc. Accordingly, they are likely to move _out_ of the Glint monorepo in the long-term, but will remain part of the Glint ecosystem and working model. +[^env]: Each environment is specific to a single context (“environment”) like Ember, etc. Accordingly, they are likely to move _out_ of the Glint monorepo in the long-term, but will remain part of the Glint ecosystem and working model. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 215879285..c0faa13cb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,7 +42,7 @@ There are a few VSCode Launch Configurations within `./vscode/launch.json` that - In this mode, both language servers will provide duplicate completions and suggestions, which can be useful for testing out feature parity between Glint and TS - Debug Extension (Glint Only) - This is useful for testing out the "takeover" mode of running Glint, where Glint is responsible for providing all of the language features (debugging, diagnostics, etc); this is the ideal way to run Glint, but at the time of writing we have not yet achieved feature parity with built-in TS -- By default these extensions will launch the VSCode Extension Host in the `test-packages` subfolder, which have Ember and Glimmerx apps that you can do some basic testing on +- By default these extensions will launch the VSCode Extension Host in the `test-packages` subfolder, which have Ember apps that you can do some basic testing on - _TIP_: you can open any workspace with the Extension Host, meaning you can even debug the language server with breakpoints on a totally separate Ember repo, for example. - _NOTE_: debugging takes place within the `glint` workspace, i.e. if you are debugging completions, you'd trigger a completion within the Extension Host, and the breakpoint would pause within the Glint workspace VSCode instance. diff --git a/README.md b/README.md index 327cc5ba6..1ed71a46d 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,10 @@ TypeScript-powered tooling for Glimmer templates. ## Overview -[Glint] is a set of tools to aid in developing code that uses the Glimmer VM for rendering, such as [Ember.js] v3.24+ and [GlimmerX] projects. Similar to [Vetur] for Vue projects or [Svelte Language Tools], Glint consists of a CLI and a language server to provide feedback and enforce correctness both locally during editing and project-wide in CI. +[Glint] is a set of tools to aid in developing code that uses the Glimmer VM for rendering, such as [Ember.js] v3.24+. Similar to [Vetur] for Vue projects or [Svelte Language Tools], Glint consists of a CLI and a language server to provide feedback and enforce correctness both locally during editing and project-wide in CI. [glint]: https://typed-ember.gitbook.io/glint [ember.js]: https://www.emberjs.com -[glimmerx]: https://github.com/glimmerjs/glimmer-experimental [vetur]: https://github.com/vuejs/vetur [svelte language tools]: https://github.com/sveltejs/language-tools @@ -16,11 +15,10 @@ TypeScript-powered tooling for Glimmer templates. Glint is broken into several different packages that you may use, depending on the details of your project. Typically you'll add `@glint/core`, `@glint/template` and a Glint environment package that reflects the type of project you're working on, then add a `"glint"` key to your `tsconfig.json` that tells Glint what it should look at. -For more specific details on setting up Glint in your project, take a look at [the documentation], in particular the Installation pages [for Ember.js projects] and [for GlimmerX projects]. +For more specific details on setting up Glint in your project, take a look at [the documentation], in particular the Installation pages [for Ember.js projects]. [the documentation]: https://typed-ember.gitbook.io/glint [for ember.js projects]: https://typed-ember.gitbook.io/glint/environments/ember/installation -[for glimmerx projects]: https://typed-ember.gitbook.io/glint/environments/glimmerx/installation ## Using Glint diff --git a/docs/configuration/_index.md b/docs/configuration/_index.md index a66c9ba51..35fe25155 100644 --- a/docs/configuration/_index.md +++ b/docs/configuration/_index.md @@ -34,8 +34,7 @@ Some environments may accept user-specified configuration. To pass configuration ```javascript "glint" { "environment": { - "ember-loose": {}, - "glimmerx": { + "ember-template-imports": { "additionalGlobals": ["my-special-template-macro"] } } diff --git a/docs/configuration/project-references.md b/docs/configuration/project-references.md index 7efe192f7..5996870f1 100644 --- a/docs/configuration/project-references.md +++ b/docs/configuration/project-references.md @@ -38,14 +38,13 @@ Then each project within can use the `extends` key to reuse both TypeScript and ## Per-project configuration -To work with Glint, each sub-project needs to include the Glint environment imports it uses. (See [Ember: Installation][ei] and [GlimmerX: Installation][gi] for details.) For example, a project using `ember-template-imports` should have this import visible somewhere: +To work with Glint, each sub-project needs to include the Glint environment imports it uses. (See [Ember: Installation][ei] for details.) For example, a project using `ember-template-imports` should have this import visible somewhere: ```ts import '@glint/environment-ember-template-imports'; ``` [ei]: ../ember/installation.md -[gi]: ../glimmerx/installation.md The easiest way to do this is to add it to a shared file all projects can reference using the `include` key in each sub-project's `tsconfig.json`. If you do not already have something filling this role, you should introduce a `local-types` directory (named however you like) in the root of your project, with an `index.d.ts` in it. diff --git a/docs/contents.md b/docs/contents.md index 7ac3fc3ee..f6e54df31 100644 --- a/docs/contents.md +++ b/docs/contents.md @@ -24,10 +24,6 @@ * [Using Addons](ember/using-addons.md) * [Authoring Addons](ember/authoring-addons.md) * [Template Imports](ember/template-imports.md) -* [GlimmerX](using-glint/glimmerx/README.md) - * [Installation](glimmerx/installation.md) - * [Component Signatures](glimmerx/component-signatures.md) - * [Template Components](glimmerx/template-components.md) ## Troubleshooting * [Migration Notes](migrating.md) diff --git a/docs/getting-started.md b/docs/getting-started.md index 3f40a08c7..58d39438a 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -6,7 +6,6 @@ Then, add a `"glint"` key in your `tsconfig.json` that tells Glint what environm See the [Configuration](configuration/_index.md) page for more details about options you can specify under the `"glint"` key. For setup instructions specific to your project type, check out the links below: -- [GlimmerX Installation](glimmerx/installation.md) - [Ember.js Installation](ember/installation.md) ## Using Glint diff --git a/docs/glimmerx/component-signatures.md b/docs/glimmerx/component-signatures.md deleted file mode 100644 index 3025cedb8..000000000 --- a/docs/glimmerx/component-signatures.md +++ /dev/null @@ -1,37 +0,0 @@ -While GlimmerX components accept `Args` as a type parameter, the Glint version accepts `Signature`, which contains types for `Element`, `Args` and `Yields`. - -The `Element` field declares what type of element(s), if any, the component applies its passed `...attributes` to. This is often the component's root element. Tracking this type ensures any modifiers used on your component will be compatible with the DOM element(s) they're ultimately attached to. If no `Element` is specified, it will be a type error to set any HTML attributes when invoking your component. - -The `Blocks` field specifies the names of any blocks the component yields to, as well as the type of any parameter(s) they'll receive. See the [Yieldable Named Blocks RFC] for further details. -(Note that the `inverse` block is an alias for `else`. These should be defined in `Yields` as `else`, though `{{yield to="inverse"}}` will continue to work.) - -```typescript -import Component, { hbs } from '@glimmerx/component'; - -export interface ShoutSignature { - // We have a `
` as our root element - Element: HTMLDivElement; - // We accept one required argument, `message` - Args: { - message: string; - }; - // We yield a single string to the default block, `shoutedMessage` - Blocks: { - default?: [shoutedMessage: string]; - }; -} - -export class Shout extends Component { - private get louderPlease() { - return `${this.args.message.toUpperCase()}!`; - } - - public static template = hbs` -
- {{yield this.louderPlease}} -
- `; -} -``` - -[yieldable named blocks rfc]: https://github.com/emberjs/rfcs/blob/master/text/0460-yieldable-named-blocks.md diff --git a/docs/glimmerx/installation.md b/docs/glimmerx/installation.md deleted file mode 100644 index 01615ff49..000000000 --- a/docs/glimmerx/installation.md +++ /dev/null @@ -1,48 +0,0 @@ -To use Glint with [GlimmerX](https://github.com/glimmerjs/glimmer-experimental), you'll add the `@glint/core`, `@glint/template` and `@glint/environment-glimmerx` packages to your project's `devDependencies`, then add a `"glint"` key to your project's `tsconfig.json`. - -{% tabs %} -{% tab title="Yarn" %} - -```sh -yarn add --dev @glint/core @glint/template @glint/environment-glimmerx -``` - -{% endtab %} -{% tab title="npm" %} - -```sh -npm install -D @glint/core @glint/template @glint/environment-glimmerx -``` - -{% endtab %} -{% endtabs %} - -{% code title="tsconfig.json" %} - -```javascript -{ - "compilerOptions": { /* ... */ }, - "glint": { - "environment": "glimmerx" - } -} -``` - -{% endcode %} - -Note that, by default, Glint will assume you want it to analyze all templates in the codebase that are covered by your `tsconfig.json`. To ignore any type errors up front so that you can incrementally migrate your project to typesafe templates, consider using [the `auto-glint-nocheck` script](https://github.com/typed-ember/glint/tree/main/packages/scripts#auto-glint-nocheck) to add [`@glint-nocheck` comments](../directives.md#glint-nocheck) to your existing templates that would produce errors. - -{% hint style="info" %} - -To minimize spurious errors when typechecking with vanilla `tsc` or your editor's TypeScript integration, you should add `import '@glint/environment-glimmerx';` somewhere in your project's source or type declarations. You may also choose to disable TypeScript's "unused symbol" warnings in your editor, since `tsserver` won't understand that templates actually are using them. - -{% endhint %} - -## Version Requirements - -Because Glint uses your project-local copy of TypeScript and the packages whose types it augments for use in templates, it requires certain minimum versions of those packages for compatibility. - -| Package | Minimum Version | -| ------------- | --------------- | -| `typescript` | 4.8.0 | -| `@glimmerx/*` | 0.6.7 | diff --git a/docs/glimmerx/template-components.md b/docs/glimmerx/template-components.md deleted file mode 100644 index 894ce3d67..000000000 --- a/docs/glimmerx/template-components.md +++ /dev/null @@ -1,25 +0,0 @@ -In GlimmerX, standalone templates can be invoked as components. Like class-based components, you can declare a signature for a template component in order for Glint to understand how it can be used. - -The class-based component above could as a template component like so: - -```typescript -import type { TemplateComponent } from '@glimmerx/component'; - -interface ShoutSignature { - /* same as above */ -} - -const shout = (message: string) => `${message.toUpperCase()}!`; - -const Shout: TemplateComponent = hbs` -
- {{yield (shout @message)}} -
-`; -``` - -Note that, similar to React's `FunctionComponent` and `FC`, you can also import and use the `TC` type alias as a shorthand for `TemplateComponent`: - -```typescript -import type { TC } from '@glimmerx/component'; -``` diff --git a/docs/migrating.md b/docs/migrating.md index 14bc4717d..a0669797a 100644 --- a/docs/migrating.md +++ b/docs/migrating.md @@ -236,20 +236,11 @@ When you've finished your migration, you can update to Glint 0.8 and remove the `import '@glint/environment-ember-loose/native-integration';` line from your project, leaving only `import '@glint/environment-ember-loose';`. -{% hint style="warning" %} -Note: `@glint/environment-glimmerx` currently does not support native imports and has been held back temporarily from -release for version 0.8.0. Until a new release of GlimmerX is available, please remain on Glint 0.7 for projects using -GlimmerX. -{% endhint %} - ## Native Signatures and Imports This guide provides direction for migrating from custom Glint-specific import paths and signature formats to the native imports and standardized signatures for `@ember/component`, `@glimmer/component` and `ember-modifier`. -Note that this guide applies to `@glint/environment-ember-loose`, but `@glint/environment-glimmerx` doesn't yet support -native imports, pending an upgrade of GlimmerX's own dependencies. - ### Background Prior to version `0.7.4`, Glint required users to import the factories and base classes for components, helpers and diff --git a/docs/overview.md b/docs/overview.md index e4bf4c22b..8f88a9899 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -1,4 +1,4 @@ -Glint is a set of tools to aid in developing code that uses the Glimmer VM for rendering, such as [Ember.js] v3.24+ and [GlimmerX] projects. Similar to [Vetur] for Vue projects or [Svelte Language Tools], Glint consists of a CLI and a language server to provide feedback and enforce correctness both locally during editing and project-wide in CI. +Glint is a set of tools to aid in developing code that uses the Glimmer VM for rendering, such as [Ember.js] v3.24+. Similar to [Vetur] for Vue projects or [Svelte Language Tools], Glint consists of a CLI and a language server to provide feedback and enforce correctness both locally during editing and project-wide in CI. ## Glint CLI @@ -19,7 +19,6 @@ The Glint language server implements the standardized [Language Server Protocol] ![Suggesting component arguments in typeahead with type information and documentation](https://user-images.githubusercontent.com/108688/111070948-3f9b2f00-84d4-11eb-9eaa-077cadf6f380.png) [ember.js]: https://www.emberjs.com -[glimmerx]: https://github.com/glimmerjs/glimmer-experimental [vetur]: https://github.com/vuejs/vetur [svelte language tools]: https://github.com/sveltejs/language-tools [language server protocol]: https://microsoft.github.io/language-server-protocol/ diff --git a/docs/using-glint/glimmerx/README.md b/docs/using-glint/glimmerx/README.md deleted file mode 100644 index 1918d1603..000000000 --- a/docs/using-glint/glimmerx/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# GlimmerX - diff --git a/docs/with-js.md b/docs/with-js.md index 37d04e8a2..1b64b8882 100644 --- a/docs/with-js.md +++ b/docs/with-js.md @@ -45,34 +45,32 @@ You can also use a `tsconfig.json` file with `compilerOptions.allowJs: true`. To receive equivalent rich editor support for component JS files in your project, you will need to document your components with valid JSDoc. For example: -```javascript -// SimpleComponent.js - -import Component from '@glint/environment-glimmerx/component'; -import { hbs } from '@glimmerx/component'; -import { helper } from '@glint/environment-glimmerx/helper'; - -const or = helper( - /** - * @template T - * @template U - * @param {[a: T, b: U]} param - * @returns T | U - */ - ([a, b]) => a || b -); +```gjs +// SimpleComponent.gjs + +import Component from '@glimmer/component'; + +/** + * Multiplies two numbers + * @param {number} a - The first operand + * @param {number} b - The second operand + * @returns {number} The multiplied value. + */ +const multiply = (a, b) => a * b; /** * @typedef SimpleComponentSignature * @property {object} Args - * @property {string} Args.message + * @property {number} Args.num */ /** @extends {Component} */ export default class SimpleComponent extends Component { - static template = hbs` -

This is my simple message: {{or @message 'hello'}}

- `; + foo = 5 + + } ``` diff --git a/packages/core/__tests__/cli/check.test.ts b/packages/core/__tests__/cli/check.test.ts index bc4b52d2d..f7a59b7e5 100644 --- a/packages/core/__tests__/cli/check.test.ts +++ b/packages/core/__tests__/cli/check.test.ts @@ -15,7 +15,7 @@ describe('CLI: single-pass typechecking', () => { test('passes a valid project', async () => { let code = stripIndent` - import Component, { hbs } from '@glimmerx/component'; + import Component from '@glimmer/component'; type ApplicationArgs = { version: string; @@ -24,14 +24,14 @@ describe('CLI: single-pass typechecking', () => { export default class Application extends Component<{ Args: ApplicationArgs }> { private startupTime = new Date().toISOString(); - public static template = hbs\` + } `; - project.write('index.ts', code); + project.write('index.gts', code); let checkResult = await project.check(); @@ -101,7 +101,7 @@ describe('CLI: single-pass typechecking', () => { test('reports diagnostics for a template syntax error', async () => { let code = stripIndent` - import Component, { hbs } from '@glimmerx/component'; + import Component from '@glimmer/component'; type ApplicationArgs = { version: string; @@ -110,21 +110,21 @@ describe('CLI: single-pass typechecking', () => { export default class Application extends Component<{ Args: ApplicationArgs }> { private startupTime = new Date().toISOString(); - public static template = hbs\` + } `; - project.write('index.ts', code); + project.write('index.gts', code); let checkResult = await project.check({ reject: false }); expect(checkResult.exitCode).toBe(1); expect(checkResult.stdout).toEqual(''); expect(stripAnsi(checkResult.stderr)).toMatchInlineSnapshot(` - "index.ts:11:24 - error TS0: Parse error on line 2: + "index.gts:11:24 - error TS0: Parse error on line 2: ...e to app v{{@version}. The current t -----------------------^ Expecting 'CLOSE_RAW_BLOCK', 'CLOSE', 'CLOSE_UNESCAPED', 'OPEN_SEXPR', 'CLOSE_SEXPR', 'ID', 'OPEN_BLOCK_PARAMS', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', 'SEP', got 'INVALID' @@ -137,7 +137,7 @@ describe('CLI: single-pass typechecking', () => { test('reports diagnostics for an inline template type error', async () => { let code = stripIndent` - import Component, { hbs } from '@glimmerx/component'; + import Component from '@glimmer/component'; type ApplicationArgs = { version: string; @@ -146,26 +146,27 @@ describe('CLI: single-pass typechecking', () => { export default class Application extends Component<{ Args: ApplicationArgs }> { private startupTime = new Date().toISOString(); - public static template = hbs\` + } `; - project.write('index.ts', code); + project.write('index.gts', code); let checkResult = await project.check({ reject: false }); expect(checkResult.exitCode).toBe(1); expect(checkResult.stdout).toEqual(''); + expect(stripAnsi(checkResult.stderr)).toMatchInlineSnapshot(` - "index.ts:12:32 - error TS2551: Property 'startupTimee' does not exist on type 'Application'. Did you mean 'startupTime'? + "index.gts:12:32 - error TS2551: Property 'startupTimee' does not exist on type 'Application'. Did you mean 'startupTime'? 12 The current time is {{this.startupTimee}}. ~~~~~~~~~~~~ - index.ts:8:11 + index.gts:8:11 8 private startupTime = new Date().toISOString(); ~~~~~~~~~~~ 'startupTime' is declared here. diff --git a/packages/core/__tests__/cli/declaration.test.ts b/packages/core/__tests__/cli/declaration.test.ts index 537e10f47..5f0ba068a 100644 --- a/packages/core/__tests__/cli/declaration.test.ts +++ b/packages/core/__tests__/cli/declaration.test.ts @@ -14,7 +14,7 @@ describe('CLI: emitting declarations', () => { test('emit for a valid project with embedded templates', async () => { let code = stripIndent` - import Component, { hbs } from '@glimmerx/component'; + import Component from '@glimmer/component'; export interface ApplicationArgs { version: string; @@ -23,21 +23,21 @@ describe('CLI: emitting declarations', () => { export default class Application extends Component<{ Args: ApplicationArgs }> { private startupTime = new Date().toISOString(); - public static template = hbs\` + } `; - project.write('index.ts', code); + project.write('index.gts', code); let emitResult = await project.check({ flags: ['--declaration'] }); expect(emitResult.exitCode).toBe(0); expect(project.read('index.d.ts')).toMatchInlineSnapshot(` - "import Component from '@glimmerx/component'; + "import Component from '@glimmer/component'; export interface ApplicationArgs { version: string; } @@ -45,7 +45,6 @@ describe('CLI: emitting declarations', () => { Args: ApplicationArgs; }> { private startupTime; - static template: abstract new () => unknown; } " `); diff --git a/packages/core/__tests__/cli/incremental.test.ts b/packages/core/__tests__/cli/incremental.test.ts index c04b8b07b..12635ca04 100644 --- a/packages/core/__tests__/cli/incremental.test.ts +++ b/packages/core/__tests__/cli/incremental.test.ts @@ -143,7 +143,7 @@ describe('CLI: --incremental', () => {