Skip to content

chore(repo): new plugin data-uri #150

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

Merged
merged 14 commits into from
Jan 9, 2020
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
5 changes: 5 additions & 0 deletions packages/data-uri/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# @rollup/plugin-data-uri ChangeLog

## 0.1.0

- First Release
74 changes: 74 additions & 0 deletions packages/data-uri/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
[npm]: https://img.shields.io/npm/v/@rollup/plugin-data-uri
[npm-url]: https://www.npmjs.com/package/@rollup/plugin-data-uri
[size]: https://packagephobia.now.sh/badge?p=@rollup/plugin-data-uri
[size-url]: https://packagephobia.now.sh/result?p=@rollup/plugin-data-uri

[![npm][npm]][npm-url]
[![size][size]][size-url]
[![libera manifesto](https://img.shields.io/badge/libera-manifesto-lightgrey.svg)](https://liberamanifesto.com)

# @rollup/plugin-data-uri

🍣 A Rollup plugin which imports modules from Data URIs.

## Requirements

This plugin requires an [LTS](https://github.com/nodejs/Release) Node version (v8.0.0+) and Rollup v1.20.0+.

## Install

Using npm:

```console
npm install @rollup/plugin-data-uri --save-dev
```

## Usage

Create a `rollup.config.js` [configuration file](https://www.rollupjs.org/guide/en/#configuration-files) and import the plugin:

```js
import dataUri from '@rollup/plugin-data-uri';

module.exports = {
input: 'src/index.js',
output: {
dir: 'output',
format: 'cjs'
},
plugins: [dataUri()]
};
```

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). If the build produces any errors, the plugin will write a "data-uri" character to stderr, which should be audible on most systems.

## Options

This plugin currently has no available options.

## Supported MIME Types

The following MIME types are supported by this plugin:

- `text/javascript`
- `application/json`

This mirrors support in the [latest version of Node.js](https://nodejs.org/api/esm.html#esm_data_imports), with the exception of WebAssembly support.

## Base64 Encoding

Base64 encoding is supported for well-formed `data:` URIs. For example:

```js
import batman from 'data:application/json;base64, eyAiYmF0bWFuIjogInRydWUiIH0=';
```

## Dynamic Imports

Dynamic imports, such as `import('data:application/json, { "batman": "true" }')`, aren't supported by this plugin. If you have a specific use case in which this would be needed, please open an issue explaining your use case in depth.

## Meta

[CONTRIBUTING](/.github/CONTRIBUTING.md)

[LICENSE (MIT)](/LICENSE)
74 changes: 74 additions & 0 deletions packages/data-uri/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"name": "@rollup/plugin-data-uri",
"version": "0.1.0",
"publishConfig": {
"access": "public"
},
"description": "Import modules from Data URIs",
"license": "MIT",
"repository": "rollup/plugins",
"author": "shellscape",
"homepage": "https://github.com/rollup/plugins/tree/master/packages/data-uri",
"bugs": "https://github.com/rollup/plugins/issues",
"main": "dist/index.js",
"engines": {
"node": ">= 8.0.0"
},
"scripts": {
"build": "rollup -c",
"ci:coverage": "nyc pnpm run test && nyc report --reporter=text-lcov > coverage.lcov",
"ci:lint": "pnpm run build && pnpm run lint",
"ci:lint:commits": "commitlint --from=${CIRCLE_BRANCH} --to=${CIRCLE_SHA1}",
"ci:test": "pnpm run test -- --verbose",
"lint": "pnpm run lint:js && pnpm run lint:docs && pnpm run lint:package",
"lint:docs": "prettier --single-quote --write README.md",
"lint:js": "eslint --fix --cache src test --ext .js,.ts",
"lint:package": "prettier --write package.json --plugin=prettier-plugin-package",
"prebuild": "del-cli dist",
"prepublishOnly": "pnpm run lint && pnpm run build",
"pretest": "pnpm run build -- --sourcemap",
"test": "ava"
},
"files": [
"dist",
"types",
"README.md",
"LICENSE"
],
"keywords": [
"data",
"data-uri",
"data-url",
"plugin",
"rollup",
"uri",
"url"
],
"peerDependencies": {
"rollup": "^1.20.0"
},
"devDependencies": {
"@rollup/plugin-typescript": "^2.1.0",
"@rollup/pluginutils": "^3.0.1",
"rollup": "^1.27.14",
"typescript": "^3.7.4"
},
"ava": {
"compileEnhancements": false,
"extensions": [
"ts"
],
"require": [
"ts-node/register"
],
"files": [
"!**/fixtures/**",
"!**/output/**",
"!**/helpers/**",
"!**/recipes/**",
"!**/types.ts"
]
},
"module": "dist/index.es.js",
"types": "types/index.d.ts"
}
13 changes: 13 additions & 0 deletions packages/data-uri/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import typescript from '@rollup/plugin-typescript';

import pkg from './package.json';

export default {
input: 'src/index.ts',
plugins: [typescript()],
external: [...Object.keys(pkg.devDependencies), 'url'],
output: [
{ format: 'cjs', file: pkg.main, sourcemap: true },
{ format: 'esm', file: pkg.module, sourcemap: true }
]
};
86 changes: 86 additions & 0 deletions packages/data-uri/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { URL } from 'url';

import { Plugin, RollupError } from 'rollup';

import { dataToEsm } from '@rollup/pluginutils';

const reDataUri = /^([^/]+\/[^;,]+)(;base64)?,([\s\S]*)$/;
const mimeTypes = {
js: 'text/javascript',
json: 'application/json'
};

export default function dataUri(): Plugin {
const resolved: { [key: string]: { mime: string | null; content: string | null } } = {};

return {
name: 'dataUri',

resolveId(id) {
if (resolved[id]) {
return id;
}

if (!reDataUri.test(id)) {
return null;
}

const uri = new URL(id);

if (uri.protocol !== 'data:') {
return null;
}

const empty = [null, null, null, null, null];
const [, mime, format, data] = reDataUri.exec(uri.pathname) || empty;

if (Object.values(mimeTypes).includes(mime as string) && data) {
const base64 = format && /base64/i.test(format.substring(1));
const content = base64 ? Buffer.from(data, 'base64').toString('utf-8') : data;

resolved[id] = { mime, content };

return id;
}

return null;
},

load(id) {
if (!resolved[id]) {
return null;
}

const { mime, content } = resolved[id];

if (!content) {
return null;
}

if (mime === 'text/javascript') {
return content;
} else if (mime === 'application/json') {
let json = '';
try {
json = JSON.parse(content);
} catch (e) {
const error: RollupError = {
message: e.toString(),
parserError: e,
plugin: '@rollup/plugin-data-uri',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this field gets set by rollup automatically

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's superfluous but not harmful.

pluginCode: 'DU$JSON'
};
this.error(error);
}

return dataToEsm(json, {
preferConst: true,
compact: false,
namedExports: true,
indent: ' '
});
}
return null;
}
};
}
9 changes: 9 additions & 0 deletions packages/data-uri/test/fixtures/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"globals": {
"t": true
},
"rules": {
"import/extensions": "off",
"import/no-unresolved": "off"
}
}
1 change: 1 addition & 0 deletions packages/data-uri/test/fixtures/bad-json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import 'data:application/json, { "batman": }';
4 changes: 4 additions & 0 deletions packages/data-uri/test/fixtures/base64.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import batman from 'data:application/json;base64, eyAiYmF0bWFuIjogInRydWUiIH0=';

t.truthy(batman.batman);
t.snapshot(batman);
4 changes: 4 additions & 0 deletions packages/data-uri/test/fixtures/import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import 'data:text/javascript, t.truthy(true);';
import { batman } from 'data:text/javascript, export const batman = true;\nconst joker = false;\nexport default joker;';

t.snapshot(batman);
4 changes: 4 additions & 0 deletions packages/data-uri/test/fixtures/json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import batman from 'data:application/json, { "batman": "true" }';

t.truthy(batman.batman);
t.snapshot(batman);
74 changes: 74 additions & 0 deletions packages/data-uri/test/snapshots/test.js.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Snapshot report for `test/test.js`

The actual snapshot is saved in `test.js.snap`.

Generated by [AVA](https://ava.li).

## bad json

> Snapshot 1

{
code: 'PLUGIN_ERROR',
plugin: 'dataUri',
pluginCode: 'DU$JSON',
}

## import

> Snapshot 1

true

> Snapshot 2

`'use strict';␊
t.truthy(true);␊
const batman = true;␊
t.snapshot(batman);␊
`

## json

> Snapshot 1

{
batman: 'true',
}

> Snapshot 2

`'use strict';␊
const batman = "true";␊
var batman$1 = {␊
batman: batman␊
};␊
t.truthy(batman$1.batman);␊
t.snapshot(batman$1);␊
`

## base64

> Snapshot 1

{
batman: 'true',
}

> Snapshot 2

`'use strict';␊
const batman = "true";␊
var batman$1 = {␊
batman: batman␊
};␊
t.truthy(batman$1.batman);␊
t.snapshot(batman$1);␊
`
Binary file added packages/data-uri/test/snapshots/test.js.snap
Binary file not shown.
Loading