Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a namespace option for public-assets plugin #1867

Merged
merged 1 commit into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/v2-faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ This is done by adding some meta data to the addon's `package.json`, specifying
}
```

If you have many files you want to expose this way, you can instead add the `addon.publicAssets()` plugin from `@embroider/addon-dev` to your Rollup config to automate the generation of this mapping data.
If you have many files you want to expose this way, you can instead add the `addon.publicAssets()` plugin from `@embroider/addon-dev` to your Rollup config to automate the generation of this mapping data. This rollup plugin will automatically prefix your public assets with a folder name that matches your addon packages name, this is to prevent any name clashes between addons. You can read more about it in the docs for the addon-dev rollup plugin utilities https://github.com/embroider-build/embroider/tree/main/packages/addon-dev#rollup-utilities


## Build setup

Expand Down
4 changes: 4 additions & 0 deletions packages/addon-dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ For a guide on porting a V1 addon to V2, see https://github.com/embroider-build/
2. Copy the `./sample-rollup.config.js` in this repo to your own `rollup.config.js`.
3. Copy the `./sample-babel.config.json` in this repo to your own `babel.config.json`.

### addon.publicAssets(path <required>, options)

A rollup plugin to expose a folder of assets. `path` is a required to define which folder to expose. `options.include` is a glob pattern passed to `walkSync.include` to pick files. `options.exlude` is a glob pattern passed to `walkSync.ignore` to exclude files. `options.namespace` is the namespace to expose files, defaults to the package name

## addon-dev command

The `addon-dev` command helps with common tasks in v2 addons.
Expand Down
30 changes: 28 additions & 2 deletions packages/addon-dev/src/rollup-public-assets.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
import { readJsonSync, writeJsonSync } from 'fs-extra';
import walkSync from 'walk-sync';
import type { Plugin } from 'rollup';
import { resolve, join } from 'path/posix';

export interface PublicAssetsOptions {
/**
* glob pattern passed to `walkSync.include` to pick files
*/
include?: string[];

/**
* glob pattern passed to `walkSync.ignore` to exclude files
*/
exclude?: string[];

/**
* namespace to expose files
*/
namespace?: string;
}

/**
* A rollup plugin to expose a folder of assets
*
* @param path - the public folder that you want to add as public assets
* @returns
*/
export default function publicAssets(
path: string,
opts: { include: string[]; exclude: string[] }
opts?: PublicAssetsOptions
): Plugin {
const includeGlobPatterns = opts?.include;
const excludedGlobPatterns = opts?.exclude || [];
Expand All @@ -27,7 +51,9 @@ export default function publicAssets(
});
const publicAssets: Record<string, string> = filenames.reduce(
(acc: Record<string, string>, v): Record<string, string> => {
acc[`./${path}/${v}`] = ['/', pkg.name, '/', path, '/', v].join('');
acc[`./${path}/${v}`] = resolve(
'/' + join(opts?.namespace ?? pkg.name, path, v)
);
return acc;
},
{}
Expand Down
7 changes: 5 additions & 2 deletions packages/addon-dev/src/rollup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import type { Options as DelOptions } from 'rollup-plugin-delete';
import { default as clean } from 'rollup-plugin-delete';
import { default as keepAssets } from './rollup-keep-assets';
import { default as dependencies } from './rollup-addon-dependencies';
import { default as publicAssets } from './rollup-public-assets';
import {
default as publicAssets,
type PublicAssetsOptions,
} from './rollup-public-assets';
import type { Plugin } from 'rollup';

export class Addon {
Expand Down Expand Up @@ -102,7 +105,7 @@ export class Addon {
return dependencies();
}

publicAssets(path: string, opts: { include: string[]; exclude: string[] }) {
publicAssets(path: string, opts?: PublicAssetsOptions) {
return publicAssets(path, opts);
}
}
101 changes: 91 additions & 10 deletions tests/scenarios/v2-addon-dev-test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'path';
import { appScenarios, baseV2Addon } from './scenarios';
import { PreparedApp } from 'scenario-tester';
import { PreparedApp, type Project } from 'scenario-tester';
import QUnit from 'qunit';
import merge from 'lodash/merge';
import type { ExpectFile } from '@embroider/test-support/file-assertions/qunit';
Expand Down Expand Up @@ -74,6 +74,7 @@ appScenarios
addon.hbs(),
addon.gjs(),
addon.dependencies(),
addon.publicAssets('public'),

babel({ babelHelpers: 'bundled', extensions: ['.js', '.hbs', '.gjs'] }),

Expand Down Expand Up @@ -151,19 +152,87 @@ appScenarios
},
},
},
public: {
'thing.txt': 'hello there',
},
});

addon.linkDependency('@embroider/addon-shim', { baseDir: __dirname });
addon.linkDependency('@embroider/addon-dev', { baseDir: __dirname });
addon.linkDependency('babel-plugin-ember-template-compilation', { baseDir: __dirname });
addon.linkDevDependency('@babel/core', { baseDir: __dirname });
addon.linkDevDependency('@babel/plugin-transform-class-static-block', { baseDir: __dirname });
addon.linkDevDependency('@babel/plugin-transform-class-properties', { baseDir: __dirname });
addon.linkDevDependency('@babel/plugin-proposal-decorators', { baseDir: __dirname });
addon.linkDevDependency('@rollup/plugin-babel', { baseDir: __dirname });
addon.linkDevDependency('rollup', { baseDir: __dirname });
let addonNoNamespace = baseV2Addon();
addonNoNamespace.pkg.name = 'v2-addon-no-namespace';
addonNoNamespace.pkg.scripts = {
build: 'node ./node_modules/rollup/dist/bin/rollup -c ./rollup.config.mjs',
};

merge(addonNoNamespace.files, {
src: {
components: {
'hello.hbs': '<h1>hello</h1>',
},
},
public: {
'other.txt': 'we meet again',
},
'babel.config.json': `
{
"plugins": [
"@embroider/addon-dev/template-colocation-plugin",
"@babel/plugin-transform-class-static-block",
["babel-plugin-ember-template-compilation", {
targetFormat: 'hbs',
compilerPath: 'ember-source/dist/ember-template-compiler',
}],
["@babel/plugin-proposal-decorators", { "legacy": true }],
[ "@babel/plugin-transform-class-properties" ]
]
}
`,
'rollup.config.mjs': `
import { babel } from '@rollup/plugin-babel';
import { Addon } from '@embroider/addon-dev/rollup';

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

