依赖重定向


应用程序可能需要发布模块的补丁版本或阻止模块允许所有模块访问所有其他模块。 可以通过拦截加载希望被替换的模块的尝试来使用重定向。

{
  "resources": {
    "./app/checked.js": {
      "dependencies": {
        "fs": true,
        "os": "./app/node_modules/alt-os",
        "http": { "import": true }
      }
    }
  }
}

依赖项由请求的说明符字符串作为键,并且具有 truenull、指向要解析的模块的字符串或条件对象的值。

说明符字符串不执行任何搜索,并且必须与提供给 require()import 的内容完全匹配,但规范化步骤除外。 因此,如果策略使用多个不同的字符串指向同一个模块(例如排除扩展名),则可能需要多个说明符。

说明符字符串已规范化,但在用于匹配之前未解析,以便与导入映射具有某种兼容性,例如,如果资源 file:///C:/app/server.js 从位于 file:///C:/app/policy.json 的策略中获得以下重定向:

{
  "resources": {
    "file:///C:/app/utils.js": {
      "dependencies": {
        "./utils.js": "./utils-v2.js"
      }
    }
  }
}

任何用于加载 file:///C:/app/utils.js 的说明符将被拦截并重定向到 file:///C:/app/utils-v2.js,而不考虑使用绝对或相对说明符。 但是,如果使用的说明符不是绝对或相对 URL 字符串,则不会被截取。 所以,如果使用了 import('#utils') 之类的导入,则不会被拦截。

如果重定向的值为 true,将使用策略文件顶部的 "dependencies" 字段。 如果策略文件顶部的字段是 true,则使用默认节点搜索算法来查找模块。

如果重定向的值是字符串,则相对于清单进行解析,然后立即使用而无需搜索。

根据策略,任何尝试解析且未在依赖项中列出的说明符字符串都会导致错误。

重定向不会阻止通过直接访问 require.cache 或通过允许访问加载模块的 module.constructor 等方式访问 API。 策略重定向只影响到 require()import 的说明符。 其他方法,例如防止通过变量对 API 的非期望访问,对于锁定加载模块的路径是必要的。

可以指定依赖项映射的布尔值 true 以允许模块加载任何说明符而无需重定向。 这对本地开发很有用,并且在生产中可能有一些有效的用途,但只有在审核模块以确保其行为有效后才应谨慎使用。

package.json 中的 "exports" 类似,依赖项也可以指定为包含条件的对象,这些条件分支如何加载依赖关系。 在前面的示例中,当 "import" 条件是加载它的一部分时,允许 "http"

解析值的值 null 会导致解析失败。 这可用于确保明确阻止某些类型的动态访问。

已解析模块位置的未知值会导致失败,但不能保证向前兼容。

An application may need to ship patched versions of modules or to prevent modules from allowing all modules access to all other modules. Redirection can be used by intercepting attempts to load the modules wishing to be replaced.

{
  "resources": {
    "./app/checked.js": {
      "dependencies": {
        "fs": true,
        "os": "./app/node_modules/alt-os",
        "http": { "import": true }
      }
    }
  }
}

The dependencies are keyed by the requested specifier string and have values of either true, null, a string pointing to a module to be resolved, or a conditions object.

The specifier string does not perform any searching and must match exactly what is provided to the require() or import except for a canonicalization step. Therefore, multiple specifiers may be needed in the policy if it uses multiple different strings to point to the same module (such as excluding the extension).

Specifier strings are canonicalized but not resolved prior to be used for matching in order to have some compatibility with import maps, for example if a resource file:///C:/app/server.js was given the following redirection from a policy located at file:///C:/app/policy.json:

{
  "resources": {
    "file:///C:/app/utils.js": {
      "dependencies": {
        "./utils.js": "./utils-v2.js"
      }
    }
  }
}

Any specifier used to load file:///C:/app/utils.js would then be intercepted and redirected to file:///C:/app/utils-v2.js instead regardless of using an absolute or relative specifier. However, if a specifier that is not an absolute or relative URL string is used, it would not be intercepted. So, if an import such as import('#utils') was used, it would not be intercepted.

If the value of the redirection is true, a "dependencies" field at the top of the policy file will be used. If that field at the top of the policy file is true the default node searching algorithms are used to find the module.

If the value of the redirection is a string, it is resolved relative to the manifest and then immediately used without searching.

Any specifier string for which resolution is attempted and that is not listed in the dependencies results in an error according to the policy.

Redirection does not prevent access to APIs through means such as direct access to require.cache or through module.constructor which allow access to loading modules. Policy redirection only affects specifiers to require() and import. Other means, such as to prevent undesired access to APIs through variables, are necessary to lock down that path of loading modules.

A boolean value of true for the dependencies map can be specified to allow a module to load any specifier without redirection. This can be useful for local development and may have some valid usage in production, but should be used only with care after auditing a module to ensure its behavior is valid.

Similar to "exports" in package.json, dependencies can also be specified to be objects containing conditions which branch how dependencies are loaded. In the preceding example, "http" is allowed when the "import" condition is part of loading it.

A value of null for the resolved value causes the resolution to fail. This can be used to ensure some kinds of dynamic access are explicitly prevented.

Unknown values for the resolved module location cause failures but are not guaranteed to be forward compatible.