Skip to content

Commit

Permalink
make addon a module
Browse files Browse the repository at this point in the history
Addon-main is cjs, it should have cjs extension

Reproduction success

Make separate scenario

Test file must end with -test

Need to update the app's ember-cli-babel

Test is passing, now let's break it again...

Break successful
  • Loading branch information
NullVoxPopuli committed May 7, 2024
1 parent 6fa063b commit 698cfcf
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 4 deletions.
16 changes: 15 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions tests/scenarios/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"@embroider/test-support": "workspace:*",
"@embroider/webpack": "workspace:*",
"@types/qunit": "^2.11.1",
"decorator-transforms": "^1.0.1",
"ember-auto-import": "^2.6.3",
"fastboot": "^4.1.1",
"fs-extra": "^10.0.0",
Expand Down Expand Up @@ -67,6 +68,7 @@
"ember-cli-beta": "npm:ember-cli@beta",
"ember-cli-fastboot": "^4.1.1",
"ember-cli-latest": "npm:ember-cli@latest",
"ember-cli-babel-8": "npm:ember-cli-babel@^8.2.0",
"ember-composable-helpers": "^4.4.1",
"ember-data": "~3.28.0",
"ember-data-4.4": "npm:ember-data@~4.4.0",
Expand Down
4 changes: 2 additions & 2 deletions tests/scenarios/v2-addon-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ appScenarios
'example-component.css': '/* not empty */ h1 { color: red }',
},
'import-from-npm.js': `
export default async function() {
export default async function() {
let { message } = await import('third-party');
return message()
return message()
}
`,
});
Expand Down
216 changes: 216 additions & 0 deletions tests/scenarios/v2-addon-type-module-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
import path from 'path';
import { appScenarios, baseV2Addon } from './scenarios';
import { PreparedApp } from 'scenario-tester';
import QUnit from 'qunit';
import merge from 'lodash/merge';
import { pathExistsSync, readJsonSync, readFileSync } from 'fs-extra';

const { module: Qmodule, test } = QUnit;

