官术网_书友最值得收藏!

  • Node.js Web Development
  • David Herron
  • 599字
  • 2021-06-25 21:54:05

Module identifiers and pathnames

Generally speaking, the module name is a pathname, but with the file extension removed. Earlier, when we wrote require('./simple'), Node.js knew to add .js to the filename and load in simple.js. Similarly, Node.js would recognize simple.json or simple.node as the filename legitimately satisfying require('./simple').

There are three types of module identifiers: relative, absolute, and top-level:

  • Relative module identifiers: These begin with ./ or ../ and absolute identifiers begin with /. The module name is identical with POSIX filesystem semantics. The resultant pathname is interpreted relative to the location of the file being executed. That is, a module identifier beginning with ./ is looked for in the current directory, whereas one starting with ../ is looked for in the parent directory.
  • Absolute module identifiers: These begin with/and are, of course, looked for in the root of the filesystem, but this is not a recommended practice.
  • Top-level module identifiers: These begin with none of those strings and are just the module name, or else module-name/path/to/module. These must be stored in a node_modules directory, and the Node.js runtime has a nicely flexible algorithm for locating the correct node_modules directory:
    • In the case of module-name/path/to/module specifiers, what will be loaded is a module path/to/module within the top-level module named module-name
    • The baked-in modules are specified using top-level module names

The search begins in the directory containing the file calling require(). If that directory contains a node_modules directory, which then contains either a matching directory module or a matching file module, then the search is satisfied. If the local node_modules directory does not contain a suitable module, it tries again in the parent directory, and it will continue upward in the filesystem until it either finds a suitable module or it reaches the root directory.

That is, with a require call in /home/david/projects/notes/foo.js, the following directories will be consulted:

  • /home/david/projects/notes/node_modules
  • /home/david/projects/node_modules
  • /home/david/node_modules
  • /home/node_modules
  • /node_modules

If the module is not found through this search, there are global folders in which modules can be located. The first is specified in the NODE_PATH environment variable. This is interpreted as a colon-delimited list of absolute paths similar to the PATH environment variable. On Windows, the elements of NODE_PATH are of course separated by semicolons. Node.js will search those directories for a matching module.

The NODE_PATH approach is not recommended, because of surprising behavior which can happen if people are unaware that this variable must be set. If a specific module located in a specific directory referenced in NODE_PATH is required for proper function, and the variable is not set, the application will likely fail. As the Twelve-Factor Application model suggests, it is best for all dependencies to be explicitly declared, and with Node.js that means listing all dependencies in the package.json so that npm or yarn can manage the dependencies.

This variable was implemented before the module resolution algorithm just described was finalized. Because of that algorithm, NODE_PATH is largely unnecessary. 

There are three additional locations that can hold modules:

  • $HOME/.node_modules
  • $HOME/.node_libraries
  • $PREFIX/lib/node

In this case, $HOME is what you expect, the user's home directory, and $PREFIX is the directory where Node.js is installed.

Some are beginning to recommend against using global modules. The rationale is the desire for repeatability and deployability. If you've tested an app, and all its code is conveniently located within a directory tree, you can copy that tree for deployment to other machines. But, what if the app depended on some other file that was magically installed elsewhere on the system? Will you remember to deploy such files?

主站蜘蛛池模板: 兴城市| 墨竹工卡县| 贵州省| 宝丰县| 丹寨县| 宣威市| 江西省| 确山县| 乌审旗| 天津市| 外汇| 桃园市| 韶关市| 江都市| 高台县| 桂林市| 长春市| 郴州市| 吉水县| 互助| 察隅县| 弥渡县| 乾安县| 佛坪县| 安图县| 铜川市| 凤阳县| 潍坊市| 遂溪县| 来宾市| 闻喜县| 济源市| 锦屏县| 郎溪县| 南江县| 灵台县| 雅江县| 陇西县| 阳城县| 塔河县| 安图县|