{"id":13847158,"url":"https://github.com/agoldis/webpack-require-from","last_synced_at":"2025-04-04T13:06:42.221Z","repository":{"id":17261048,"uuid":"80602788","full_name":"agoldis/webpack-require-from","owner":"agoldis","description":"Webpack plugin that allows to configure path or URL for fetching dynamic imports","archived":false,"fork":false,"pushed_at":"2023-02-17T05:44:14.000Z","size":2636,"stargazers_count":192,"open_issues_count":38,"forks_count":31,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-30T03:42:06.812Z","etag":null,"topics":["code-splitting","dynamic","hacktoberfest","import","javascript","require","webpack","webpack-plugin"],"latest_commit_sha":null,"homepage":"","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/agoldis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":["agoldis"]}},"created_at":"2017-02-01T08:47:31.000Z","updated_at":"2024-08-30T21:15:27.000Z","dependencies_parsed_at":"2024-06-18T13:37:54.302Z","dependency_job_id":"7292e9c0-a1e4-4da9-b81a-3d110ba9df65","html_url":"https://github.com/agoldis/webpack-require-from","commit_stats":{"total_commits":113,"total_committers":11,"mean_commits":"10.272727272727273","dds":0.2743362831858407,"last_synced_commit":"999e853b6db187db8c5074527307d57fb30dcf93"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agoldis%2Fwebpack-require-from","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agoldis%2Fwebpack-require-from/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agoldis%2Fwebpack-require-from/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agoldis%2Fwebpack-require-from/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/agoldis","download_url":"https://codeload.github.com/agoldis/webpack-require-from/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247177775,"owners_count":20896712,"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":["code-splitting","dynamic","hacktoberfest","import","javascript","require","webpack","webpack-plugin"],"created_at":"2024-08-04T18:00:56.642Z","updated_at":"2025-04-04T13:06:42.179Z","avatar_url":"https://github.com/agoldis.png","language":"JavaScript","readme":"[![npm version](https://badge.fury.io/js/webpack-require-from.svg)](https://badge.fury.io/js/webpack-require-from)\n[![npm](https://img.shields.io/npm/dm/webpack-require-from.svg)](https://www.npmjs.com/package/webpack-require-from)\n[![CircleCI](https://circleci.com/gh/agoldis/webpack-require-from.svg?style=svg)](https://circleci.com/gh/agoldis/webpack-require-from)\n\n# webpack-require-from\n\nControl the dynamic imports path / URL at runtime\n\n- Compatible with webpack 5, 4, 3, 2\n- Supports web-workers loading (https://github.com/webpack-contrib/worker-loader)\n- Production-ready\n- No dependencies\n- Lightweight\n- Tested\n\n## Table of contents\n\n- [Why changing dynamic imports path at runtime?](#Why-changing-dynamic-imports-path-at-runtime)\n- [How to use](#How-to-use)\n- [Configuration](#configuration)\n  - [`path`](#path)\n  - [`variableName`](#variableName)\n  - [`methodName`](#methodName)\n  - [`replaceSrcMethodName`](#replaceSrcMethodName)\n  - [`suppressErrors`](#suppressErrors)\n- [Global methods and variables](#Global-methods-and-variables)\n- [Web workers](#Web-Workers)\n- [Troubleshooting](#Troubleshooting)\n- [Tests](#tests)\n\n# Why changing dynamic imports path at runtime?\n\nWebpack allows to split and load code atomatically using [`require.ensure`](https://webpack.js.org/api/module-methods/#require-ensure) or [dynamic import](https://webpack.js.org/guides/code-splitting/#dynamic-imports) `import()`. Modules are fetched \"on-demand\" when your main bundle is running in browser.\n\nWebpack loads the modules (chunks) from a static URL, which is determined by `config.output.publicPath` of [webpack configuration](https://webpack.js.org/guides/public-path/#on-the-fly).\n\nSometimes you need to control this modules (chunks) URL at runtime, for example:\n\n- Chunks are hosted at a CDN\n- Different environments use different URLs for loading assets (production, staging, qa)\n- Your `index` file is served from a different location / port\n- You need to dynamically load pre-compiled files from a different location\n- You need to load 3rd part web worker from a CDN\n\n# How to use\n\n```javascript\n// webpack.config.js\nconst WebpackRequireFrom = require(\"webpack-require-from\");\nconst webpackRequireFromConfig = (module.exports = {\n  output: {\n    publicPath: \"/webpack/\"\n  },\n  plugins: [\n    new WebpackRequireFrom({\n      // see configuration options below\n    })\n  ]\n});\n```\n\n# Configuration\n\nIf no options provided, the plugin will use the default [`config.output.publicPath`](https://webpack.js.org/guides/public-path/#on-the-fly). Check out the \"example\" directory.\n\n## `path`\n\nSet path for dynamically loading modules. The value you provide will replace `config.output.publicPath` when dynamically importing chunks.\n\nFor example, if default URL is `https://localhost`, chunk name is `0.js` and options object is `{path: \"customPath/\" }`, the chunk will be fetched from `https://localhost/customPath/0.js`\n\n\u003e **NOTE** `path`, `methodName` and `variableName` are mutualy exclusive and cannot be used together\n\n## `variableName`\n\n`variableName` is the globaly defined variable that will be evaluated at runtime, `variableName` is the name of a variable with string value that represents a path / URL that will be used for dynamically importing of chunks.\n\nFor example, if default URL is `https://localhost`, chunk name is `0.js` and options object is `{variableName: \"chunkURL\" }`, while `window.chunkURL` is defined to be:\n\n```javascript\nwindow.chunkURL = \"https://app.cdn.com/buildXXX/\";\n```\n\nthe chunk will be fetched from `https://app.cdn.com/buildXXX/0.js`\n\n## `methodName`\n\nName of the globaly defined method that will be invoked at runtime, the method should return a path / URL that will be used for dynamically importing of chunks.\n\nFor example, if default URL is `https://localhost`, chunk name is `0.js` and options object is `{methodName: \"getChunkURL\" }`, while `window.getChunkURL` is defined to be:\n\n```javascript\nwindow.getChunkURL = function() {\n  if (true) {\n    // use any condition to choose the URL\n    return \"https://app.cdn.com/buildXXX/\";\n  }\n};\n```\n\nthe chunk will be fetched from `https://app.cdn.com/buildXXX/0.js`\n\nIf used together with `replaceSrcMethodName`, chunks URL will be first modified by `window[methodName]` and then, the modified values are passed as an argument to `window[replaceSrcMethodName]` function.\n\n\u003e **NOTE** `path`, `methodName` and `variableName` are mutualy exclusive and cannot be used together\n\n\u003e **NOTE** that the method should be defined in a global namespace and should be defined before `require.ensure` or `import()` is invoked. See examples below\n\n## `replaceSrcMethodName`\n\nName of the globaly defined method that will be invoked at runtime; the method receives the **full URL** of the dynamically required chunk as its argument and should return a `string` with the new URL.\n\nFor example, if default URL is `https://localhost`, chunk names are `0.js` and `common.js`, options object is `{replaceSrcMethodName: \"replaceSrc\" }`, while `window.replaceSrc` is defined to be:\n\n```javascript\nwindow.replaceSrc = function(originalSrc) {\n  if (originalSrc.match(/common/)) {\n    // rename specific chunk\n    return originalSrc.replace(/common/, \"static\");\n  }\n  return originalSrc;\n};\n```\n\nthe chunks will be fetched from `https://localhost/0.js` and `https://localhost/static.js`\n\nIf used together with `methodName` or `variableName`, chunks URL will be first modified by `window[methodName]` or will be modified to `window[variableName]` and then, the modified values are passed as an argument to `window[replaceSrcMethodName]` function.\n\n\u003e **NOTE** that the method should be defined in a global namespace and should be defined before `require.ensure` or `import()` is invoked.\n\n## `suppressErrors`\n\n`default: false`. The plugin will invoke `console.error` when the method name you defined in `replaceSrcMethodName`, `methodName` or `variableName` cannot be detected. Turning this option on will suppress the error messages.\n\n# Global methods and variables\n\nWhen your JS code is executed in browser, the variable/methods whose names you mention as `variableName`, `methodName` or `replaceSrcMethodName` value, should be set **before** the first call to `require.ensure()` or `import()` is executed.\n\nThe return value of the methods will be used to build the URL for fetching resources.\n\nFor example, let's define `veryFirst` method to be globally available before you main bundle is being executed.\n\nAdd the method definition at the very first line of you bundle:\n\n```javascript\nconst window.veryFirst = function () {\n console.log(\"I am very first!\");\n}\n```\n\nYou can use a separate file and use `webpack`'s [entry point list](https://webpack.js.org/configuration/entry-context/#entry):\n\n```javascript\n// filename: veryFirst.js\nconst window.veryFirst = function () {\n console.log(\"I am very first!\");\n}\n\n// file webpack.config.js\nmodule.exports = {\n  entry: {\n    ['./veryFirst.js', './index.js']\n  }\n}\n```\n\nAnother approach is to define `veryFirst` as part of `index.html` when building it on your server:\n\n```javascript\n// filename: server/app.js\napp.get(\"/\", (req, res) =\u003e\n  res.render(\"views/index\", {\n    cdnPath: \"https://qa.cdn.com/|https://prod.cdn.com/\"\n  })\n);\n```\n\n```HTML\n\u003c!-- filename: views/index.ejs --\u003e\n\u003chtml\u003e\n\u003cscript\u003e\n  const baseCDN = \"\u003c%= cdnPath %\u003e\";\n  window.veryFirst = function () {\n      console.log(`${baseCDN}/js/`);\n  }\n\u003c/script\u003e\n...\n\u003c/html\u003e\n```\n\n# Web Workers\n\n**TL;DR**\n\nUse [`replaceSrcMethodName`](#replacesrcmethodname) to provide a method for modifying web-worker loading path. The method must be globally available and defined before `import()` calls within your web-worker. From `example` directory:\n\n```javascript\n/* webpack.config.js */\n  // ...\n  module: {\n    rules: [\n      {\n        test: /worker\\.js$/,\n        use: {\n          loader: `worker-loader`\n        }\n      }\n    ]\n  },\n  plugins: [\n    new HtmlWebpackPlugin(),\n    new RequireFrom({\n      replaceSrcMethodName: \"getSrc\"\n    })\n  ]\n  // ...\n\n\n/* worker.js */\nrequire(\"./globals.js\");\n\nimport(\"./worker-module.js\").then(workerModule =\u003e {\n  workerModule.default();\n  console.log(\"loaded workerModule\");\n});\n\n```\n\n**Details**\n\nThe plugin allows to change the loading path of web-workers.\n\nDo to so, use the [`worker-loader`](https://github.com/webpack-contrib/worker-loader) loader. The loader uses [`importScripts`](https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts) to dynamically load modules from within your web-worker and support [cross-domain web workers](https://benohead.com/cross-domain-cross-browser-web-workers/). More specifically it:\n\n1.  Creates a new webpack entry that only contains `new Worker(workerURL)`, while `workerURL` is your main webworker module\n2.  Enhances your webworker main module with webpack runtime utilities\n3.  Uses `importScripts` to dynamically load new modules within webworker context (thus avoiding cross-domain limitations)\n\nThe plugin monkey-patches `importScripts` and invokes the method you've defined within [`replaceSrcMethodName`](#replacesrcmethodname) configuration option. The method you've provided will be invoked just before calling `importScripts` with the required module path as the single argument.\n\nCheck out the working example of using the plugin with web-workers at [web2fs-notepad](https://github.com/sushain97/web2fs-notepad/commit/06b3ece074f1c1c96d9bb75436181147943f6026#diff-028b78cada5fa9a59260b989f3b86ffeR52) by @sushain97.\n\n# Troubleshooting\n\n\u003e `${methodName} is not a function or not available at runtime.`\n\n- Make sure your method name in `webpack.config.js` matches the method name you define on global `window` object.\n\n- Make sure the method is defined **before** the very first invocation of either `require.ensure()` or `import()`\n\n\u003e `Specify either \"methodName\" or \"path\", not together.`\n\n- `path` and `methodName` are mutualy exclusive and cannot be used together, use either of them\n\n\u003e `'${methodName}' does not return string.`\n\n- when using `replaceSrcMethodName` options the result of invoking `window[replaceSrcMethodName]` is validated - it\n  should be defined and be a string\n\n- make sure you return a string value from `window[replaceSrcMethodName]`\n\nDon't hesitate to open issues.\n\n# Tests\n\n`yarn test`\n","funding_links":["https://github.com/sponsors/agoldis"],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagoldis%2Fwebpack-require-from","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fagoldis%2Fwebpack-require-from","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagoldis%2Fwebpack-require-from/lists"}