diff --git a/.eslintignore b/.eslintignore
index c0f5a1421..74810a41d 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -4,10 +4,11 @@
/packages/test-runner-mocha/*.d.ts
/packages/config-loader/
/packages/*/test/**/fixtures
+/packages/*/test/**/snapshots
/packages/dev-server-rollup/test/browser/**/*
node_modules
dist
demo
CHANGELOG.md
.changeset
-_site
\ No newline at end of file
+_site
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000..4964429a8
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.js eol=lf
diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml
index d34ebf2f0..4945cb281 100644
--- a/.github/workflows/verify.yml
+++ b/.github/workflows/verify.yml
@@ -51,6 +51,11 @@ jobs:
name: Verify windows
runs-on: windows-latest
steps:
+ - name: Set git to use LF
+ run: |
+ git config --global core.autocrlf false
+ git config --global core.eol lf
+
- uses: actions/checkout@v2
- name: Setup Node 12.x
diff --git a/docs/docs/building/rollup-plugin-import-meta-assets.md b/docs/docs/building/rollup-plugin-import-meta-assets.md
new file mode 100644
index 000000000..563fe3673
--- /dev/null
+++ b/docs/docs/building/rollup-plugin-import-meta-assets.md
@@ -0,0 +1,135 @@
+---
+title: Rollup Plugin import-meta-assets
+eleventyNavigation:
+ key: Rollup Plugin import-meta-assets
+ parent: Building
+ order: 2
+---
+
+Rollup plugin that detects assets references relative to modules using patterns such as `new URL('./path/to/asset.ext', import.meta.url)`. The assets are added to the rollup pipeline, allowing them to be transformed and hash the filenames.
+
+## Install
+
+Using npm:
+
+```
+npm install @web/rollup-plugin-import-meta-assets --save-dev
+```
+
+## Usage
+
+Create a rollup.config.js [configuration file](https://www.rollupjs.org/guide/en/#configuration-files) and import the plugin:
+
+```js
+import { importMetaAssets } from '@web/rollup-plugin-import-meta-assets';
+
+export default {
+ input: 'src/index.js',
+ output: {
+ dir: 'output',
+ format: 'es',
+ },
+ plugins: [importMetaAssets()],
+};
+```
+
+Then call `rollup` either via the [CLI](https://www.rollupjs.org/guide/en/#command-line-reference) or the [API](https://www.rollupjs.org/guide/en/#javascript-api).
+
+## Options
+
+### `exclude`
+
+Type: `String` | `Array[...String]`
+Default: `null`
+
+A [picomatch pattern](https://github.com/micromatch/picomatch#globbing-features), or array of patterns, which specifies the files in the build the plugin should _ignore_.
+By default no files are ignored.
+
+### `include`
+
+Type: `String` | `Array[...String]`
+Default: `null`
+
+A [picomatch pattern](https://github.com/micromatch/picomatch#globbing-features), or array of patterns, which specifies the files in the build the plugin should operate on.
+By default all files are targeted.
+
+### `warnOnError`
+
+Type: `Boolean`
+Default: `false`
+
+By default, the plugin quits the build process when it encounters an error. If you set this option to true, it will throw a warning instead and leave the code untouched.
+
+### `transform`
+
+Type: `Function`
+Default: `null`
+
+By default, referenced assets detected by this plugin are just copied as is to the output directory, according to your configuration.
+
+When `transform` is defined, this function will be called for each asset with two parameters, the content of the asset as a [Buffer](https://nodejs.org/api/buffer.html) and the absolute path.
+This allows you to conditionnaly match on the absolute path and maybe transform the content.
+
+In this example, we use it to optimize SVG images with [svgo](https://github.com/svg/svgo):
+
+```js
+import { importMetaAssets } from '@web/rollup-plugin-import-meta-assets';
+const svgo = new SVGO({
+ // See https://github.com/svg/svgo#what-it-can-do
+ plugins: [ /* plugins here */],
+});
+
+export default {
+ input: 'src/index.js',
+ output: {
+ dir: 'output',
+ format: 'es',
+ },
+ plugins: [
+ importMetaAssets({
+ transform: (assetBuffer, assetPath) => {
+ return assetPath.endsWith('.svg')
+ ? svgo.optimize(assetBuffer.toString()).then(({ data }) => data);
+ : assetBuffer;
+ },
+ }),
+ ],
+};
+```
+
+## Examples
+
+Source directory:
+
+```
+.
+├── one
+│ └── two
+│ └── the-image.svg
+├──
+└── entrypoint.js
+```
+
+With `entrypoint.js` containing this:
+
+```js
+const imageUrl = new URL('./one/two/the-image.svg', import.meta.url).href;
+console.log(imageUrl);
+```
+
+Output directory:
+
+```
+.
+├── assets
+│ └── the-image.svg
+└── bundle.js
+```
+
+With `bundle.js` containing this:
+
+```js
+const imageUrl = new URL(new URL('asset/the-image.svg', import.meta.url).href, import.meta.url)
+ .href;
+console.log(imageUrl);
+```
diff --git a/packages/rollup-plugin-import-meta-assets/CHANGELOG.md b/packages/rollup-plugin-import-meta-assets/CHANGELOG.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/packages/rollup-plugin-import-meta-assets/README.md b/packages/rollup-plugin-import-meta-assets/README.md
new file mode 100644
index 000000000..a4dbdcd72
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/README.md
@@ -0,0 +1,34 @@
+# Rollup Plugin import-meta-assets
+
+Rollup plugin that detects assets references relative to modules using patterns such as `new URL('./path/to/asset.ext', import.meta.url)`. The assets are added to the rollup pipeline, allowing them to be transformed and hash the filenames.
+
+## Install
+
+Using npm:
+
+```
+npm install @web/rollup-plugin-import-meta-assets --save-dev
+```
+
+## Usage
+
+Create a rollup.config.js [configuration file](https://www.rollupjs.org/guide/en/#configuration-files) and import the plugin:
+
+```js
+import { importMetaAssets } from '@web/rollup-plugin-import-meta-assets';
+
+export default {
+ input: 'src/index.js',
+ output: {
+ dir: 'output',
+ format: 'es',
+ },
+ plugins: [importMetaAssets()],
+};
+```
+
+Then call `rollup` either via the [CLI](https://www.rollupjs.org/guide/en/#command-line-reference) or the [API](https://www.rollupjs.org/guide/en/#javascript-api).
+
+## Documentation
+
+See [our website](https://modern-web.dev/docs/building/rollup-plugin-import-meta-assets/) for full documentation.
diff --git a/packages/rollup-plugin-import-meta-assets/index.mjs b/packages/rollup-plugin-import-meta-assets/index.mjs
new file mode 100644
index 000000000..6304b074d
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/index.mjs
@@ -0,0 +1,5 @@
+import cjsEntrypoint from './src/rollup-plugin-import-meta-assets.js';
+
+const { importMetaAssets } = cjsEntrypoint;
+
+export { importMetaAssets };
diff --git a/packages/rollup-plugin-import-meta-assets/package.json b/packages/rollup-plugin-import-meta-assets/package.json
new file mode 100644
index 000000000..a6de3f3b9
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "@web/rollup-plugin-import-meta-assets",
+ "version": "0.0.0",
+ "publishConfig": {
+ "access": "public"
+ },
+ "description": "Rollup plugin that detects assets references relative to modules using patterns such as `new URL('./path/to/asset.ext', import.meta.url)`. The assets are added to the rollup pipeline, allowing them to be transformed and hash the filenames.",
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/modernweb-dev/web.git",
+ "directory": "packages/rollup-plugin-import-meta-assets"
+ },
+ "author": "modern-web",
+ "homepage": "https://github.com/modernweb-dev/web/tree/master/packages/rollup-plugin-import-meta-assets",
+ "main": "dist/index.js",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "scripts": {
+ "test": "npm run test:node",
+ "test:node": "mocha test/**/*.test.js test/*.test.js",
+ "test:update-snapshots": "mocha test/**/*.test.js test/*.test.js --update-snapshots",
+ "test:watch": "npm run test:node -- --watch"
+ },
+ "files": [
+ "dist"
+ ],
+ "keywords": [
+ "rollup",
+ "plugin",
+ "import-meta"
+ ],
+ "dependencies": {
+ "@rollup/pluginutils": "^3.1.0",
+ "estree-walker": "^2.0.1",
+ "magic-string": "^0.25.7"
+ }
+}
diff --git a/packages/rollup-plugin-import-meta-assets/src/rollup-plugin-import-meta-assets.js b/packages/rollup-plugin-import-meta-assets/src/rollup-plugin-import-meta-assets.js
new file mode 100644
index 000000000..cf9901958
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/src/rollup-plugin-import-meta-assets.js
@@ -0,0 +1,109 @@
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+const { createFilter } = require('@rollup/pluginutils');
+const { asyncWalk } = require('estree-walker');
+const MagicString = require('magic-string');
+
+/**
+ * Extract the relative path from an AST node representing this kind of expression `new URL('./path/to/asset.ext', import.meta.url)`.
+ *
+ * @param {import('estree').Node} node - The AST node
+ * @returns {string} The relative path
+ */
+function getRelativeAssetPath(node) {
+ const browserPath = node.arguments[0].value;
+ return browserPath.split('/').join(path.sep);
+}
+
+/**
+ * Checks if a AST node represents this kind of expression: `new URL('./path/to/asset.ext', import.meta.url)`.
+ *
+ * @param {import('estree').Node} node - The AST node
+ * @returns {boolean}
+ */
+function isNewUrlImportMetaUrl(node) {
+ return (
+ node.type === 'NewExpression' &&
+ node.callee.type === 'Identifier' &&
+ node.callee.name === 'URL' &&
+ node.arguments.length === 2 &&
+ node.arguments[0].type === 'Literal' &&
+ typeof getRelativeAssetPath(node) === 'string' &&
+ node.arguments[1].type === 'MemberExpression' &&
+ node.arguments[1].object.type === 'MetaProperty' &&
+ node.arguments[1].property.type === 'Identifier' &&
+ node.arguments[1].property.name === 'url'
+ );
+}
+
+/**
+ * Detects assets references relative to modules using patterns such as `new URL('./path/to/asset.ext', import.meta.url)`.
+ * The assets are added to the rollup pipeline, allowing them to be transformed and hash the filenames.
+ *
+ * @param {object} options
+ * @param {string|string[]} [options.include] A picomatch pattern, or array of patterns, which specifies the files in the build the plugin should operate on. By default all files are targeted.
+ * @param {string|string[]} [options.exclude] A picomatch pattern, or array of patterns, which specifies the files in the build the plugin should _ignore_. By default no files are ignored.
+ * @param {boolean} [options.warnOnError] By default, the plugin quits the build process when it encounters an error. If you set this option to true, it will throw a warning instead and leave the code untouched.
+ * @param {function} [options.transform] A function to transform assets.
+ * @return {import('rollup').Plugin} A Rollup Plugin
+ */
+function importMetaAssets({ include, exclude, warnOnError, transform } = {}) {
+ const filter = createFilter(include, exclude);
+
+ return {
+ name: 'rollup-plugin-import-meta-assets',
+
+ async transform(code, id) {
+ if (!filter(id)) {
+ return null;
+ }
+
+ const ast = this.parse(code);
+ const magicString = new MagicString(code);
+
+ await asyncWalk(ast, {
+ enter: async node => {
+ if (isNewUrlImportMetaUrl(node)) {
+ const absoluteScriptDir = path.dirname(id);
+ const relativeAssetPath = getRelativeAssetPath(node);
+ const absoluteAssetPath = path.resolve(absoluteScriptDir, relativeAssetPath);
+ const assetName = path.basename(absoluteAssetPath);
+
+ try {
+ const assetContents = await fs.promises.readFile(absoluteAssetPath);
+ const transformedAssetContents =
+ transform != null
+ ? await transform(assetContents, absoluteAssetPath)
+ : assetContents;
+ const ref = this.emitFile({
+ type: 'asset',
+ name: assetName,
+ source: transformedAssetContents,
+ });
+ magicString.overwrite(
+ node.arguments[0].start,
+ node.arguments[0].end,
+ `import.meta.ROLLUP_FILE_URL_${ref}`,
+ );
+ } catch (error) {
+ if (warnOnError) {
+ this.warn(error, node.object.arguments[0].start);
+ } else {
+ this.error(error, node.object.arguments[0].start);
+ }
+ }
+ }
+ },
+ });
+
+ return {
+ code: magicString.toString(),
+ map: magicString.generateMap(),
+ };
+ },
+ };
+}
+
+module.exports = { importMetaAssets };
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/four.svg b/packages/rollup-plugin-import-meta-assets/test/fixtures/four.svg
new file mode 100644
index 000000000..86eb06cfd
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/four.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/image.jpg b/packages/rollup-plugin-import-meta-assets/test/fixtures/image.jpg
new file mode 100644
index 000000000..b0f2052e0
Binary files /dev/null and b/packages/rollup-plugin-import-meta-assets/test/fixtures/image.jpg differ
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/multi-level-entrypoint.js b/packages/rollup-plugin-import-meta-assets/test/fixtures/multi-level-entrypoint.js
new file mode 100644
index 000000000..bf15f8c13
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/multi-level-entrypoint.js
@@ -0,0 +1,11 @@
+import { imageOne, nameOne } from './one/one.js';
+import { imageTwo, nameTwo } from './one/two/two.js';
+import { imageThree, nameThree } from './one/two/three/three.js';
+import { imageFour, nameFour } from './one/two/three/four/four.js';
+
+console.log({
+ [nameOne]: imageOne,
+ [nameTwo]: imageTwo,
+ [nameThree]: imageThree,
+ [nameFour]: imageFour,
+});
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/one.svg b/packages/rollup-plugin-import-meta-assets/test/fixtures/one.svg
new file mode 100644
index 000000000..dfe13a152
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/one.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/one/one-deep.svg b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/one-deep.svg
new file mode 100644
index 000000000..dfe13a152
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/one-deep.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/one/one.js b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/one.js
new file mode 100644
index 000000000..4688ba51f
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/one.js
@@ -0,0 +1,2 @@
+export const nameOne = 'one-name';
+export const imageOne = new URL('../one.svg', import.meta.url).href;
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/different-asset-levels-entrypoint.js b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/different-asset-levels-entrypoint.js
new file mode 100644
index 000000000..81dacfe5d
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/different-asset-levels-entrypoint.js
@@ -0,0 +1,18 @@
+const nameOne = 'one-name';
+const imageOne = new URL('../one-deep.svg', import.meta.url).href;
+
+const nameTwo = 'two-name';
+const imageTwo = new URL('./two-deep.svg', import.meta.url).href;
+
+const nameThree = 'three-name';
+const imageThree = new URL('./three/three-deep.svg', import.meta.url).href;
+
+const nameFour = 'four-name';
+const imageFour = new URL('./three/four/four-deep.svg', import.meta.url).href;
+
+console.log({
+ [nameOne]: imageOne,
+ [nameTwo]: imageTwo,
+ [nameThree]: imageThree,
+ [nameFour]: imageFour,
+});
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/four/four-deep.svg b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/four/four-deep.svg
new file mode 100644
index 000000000..86eb06cfd
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/four/four-deep.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/four/four.js b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/four/four.js
new file mode 100644
index 000000000..56c5feb19
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/four/four.js
@@ -0,0 +1,2 @@
+export const nameFour = 'four-name';
+export const imageFour = new URL('../../../../four.svg', import.meta.url).href;
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/four/multi-level-entrypoint-deep.js b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/four/multi-level-entrypoint-deep.js
new file mode 100644
index 000000000..a5cdec821
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/four/multi-level-entrypoint-deep.js
@@ -0,0 +1,11 @@
+import { imageOne, nameOne } from '../../../one.js';
+import { imageTwo, nameTwo } from '../../two.js';
+import { imageThree, nameThree } from '../three.js';
+import { imageFour, nameFour } from './four.js';
+
+console.log({
+ [nameOne]: imageOne,
+ [nameTwo]: imageTwo,
+ [nameThree]: imageThree,
+ [nameFour]: imageFour,
+});
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/three-deep.svg b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/three-deep.svg
new file mode 100644
index 000000000..9ebc1e489
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/three-deep.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/three.js b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/three.js
new file mode 100644
index 000000000..fa3ec8b3c
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/three/three.js
@@ -0,0 +1,2 @@
+export const nameThree = 'three-name';
+export const imageThree = new URL('../../../three.svg', import.meta.url).href;
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/two-deep.svg b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/two-deep.svg
new file mode 100644
index 000000000..071582b8f
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/two-deep.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/two.js b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/two.js
new file mode 100644
index 000000000..11f10a4b4
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/one/two/two.js
@@ -0,0 +1,2 @@
+export const nameTwo = 'two-name';
+export const imageTwo = new URL('../../two.svg', import.meta.url).href;
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/simple-entrypoint.js b/packages/rollup-plugin-import-meta-assets/test/fixtures/simple-entrypoint.js
new file mode 100644
index 000000000..31b2a660e
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/simple-entrypoint.js
@@ -0,0 +1,11 @@
+const justUrlObject = new URL('./one.svg', import.meta.url);
+const href = new URL('./two.svg', import.meta.url).href;
+const pathname = new URL('./three.svg', import.meta.url).pathname;
+const searchParams = new URL('./four.svg', import.meta.url).searchParams;
+
+console.log({
+ justUrlObject,
+ href,
+ pathname,
+ searchParams,
+});
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/three.svg b/packages/rollup-plugin-import-meta-assets/test/fixtures/three.svg
new file mode 100644
index 000000000..9ebc1e489
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/three.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/transform-entrypoint.js b/packages/rollup-plugin-import-meta-assets/test/fixtures/transform-entrypoint.js
new file mode 100644
index 000000000..313e3f8f9
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/transform-entrypoint.js
@@ -0,0 +1,13 @@
+const justUrlObject = new URL('./one.svg', import.meta.url);
+const href = new URL('./two.svg', import.meta.url).href;
+const pathname = new URL('./three.svg', import.meta.url).pathname;
+const searchParams = new URL('./four.svg', import.meta.url).searchParams;
+const someJpg = new URL('./image.jpg', import.meta.url);
+
+console.log({
+ justUrlObject,
+ href,
+ pathname,
+ searchParams,
+ someJpg,
+});
diff --git a/packages/rollup-plugin-import-meta-assets/test/fixtures/two.svg b/packages/rollup-plugin-import-meta-assets/test/fixtures/two.svg
new file mode 100644
index 000000000..071582b8f
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/fixtures/two.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/integration.test.js b/packages/rollup-plugin-import-meta-assets/test/integration.test.js
new file mode 100644
index 000000000..e2857cfa0
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/integration.test.js
@@ -0,0 +1,184 @@
+const fs = require('fs');
+const path = require('path');
+const rollup = require('rollup');
+const { expect } = require('chai');
+
+const { importMetaAssets } = require('../src/rollup-plugin-import-meta-assets.js');
+
+const outputConfig = {
+ format: 'es',
+ dir: 'dist',
+};
+
+function expectChunk(output, shapshotUrl, chunkName, referencedFiles) {
+ const bundleJsSource = fs.readFileSync(path.join(__dirname, shapshotUrl));
+ const bundleJs = output.find(({ fileName }) => fileName === chunkName);
+ expect(bundleJs.type).to.equal('chunk');
+ expect(bundleJs.code).to.deep.equal(bundleJsSource.toString());
+ expect(bundleJs.referencedFiles).to.deep.equal(referencedFiles);
+}
+
+function expectAsset(output, snapshotUrl, assetName, distName) {
+ const snapshotSource = fs.readFileSync(path.join(__dirname, snapshotUrl));
+ const asset = output.find(({ name }) => name === assetName);
+ expect(typeof asset).to.equal('object');
+ expect(asset.type).to.equal('asset');
+ expect(asset.source.toString()).to.equal(snapshotSource.toString());
+ expect(asset.fileName).to.equal(distName);
+ return distName;
+}
+
+describe('rollup-plugin-import-meta-assets', () => {
+ it("simple bundle with different new URL('', import.meta.url)", async () => {
+ const config = {
+ input: { 'simple-bundle': require.resolve('./fixtures/simple-entrypoint.js') },
+ plugins: [importMetaAssets()],
+ };
+
+ const bundle = await rollup.rollup(config);
+ const { output } = await bundle.generate(outputConfig);
+
+ expect(output.length).to.equal(5);
+ expectChunk(output, 'snapshots/simple-bundle.js', 'simple-bundle.js', [
+ expectAsset(output, 'snapshots/one.svg', 'one.svg', 'assets/one-134aaf72.svg'),
+ expectAsset(output, 'snapshots/two.svg', 'two.svg', 'assets/two-e4de930c.svg'),
+ expectAsset(output, 'snapshots/three.svg', 'three.svg', 'assets/three-3f2c16b3.svg'),
+ expectAsset(output, 'snapshots/four.svg', 'four.svg', 'assets/four-b40404a7.svg'),
+ ]);
+ });
+
+ it('simple bundle with transform assets', async () => {
+ const config = {
+ input: { 'transform-bundle': require.resolve('./fixtures/transform-entrypoint.js') },
+ plugins: [
+ importMetaAssets({
+ transform: async (assetBuffer, assetPath) => {
+ // Only minify SVG files
+ return assetPath.endsWith('.svg')
+ ? // Fake minification with an XML comment
+ assetBuffer.toString() + '\n'
+ : assetBuffer;
+ },
+ }),
+ ],
+ };
+
+ const bundle = await rollup.rollup(config);
+ const { output } = await bundle.generate(outputConfig);
+
+ expect(output.length).to.equal(6);
+ expectChunk(output, 'snapshots/transform-bundle.js', 'transform-bundle.js', [
+ expectAsset(output, 'snapshots/one.min.svg', 'one.svg', 'assets/one-d81655b9.svg'),
+ expectAsset(output, 'snapshots/two.min.svg', 'two.svg', 'assets/two-00516e7a.svg'),
+ expectAsset(output, 'snapshots/three.min.svg', 'three.svg', 'assets/three-0ba6692d.svg'),
+ expectAsset(output, 'snapshots/four.min.svg', 'four.svg', 'assets/four-a00e2e1d.svg'),
+ expectAsset(output, 'snapshots/image.jpg', 'image.jpg', 'assets/image-d6eb190c.jpg'),
+ ]);
+ });
+
+ it('multiple level bundle (downward modules)', async () => {
+ const config = {
+ input: { 'multi-level-bundle': require.resolve('./fixtures/multi-level-entrypoint.js') },
+ plugins: [importMetaAssets()],
+ };
+
+ const bundle = await rollup.rollup(config);
+ const { output } = await bundle.generate(outputConfig);
+
+ expect(output.length).to.equal(5);
+ expectChunk(output, 'snapshots/multi-level-bundle.js', 'multi-level-bundle.js', [
+ expectAsset(output, 'snapshots/one.svg', 'one.svg', 'assets/one-134aaf72.svg'),
+ expectAsset(output, 'snapshots/two.svg', 'two.svg', 'assets/two-e4de930c.svg'),
+ expectAsset(output, 'snapshots/three.svg', 'three.svg', 'assets/three-3f2c16b3.svg'),
+ expectAsset(output, 'snapshots/four.svg', 'four.svg', 'assets/four-b40404a7.svg'),
+ ]);
+ });
+
+ it('multiple level bundle (upward modules)', async () => {
+ const config = {
+ input: {
+ 'multi-level-bundle': require.resolve(
+ './fixtures/one/two/three/four/multi-level-entrypoint-deep.js',
+ ),
+ },
+ plugins: [importMetaAssets()],
+ };
+
+ const bundle = await rollup.rollup(config);
+ const { output } = await bundle.generate(outputConfig);
+
+ expect(output.length).to.equal(5);
+ expectChunk(output, 'snapshots/multi-level-bundle.js', 'multi-level-bundle.js', [
+ expectAsset(output, 'snapshots/one.svg', 'one.svg', 'assets/one-134aaf72.svg'),
+ expectAsset(output, 'snapshots/two.svg', 'two.svg', 'assets/two-e4de930c.svg'),
+ expectAsset(output, 'snapshots/three.svg', 'three.svg', 'assets/three-3f2c16b3.svg'),
+ expectAsset(output, 'snapshots/four.svg', 'four.svg', 'assets/four-b40404a7.svg'),
+ ]);
+ });
+
+ it('different asset levels', async () => {
+ const config = {
+ input: {
+ 'different-asset-levels-bundle': require.resolve(
+ './fixtures/one/two/different-asset-levels-entrypoint.js',
+ ),
+ },
+ plugins: [importMetaAssets()],
+ };
+
+ const bundle = await rollup.rollup(config);
+ const { output } = await bundle.generate(outputConfig);
+
+ expect(output.length).to.equal(5);
+ expectChunk(
+ output,
+ 'snapshots/different-asset-levels-bundle.js',
+ 'different-asset-levels-bundle.js',
+ [
+ expectAsset(output, 'snapshots/one.svg', 'one-deep.svg', 'assets/one-deep-d40c1b4b.svg'),
+ expectAsset(output, 'snapshots/two.svg', 'two-deep.svg', 'assets/two-deep-e73b0d96.svg'),
+ expectAsset(
+ output,
+ 'snapshots/three.svg',
+ 'three-deep.svg',
+ 'assets/three-deep-801763e8.svg',
+ ),
+ expectAsset(output, 'snapshots/four.svg', 'four-deep.svg', 'assets/four-deep-c65478aa.svg'),
+ ],
+ );
+ });
+
+ it('include/exclude options', async () => {
+ const config = {
+ input: {
+ 'one-bundle': require.resolve('./fixtures/one/one.js'),
+ 'two-bundle': require.resolve('./fixtures/one/two/two.js'),
+ 'three-bundle': require.resolve('./fixtures/one/two/three/three.js'),
+ 'four-bundle': require.resolve('./fixtures/one/two/three/four/four.js'),
+ },
+ plugins: [
+ importMetaAssets({
+ // include everything in "*/one/two/**"
+ // but exclude "*/one/two/two.js"
+ // which means just include "*/one/two/three.js" and "*/one/two/three/four.js"
+ include: '**/one/two/**',
+ exclude: '**/one/two/two.js',
+ }),
+ ],
+ };
+
+ const bundle = await rollup.rollup(config);
+ const { output } = await bundle.generate(outputConfig);
+
+ // 4 ES modules + 2 assets
+ expect(output.length).to.equal(6);
+ expectChunk(output, 'snapshots/one-bundle.js', 'one-bundle.js', []);
+ expectChunk(output, 'snapshots/two-bundle.js', 'two-bundle.js', []);
+ expectChunk(output, 'snapshots/three-bundle.js', 'three-bundle.js', [
+ expectAsset(output, 'snapshots/three.svg', 'three.svg', 'assets/three-3f2c16b3.svg'),
+ ]);
+ expectChunk(output, 'snapshots/four-bundle.js', 'four-bundle.js', [
+ expectAsset(output, 'snapshots/four.svg', 'four.svg', 'assets/four-b40404a7.svg'),
+ ]);
+ });
+});
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/different-asset-levels-bundle.js b/packages/rollup-plugin-import-meta-assets/test/snapshots/different-asset-levels-bundle.js
new file mode 100644
index 000000000..7051bc170
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/different-asset-levels-bundle.js
@@ -0,0 +1,18 @@
+const nameOne = 'one-name';
+const imageOne = new URL(new URL('assets/one-deep-d40c1b4b.svg', import.meta.url).href, import.meta.url).href;
+
+const nameTwo = 'two-name';
+const imageTwo = new URL(new URL('assets/two-deep-e73b0d96.svg', import.meta.url).href, import.meta.url).href;
+
+const nameThree = 'three-name';
+const imageThree = new URL(new URL('assets/three-deep-801763e8.svg', import.meta.url).href, import.meta.url).href;
+
+const nameFour = 'four-name';
+const imageFour = new URL(new URL('assets/four-deep-c65478aa.svg', import.meta.url).href, import.meta.url).href;
+
+console.log({
+ [nameOne]: imageOne,
+ [nameTwo]: imageTwo,
+ [nameThree]: imageThree,
+ [nameFour]: imageFour,
+});
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/four-bundle.js b/packages/rollup-plugin-import-meta-assets/test/snapshots/four-bundle.js
new file mode 100644
index 000000000..91fa57cf2
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/four-bundle.js
@@ -0,0 +1,4 @@
+const nameFour = 'four-name';
+const imageFour = new URL(new URL('assets/four-b40404a7.svg', import.meta.url).href, import.meta.url).href;
+
+export { imageFour, nameFour };
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/four.min.svg b/packages/rollup-plugin-import-meta-assets/test/snapshots/four.min.svg
new file mode 100644
index 000000000..2a566f173
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/four.min.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/four.svg b/packages/rollup-plugin-import-meta-assets/test/snapshots/four.svg
new file mode 100644
index 000000000..86eb06cfd
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/four.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/image.jpg b/packages/rollup-plugin-import-meta-assets/test/snapshots/image.jpg
new file mode 100644
index 000000000..b0f2052e0
Binary files /dev/null and b/packages/rollup-plugin-import-meta-assets/test/snapshots/image.jpg differ
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/multi-level-bundle.js b/packages/rollup-plugin-import-meta-assets/test/snapshots/multi-level-bundle.js
new file mode 100644
index 000000000..1f3e14c4f
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/multi-level-bundle.js
@@ -0,0 +1,18 @@
+const nameOne = 'one-name';
+const imageOne = new URL(new URL('assets/one-134aaf72.svg', import.meta.url).href, import.meta.url).href;
+
+const nameTwo = 'two-name';
+const imageTwo = new URL(new URL('assets/two-e4de930c.svg', import.meta.url).href, import.meta.url).href;
+
+const nameThree = 'three-name';
+const imageThree = new URL(new URL('assets/three-3f2c16b3.svg', import.meta.url).href, import.meta.url).href;
+
+const nameFour = 'four-name';
+const imageFour = new URL(new URL('assets/four-b40404a7.svg', import.meta.url).href, import.meta.url).href;
+
+console.log({
+ [nameOne]: imageOne,
+ [nameTwo]: imageTwo,
+ [nameThree]: imageThree,
+ [nameFour]: imageFour,
+});
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/one-bundle.js b/packages/rollup-plugin-import-meta-assets/test/snapshots/one-bundle.js
new file mode 100644
index 000000000..ad74d524a
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/one-bundle.js
@@ -0,0 +1,4 @@
+const nameOne = 'one-name';
+const imageOne = new URL('../one.svg', import.meta.url).href;
+
+export { imageOne, nameOne };
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/one.min.svg b/packages/rollup-plugin-import-meta-assets/test/snapshots/one.min.svg
new file mode 100644
index 000000000..01f16c285
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/one.min.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/one.svg b/packages/rollup-plugin-import-meta-assets/test/snapshots/one.svg
new file mode 100644
index 000000000..dfe13a152
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/one.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/simple-bundle.js b/packages/rollup-plugin-import-meta-assets/test/snapshots/simple-bundle.js
new file mode 100644
index 000000000..16e8b1a95
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/simple-bundle.js
@@ -0,0 +1,11 @@
+const justUrlObject = new URL(new URL('assets/one-134aaf72.svg', import.meta.url).href, import.meta.url);
+const href = new URL(new URL('assets/two-e4de930c.svg', import.meta.url).href, import.meta.url).href;
+const pathname = new URL(new URL('assets/three-3f2c16b3.svg', import.meta.url).href, import.meta.url).pathname;
+const searchParams = new URL(new URL('assets/four-b40404a7.svg', import.meta.url).href, import.meta.url).searchParams;
+
+console.log({
+ justUrlObject,
+ href,
+ pathname,
+ searchParams,
+});
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/three-bundle.js b/packages/rollup-plugin-import-meta-assets/test/snapshots/three-bundle.js
new file mode 100644
index 000000000..fb7158924
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/three-bundle.js
@@ -0,0 +1,4 @@
+const nameThree = 'three-name';
+const imageThree = new URL(new URL('assets/three-3f2c16b3.svg', import.meta.url).href, import.meta.url).href;
+
+export { imageThree, nameThree };
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/three.min.svg b/packages/rollup-plugin-import-meta-assets/test/snapshots/three.min.svg
new file mode 100644
index 000000000..342277191
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/three.min.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/three.svg b/packages/rollup-plugin-import-meta-assets/test/snapshots/three.svg
new file mode 100644
index 000000000..9ebc1e489
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/three.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/transform-bundle.js b/packages/rollup-plugin-import-meta-assets/test/snapshots/transform-bundle.js
new file mode 100644
index 000000000..b2673befd
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/transform-bundle.js
@@ -0,0 +1,13 @@
+const justUrlObject = new URL(new URL('assets/one-d81655b9.svg', import.meta.url).href, import.meta.url);
+const href = new URL(new URL('assets/two-00516e7a.svg', import.meta.url).href, import.meta.url).href;
+const pathname = new URL(new URL('assets/three-0ba6692d.svg', import.meta.url).href, import.meta.url).pathname;
+const searchParams = new URL(new URL('assets/four-a00e2e1d.svg', import.meta.url).href, import.meta.url).searchParams;
+const someJpg = new URL(new URL('assets/image-d6eb190c.jpg', import.meta.url).href, import.meta.url);
+
+console.log({
+ justUrlObject,
+ href,
+ pathname,
+ searchParams,
+ someJpg,
+});
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/two-bundle.js b/packages/rollup-plugin-import-meta-assets/test/snapshots/two-bundle.js
new file mode 100644
index 000000000..0b472bb93
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/two-bundle.js
@@ -0,0 +1,4 @@
+const nameTwo = 'two-name';
+const imageTwo = new URL('../../two.svg', import.meta.url).href;
+
+export { imageTwo, nameTwo };
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/two.min.svg b/packages/rollup-plugin-import-meta-assets/test/snapshots/two.min.svg
new file mode 100644
index 000000000..f37fafe51
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/two.min.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/packages/rollup-plugin-import-meta-assets/test/snapshots/two.svg b/packages/rollup-plugin-import-meta-assets/test/snapshots/two.svg
new file mode 100644
index 000000000..071582b8f
--- /dev/null
+++ b/packages/rollup-plugin-import-meta-assets/test/snapshots/two.svg
@@ -0,0 +1,5 @@
+