appScenarios
.only('release')
.map('v2-addon-as-type-module', async project => {
let addon = baseV2Addon();
addon.pkg.name = 'v2-addon';
addon.pkg.type = 'module';
addon.pkg.files = ['dist'];
addon.pkg.exports = {
'./*': './dist/*.js',
'./addon-main.cjs': './addon-main.cjs',
// needed for our "inDependency" function defined in this test
'./package.json': './package.json',
};
addon.pkg.scripts = {
build: 'node ./node_modules/rollup/dist/bin/rollup -c ./rollup.config.mjs',
};

merge(addon.files, {
'babel.config.json': `
{
"plugins": [
["babel-plugin-ember-template-compilation", {
"targetFormat": "hbs",
"transforms": []
}],
["module:decorator-transforms", { "runtime": { "import": "decorator-transforms/runtime" } }]
]
}
`,
'rollup.config.mjs': `
import { Addon } from '@embroider/addon-dev/rollup';
import { babel } from '@rollup/plugin-babel';
const addon = new Addon({
srcDir: 'src',
destDir: 'dist',
});
export default {
output: addon.output(),
plugins: [
addon.publicEntrypoints(['**/*.js']),
addon.appReexports(['components/*.js']),
addon.dependencies(),
babel({ extensions: ['.js', '.gjs', '.ts', '.gts'], babelHelpers: 'bundled' }),
addon.gjs(),
addon.hbs(),
addon.keepAssets(["**/*.css"]),
addon.clean(),
],
};
`,
src: {
components: {
'styles.css': `button { font-weight: bold; color: blue; }`,
'demo.gjs': `
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { on } from '@ember/modifier';
import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros';
if (macroCondition(isDevelopingApp())) {
importSync('./styles.css');
}
export default class ExampleComponent extends Component {
@tracked active = false;
flip = () => (this.active = !this.active);
<template>
Hello there!
<out>{{this.active}}</out>
<button {{on 'click' this.flip}}>flip</button>
</template>
}
`,
},
},
});

addon.linkDependency('@embroider/addon-shim', { baseDir: __dirname });
addon.linkDependency('@embroider/addon-dev', { baseDir: __dirname });
addon.linkDependency('@babel/runtime', { baseDir: __dirname });
addon.linkDevDependency('@babel/core', { baseDir: __dirname });
addon.linkDevDependency('@rollup/plugin-babel', { baseDir: __dirname });
addon.linkDependency('decorator-transforms', { baseDir: __dirname });
addon.linkDevDependency('rollup', { baseDir: __dirname });

project.addDevDependency(addon);
project.linkDevDependency('ember-cli-babel', { baseDir: __dirname, resolveName: 'ember-cli-babel-8' });
project.linkDevDependency('@embroider/macros', { baseDir: __dirname });

merge(project.files, {
tests: {
// the app is not set up with typescript
'the-test.js': `
import { click, render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
module('v2 addon tests', function (hooks) {
setupRenderingTest(hooks);
test('<Demo />', async function (assert) {
await render(hbs\`<Demo />\`);
assert.dom('out').containsText('false');
await click('button');
assert.dom('out').containsText('true');
});
});
`,
},
'ember-cli-build.js': `
'use strict';
const EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function (defaults) {
let app = new EmberApp(defaults, {
});
const { compatBuild, recommendedOptions } = require('@embroider/compat');
const Webpack = require('@embroider/webpack').Webpack;
return compatBuild(app, Webpack, {
...recommendedOptions.optimized,
skipBabel: [
{ package: 'qunit' },
],
});
};
`,
});
})
.forEachScenario(scenario => {
Qmodule(scenario.name, function (hooks) {
let app: PreparedApp;

hooks.before(async () => {
app = await scenario.prepare();
let result = await inDependency(app, 'v2-addon').execute('pnpm build');
if (result.exitCode !== 0) {
throw new Error(result.output);
}
});

Qmodule('The addon', function () {
test('output directories exist', async function (assert) {
let { dir } = inDependency(app, 'v2-addon');
assert.strictEqual(pathExistsSync(path.join(dir, 'dist')), true, 'dist/');
assert.strictEqual(pathExistsSync(path.join(dir, 'dist', '_app_')), true, 'dist/_app_');
});

test('package.json is modified appropriately', async function (assert) {
let { dir } = inDependency(app, 'v2-addon');
let reExports = readJsonSync(path.join(dir, 'package.json'))['ember-addon']['app-js'];

assert.deepEqual(reExports, {
'./components/demo.js': './dist/_app_/components/demo.js',
});
});

test('the addon was built successfully', async function (assert) {
let { dir } = inDependency(app, 'v2-addon');
let expectedModules = {
'./dist/_app_/components/demo.js': 'export { default } from "v2-addon/components/demo";\n',
};

assert.strictEqual(
Object.keys(readJsonSync(path.join(dir, 'package.json'))['ember-addon']['app-js']).length,
Object.keys(expectedModules).length
);

for (let [pathName, moduleContents] of Object.entries(expectedModules)) {
let filePath = path.join(dir, pathName);
assert.deepEqual(pathExistsSync(filePath), true, `pathExists: ${pathName}`);
assert.strictEqual(
readFileSync(filePath, { encoding: 'utf8' }),
moduleContents,
`has correct reexport: ${pathName}`
);
}
});
});

Qmodule('Consuming app', function () {
test(`pnpm test`, async function (assert) {
let result = await app.execute('pnpm test');
assert.equal(result.exitCode, 0, result.output);
});
});
});
});

// https://github.com/ef4/scenario-tester/issues/5
function inDependency(app: PreparedApp, dependencyName: string): PreparedApp {
return new PreparedApp(path.dirname(require.resolve(`${dependencyName}/package.json`, { paths: [app.dir] })));
}
File renamed without changes.
2 changes: 1 addition & 1 deletion tests/v2-addon-template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"type": "addon",
"version": 2,
"app-js": {},
"main": "addon-main.js"
"main": "addon-main.cjs"
},
"exports": {
"./*": "./*"
Expand Down

0 comments on commit 698cfcf

Please sign in to comment.