export default {
output: addon.output(),

plugins: [
addon.publicEntrypoints([
'components/**/*.js',
], {
exclude: ['**/-excluded/**/*'],
}),

addon.hbs(),
addon.publicAssets('public', { namespace: '' }),

babel({ babelHelpers: 'bundled', extensions: ['.js', '.hbs', '.gjs'] }),

addon.clean(),
],
};
`,
});

function linkDependencies(addon: Project) {
addon.linkDependency('@embroider/addon-shim', { baseDir: __dirname });
addon.linkDependency('@embroider/addon-dev', { baseDir: __dirname });
addon.linkDependency('babel-plugin-ember-template-compilation', { baseDir: __dirname });
addon.linkDevDependency('@babel/core', { baseDir: __dirname });
addon.linkDevDependency('@babel/plugin-transform-class-static-block', { baseDir: __dirname });
addon.linkDevDependency('@babel/plugin-transform-class-properties', { baseDir: __dirname });
addon.linkDevDependency('@babel/plugin-proposal-decorators', { baseDir: __dirname });
addon.linkDevDependency('@rollup/plugin-babel', { baseDir: __dirname });
addon.linkDevDependency('rollup', { baseDir: __dirname });
}

linkDependencies(addon);
linkDependencies(addonNoNamespace);

project.addDevDependency(addon);
project.addDependency(addonNoNamespace);

merge(project.files, {
tests: {
Expand Down Expand Up @@ -226,6 +295,7 @@ appScenarios
if (result.exitCode !== 0) {
throw new Error(result.output);
}
await inDependency(app, 'v2-addon-no-namespace').execute('pnpm build');
});

hooks.beforeEach(assert => {
Expand Down Expand Up @@ -301,6 +371,17 @@ setComponentTemplate(
export { SingleFileComponent as default };
//# sourceMappingURL=single-file-component.js.map`);
});

test('publicAssets are namespaced correctly', async function (assert) {
let expectNoNamespaceFile = expectFilesAt(inDependency(app, 'v2-addon-no-namespace').dir, { qunit: assert });

expectFile('package.json').json('ember-addon.public-assets').deepEquals({
'./public/thing.txt': '/v2-addon/public/thing.txt',
});
expectNoNamespaceFile('package.json').json('ember-addon.public-assets').deepEquals({
'./public/other.txt': '/public/other.txt',
});
});
});

Qmodule('Consuming app', function () {
Expand Down
Loading