{"id":20489326,"url":"https://github.com/morganney/magic-comments","last_synced_at":"2026-02-13T19:31:53.615Z","repository":{"id":177667628,"uuid":"660728828","full_name":"morganney/magic-comments","owner":"morganney","description":"Node.js tool for adding Webpack magic comments at build time.","archived":false,"fork":false,"pushed_at":"2026-02-07T19:13:56.000Z","size":176,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-08T03:26:08.998Z","etag":null,"topics":["build-tool","magic-comments","nodejs","webpack"],"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/morganney.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,"zenodo":null}},"created_at":"2023-06-30T17:37:06.000Z","updated_at":"2026-02-07T19:09:35.000Z","dependencies_parsed_at":"2025-05-09T04:32:33.647Z","dependency_job_id":"6123bafd-2c41-444f-a3e8-e973965331d0","html_url":"https://github.com/morganney/magic-comments","commit_stats":null,"previous_names":["morganney/magic-comments"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/morganney/magic-comments","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morganney%2Fmagic-comments","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morganney%2Fmagic-comments/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morganney%2Fmagic-comments/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morganney%2Fmagic-comments/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/morganney","download_url":"https://codeload.github.com/morganney/magic-comments/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morganney%2Fmagic-comments/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29415569,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T06:24:03.484Z","status":"ssl_error","status_checked_at":"2026-02-13T06:23:12.830Z","response_time":78,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["build-tool","magic-comments","nodejs","webpack"],"created_at":"2024-11-15T17:12:28.098Z","updated_at":"2026-02-13T19:31:53.591Z","avatar_url":"https://github.com/morganney.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ✨ [`magic-comments`](https://www.npmjs.com/package/magic-comments)\n\n![CI](https://github.com/morganney/magic-comments/actions/workflows/ci.yml/badge.svg)\n[![codecov](https://codecov.io/gh/morganney/magic-comments/branch/main/graph/badge.svg?token=5O23HMHBKG)](https://codecov.io/gh/morganney/magic-comments)\n[![NPM version](https://img.shields.io/npm/v/magic-comments.svg)](https://www.npmjs.com/package/magic-comments)\n\nTooling utility to add configurable webpack [magic comments](https://webpack.js.org/api/module-methods/#magic-comments) to dynamic `import()` expressions at build time.\n\nUseful when working with:\n\n* [Babel plugins](https://babeljs.io/docs/plugins)\n* [Webpack loaders](https://webpack.js.org/loaders/)\n* [Vite plugins](https://vitejs.dev/guide/api-plugin.html)\n* Anywhere you want to add magic comments to your source code before running through webpack.\n\n## Getting Started\n\nFirst install `magic-comments`:\n\n```\nnpm install magic-comments\n```\n\nNext, for each file processed provide the following **required** information for every `import()` found:\n\n* The absolute filename of the file being processed (`modulePath`).\n* The dynamic import's specifier (`importPath`).\n\nThen pass those values to `getMagicComment()` to generate a magic comment that can be inserted into the corresponding `import()`:\n\n**src/file.js**\n\n```js\nconst mod = import('./folder/module.js')\n```\n\n**tooling**\n```js\nimport { resolve } from 'node:path'\nimport { readFileSync } from 'node:fs'\nimport { parse } from 'acorn' // Or another parser\nimport { getMagicComment } from 'magic-comments'\nimport { traverseForImportSpecifier } from './utils.js'\n\nconst filename = resolve(cwd, './src/file.js')\nconst code = readFileSync(filename)\nconst ast = parse(code)\nconst dynamicImports = traverseForImportSpecifiers(ast)\n\ndynamicImports.forEach(({ specifier }) =\u003e {\n  const magicComment = getMagicComment({\n    modulePath: filename,\n    importPath: specifier,\n    // The options are names of webpack magic comments\n    options: {\n      webpackChunkName: true,\n      webpackFetchPriority: (modulePath, importPath) =\u003e {\n        if (importPath.endsWith('important.js')) {\n          return 'high'\n        }\n      }\n    }\n  })\n\n  console.log(magicComment)\n  // /* webpackChunkName: \"module-important\", webpackFetchPriority: \"high\" */\n})\n```\n\n## `getMagicComment()`\n\nGenerates a webpack magic comment.\n\n```js\ngetMagicComment(ctx: MagicCommentsContext) =\u003e string\n```\n\nThe only parameter is an object with the following properties.\n\n```ts\ninterface MagicCommentsContext {\n  importPath: string\n  modulePath: string\n  match?: 'module' | 'import'\n  open?: boolean\n  options?: MagicComments\n}\n```\n\n### `MagicCommentsContext`\n\nThe only required properties are `modulePath` and `importPath`:\n\n* [`modulePath`](#modulepath)\n* [`importPath`](#importpath)\n* [`open`](#open)\n* [`match`](#match)\n* [`options`](#options)\n\n### `modulePath`\n\n**required**\u003csup\u003e*\u003c/sup\u003e\n\nThe absolute path to the file with the dynamic imports.\n\n### `importPath`\n\n**required**\u003csup\u003e*\u003c/sup\u003e\n\nThe specifier from the dynamic import. For example, for `import('./specifier.js')` the `importPath` would be `./specifier.js`.\n\n### `open`\n\n**default** `false`\n\nWhether the returned comment should be surrounded by `/*` and `*/`, for example, `/* comment */` vs ``  comment  ``.\n\n### `match`\n\n**default** `'module'`\n\nSets how globs are matched, either the module file path, or the `import()` specifier.\n\n### `options`\n\nAn object with properties corresponding to [magic comments supported by webpack](https://webpack.js.org/api/module-methods/#magic-comments). \n\nAll options can be defined with a [`CommentFunc`](#commentfunc) or a [`CommentConfig`](#commentconfig) to support overrides of [`CommentOptions`](#commentoptions). Options that support globs use [`micromatch`](https://github.com/micromatch/micromatch) for pattern matching, where `type Glob = string | string[]`.\n\n* [`webpackChunkName`](#webpackchunkname)\n* [`webpackFetchPriority`](#webpackfetchpriority)\n* [`webpackMode`](#webpackmode)\n* [`webpackPrefetch`](#webpackprefetch)\n* [`webpackPreload`](#webpackpreload)\n* [`webpackInclude`](#webpackinclude)\n* [`webpackExclude`](#webpackexclude)\n* [`webpackExports`](#webpackexports)\n* [`webpackIgnore`](#webpackignore)\n\n#### `CommentFunc`\n\nAll options can be defined as a function to dynamically determine their value, or turn on and off.\n\n```ts\ninterface CommentFunc\u003cT\u003e {\n  (modulePath: string, importPath: string): T\n}\n```\n\nThe exact shape of `T` is determined by the magic comment the option is associated with, similar to `CommentOptions`.\n\n#### `CommentConfig`\n\nTo allow overrides based on module or import paths, all options can be defined with an object having the following interface:\n\n```ts\ninterface CommentConfig\u003cT extends CommentOptions\u003e {\n  options: T\n  overrides?: Array\u003c{\n    files: string | string[]\n    options: T\n  }\u003e\n}\n```\n\n#### `CommentOptions`\n\nThe exact shape defining `options` is determined by the magic comment it is associated with, but the interface always extends `CommentOptions`:\n\n```ts\ninterface CommentOptions {\n  active?: boolean | ((modulePath: string, importPath: string): boolean)\n}\n```\n\nThe `active` property turns the option on or off. Each particular magic comment extends this interface in their own way, adding additional properties relevant to their functioning.\n\nFor example, `webpackChunkName` adds a couple additional properties for adjusting the chunk name used:\n\n```ts\ninterface WebpackChunkNameOptions extends CommentOptions {\n  /**\n   * Use the basename of the import specifier as the chunk name.\n   */\n  basename?: boolean\n  /**\n   * Provide a custom chunk name for all dynamic imports or\n   * those matching a particular override glob.\n   */\n  name?: string\n}\n```\n\nYou can skip to the [overrides example](#overrides) to get a better sense of how this all works.\n\n\n#### `webpackChunkName`\n\n**type**\n\n```ts\nboolean\n| Glob\n| CommentFunc\u003cstring | false\u003e\n| CommentConfig\u003cWebpackChunkNameOptions\u003e\n```\n\n**default** `true`\n\nAdds `webpackChunkName` magic comments. The assumption is that this is the most popular webpack magic comment, so **it will be enabled by default when `options` is empty of falsy**.\n\nWhen using a [`CommentConfig`](#commentconfig) the following comment options are supported:\n\n```ts\n{\n  // Use the basename of the import specifier as the chunk name.\n  basename?: boolean\n  // If overrides are not used, this will apply to ALL dynamic imports.\n  name?: string\n}\n```\n\nPossible values:\n* `true` - Adds `webpackChunkName` comments to **all** dynamic imports using the derived path from the import specifier in kebab-case as the chunk name. This is the default.\n* `false` - Disables adding the `webpackChunkName` comment globally.\n* `string | string[]` - When the glob(s) match a path from a [`match`](#match) path, a `webpackChunkName` comment is added using the derived path from the import specifier in kebab-case as the chunk name.\n* `(modulePath: string, importPath: string) =\u003e string | false` - Return a string to be used as the chunk name. Returning a falsy value will skip adding the comment.\n* `options.basename`:\n  * `true` - Use only the [basename](https://nodejs.org/api/path.html#pathbasenamepath-suffix) from the import specifier as the chunk name. Might result in name collisions. Use in areas where you know the basenames are unique.\n  * `false` - Use the full derived path from the import specifier in kebab-case as the chunk name, same as the default behavior.\n* `options.name`:\n  * `string` - Set a fixed string to be used for all dynamic imports, or based on overrides.\n* `options.active`:\n  * `true` - Disable the comment.\n  * `false` - Enable the comment.\n\n### `webpackFetchPriority`\n\n**type**\n\n```ts\nboolean\n| FetchPriority\n| CommentFunc\u003cfalse | FetchPriority\u003e\n| CommentConfig\u003cWebpackFetchPriorityOptions\u003e\n```\n\n**default** None\n\nAdds `webpackFetchPriority` magic comments.\n\n`FetchPriority` is an enum:\n\n```ts\nenum FetchPriority {\n  AUTO = 'auto',\n  HIGH = 'high',\n  LOW = 'low'\n}\n```\n\nWhen using a [`CommentConfig`](#commentconfig) the following comment options are supported:\n\n```ts\n{\n  fetchPriority?: FetchPriority | CommentFunc\u003cfalse | FetchPriority\u003e\n}\n```\n\nPossible values:\n* `false` - Disables the comment globally. This is the default behavior.\n* `true` - Add `webpackFetchPriority` magic comments to **all** dynamic imports with the default value of `'auto'`.\n* `string` - Add `webpackFetchPriority` magic comments to **all** dynamic imports with the provided string value as the priority. If the string is not `'high'`, `'low'`, or `'auto'` the comment will **not** be added.\n* `(modulePath: string, importPath: string) =\u003e FetchPriority | false` - Return a string to be used as the priority. Returning a falsy value or an unsupported string will **not** add the comment.\n* `options.fetchPriority`:\n  * `FetchPriority` - Sets the fetch priority to the provided value when adding the comment.\n  * `(modulePath: string, importPath: string) =\u003e FetchPriority | false` - Same as using a function for the value.\n* `options.active`:\n  * `true` - Disable the comment.\n  * `false` - Enable the comment.\n\n### `webpackMode`\n\n**type**\n\n```ts\nboolean\n| Mode\n| CommentFunc\u003cfalse | Mode\u003e\n| CommentConfig\u003cWebpackModeOptions\u003e\n```\n\n**default** None\n\nAdds `webpackMode` magic comments.\n\n`Mode` is an enum:\n\n```ts\nenum Mode {\n  LAZY = 'lazy',\n  LAZY_ONCE = 'lazy-once',\n  EAGER = 'eager',\n  WEAK = 'weak'\n}\n```\n\nWhen using a [`CommentConfig`](#commentconfig) the following comment options are supported:\n```ts\n{\n  mode?: Mode | CommentFunc\u003cfalse | Mode\u003e\n}\n```\n\nPossible values:\n* `false` - Disables the comment globally. This is the default behavior.\n* `true` - Add `webpackMode` magic comments to **all** dynamic imports with the default value of `'lazy'`.\n* `string` - Add `webpackMode` magic comments to **all** dynamic imports with the provided string value as the mode. If the string is not `'lazy'`, `'lazy-once'`, `'eager'`, or `'weak'` the comment will **not** be added.\n* `(modulePath: string, importPath: string) =\u003e Mode | false` - Return a string to be used as the mode. Returning a falsy value or an unsupported string will **not** add the comment.\n* `options.mode`:\n  * `Mode` - Sets the chunk loading mode to the provided value when adding the comment.\n  * `(modulePath: string, importPath: string) =\u003e Mode | false` - Same as using a function for the value.\n* `options.active`:\n  * `true` - Disable the comment.\n  * `false` - Enable the comment.\n\n### [`webpackPrefetch`](https://webpack.js.org/guides/code-splitting/#prefetchingpreloading-modules)\n\n**type**\n\n```ts\nboolean\n| Glob\n| CommentFunc\u003cboolean\u003e\n| CommentConfig\u003cCommentOptions\u003e\n```\n\n**default** None\n\nAdds `webpackPrefetch` magic comments.\n\nWhen using a [`CommentConfig`](#commentconfig) this option **does not add additional properties** to [`CommentOptions`](#commentoptions).\n\nPossible values:\n* `false` - Disables the comment globally. This is the default behavior.\n* `true` - Add `webpackPrefetch` magic comments with a value of `true` to **all** dynamic imports. \n* `string | string[]` - Add `webpackPrefetch` comment with a value of `true` when the glob(s) match a path from a [`match`](#match) path.\n* `(modulePath: string, importPath: string) =\u003e boolean` - Returning `false` will disable adding the comment, otherwise it will be added.\n* `options.active`:\n  * `true` - Disable the comment.\n  * `false` - Enable the comment.\n\n### [`webpackPreload`](https://webpack.js.org/guides/code-splitting/#prefetchingpreloading-modules)\n\n**type**\n\n```ts\nboolean\n| Glob\n| CommentFunc\u003cboolean\u003e\n| CommentConfig\u003cCommentOptions\u003e\n```\n\n**default** None\n\nAdds `webpackPreload` magic comments.\n\nWhen using a [`CommentConfig`](#commentconfig) this option **does not add additional properties** to [`CommentOptions`](#commentoptions).\n\nPossible values:\n* `false` - Disables the comment globally. This is the default behavior.\n* `true` - Add `webpackPreload` magic comments with a value of `true` to **all** dynamic imports. \n* `string | string[]` - Add `webpackPreload` comment with a value of `true` when the glob(s) match a path from a [`match`](#match) path.\n* `(modulePath: string, importPath: string) =\u003e boolean` - Returning `false` will disable adding the comment, otherwise it will be added.\n* `options.active`:\n  * `true` - Disable the comment.\n  * `false` - Enable the comment.\n\n### `webpackInclude`\n\n**type**\n\n```ts\nRegExp\n| CommentFunc\u003cRegExp\u003e\n| CommentConfig\u003cWebpackIncludeOptions\u003e\n```\n\n**default** None\n\nAdds `webpackInclude` magic comments.\n\nWhen using a [`CommentConfig`](#commentconfig) the following comment options are supported:\n```ts\n{\n  include?: RegExp | CommentFunc\u003cRegExp\u003e\n}\n```\n\nPossible values:\n*  `RegExp` - Adds a `webpackInclude` comment to **all** dynamic imports using the provided regular expression.\n*  `(modulePath: string, importPath: string) =\u003e RegExp` - Adds a `webpackInclude` comment using the provided regular expression. Returning anything other than a regular expression does **not** add the comment.\n*  `options.include`:\n   * `RegExp` - Adds a `webpackInclude` comment to **all** dynamic imports, or only those matching a path from the [`match`](#match) path if using overrides.\n   * `(modulePath: string, importPath: string) =\u003e RegExp` - Same as using a function for the value.\n* `options.active`:\n  * `true` - Disable the comment.\n  * `false` - Enable the comment.\n\n### `webpackExclude`\n\n**type**\n\n```ts\nRegExp\n| CommentFunc\u003cRegExp\u003e\n| CommentConfig\u003cWebpackExcludeOptions\u003e\n```\n\n**default** None\n\nAdds `webpackExclude` magic comments.\n\nWhen using a [`CommentConfig`](#commentconfig) the following comment options are supported:\n```ts\n{\n  exclude?: RegExp | CommentFunc\u003cRegExp\u003e\n}\n```\n\nPossible values:\n*  `RegExp` - Adds a `webpackExclude` comment to **all** dynamic imports using the provided regular expression.\n*  `(modulePath: string, importPath: string) =\u003e RegExp` - Adds a `webpackExclude` comment using the provided regular expression. Returning anything other than a regular expression does **not** add the comment.\n*  `options.exclude`:\n   * `RegExp` - Adds a `webpackExclude` comment to **all** dynamic imports, or only those matching a path from the [`match`](#match) path if using overrides.\n   * `(modulePath: string, importPath: string) =\u003e RegExp` - Same as using a function for the value.\n* `options.active`:\n  * `true` - Disable the comment.\n  * `false` - Enable the comment.\n\n### `webpackExports`\n\n**type**\n\n```ts\nCommentFunc\u003cstring[]\u003e | CommentConfig\u003cWebpackExportsOptions\u003e\n```\n\n**default** None\n\nAdds `webpackExports` magic comments.\n\nWhen using a [`CommentConfig`](#commentconfig) the following comment options are supported:\n```ts\n{\n  exports?: CommentFunc\u003cstring[]\u003e\n}\n```\n\nPossible values:\n* `(modulePath: string, importPath: string) =\u003e string[]` - Adds a `webpackExports` comment using the strings in the returned array as the export names. Returning anything other than an array will **not** add the comment.\n* `options.exports`:\n  * `(modulePath: string, importPath: string) =\u003e string[]` - Same as using a function for the value.\n* `options.active`:\n  * `true` - Disable the comment.\n  * `false` - Enable the comment.\n\n\n### `webpackIgnore`\n\n**type**\n\n```ts\nboolean\n| Glob\n| CommentFunc\u003cboolean\u003e\n| CommentConfig\u003cCommentOptions\u003e\n```\n\n**default** None\n\nAdds `webpackIgnore` magic comments.\n\nWhen using a [`CommentConfig`](#commentconfig) this option **does not add additional properties** to [`CommentOptions`](#commentoptions).\n\nPossible values:\n* `false` - Disables the comment globally. This is the default behavior.\n* `true` - Add `webpackIgnore` magic comments with a value of `true` to **all** dynamic imports. Effectively, opt-out of webpack code-splitting for dynamic imports. \n* `string | string[]` - Add `webpackIgnore` comment with a value of `true` when the glob(s) match a path from a [`match`](#match) path.\n* `(modulePath: string, importPath: string) =\u003e boolean` - Returning `false` will **not** add the comment, otherwise it will be added.\n* `options.active`:\n  * `true` - Disable the comment.\n  * `false` - Enable the comment.\n\n## Examples\n\nBelow are some examples. Consult one of the [used by](#used-by) packages, or the unit tests in this repo for something more comprehensive. Particularly, the [loader specification from `magic-comments-loader`](https://github.com/morganney/magic-comments-loader/blob/main/__tests__/loader.spec.js).\n\n\n### Multiple\n\nSince [`options`](#options) is an object, you can define more than one type of a webpack magic comment.\n\n```js\nimport { getMagicComment, Mode } from 'magic-comments'\n\nconst magicComment = getMagicComment({\n  modulePath: '/path/file.js',\n  importPath: './import/module.js',\n  options: {\n    webpackMode: Mode.EAGER,\n    webpackPreload: (modulePath, importPath) =\u003e {\n      return importPath.includes('module')\n    }\n  }\n})\n\nconsole.log(magicComment) // /* webpackMode: \"eager\", webpackPreload: true */\n```\n\n### Overrides\n\nWhen using a [`CommentConfig\u003cT\u003e`](#commentconfig) object, you can override the configuration passed in the `options` property by defining `overrides`. It is an array of objects that look like:\n\n```ts\nArray\u003c{\n  files: string | string[];\n  options: T;\n}\u003e\n```\n\nWhere the generic `T` is related to the magic comment the options are associated with. The `files` and `options` properties are both **required**, where the former is a glob string, or an array thereof, and the latter is the associated magic comment's [`CommentOptions`](#commentoptions).\n\nHere's a more complete example of how overrides can be applied.\n\n```js\nimport  { getMagicComment } from 'magic-comments'\n\nconst comment = getMagicComment({\n  modulePath: '/file/module.js',\n  importPath: './dynamic/import.js',\n  options: {\n    webpackChunkName: {\n      options: { active: false },\n      overrides: [\n        {\n          files: '**/file/*.js',\n          options: {\n            active: true,\n            name: 'override'\n          }\n        }\n      ]\n    }\n  }\n})\n\nconsole.log(comment) // /* webpackChunkName: \"override\" */\n```\n\nHere, [`match`](#match) is set to `import`, so the glob used in the override will **not match**.\n\n```js\nconst comment = getMagicComment({\n  match: 'import',\n  modulePath: '/file/module.js',\n  importPath: './dynamic/import.js',\n  options: {\n    webpackChunkName: {\n      options: { active: true },\n      overrides: [\n        {\n          files: '**/file/*.js',\n          options: {\n            basename: true\n          }\n        }\n      ]\n    }\n  }\n})\n\nconsole.log(comment) // /* webpackChunkName: \"dynamic-import\" */\n```\n\nChanging the glob to `**/dynamic/*.js` will then match, and the override options will be used.\n\n```js\nconsole.log(comment) // /* webpackChunkName: \"import\" */\n```\n\n## Used by\n\n* [`magic-comments-loader`](https://github.com/morganney/magic-comments-loader)\n* [`babel-plugin-magic-comments`](https://github.com/morganney/babel-plugin-magic-comments)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorganney%2Fmagic-comments","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmorganney%2Fmagic-comments","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorganney%2Fmagic-comments/lists"}