Skip to content

Commit

Permalink
Merge pull request #56 from UmamiAppearance/regex-module-selection_pl…
Browse files Browse the repository at this point in the history
…ugin

Regex module selection
  • Loading branch information
UmamiAppearance authored May 12, 2023
2 parents 98bc2ad + 67a5df8 commit 07846b5
Show file tree
Hide file tree
Showing 7 changed files with 391 additions and 88 deletions.
169 changes: 158 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ A Rollup plugin which makes it possible to manipulate import statements. Feature
- [`warnings`](#warnings)
- [`units`](#units)
- [`module`](#module-option-for-units)
- [`rawModule`](#rawmodule-option-for-units)
- [`hash`](#hash-option-for-units)
- [`id`](#id-option-for-units)
- [`file`](#file-option-for-units)
Expand Down Expand Up @@ -54,14 +55,18 @@ A Rollup plugin which makes it possible to manipulate import statements. Feature
- [Removing an Import Statement](#removing-an-import-statement)
- [Shorthand Method](#shorthand-method)
- [Moving an Import Statement (cut and paste)](#moving-an-import-statement-cut-and-paste)
- [Changing the module](#changing-the-module)
- [Modifying the module](#changing-the-module)
- [Changing a relative path to an absolute path (passing a String to rename)](#changing-a-relative-path-to-an-absolute-path-passing-a-string-to-rename)
- [Changing a relative path to different directory (making use of a rename Function)](#changing-a-relative-path-to-different-directory-making-use-of-a-rename-function)
- [Addressing the (default) members](#addressing-the-default-members)
- [Adding a defaultMember](#adding-a-defaultmember)
- [Removing a member](#removing-a-member)
- [Removing a group of members](#removing-a-group-of-members)
- [Changing a defaultMember name](#changing-a-defaultmember-name)
- [Renaming but keeping the alias](#renaming-but-keeping-the-alias)
- [Addressing an alias](#addressing-an-alias)
- [Applying RegExp for module matching](#applying-regexp-for-module-matching)
- [Using rawModule for module matching](#using-rawmodule-for-module-matching)
- [General Hints](#general-hints)
- [Chaining](#chaining)
- [Array and Object shortening](#array-and-object-shortening)
Expand Down Expand Up @@ -162,7 +167,7 @@ This is where the plugin comes to life. Here is the place where units are gettin
---

#### `module` <samp>[option for units]</samp>
Type: `String`
Type: `String` | `Object`
Default: `null`

Selects a unit by its module name. Each import has a name object. This is constructed from the module.
Expand All @@ -171,16 +176,34 @@ Path information are getting removed. Consider this basic es6 import statement:
import foo from "./path/bar.js";
```
The corresponding unit assigns the module name `bar.js` which can be matched with: `module: "bar.js"`
(The matching method is actually a little more generous. You can skip the extension or even bigger parts if you like and if this doesn't lead to multiple matches).

The matching method is actually a little more generous. If the value is a `String` the provided value will get searched anywhere in the module name. You can skip the extension or even bigger parts if you like and if this doesn't lead to multiple matches. However, if you need more control, you can always use a [Regular Expression Object](#applying-regexp-for-module-matching). (If you need access to the full path you should use the [`rawModule`](#rawmodule-option-for-units) matching method.)

Absolute imports are directly assigned as the name attribute. So, the following example can be matched with `module: "bar"`
```js
import foo from "bar";
```

To match to an exact module name like `react` but exclude `react-table` for example, you can provide a `RegExp`:
`module: /^react$/`.

Also see this [example](#changing-the-module) of matching a module and changing it.



#### `rawModule` <samp>[option for units]</samp>
Type: `String` | `Object`
Default: `null`

Selects a unit by its raw module name. `rawModule` works exactly the same as [`module`](#module-option-for-units). The only difference is, that is using the raw full module path. Consider the example from above:
```js
import foo from "./path/bar.js";
```
The raw module stores the value `"./path/bar.js"` including the quotation marks, which can be matched as shown before via `String` or `RegExp`. See this [example](#using-rawmodule-for-module-matching).

_If any other matching option is set, `rawModule` gets ignored._


#### `hash` <samp>[option for units]</samp>
Type: `String`
Default: `null`
Expand All @@ -189,7 +212,7 @@ Selects a unit by its hash. If - for any reason - it is not possible to match vi

The hash is generated by the module name, its members and also the filename. If the filename or any of the other properties are changing so is the hash. So, if a module is selected via hash and any of the properties are changed, the build will fail afterwards as the hash is no longer existent. This is why the matching via module name should be preferred.

If the hash option is set, the [module](#module-option-for-units) option will get ignored.
_If the hash option is set, the [module](#module-option-for-units) option will get ignored._


#### `id` <samp>[option for units]</samp>
Expand All @@ -206,7 +229,7 @@ Internally every unit gets an Id. There are different scopes for the generation:

The first ES6 Import statement of a file will have the Id `1000`, the second `1001` and so forth. For a quick test, you can select via Id (if the [filename](#file) is specified). But actually this is only an internal method to locate the statements. Testing is the only other reason to use it. If the order or number of import statements changes, this will directly affect the Ids. This selection method should therefore never been used in production.

If the Id option is set, [hash](#hash-option-for-units) and [module](#module-option-for-units) will get ignored.
_If the Id option is set, [hash](#hash-option-for-units) and [module](#module-option-for-units) will get ignored._


#### `file` <samp>[option for units]</samp>
Expand Down Expand Up @@ -353,10 +376,21 @@ An option to target an alias of a [selected](#select-option-for-actions) `defaul


##### `rename` <samp>[option for actions]</samp>
Type: `String`
Type: `String` | `Function` _(when targeting the module)_
Default: `null`

This option is used to rename a [selected](#select-option-for-actions) specific part (`defaultMember`, `member`, `module`). The value is the new name of the selected part. See this [example](#changing-the-module).
This option is used to rename a [selected](#select-option-for-actions) specific part (`defaultMember`, `member`, `module`). The value is a string of the new name of the selected part.

Examples:
* [Changing a relative path to an absolute path](#changing-a-relative-path-to-an-absolute-path-passing-a-string-to-rename)
* [Changing a defaultMember name](#changing-a-defaultmember-name)

<br>
If the selected part is `module`, the value could alternatively be a function. The function must return a raw full module name (eg. `() => '"./new-module-name"'`) as a `String`. The original raw name is getting passed to the function and can be accessed by passing a variable to the function: `oldRawName => oldRawName.replace("foo", "bar")`.

When passing a function the [`modType`](#modtype-option-for-actions) is getting ignored. Always make sure the return value includes quotation marks if the import statement requires it.

See this [example](#changing-a-relative-path-to-different-directory-making-use-of-a-rename-function).


##### `modType` <samp>[option for actions]</samp>
Expand Down Expand Up @@ -439,9 +473,9 @@ import "foobar";
import bar as pub from "baz";
import bar, { baz as qux } from "./path/to/foo.js"; // <--
```

___


#### Basic CJS Statement via [`createModule`](#createmodule-option-for-units)
CJS Imports are also supported. But this time the [`type`](#type-option-for-units) needs to be specified. Also a variable name has to be set. In this example the [`const`](#const-option-for-units) _foo_. (Other declaration types are: [`let`](#let-option-for-units), [`var`](#var-option-for-units) and [`global`](#global-option-for-units)).

Expand Down Expand Up @@ -695,7 +729,7 @@ plugins: [
```
___

#### Moving an Import Statement (cut and paste):
### Moving an Import Statement (cut and paste):

###### Source Code
```js
Expand Down Expand Up @@ -727,8 +761,11 @@ import { foo } from "bar"; // |
```
___

### Changing the module
In this example there is a relative path that should be changed to a non relative module. This can be achieved like this:
### Modifying the module
To change a module in any way, first it must be [`select`](#select-option-for-actions)ed and then [`rename`](#rename-option-for-actions)ed, which can be fed with a `String` or a `Function` for module manipulation.

#### Changing a relative path to an absolute path (passing a `String` to [`rename`](#rename-option-for-actions))
In this example there is a relative path, that should be changed to a non relative module. This can be achieved like this:

###### Source Code
```js
Expand Down Expand Up @@ -757,6 +794,53 @@ import foo from "bar";
```
___


#### Changing a relative path to different directory (making use of a [`rename`](#rename-option-for-actions) function)
In this example there is a relative path, that should be changed to a sub-directory. This time a function is used for the goal, also a little help of an external function from [path](https://nodejs.org/api/path.html), which must be available (imported) in the rollup config file.

_(keep in mind, that a function in `rename` is only valid for modules)_

###### Source Code
```js
import foo from "./path/to/bar.js";
```

###### Rollup Config
```js

plugins: [
importManager({
units: {
file: "**/my-file.js",
module: "bar.js",
actions: {
select: "module",
rename: moduleSourceRaw => {

// Get rid of the quotes
const importPath = moduleSourceRaw.slice(1, -1);

// Parse the path into its parts (path must be imported for this example)
const importInfo = path.parse(importPath);

// Build the new import path with the sub-directory
const newPath = [importInfo.dir, "build-temp", importInfo.base].join("/");

// Remember to add quotes again
return `"${newPath}"`;
}
}
}
})
]
```

###### Bundle Code
```js
import foo from "./path/to/build-temp/bar.js";
```
___

### Addressing the (default) members
`defaultMembers` and `members` are using the exact same methods. It is only important to keep in mind to address default members with `select: "defaultMembers"` or for a specific one `select: "defaultMember"`; for members `select: "members"` and `select: "member"`.

Expand Down Expand Up @@ -991,6 +1075,69 @@ import { foo, baz as corge, quux as grault } from "quuz";
```
___

### Applying RegExp for [module](#module-option-for-units) matching
This example demonstrates a case, where matching the module via a regular expression is necessary. Exemplary the first import statement of the following source code should be matched and removed. Searching for 'bar' or 'bar.js' is not an option, as this matches both statements. RegExp to the rescue:

###### Source Code
```js
import foo from "./path/to/bar.js";
import baz from "./path/to/foobar.js";
```

###### Rollup Config
```js

plugins: [
importManager({
units: {
file: "**/my-file.js",
module: /[^foo]bar\.js/,
actions: "remove"
}
})
]
```

###### Bundle Code
```js
import baz from "./path/to/foobar.js";
```
___


### Using [`rawModule`](#rawmodule-option-for-units) for module matching
This example demonstrates a case, where it is desired to match a module by its raw module-name part.

_(Be aware of the quotation marks, which are also part of the raw string in this case and might introduce problems when applying RegExp without taken them into account.)_

###### Source Code
```js
import foo from "./path/to/bar.js";
import baz from "./path/to/foobar.js";
```

###### Rollup Config
```js

plugins: [
importManager({
units: {
file: "**/my-file.js",
rawModule: "./path/to/bar.js", // or eg. /\/bar.js/
actions: "remove"
}
})
]
```

###### Bundle Code
```js
import baz from "./path/to/foobar.js";
```
___



## General Hints

### Chaining
Expand Down
Loading

0 comments on commit 07846b5

Please sign in to comment.