{"id":28220841,"url":"https://github.com/morulus/import-sub","last_synced_at":"2025-10-19T03:34:07.448Z","repository":{"id":57273036,"uuid":"84347228","full_name":"morulus/import-sub","owner":"morulus","description":"Resolver for import-sub","archived":false,"fork":false,"pushed_at":"2019-01-06T20:12:38.000Z","size":175,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-26T00:52:06.533Z","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/morulus.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}},"created_at":"2017-03-08T17:21:11.000Z","updated_at":"2019-01-06T20:11:18.000Z","dependencies_parsed_at":"2022-08-25T05:24:28.956Z","dependency_job_id":null,"html_url":"https://github.com/morulus/import-sub","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morulus%2Fimport-sub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morulus%2Fimport-sub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morulus%2Fimport-sub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morulus%2Fimport-sub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/morulus","download_url":"https://codeload.github.com/morulus/import-sub/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morulus%2Fimport-sub/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259172976,"owners_count":22816560,"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":"2025-05-18T04:16:22.849Z","updated_at":"2025-10-19T03:34:07.348Z","avatar_url":"https://github.com/morulus.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Import substitution\n==\n\nThe async function that calculates path redirection according to the specified rules.\n\nThis is an auxiliary function for writing plugins, loaders, and other paths resolve mechanisms.\n\nUsed in packages:\n- [postcss-redirect-import](https://www.npmjs.com/package/postcss-redirect-import)\n- [webpack-import-sub-plugin](https://www.npmjs.com/package/webpack-import-sub-plugin)\n\nUsage\n--\n\nThe resolver accepts rules and options. The rules describe the cases in which user requests should be replaced and to what exactly values they should be replaced. The options describe the detail of a custom query.\n\n```js\nconst rules = {\n  // Describes match case\n  match: {\n    // Match user request\n    request: /\\.\\/bar\\.js$/,\n    // Match base directory\n    base: /src\\/foo$/\n  },\n  // What we should fo if request has matched\n  use: {\n    // Keep original request\n    // But to substitute base directory\n    base: '\u003croot\u003e/src/custom/foo'\n  },\n}\n\nresolve(rules, {\n  // The directory from which the request was made\n  base: 'src/foo',\n  // Original request\n  request: './bar.js',\n  // Project root\n  root: '/'\n})\n.then(function(request) {\n  // As result, we have substituted a segment\n  // between the application root\n  // and the user request.\n  console.log(request)\n  // Log: src/custom/foo/bar.js\n})\n```\n\nAll names used in the rules and the options refer to the specific detail of request.\n\nFirst of all you need to learn that сonventional names to better understand the contents of the properties.\n\n## Сonventional names\n\n### `request`\nIs the string that user specified in quotation marks. For example:\n```js\nimport './bar.js';\n```\nWhere `./bar.js` is our **request**.\n\nIt can be matched by regular expression `\\/bar\\.js$/`.\n\n---\n\n### `base`\nThe directory from which the request is made. For example:\n\n*The file `src/foo/index.js` requires `./bar.js`.*\n\nWhere `src/foo` is our **base**.\n\nIt can be strict matched by regular expression `src\\/foo`;\n\n---\n\n### `basename` (placeholder)\nif `src/foo` is **base**, then `foo` is **basename**.\n\n---\n\n### `root` (placeholder)\nThe root directory of the project. In typical cases `root` is `process.cwd()`, but can be specified in options.\n\n---\n\n### `id` (placeholder)\nRequested filename. If `request` is `./bar.js`, then `id` is `bar.js`.\n\n## Rules\n\nThe rule contains at least two properties - `match` and `use`.\nThe `match` contains instructions for which the request should be matched. The `use` property describes how to substitute a user request.\n\nBoth of them can include properties `request` and `base`, where _request_ is a original user request, and `base` is a directory from which request performed.\n\nEach property (request, base) in the `match` section can be either a string or a regular expression.\n\n```js\n{\n  match: {\n    request: 'foo.js',\n    base: /bar/\n  },\n  use: {\n    request: 'bar.js',\n    base: 'foo'\n  }\n}\n```\n\nAnd both the `request` and the `base` may be subject to matching and can be substituted.\n\nBy matching two values (`request` and `base`) you can determine exactly what file is requested and where from, and the concrete case of the customization.\n\nIn `use` section you describes what property of the request should be substituted. You may substitute `request` or `base`, or both of them.\n\nIn the simplest view, this works as aliases. But when using regular expressions and placeholders, usage becomes a lot more flexible.\n\n## Options\n\nOptions define the values that will be involved in resolving a particular request.\n\n### `root`\nThe project root. By the default it is `process.cwd()`.\n\n### `request`*\n\nUser request (for example, what exactly taped in the `import` statement).\n\n### `base`*\n\nThe directory from which the request is made.\n\n### `resolve`\n\nAlternate resolver, which will be called if the current request does not match the rules.\n\n### `originalResolve`\n\nIs the function, which accepts current `request` and `base` and resolve file in original way.\n\nBy the default, it is:\n\n```js\nfunction defaultResolver(id, base) {\n  return path.resolve(base, id);\n}\n```\n\nBut, if you are use _importSub_ for customizing another resolve function, which already have own resolve logic, you may wish to pre-resolve request, and is this case you should specify this option.\n\nFor example, if _importSub_ used with postcss-import `originalResolve` should be imported from `postcss-import/lib/resolve-id.js`.\n\n### `explain` _(function)_\n\nAllows you to specify log function, which will be accept all verbose explanation.\n\n```\nexplain: console.log\n```\n\n## `strict` _(bool)_\n\nIf _true_ throws an error if path, returned by redirection, does not exist.\n\n### Placeholders\n\nWhen you describes the rules you may use a special placeholders in section `use`.\n\nPlaceholders are wrapped with characters `\u003c\u003e` and contains values selected from user options or resolved relative it.\n\nAll placeholders names correspond to [Сonventional names](#Сonventional-names).\n\n```js\n{\n  \"request\": request,\n  \"root\": root,\n  \"base\": base,\n  \"id\": path.parse(request).base,\n  \"basename\": basename,\n}\n```\n\nPlaceholders usage example:\n\n```js\n{\n  match: {\n    request: /\\.\\/bar\\.js$/,\n    base: /src\\/[^\\/]$/\n  },\n  use: {\n    request: '\u003croot\u003e/custom/\u003cbasename\u003e/bar.js',\n  },\n}\n```\n\n### Custom placeholders\n\nFor more flexible compilation of the path, you can determine the placeholders by yourself. To do that use round brackets in regular expression.\n\n```js\n{\n  match: {\n    request: /\\.\\/([\\w])\\.js$/i\n  },\n  ...\n}\n```\n\nThen the custom placeholder will get the hash `\u003crequest:1\u003e`. If there were more groups, then they would be hashed with the index number `\u003crequest:2\u003e`, `\u003crequest:3\u003e`, etc.\n\n```js\n{\n  ...,\n  use: {\n    request: './\u003crequest:0\u003e.jsx'\n  }\n}\n```\n\nYou probably already guessed that such capturing groups in the `base` will create the placeholders `\u003cbase:1\u003e`, `\u003cbase:2\u003e`, etc.\n\n#### Use function\n\nYou are allowed to define property `use` as a function. In this case, you may implement the custom logic of path generation.\n\n```js\n{\n  match: {\n    request: /theme\\.css$/i\n  },\n  use: (data) =\u003e {\n    return path.join(data.base, 'themes/default.css')\n  },\n}\n```\n\nThe function accepts an object with comprehensive information about the requested file.\n\n```js\n{\n  use: ({\n    root, // Project root\n    base, // Base path\n    request, // Use request\n    id, // id\n    basename, // Name of folder, file required from\n  }) =\u003e {\n    return `custom/path/to/${id}`\n  }\n}\n```\n\nAs second argument it accepts internally replace function, which can handle a pattern string with placeholders.\n\nExamples\n--\n\nWe need to substitute required file `./bar.js` from `src/foo` to `../../custom/foo/bar.js`.\n\n```js\n{\n  match: {\n    request: /\\.\\/bar\\.js$/,\n    base: /src\\/foo$/\n  },\n  use: {\n    request: '../../custom/foo/bar.js'\n  },\n}\n```\n\nAnother way. Using custom `base`.\n\n```js\n{\n  match: {\n    request: /\\.\\/bar\\.js$/,\n    base: /src\\/foo$/\n  },\n  use: {\n    base: '\u003croot\u003e/custom/foo'\n  },\n}\n```\n---\n\nSame situation, but for all modules in `src` folder.\n\n```js\n{\n  match: {\n    request: /\\.\\/bar\\.js$/,\n    base: /src\\/[^\\/]$/\n  },\n  use: {\n    request: '../../custom/\u003cbasename\u003e/bar.js',\n  },\n}\n```\nHere we use the placeholder `\u003cbasename\u003e`, which in this case will have value `foo`.\n\n---\n\n# License\n\nMIT, Vladimir Kalmykov \u003cvladimirmorulus@gmail.com\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorulus%2Fimport-sub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmorulus%2Fimport-sub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorulus%2Fimport-sub/lists"}