webpack在编译构建的过程中,需要通过模块引用声明的路径来获取相应的模块,代码如下

import foo from 'path/to/module';
// 或者
require('path/to/module');

webpack如何解析模块路径

webpack通过 enhanced-resolve 来解析模块路径,规则如下,权重从高到低

绝对路径

import '/home/module';
import 'C:\\Users\module';

绝对路径权重最大,此时直接获取对应路径下的文件

相对路径

import '../src/file1';
import './file2';

importrequire 的资源文件所处的目录,确定了上下文目录。然后通过相对路径,生成模块的绝对路径

模块路径

import React from 'react';

如果路径不是相对或者绝对路径,那么首先webpack需要通过 resolvemodules 选项来确定目录搜索范围,比如

module.exports = {
  //...
  resolve: {
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
  },
};

modules 数组指定的目录优先级从左到右,权重依次降低

确定好目录搜索范围后,通过 resolvealias 选项来替换模块的路径

resolve: {
  alias: {
    Utilities: path.resolve(__dirname, 'src/utilities/'),
  },
},

那么模块的引入写法可以从

import Utility from '../../utilities/utility';

调整为

import Utility from 'Utilities/utility';

具体使用方法可以查看官方文档

模块路径是文件或者文件夹

确定上述解析范围后,还需要判断文件类型,优先级如下

  1. 有扩展名,直接引入,否则使用 resolveextensions 选项拼接文件扩展名
  2. 如果路径是文件夹
    1. 文件夹包含 package.json 文件,通过 resolvemainFields 选项的字段查找,根据 package.json 符合配置要求的第一个字段确定文件路径
    2. 如果不存在 package.json 文件或 resolve.mainFields 没有返回有效路径,则会根据 resolve.mainFiles 配置选项中指定的文件名顺序查找,看是否能在 import/require 的目录下匹配到一个存在的文件名,resolve.extensions 选项,以类似的方式解析文件扩展名