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 @@ + + +