Due to not having a scope bag, rollup (or some babel plugin) optimizes away unused identifiers
The resulting dist file only has one component, w/ the eval remainaing, and no second component, resulting in an error at runtime.
source
```gts
import Component from '@glimmer/component';
import { TrackedArray } from 'tracked-built-ins';
import { registerDestructor } from '@ember/destroyable';
const original = {
log: console.log,
warn: console.warn,
error: console.error,
debug: console.debug,
info: console.info,
};
const LEVELS = Object.keys(original);
const LogList =
{{#each @logs as |logEntry|}}
{{format logEntry.timestamp}}{{logEntry.message}}
{{ (scrollToBottom) }}
{{/each}}
;
export class Logs extends Component {
logs = new TrackedArray();
constructor(...args) {
super(...args);
registerDestructor(this, () => LEVELS.forEach((level) => console[level] = original[level]));
for (let level of LEVELS) {
console[level] = (...messageParts) => {
// If our thing fails, we want the normal
// log to still happen, just in case.
// Makes debugging easier
original[level](...messageParts);
this.logs.push({
level,
message: messageParts.join(' '),
timestamp: new Date(),
});
};
}
}
}
let frame;
function scrollToBottom() {
if (frame) {
cancelAnimationFrame(frame);
}
frame = requestAnimationFrame(() => {
let el = document.querySelector('.kolay__log-list__scroll');
el.scrollTo({
top: el.scrollHeight,
left: 0,
behavior: 'smooth',
});
});
}
let formatter = new Intl.DateTimeFormat('en-GB', {
hour: "numeric",
minute: "numeric",
second: "numeric",
fractionalSecondDigits: 2,
});
const format = (date) => formatter.format(date);
```
output
```js
import { template } from '@ember/template-compiler';
import Component from '@glimmer/component';
import { TrackedArray } from 'tracked-built-ins';
import { registerDestructor } from '@ember/destroyable';
const original = {
log: console.log,
warn: console.warn,
error: console.error,
debug: console.debug,
info: console.info
};
const LEVELS = Object.keys(original);
template(`
{{#each @logs as |logEntry|}}
{{format logEntry.timestamp}}{{logEntry.message}}
{{ (scrollToBottom) }}
{{/each}}
`, {
eval () {
return eval(arguments[0]);
}
});
class Logs extends Component {
logs = new TrackedArray();
constructor(...args1){
super(...args1);
registerDestructor(this, ()=>LEVELS.forEach((level1)=>console[level1] = original[level1]));
for (let level1 of LEVELS){
console[level1] = (...messageParts1)=>{
// If our thing fails, we want the normal
// log to still happen, just in case.
// Makes debugging easier
original[level1](...messageParts1);
this.logs.push({
level: level1,
message: messageParts1.join(' '),
timestamp: new Date()
});
};
}
}
static{
template(`
`, {
component: this,
eval () {
return eval(arguments[0]);
}
});
}
}
export { Logs };
//# sourceMappingURL=logs.js.map
```
babel.config.json
```js
{
"plugins": [
"@embroider/addon-dev/template-colocation-plugin",
["babel-plugin-ember-template-compilation", {
"targetFormat": "hbs",
"transforms": []
}],
["module:decorator-transforms", { "runtime": { "import": "decorator-transforms/runtime" } }],
]
}
```
rollup.config.mjs
```js
import { babel } from '@rollup/plugin-babel';
import copy from 'rollup-plugin-copy';
import { Addon } from '@embroider/addon-dev/rollup';
const addon = new Addon({
srcDir: 'src',
destDir: 'dist',
});
export default {
// This provides defaults that work well alongside `publicEntrypoints` below.
// You can augment this if you need to.
output: addon.output(),
plugins: [
// These are the modules that users should be able to import from your
// addon. Anything not listed here may get optimized away.
// By default all your JavaScript modules (**/*.js) will be importable.
// But you are encouraged to tweak this to only cover the modules that make
// up your addon's public API. Also make sure your package.json#exports
// is aligned to the config here.
// See https://github.com/embroider-build/embroider/blob/main/docs/v2-faq.md#how-can-i-define-the-public-exports-of-my-addon
addon.publicEntrypoints(['**/*.js', 'index.js']),
// These are the modules that should get reexported into the traditional
// "app" tree. Things in here should also be in publicEntrypoints above, but
// not everything in publicEntrypoints necessarily needs to go here.
addon.appReexports([
'components/**/*.js',
'helpers/**/*.js',
'modifiers/**/*.js',
'services/**/*.js',
]),
// Follow the V2 Addon rules about dependencies. Your code can import from
// `dependencies` and `peerDependencies` as well as standard Ember-provided
// package names.
addon.dependencies(),
// This babel config should *not* apply presets or compile away ES modules.
// It exists only to provide development niceties for you, like automatic
// template colocation.
//
// By default, this will load the actual babel config from the file
// babel.config.json.
babel({
extensions: ['.js', '.gjs'],
babelHelpers: 'bundled',
}),
// Ensure that standalone .hbs files are properly integrated as Javascript.
addon.hbs(),
// Ensure that .gjs files are properly integrated as Javascript
addon.gjs(),
// addons are allowed to contain imports of .css files, which we want rollup
// to leave alone and keep in the published output.
addon.keepAssets(['**/*.css']),
// Remove leftover build artifacts when starting a new build.
addon.clean(),
// Copy Readme and License into published package
copy({
targets: [
{ src: '../README.md', dest: '.' },
{ src: '../LICENSE.md', dest: '.' },
],
}),
],
};
```
This is solved by adding TS to rollup and the babel config.
Reported an issue for SEO reasons
(if you're going to use TS, don't forget to generate a project that supports TS).
Here is the situation
source
```gts import Component from '@glimmer/component'; import { TrackedArray } from 'tracked-built-ins'; import { registerDestructor } from '@ember/destroyable'; const original = { log: console.log, warn: console.warn, error: console.error, debug: console.debug, info: console.info, }; const LEVELS = Object.keys(original); const LogList =output
```js import { template } from '@ember/template-compiler'; import Component from '@glimmer/component'; import { TrackedArray } from 'tracked-built-ins'; import { registerDestructor } from '@ember/destroyable'; const original = { log: console.log, warn: console.warn, error: console.error, debug: console.debug, info: console.info }; const LEVELS = Object.keys(original); template(`babel.config.json
```js { "plugins": [ "@embroider/addon-dev/template-colocation-plugin", ["babel-plugin-ember-template-compilation", { "targetFormat": "hbs", "transforms": [] }], ["module:decorator-transforms", { "runtime": { "import": "decorator-transforms/runtime" } }], ] } ```rollup.config.mjs
```js import { babel } from '@rollup/plugin-babel'; import copy from 'rollup-plugin-copy'; import { Addon } from '@embroider/addon-dev/rollup'; const addon = new Addon({ srcDir: 'src', destDir: 'dist', }); export default { // This provides defaults that work well alongside `publicEntrypoints` below. // You can augment this if you need to. output: addon.output(), plugins: [ // These are the modules that users should be able to import from your // addon. Anything not listed here may get optimized away. // By default all your JavaScript modules (**/*.js) will be importable. // But you are encouraged to tweak this to only cover the modules that make // up your addon's public API. Also make sure your package.json#exports // is aligned to the config here. // See https://github.com/embroider-build/embroider/blob/main/docs/v2-faq.md#how-can-i-define-the-public-exports-of-my-addon addon.publicEntrypoints(['**/*.js', 'index.js']), // These are the modules that should get reexported into the traditional // "app" tree. Things in here should also be in publicEntrypoints above, but // not everything in publicEntrypoints necessarily needs to go here. addon.appReexports([ 'components/**/*.js', 'helpers/**/*.js', 'modifiers/**/*.js', 'services/**/*.js', ]), // Follow the V2 Addon rules about dependencies. Your code can import from // `dependencies` and `peerDependencies` as well as standard Ember-provided // package names. addon.dependencies(), // This babel config should *not* apply presets or compile away ES modules. // It exists only to provide development niceties for you, like automatic // template colocation. // // By default, this will load the actual babel config from the file // babel.config.json. babel({ extensions: ['.js', '.gjs'], babelHelpers: 'bundled', }), // Ensure that standalone .hbs files are properly integrated as Javascript. addon.hbs(), // Ensure that .gjs files are properly integrated as Javascript addon.gjs(), // addons are allowed to contain imports of .css files, which we want rollup // to leave alone and keep in the published output. addon.keepAssets(['**/*.css']), // Remove leftover build artifacts when starting a new build. addon.clean(), // Copy Readme and License into published package copy({ targets: [ { src: '../README.md', dest: '.' }, { src: '../LICENSE.md', dest: '.' }, ], }), ], }; ```This is solved by adding TS to rollup and the babel config.
Reported an issue for SEO reasons (if you're going to use TS, don't forget to generate a project that supports TS).