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

chore: migrate rollup-plugin-alias #15

Merged
merged 1 commit into from
Oct 30, 2019
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
39 changes: 39 additions & 0 deletions packages/alias/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# @rollup/plugin-alias Changelog

## 2.2.0
*2019-10-21*
* Support resolving `index.js` files in directories ([#64](https://github.com/rollup/rollup-plugin-alias/pull/64) by @jerriclynsjohn)

## 2.1.0
*2019-10-18*
* Add support for object syntax ([#61](https://github.com/rollup/rollup-plugin-alias/pull/61) by @Andarist)

## 2.0.1
*2019-09-27*
* Update dependencies ([#59](https://github.com/rollup/rollup-plugin-alias/pull/59) by @lukastaegert)
* Make volume letter regexp case independent ([#57](https://github.com/rollup/rollup-plugin-alias/pull/57) by @MarekLacoAXA)

## 2.0.0
*2019-08-22*
* Add RegExp support and strict order of entries ([#53](https://github.com/rollup/rollup-plugin-alias/pull/53) by @thiscantbeserious)

### Breaking Changes
Aliases always need to be provided as an array, see #53

## 1.5.2

* Update dependencies

## 1.5.1

* Update tests for Rollup@1.0 compatibility and tests ([#48](https://github.com/rollup/rollup-plugin-alias/pull/48))

## 1.4.0

* Various Windows fixes ([#22](https://github.com/rollup/rollup-plugin-alias/pull/22))
* Don't try to alias entry file ([#29](https://github.com/rollup/rollup-plugin-alias/pull/29))

## 1.3.0

* Start maintaining a changelog
* Fix `isFilePath` on Windows ([#3](https://github.com/rollup/rollup-plugin-alias/issues/3))
129 changes: 129 additions & 0 deletions packages/alias/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
[cover]: https://codecov.io/gh/rollup/plugins/alias/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/rollup/plugins/alias
[size]: https://packagephobia.now.sh/badge?p=@rollup/plugin-alias
[size-url]: https://packagephobia.now.sh/result?p=@rollup/plugin-alias

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

# @rollup/plugin-alias

🍣 A Rollup plugin for defining aliases when bundling packages.

## Alias 101

Suppose we have the following `import` defined in a hypothetical file:

```javascript
import batman from '../../../batman';
```

This probably doesn't look too bad on its own. But consider that may not be the only instance in your codebase, and that after a refactor this might be incorrect. With this plugin in place, you can alias `../../../batman` with `batman` for readability and maintainability. In the case of a refactor, only the alias would need to be changed, rather than navigating through the codebase and changing all imports.

```javascript
import batman from 'batman';
```

If this seems familiar to Webpack users, it should. This is plugin mimics the `resolve.extensions` and `resolve.alias` functionality in Webpack.

## 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-alias --save-dev
```

## Usage

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

```js
import alias from '@rollup/plugin-alias';

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

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 'alias' character to stderr, which should be audible on most systems.

## Options

### `entries`

Type: `Object | Array[Object]`<br>
Default: `null`

Specifies an `Object`, or an `Array` of `Object`, which defines aliases used to replace values in `import` or `require` statements. With either format, the order of the entries is important, in that the first defined rules are applied first. This option also supports [Regular Expression Alias](#regular-expression-aliases) matching.

#### `Object` Format

The `Object` format allows specifying aliases as a key, and the corresponding value as the actual `import` value. For example:

```js
alias({
entries: {
utils: '../../../utils',
'batman-1.0.0': './joker-1.5.0'
}
});
```

#### `Array[Object]` Format

The `Array[Object]` format allows specifying aliases as objects, which can be useful for complex key/value pairs.

```js
entries: [
{ find: 'utils', replacement: '../../../utils' },
{ find: 'batman-1.0.0', replacement: './joker-1.5.0' }
];
```

### `resolve`

Type: `Array[String]`<br>
Default: `['.js']`

Specifies an array of file extensions to use when attempting to resolve an `import` (or `require`). The extensions will be tried in the order they are specified. By default, this option is configured to resolve only files that have the `.js` extension. For example; to resolve both `JSX` and `JS` files:

```js
alias({ resolve: ['.jsx', '.js'] });
```

## Regular Expression Aliases

Regular Expressions can be used to search in a more distinct and complex manner. e.g. To perform partial replacements via sub-pattern matching.

To remove something in front of an import and append an extension, use a pattern such as:

```js
{ find:/^i18n\!(.*)/, replacement: '$1.js' }
```

This would be useful for loaders, and files that were previously transpiled via the AMD module, to properly handle them in rollup as internals.

To replace extensions with another, a pattern like the following might be used:

```js
{ find:/^(.*)\.js$/, replacement: '$1.wasm' }
```

This would replace the file extension for all imports ending with `.js` to `.wasm`.

## Meta

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

[LICENSE (MIT)](./LICENSE)
61 changes: 61 additions & 0 deletions packages/alias/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"name": "@rollup/plugin-alias",
"version": "2.2.0",
"description": "Resolves aliases with Rollup",
"license": "MIT",
"repository": "rollup/plugins",
"author": "Johannes Stein",
"homepage": "https://github.com/rollup/plugins",
"bugs": "https://github.com/rollup/plugins/issues",
"main": "dist/index.js",
"scripts": {
"build": "rollup -c",
"ci:coverage": "nyc pnpm run test && nyc report --reporter=text-lcov > coverage.lcov",
"ci:coverage:submit": "curl -s https://codecov.io/bash | bash -s - -F alias",
"ci:lint": "pnpm run build && pnpm run lint && pnpm run security",
"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",
"lint:package": "prettier --write package.json --plugin=prettier-plugin-package",
"prebuild": "del-cli dist",
"prepare": "npm run build",
"prepublishOnly": "npm run lint && npm run test",
"pretest": "npm run build",
"security": "echo 'pnpm needs `npm audit` support'",
"test": "ava"
},
"files": [
"dist",
"src",
"README.md",
"LICENSE"
],
"keywords": [
"rollup",
"plugin",
"resolve",
"alias"
],
"peerDependencies": {
"rollup": "^1.20.0"
},
"dependencies": {
"slash": "^3.0.0"
},
"devDependencies": {
"del-cli": "^3.0.0",
"rollup": "^1.20.0"
},
"ava": {
"files": [
"!**/fixtures/**",
"!**/helpers/**",
"!**/recipes/**",
"!**/types.ts"
]
},
"jsnext:main": "dist/index.es2015.js",
"module": "dist/index.es2015.js"
}
7 changes: 7 additions & 0 deletions packages/alias/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import pkg from './package.json';

export default {
input: 'src/index.js',
output: [{ file: pkg.main, format: 'cjs' }, { file: pkg.module, format: 'es' }],
external: Object.keys(pkg.dependencies).concat(['path', 'fs', 'os'])
};
116 changes: 116 additions & 0 deletions packages/alias/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import fs from 'fs';
import { platform } from 'os';
import path, { posix } from 'path';

import slash from 'slash';

const VOLUME = /^([A-Z]:)/i;
const IS_WINDOWS = platform() === 'win32';

// Helper functions
const noop = () => null;
const matches = (pattern, importee) => {
if (pattern instanceof RegExp) {
return pattern.test(importee);
}
if (importee.length < pattern.length) {
return false;
}
if (importee === pattern) {
return true;
}
const importeeStartsWithKey = importee.indexOf(pattern) === 0;
const importeeHasSlashAfterKey = importee.substring(pattern.length)[0] === '/';
return importeeStartsWithKey && importeeHasSlashAfterKey;
};
const endsWith = (needle, haystack) => haystack.slice(-needle.length) === needle;
const isFilePath = (id) => /^\.?\//.test(id);
const exists = (uri) => {
try {
return fs.statSync(uri).isFile();
} catch (e) {
return false;
}
};

const normalizeId = (id) => {
if ((IS_WINDOWS && typeof id === 'string') || VOLUME.test(id)) {
return slash(id.replace(VOLUME, ''));
}
return id;
};

const getEntries = ({ entries }) => {
if (!entries) {
return [];
}

if (Array.isArray(entries)) {
return entries;
}

return Object.keys(entries).map((key) => {
return { find: key, replacement: entries[key] };
});
};

export default function alias(options = {}) {
const resolve = Array.isArray(options.resolve) ? options.resolve : ['.js'];
const entries = getEntries(options);

// No aliases?
if (entries.length === 0) {
return {
resolveId: noop
};
}

return {
resolveId(importee, importer) {
const importeeId = normalizeId(importee);
const importerId = normalizeId(importer);

// First match is supposed to be the correct one
const matchedEntry = entries.find((entry) => matches(entry.find, importeeId));
if (!matchedEntry || !importerId) {
return null;
}

let updatedId = normalizeId(importeeId.replace(matchedEntry.find, matchedEntry.replacement));

if (isFilePath(updatedId)) {
const directory = posix.dirname(importerId);

// Resolve file names
const filePath = posix.resolve(directory, updatedId);
const match = resolve
.map((ext) => (endsWith(ext, filePath) ? filePath : `${filePath}${ext}`))
.find(exists);

if (match) {
updatedId = match;
// To keep the previous behaviour we simply return the file path
// with extension
} else if (endsWith('.js', filePath)) {
updatedId = filePath;
} else {
const indexFilePath = posix.resolve(directory, `${updatedId}/index`);
const defaultMatch = resolve.map((ext) => `${indexFilePath}${ext}`).find(exists);
if (defaultMatch) {
updatedId = defaultMatch;
} else {
updatedId = `${filePath}.js`;
}
}
}

// if alias is windows absoulate path return resolved path or
// rollup on windows will throw:
// [TypeError: Cannot read property 'specifier' of undefined]
if (VOLUME.test(matchedEntry.replacement)) {
return path.resolve(updatedId);
}
return updatedId;
}
};
}
Empty file.
1 change: 1 addition & 0 deletions packages/alias/test/fixtures/aliasMe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 42;
1 change: 1 addition & 0 deletions packages/alias/test/fixtures/folder/anotherNumber.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 33;
Empty file.
11 changes: 11 additions & 0 deletions packages/alias/test/fixtures/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* eslint-disable import/no-unresolved, import/extensions */

import fancyNumber from 'fancyNumber';

import moreNumbers from 'numberFolder/anotherNumber';

import nonAliased from './nonAliased';
import anotherFancyNumber from './anotherFancyNumber';
import anotherNumber from './numberFolder/anotherNumber';

export default fancyNumber + anotherFancyNumber + nonAliased + anotherNumber + moreNumbers;
1 change: 1 addition & 0 deletions packages/alias/test/fixtures/localAliasMe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 42;
1 change: 1 addition & 0 deletions packages/alias/test/fixtures/nonAliased.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 24;
Loading