{"id":18761887,"url":"https://github.com/velenir/babel-plugin-import-redirect","last_synced_at":"2025-06-21T05:36:45.363Z","repository":{"id":72200441,"uuid":"89709920","full_name":"Velenir/babel-plugin-import-redirect","owner":"Velenir","description":"A plugin for Babel to redirect paths in import, export, require expressions","archived":false,"fork":false,"pushed_at":"2020-01-10T17:49:52.000Z","size":205,"stargazers_count":11,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-19T22:44:56.307Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Velenir.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-04-28T13:44:36.000Z","updated_at":"2022-09-14T07:41:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"0d97df54-f5cf-42a7-ab4a-ec8dbffe5749","html_url":"https://github.com/Velenir/babel-plugin-import-redirect","commit_stats":{"total_commits":215,"total_committers":2,"mean_commits":107.5,"dds":0.1953488372093023,"last_synced_commit":"d904f29ca6cae052a3b41f64fc8b2e1937a862ec"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/Velenir/babel-plugin-import-redirect","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Velenir%2Fbabel-plugin-import-redirect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Velenir%2Fbabel-plugin-import-redirect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Velenir%2Fbabel-plugin-import-redirect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Velenir%2Fbabel-plugin-import-redirect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Velenir","download_url":"https://codeload.github.com/Velenir/babel-plugin-import-redirect/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Velenir%2Fbabel-plugin-import-redirect/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261070524,"owners_count":23105421,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T18:18:08.049Z","updated_at":"2025-06-21T05:36:40.336Z","avatar_url":"https://github.com/Velenir.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# babel-plugin-import-redirect\n\n[![Build Status](https://travis-ci.org/Velenir/babel-plugin-import-redirect.svg?branch=master)](https://travis-ci.org/Velenir/babel-plugin-import-redirect) [![npm version](https://badge.fury.io/js/babel-plugin-import-redirect.svg)](https://badge.fury.io/js/babel-plugin-import-redirect) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) [![dependencies Status](https://david-dm.org/velenir/babel-plugin-import-redirect/status.svg)](https://david-dm.org/velenir/babel-plugin-import-redirect) [![devDependencies](https://david-dm.org/velenir/babel-plugin-import-redirect/dev-status.svg)](https://david-dm.org/velenir/babel-plugin-import-redirect?type=dev) [![Greenkeeper badge](https://badges.greenkeeper.io/Velenir/babel-plugin-import-redirect.svg)](https://greenkeeper.io/) [![codecov](https://codecov.io/gh/Velenir/babel-plugin-import-redirect/branch/master/graph/badge.svg)](https://codecov.io/gh/Velenir/babel-plugin-import-redirect) [![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/velenir/babel-plugin-import-redirect/blob/master/LICENSE)\n\nA [Babel](https://babeljs.io/) plugin that allows to point **import**, **export from** declarations, **require()** and simple dynamic **import()** (only string literal as its argument) calls to custom paths. This can be especially useful in testing — for swapping regular production and development files and modules with their mock implementations.\n\nFor example, this plugin allows to transform:\n\n```\nimport \"./path/to/file\";\nexport {variable} from \"./path/to/different/file\";\nrequire(\"module\");\nimport(\"different_module\");\n```\n\nto\n\n```\nimport \"./mocks/mockFile\";\nexport {variable} from \"./mocks/differentMockFile\";\nrequire(\"./mocks/mockModule\");\nimport(\"yet_another_module\");\n```\n\n# Usage\n\nInstall the plugin with\n\n```\nnpm install --save-dev babel-plugin-import-redirect\n```\n\nThen add it to your babel configuration (e.g. in *.babelrc*). A rather exhaustive setup may look like this:\n\n```\n{\n  \"plugins\": [\n    \"syntax-dynamic-import\",\n    [\"import-redirect\",\n    {\n      \"root\": \"./tests/mocks\",\n      \"extraFunctions\": [\"custom_require_function\", \"SystemJS.import\"],\n      \"promisifyReplacementFor\": \"SystemJS.import\",\n      \"redirect\": {\n        \"connect\": \"./connect.mocked\",\n        \"path/to/(\\\\w+)\\\\.js$\": \"./$1.mocked\",\n        \"\\\\.css$\" : false,\n        \"path/to/globals\": {\"MY_GLOBAL_1\": true, \"MY_GLOBAL_2\": 42}\n      }\n    }]\n  ]\n}\n```\n\n\u003e Transforming dynamic **import()** requires that [babel-plugin-syntax-dynamic-import](https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-dynamic-import) be included in `plugins` before `import-redirect`\n\nNow when you transpile your source files, any path inside **import**, **export from** declarations, **require()** and dynamic **import()** calls that matches a *redirect.key* is resolved to point to the file from a corresponding *redirect.value*.\n\n## Example\n\nTo provide an example, given a project structure of\n\n```\n./\n  node_modules/\n    connect/\n  tests/\n    mocks/\n      connect.mocked.js\n      lib.mocked.js\n  src/\n    index.js\n    helpers/\n      globals.js\n    libs/\n      lib.js\n    style.css\n  .babelrc\n```\n\nwith *index.js* of\n\n```\nimport \"./style.css\";\nimport connect from \"connect\";\nexport {default as libFunction} from \"./libs/lib\";\nimport {MY_GLOBAL_1, MY_GLOBAL_2} from \"./helpers/globals\";\n// ...\n```\n\nand *.babelrc* of\n\n```\n{\n  \"plugins\": [\n    [\"import-redirect\",\n    {\n      \"root\": \"./tests/mocks\",\n      \"redirect\": {\n        \"connect\": \"./connect.mocked\",\n        \"/libs/(\\\\w+)\\\\.js$\": \"./$1.mocked\",\n        \"\\\\.css$\" : false,\n        \"helpers/globals.js$\": {\"MY_GLOBAL_1\": true, \"MY_GLOBAL_2\": 42}\n      }\n    }]\n  ]\n}\n```\n\nThe *index.js* will transpile to\n\n```\nimport connect from \"../tests/mocks/connect.mocked\";\nexport {default as libFunction} \"../tests/mocks/lib.mocked\";\nconst {MY_GLOBAL_1, MY_GLOBAL_2} = {\"MY_GLOBAL_1\": true, \"MY_GLOBAL_2\": 42};\n// ...\n```\n\nThe transpilation to make it happen will be performed as follows:\n\n1. **import \"./style.css\";**``\n    1. `./style.css` path is resolved to `project/src/style.css` absolute path\n    1. `project/src/style.css` is matched against `new RegExp(\"\\\\.css$\")`\n    1. the corresponding value of false triggers removal of the import declaration\n\u003e removed\n\n2. **import connect from \"connect\";**\n    1. `connect` path is resolved to `project/node_modules/connect/...` absolute path\n    2. the path matches against `new RegExp(\"connect\")`\n    3. the redirected path of `./test/mocks/connect.mocked` is resolved relative to `index.js` as  `../tests/mocks/connect.mocked`\n    4. the path is changed to `../tests/mocks/connect.mocked`\n\u003e replaced with `import connect from \"../tests/mocks/connect.mocked\";`\n\n3. **import libFunction from \"./libs/lib\";**\n    1. `./libs/lib` path is resolved to `project/libs/lib.js` absolute path\n    2. the path matches against `new RegExp(\"/libs/(\\\\w+)\\\\.js$\")`\n    3. as the redirect value contains a replacement group (`$1`), it is converted to `./tests/mocks/lib.mocked`\n    4. the redirected path of `./tests/mocks/lib.mocked` is resolved relative to `index.js` as  `../tests/mocks/lib.mocked`\n    5. the path is changed to `../tests/mocks/lib.mocked`\n\u003e replaced with `import libFunction from \"../tests/mocks/lib.mocked\";`\n\n4. **import {MY_GLOBAL_1, MY_GLOBAL_2} from \"./helpers/globals\";**\n    1. `./helpers/globals` path is resolved to `project/src/helpers/globals.js` absolute path\n    2. `project/src/helpers/globals.js` matches against `new RegExp(\"helpers/globals.js$\")`\n    3. the corresponding value of an object triggers replacement of the import declaration with a variable declaration\n\u003e replaced with `const {MY_GLOBAL_1, MY_GLOBAL_2} = {\"MY_GLOBAL_1\": true, \"MY_GLOBAL_2\": 42};`\n\n## Options\n\n```\n{\n  \"root\": String,\n  \"extraFunctions\": String | Array\u003cString\u003e,\n  \"promisifyReplacementFor\": String | Array\u003cString\u003e,\n  \"redirect\": {\n    matchPattern: replacement\n  },\n  \"extensions\": Array\u003cString\u003e,\n  \"suppressResolveWarning\": Boolean\n}\n```\n\n+ `root` : path, relative to which `replacement` paths are resolved. Equals project root folder by default.\n+ `extraFunctions` : functions to consider when matching against keys in redirect in addition to **import**, **export from** declarations, **require()** and dynamic **import()**. It can be a simple function name (`\"custom_require\"`) or an object.property pair (`\"SystemJS.import\"`).\n+ `promisifyReplacementFor` : functions, in addition to `import()`, for which `replacement` Objects should be wrapped in `Promise.resolve()`.\n+ `redirect` : Object with `matchPattern` keys and `replacement` values.\n+ `extensions`: Array of extensions to use for resolving filenames. Equals `[\".js\", \".jsx\", \".es\", \"es6\"]` by default, providing custom extensions will override the default.\n+ `suppressResolveWarning`: Boolean, `false` by default. During path resolution plugin shows a warning when it can't find a module. It will still do its best to resolve to the right path. This option suppresses that warning.\n\n#### matchPattern\n\nA `String` to be used as a pattern in a `RegExp`. This `RegExp` will be matched against the source of **import** and **export from** declarations and the first argument of **require()**, **import()** and functions from `extraFunctions`. If the match is successful the whole expression will be transformed depending on the corresponding `replacement`.\n\nTake care to escape (`\\`) every special character, namely backslash (`\\`). That is, escape twice every time you would escape once in a literal regexp. E.g. a `RegExp` constructed from `\"\\\\w+\"` pattern is equivalent to `/\\w+/`, to use backslash in your pattern escape it like so `\"\\\\\\\\\"`.\n\n\u003e To match *only* the node module `required_module` and not accidentally pick up paths that would otherwise match `/required_module/` (e.g. `\"./src/my_required_module/index.js\"`), it is recommended to specialize the pattern like this: `\"/node_modules/required_module/\"`.\n\n#### replacement\nCan be\n+ A `String` path to a file to be used in place of the originally `require`d / `import`ed file. The path will be resolved relative to `root` if provided or to project root folder (`process.cwd()`) otherwise.\nIf `replacement` contains a replacement group (e.g. `$1`), a corresponding parenthesized match result from the `matchPattern` will be substituted in prior to resolving the path.\nE.g. given a project structure of\n\n```\n./\n  src/\n    index.js\n    lib.js\n  mocks/\n    lib.js\n```\n\n`require(\"./lib\");` inside `./src/index.js` file when matched against `\"/(\\\\w+).js\": \"./mocks/$1\"` with no `root` provided will transpile to `require(\"../mocks/lib\");`.\n\n+ `false`, which will result in removal of simple `import` declarations, `require()`, `import()` and custom require function calls without side effects. That is, functions which are not part of a larger expression:\n\n```\n// will be removed\nrequire(\"path/to/file\");\nimport(\"path/to/file\");\n\n// won't be removed\nconst lib = require(\"path/to/file\");\nrequire(\"path/to/file\").prop;\nfn(require(\"path/to/file\"));\nimport(\"path/to/file\").then(module =\u003e module.default);\n```\n\nand simple, non-named, non-namespace, non-default import statements:\n\n```\n// will be removed\nimport \"path/to/file\";\n\n// won't be removed\nimport lib from \"pat/to/file\";\nimport * as lib from \"pat/to/file\";\nimport {lib} from \"pat/to/file\";\n```\n\n+ An `Object`, which will result in removal of simple `import` declarations, `require()`, `import()` and custom require function calls without side effects (same as for `false`) and in replacement of default, named, namespace `import`s, `require()`, `import()` and custom require function calls with these objects. This `Object` must be JSON-serialazable.\nAdditionally **replacement** objects for `import()` calls and calls of custom functions from `promisifyReplacementFor` will be wrapped in `Promise.resolve()`.\n\nE.g. for a `\"path/to/file\": {\"key\": val}` **matchPattern - replacement** pair\n\n| will be removed                                          | was removed\n|:---------------------------------------------------------|:-|\n| `import \"path/to/file\";`                                 |  |\n| `require(\"path/to/file\");`                               |  |\n| `import(\"path/to/file\");`                                |  |\n| **will be replaced**                                     | **was replaced with**\n| `const lib = require(\"path/to/file\");`                   | `const lib = {\"key\": val};`\n| `require(\"path/to/file\").prop; `                         | `({\"key\": val}).prop;`\n| `fn(require(\"path/to/file\"));`                           | `fn({\"key\": val});`\n| `import(\"path/to/file\").then(module =\u003e module.default);` | `Promise.resolve({\"key\": val}).then(module =\u003e module.default);`\n| `import lib from \"pat/to/file\";`                         | `const {default: lib} = {\"key\": val};`\n| `import * as lib from \"pat/to/file\";`                    | `const lib = {\"key\": val};`\n| `import {lib} from \"pat/to/file\";`                       | `const {lib} = {\"key\": val};`\n| `import lib, {lib1 as lib2} from \"./style.css\";`         | `const {default: lib, lib1: lib2} = {\"key\": val};`\n| `import lib, * as libAll from \"./style.css\";`            | `const libAll = {\"key\": val}, {default: lib} = libAll;`\n\n\u003e To summarize,\n\u003e + a `String` replacement handles **import**, **export from** declarations, **require()**, simple dynamic **import()** and custom function calls.\n\u003e + `false` replacement removes aforementioned declarations and function calls, except for **export from**, without side effects.\n\u003e + `Object` replacement does the same as `false` and also replaces relevant expressions with side effects.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvelenir%2Fbabel-plugin-import-redirect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvelenir%2Fbabel-plugin-import-redirect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvelenir%2Fbabel-plugin-import-redirect/lists"}