{"id":13660847,"url":"https://github.com/frontarm/polestar","last_synced_at":"2026-03-15T18:37:29.221Z","repository":{"id":35767389,"uuid":"164546685","full_name":"frontarm/polestar","owner":"frontarm","description":"A commonjs-ish module loader for browsers, as used in Demoboard.","archived":false,"fork":false,"pushed_at":"2022-02-11T20:14:26.000Z","size":605,"stargazers_count":32,"open_issues_count":12,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-10T15:44:26.246Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/frontarm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-08T03:04:19.000Z","updated_at":"2022-11-18T05:09:43.000Z","dependencies_parsed_at":"2022-08-08T11:15:33.227Z","dependency_job_id":null,"html_url":"https://github.com/frontarm/polestar","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontarm%2Fpolestar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontarm%2Fpolestar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontarm%2Fpolestar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontarm%2Fpolestar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/frontarm","download_url":"https://codeload.github.com/frontarm/polestar/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224714002,"owners_count":17357329,"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-08-02T05:01:26.524Z","updated_at":"2026-03-15T18:37:24.172Z","avatar_url":"https://github.com/frontarm.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"Polestar\n========\n\n*A commonjs-ish module loader for browsers, as used in [Demoboard](https://frontarm.com/demoboard/), [Laska](https://laska.io/) and the [MDX Preview extension for VS Code](https://marketplace.visualstudio.com/items?itemName=xyc.vscode-mdx-preview#overview)*\n\nPolestar loads commonjs modules from NPM and/or a virtual file system on-demand. It is highly configurable, allowing you to:\n\n- Resolve and build each `require()` call's request asynchronously (while your modules still use `require()` as a synchronous function)\n- Set appropriate global variables for your modules, including `process`, `global`, or a stubbed `window` object.\n- Capture errors while loading modules, and forward them as appropriate.\n- Display a loading indicator until the entry point is ready to execute.\n\n```bash\nyarn add polestar\n```\n\nUsage\n-----\n\n```js\nimport { Polestar } from 'polestar'\n\nlet polestar = new Polestar({\n  /**\n   * Any keys set here will be available as globals within all executed code.\n   * \n   * You can use this to provide process, global, setImmediate, etc., or to\n   * provide stubs for window, history, etc.\n   */\n  globals: {\n    process: {\n      env: {},\n    }\n  },\n\n  /**\n   * Sets the value of `this` within loaded module code\n   */\n  moduleThis: window,\n\n  /**\n   * Fetches required modules. See the \"Fetchers\" section below for details\n   * on how this function should behave.\n   */\n  fetcher: async (url: string, meta: FetcherMeta) =\u003e\n    api.fetchModule(url, meta),\n\n  /**\n   * The resolver is responsible for taking a string passed to `require`, and\n   * turning it into an id of an already loaded module, or a URL that will be\n   * passed to the fetcher.\n   * \n   * The default resolver can handle `npm://` URLs, standard HTTP urls,\n   * \"vfs://\" URLs and webpack-style loader strings, so you can probably omit\n   * this option.\n   */\n  resolver: defaultResolver,\n\n  /**\n   * Called once the first required module is ready to execute, but before it\n   * has actually executed. Useful for deciding when to show/hide loading\n   * indicators.\n   */\n  onEntry: () =\u003e {\n    api.dispatch('entry')\n  },\n\n  /**\n   * Called when for each error that occurs while executing a module, while\n   * fetching a module, etc.\n   */\n  onError: (error) =\u003e {\n    console.error(error)\n  },\n})\n\n/**\n * `polestar.require` will fetch a module's dependencies, then execute the\n * module, before finally returning a promise to the module object.\n */\nlet indexModule = await polestar.require('vfs:///index.js')\n\n/**\n * You can require any URL that your fetch function supports.\n */\npolestar.require('npm:///some-package@latest')\npolestar.require('vfs:///index.js')\npolestar.require('some-loader!vfs:///index.css')\n\n/**\n * `evaluate` takes a string and a list of dependencies. Once the dependencies\n * are available, it'll execute the string as a module, and return the module\n * object.\n */\nlet anotherModule = await polestar.evaluate(\n  ['react', 'react-dom'],\n  `\n  var React = require('react');\n  var ReactDOM = require('react-dom');\n  ReactDOM.render(\n    React.createElement('div', {}, \"Hello, world!\"),\n    document.getElementById('root')\n  )\n  `\n)\n```\n\n\nRequests, URLs \u0026 Module ids\n-------------------\n\nPolestar uses three different types of strings to reference modules.\n\n### Requests\n\n**Requests** are the strings that appear within `require()` statements. They can take any number of formats:\n\n- Paths relative to the module that contains the `require()` call, e.g. `./App.js`\n- Fully qualified URLs, e.g. `https://unpkg.com/react`\n- Bare imports, e.g. `react`\n- They can be prefixed have webpack-style loader, e.g. `style-loader!css-loader!./styles.css`\n\nWhenever Polestar encounters a request, it first resolves it to either a URL, or a module id.\n\n### URLs\n\nIn polestar, a **URL** is a string generated by the resolver that can be passed to the fetcher to request a module's source and dependencies.\n\nThe default resolver is able to create two types of URLs:\n\n- NPM URLs, e.g. `npm://react@latest`, are generated from bare imports. They always contain a package name and version range string (e.g. `@latest`, `@^1.7.2`, `@16.7.0`). They can also optionally contain a path.\n- Other URLs are treated as relative to the module making the request.\n\nOne issue with using URLs to refer to modules is that URLs can redirect to other URLs, so a single module can be referenced by multiple different URLs. For example, each of these unpkg URLs may refer to the same module:\n\n- https://unpkg.com/react\n- https://unpkg.com/react@16.6.3\n- https://unpkg.com/react@latest\n- https://unpkg.com/react@16.6.3/index.js\n\nBecause of this, polestar doesn't index modules by URL. Instead, it indexes modules by ID.\n\n### Module ids\n\nWhen the fetcher returns a result for a given URL, it'll also include an ID. This ID must be a URL, and is usually the URL at the end of any redirect chain that the fetcher encounters.\n\nOnce Polestar has loaded the module, it'll notify the resolver of the ID of the new module, as well as any URLs that map to that ID. This allows the resolver to map requests to already-loaded modules where possible, speeding up load time for frequently referenced modules like `react`.\n\nA modules relative requires (e.g. `require('./App.js)`) will also be resolved relative to the module ID.\n\n\nFetchers\n--------\n\nA minimal fetcher function just takes a URL and returns the url, id, dependencies and source of the the module at that URL.\n\n```typescript\nconst fetcher = (url: string) =\u003e ({\n  url: 'vfs:///Hello.js',\n\n  // The canonical URL of this source file, \n  id: 'vfs:///Hello.js',\n\n  // An array of requests that can be made by `require()` within this module.\n  // You can find these using a package like babel-plugin-detective.\n  dependencies: ['react']\n\n  // The source that will be evaluated for the module.\n  code: `\n    var React = require('react')\n\n    module.exports.Hello = function() {\n      return React.createElement('h1', {}, 'hello')\n    }\n  `,\n})\n```\n\nFetcher functions also receive a `meta` object with information on where the\nfetch originated, which is useful for error messages.\n\n```typescript\ntype Fetcher = (url: string, meta: FetchMeta) =\u003e Promise\u003cFetchResult\u003e\n\ninterface FetchMeta {\n  requiredById: string,\n  originalRequest: string\n}\n```\n\n### UMD modules\n\nFor UMD modules, the dependencies can be omitted and replaced with the string `umd`.\n\n```js\nconst fetcher = (url: string) =\u003e ({\n  url: 'https://unpkg.com/react@latest'\n\n  // The canonical URL of this source file. Note that you'll have to decide\n  // how to match URLs to UMD ids within your fetcher function.\n  id: 'https://unpkg.com/react@16.6.3/umd/react.development.js',\n\n  // An array of requests that can be made by `require()` within this module.\n  // You can find these using a package like babel-plugin-detective.\n  dependencies: 'umd',\n\n  code: `...`,\n})\n```\n\nThis works as dependencies are already specified within the UMD module. This is especially useful for large modules like react-dom, as parsing the received code to find the requires can be quite slow.\n\n### Version Ranges\n\nMany packages require specific versions of their dependencies to work; they won't work at all if you default to using the latest versions of all packages involved.\n\nIn order to resolve bare requests to the correct version of an NPM package, the resolver needs to have access to the `dependencies` object from a module's package.json, for modules that define one. These dependencies should be returned via the `dependencyVersionRanges` property of the fetcher's result.\n\n```js\nconst fetcher = (url: string) =\u003e ({\n  url: 'https://unpkg.com/react-dom@latest'\n  id: 'https://unpkg.com/react-dom@16.6.3/umd/react-dom.development.js',\n  code: `...`,\n  dependencies: 'umd',\n  dependencyVersionRanges: {\n    // As read from https://unpkg.com/react-dom@16.6.3/package.json\n    \"loose-envify\": \"^1.1.0\",\n    \"object-assign\": \"^4.1.1\",\n    \"prop-types\": \"^15.6.2\",\n    \"scheduler\": \"^0.11.2\"\n  }\n})\n```\n\n### Full Fetcher types\n\n```typescript\ntype VersionRanges = { [name: string]: string }\n\ntype Fetcher = (url: string, meta: FetchMeta) =\u003e Promise\u003cFetchResult\u003e\n\ninterface FetchMeta {\n  requiredById: string,\n  originalRequest: string\n}\n\ninterface FetchResult {\n  id: string,\n  url: string,\n\n  // Should already include any source map / source url\n  code: string, \n\n  // Things that can be required by the module (as specified in require() statements)\n  // If the string 'umd' is specified, the module will be treated as a umd module,\n  // and it's dependencies will be loaded.\n  // If undefined, a `require` function will not be made available.\n  dependencies?: 'umd' | string[], \n\n  // Hints for what versions required dependencies should resolve to\n  dependencyVersionRanges?: VersionRanges,\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrontarm%2Fpolestar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrontarm%2Fpolestar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrontarm%2Fpolestar/lists"}