Skip to content

Commit a27ed84

Browse files
feat(compiler): add support for Ember (#419)
Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>
1 parent cfc8357 commit a27ed84

28 files changed

+9603
-727
lines changed

README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,79 @@ See [the Qwik example](examples/vite-qwik) for a working example project.
734734

735735
<br></details>
736736

737+
<details>
738+
<summary>Ember</summary><br>
739+
740+
Ember support requires using either Webpack or Vite
741+
742+
```ts
743+
Icons({ compiler: 'ember' })
744+
```
745+
746+
For Vite applications, add the Icon plugin to the plugins array in `vite.config.js`:
747+
748+
```ts
749+
import { ember, extensions } from '@embroider/vite'
750+
import { babel } from '@rollup/plugin-babel'
751+
import Icons from 'unplugin-icons/vite'
752+
import { defineConfig } from 'vite'
753+
754+
export default defineConfig({
755+
plugins: [
756+
ember(),
757+
Icons({
758+
compiler: 'ember',
759+
}),
760+
babel({
761+
babelHelpers: 'runtime',
762+
extensions,
763+
}),
764+
],
765+
})
766+
```
767+
768+
Type Declarations:
769+
770+
```jsonc
771+
// tsconfig.json
772+
{
773+
"compilerOptions": {
774+
"types": [
775+
// ... existing declarations omitted ...
776+
"unplugin-icons/types/ember"
777+
]
778+
}
779+
}
780+
```
781+
782+
<details><summary>Ember + Webpack</summary>
783+
784+
Assuming your app was generated with `--embroider`, or manually migrated to embroider following the instructions on [the old embroider readme](https://github.com/embroider-build/embroider/tree/stable?tab=readme-ov-file#how-to-try-it)
785+
786+
Add the Icon plugin to the webpack plugins array in `ember-cli-build.js`:
787+
788+
<!-- eslint-skip -->
789+
790+
```ts
791+
return require('@embroider/compat').compatBuild(app, Webpack, {
792+
packagerOptions: {
793+
webpackConfig: {
794+
plugins: [
795+
Icons({
796+
compiler: 'ember',
797+
}),
798+
],
799+
},
800+
},
801+
// ...other options
802+
```
803+
804+
</details>
805+
806+
See the [Ember (with Webpack)](examples/webpack-ember) or [Ember vite example](examples/vite-ember) for a working example project.
807+
808+
<br></details>
809+
737810
## Use RAW compiler from query params
738811
739812
From `v0.13.2` you can also use `raw` compiler to access the `svg` icon and use it on your html templates, just add `raw` to the icon query param.

eslint.config.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
// @ts-check
22
import antfu from '@antfu/eslint-config'
33

4-
export default antfu()
4+
export default antfu({}, {
5+
name: 'array-callback-return-override',
6+
files: ['examples/*-ember/**'],
7+
rules: {
8+
// This rule assumes that all map() calls are from Array.protoype.
9+
// In the ember examples, the Router uses map() to mean "sitemap"
10+
'array-callback-return': 'off',
11+
},
12+
})

examples/vite-ember/app/app.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import EmberRouter from '@embroider/router'
2+
import Application from 'ember-strict-application-resolver'
3+
4+
class Router extends EmberRouter {
5+
location = 'history'
6+
rootURL = '/'
7+
}
8+
9+
Router.map(() => {
10+
// Add route declarations here
11+
})
12+
13+
export default class App extends Application {
14+
modules = {
15+
'./router': Router,
16+
...import.meta.glob('./templates/**/*.{gjs,gts}', { eager: true }),
17+
}
18+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import Tomster from '~icons/logos/ember-tomster';
2+
3+
import FileJavaScript from '~icons/devicon/javascript';
4+
import styles from './application.module.css';
5+
6+
<template>
7+
<h2 id="title">Welcome to Ember</h2>
8+
<Tomster />
9+
<FileJavaScript class={{styles.large}} />
10+
11+
{{outlet}}
12+
</template>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.large {
2+
width: 50px;
3+
height: 50px;
4+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
const { buildMacros } = require('@embroider/macros/babel')
2+
3+
const macros = buildMacros()
4+
5+
module.exports = {
6+
plugins: [
7+
[
8+
'@babel/plugin-transform-typescript',
9+
{
10+
allExtensions: true,
11+
onlyRemoveTypeImports: true,
12+
allowDeclareFields: true,
13+
},
14+
],
15+
[
16+
'babel-plugin-ember-template-compilation',
17+
{
18+
compilerPath: 'ember-source/dist/ember-template-compiler.js',
19+
enableLegacyModules: [
20+
'ember-cli-htmlbars',
21+
'ember-cli-htmlbars-inline-precompile',
22+
'htmlbars-inline-precompile',
23+
],
24+
transforms: [...macros.templateMacros],
25+
26+
},
27+
],
28+
[
29+
'module:decorator-transforms',
30+
{
31+
runtime: {
32+
import: require.resolve('decorator-transforms/runtime-esm'),
33+
},
34+
},
35+
],
36+
[
37+
'@babel/plugin-transform-runtime',
38+
{
39+
absoluteRuntime: __dirname,
40+
useESModules: true,
41+
regenerator: false,
42+
},
43+
],
44+
...macros.babelMacros,
45+
46+
],
47+
48+
generatorOpts: {
49+
compact: false,
50+
},
51+
}

examples/vite-ember/index.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>EmberViteExample</title>
6+
<meta name="description" content="">
7+
<meta name="viewport" content="width=device-width, initial-scale=1">
8+
</head>
9+
<body>
10+
<script type="module">
11+
import Application from './app/app';
12+
13+
Application.create({});
14+
</script>
15+
</body>
16+
</html>

examples/vite-ember/package.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "ember-vite-example",
3+
"type": "module",
4+
"private": true,
5+
"license": "MIT",
6+
"exports": {
7+
"./tests/*": "./tests/*",
8+
"./*": "./app/*"
9+
},
10+
"engines": {
11+
"node": ">= 22"
12+
},
13+
"scripts": {
14+
"start": "vite"
15+
},
16+
"devDependencies": {
17+
"@babel/core": "^7.27.1",
18+
"@babel/plugin-transform-runtime": "^7.27.1",
19+
"@babel/plugin-transform-typescript": "^7.27.1",
20+
"@babel/runtime": "^7.27.1",
21+
"@ember/app-tsconfig": "^1.0.3",
22+
"@embroider/core": "^4.1.0",
23+
"@embroider/macros": "^1.18.0",
24+
"@embroider/router": "^3.0.1",
25+
"@embroider/vite": "^1.1.5",
26+
"@glimmer/component": "^2.0.0",
27+
"@glint/ember-tsc": "^1.0.3",
28+
"@glint/template": "^1.6.1",
29+
"@glint/tsserver-plugin": "^2.0.3",
30+
"@iconify-json/devicon": "^1.2.29",
31+
"@iconify-json/logos": "^1.2.5",
32+
"@rollup/plugin-babel": "^6.0.4",
33+
"@types/rsvp": "^4.0.9",
34+
"babel-plugin-ember-template-compilation": "^2.4.1",
35+
"decorator-transforms": "^2.3.0",
36+
"ember-source": "~6.7.0",
37+
"ember-strict-application-resolver": "0.1.0",
38+
"typescript": "^5.8.3",
39+
"unplugin-icons": "workspace:*",
40+
"vite": "^7.1.9"
41+
}
42+
}

examples/vite-ember/tsconfig.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"extends": "@ember/app-tsconfig",
3+
"compilerOptions": {
4+
"paths": {
5+
"ember-vite-example/tests/*": ["./tests/*"],
6+
"ember-vite-example/*": ["./app/*"],
7+
"*": ["./types/*"]
8+
},
9+
"types": [
10+
"ember-source/types",
11+
"@embroider/core/virtual",
12+
"vite/client",
13+
"unplugin-icons/types/ember"
14+
],
15+
"allowJs": true
16+
}
17+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { ember, extensions } from '@embroider/vite'
2+
import { babel } from '@rollup/plugin-babel'
3+
import Icons from 'unplugin-icons/vite'
4+
import { defineConfig } from 'vite'
5+
6+
export default defineConfig({
7+
plugins: [
8+
ember(),
9+
Icons({
10+
compiler: 'ember',
11+
}),
12+
// extra plugins here
13+
babel({
14+
babelHelpers: 'runtime',
15+
extensions,
16+
}),
17+
],
18+
})

0 commit comments

Comments
 (0)