# 三.路径相关配置

在 webpack 中,我们可以使用import * as m from './index.js'来引用代码模块index.js

第三方类库则是像这样:import React from 'react'

webpack 构建的时候,会解析依赖后,然后再去加载依赖的模块文件,webpack 中有一个很关键的模块enhanced-resolve就是处理依赖模块路径的解析的

# 1.模块解析规则

  • 解析相对路径
    • 1.查找相对当前模块的路径下是否有相应的文件或文件夹
    • 2.是文件则直接加载
    • 3.是文件夹则继续查找文件夹下的 package.json 文件
    • 4.有 package.json 文件则按照文件中main字段的文件名来查找文件
    • 5.无 package.json 或者无mian字段则查找index.js文件
  • 解析模块名
    • 查找当前文件目录下,父级目录以及上目录下node_modules文件夹,看是否有对应名称的模块
  • 解析绝对路径
    • 直接查找文件对应路径的文件

在 webpack 配置中,和模块路径继续相关的配置都在resolve字段下:

module.exports = {
  resolve: {
    // ...
  },
}
1
2
3
4
5

# 2.常用的一些配置

  • resolve.alias
alias: {
  utils: path.resolve(__dirname, "src/utils") //这里使用path.resolve和__dirname来获取绝对路径
}
1
2
3

上述的配置是模糊匹配,意味着只要模块路径中携带了utils就可以被替换,如:

import "utils/query.js" //等同于import '项目绝对路径'//src/utils/query.js
1

如果需要进行精确匹配可以使用:

alias: {
  utils$: path.resolve(__dirname, "src/utils") //只会匹配 import 'utils'
}
1
2
3
  • resolve.extensions
extensions: [".wasm", ".mjs", ".js", ".json", ".jsx", ".css"] //这里的顺序代表匹配后缀的优先级,例如对于index.js和index.jsx,会优先选择index.js
1

src/utils/common.js文件引用

import * as common from "./src/utils/common"
1
  • reslove.modules

前面的内容有提到,对于直接声明依赖名的模块(如react),webpack 会类似 Node.js 一样进行路径搜索,搜索 node_modules 目录,这个目录就是使用resolve.modules字段进行配置,默认就是:

resolve: {
  modules: ["node_modules"]
}
1
2
3

如果可以确定项目内所有的第三方依赖模块都是在项目根目录下的 node_modules 中的话,那么可以在 node_modules 之前配置一个确定的绝对路径,这样配置在某种程度上可以简化模块的查找,提升构建速度

resolve: {
  modules: [
    path.resolve(__dirname, "node_modules"), //指定当前目录下的node_modules优先查找
    "node_modules", //如果有一些类库是放在一些奇怪的地方的,你可以添加自定义的路径或者目录
  ]
}
1
2
3
4
5
6
  • resolve.mainFields

当引用的是一个模块或者一个目录时,会使用 package.json 文件的哪一个字段下指定的文件,默认的配置是这样的:

resolve: {
  mainFields: ["browser", "module", "main"],// 配置target === 'web'或者target==='webworker'时mainFields 默认值是
  mainFields: ['module','main']// target的值为其他时,mainFields默认值为
}
1
2
3
4

因为通常情况下,模块的 package 都不会声明browser或者modules字段,所以便是使用main了。

在 NPM packages 中,会有些 package 提供了两个实现,分别给浏览器和 Node.js 两个不同的运行时使用,这个时候就需要区分不同的实现入口在哪里

  • resolve.mainFiles

当目录下没有 package.json 文件时,我们说会默认使用目录下的 index.js 这个文件,其实这个也是可以配置的,是的,使用resolve.mainFiles字段,默认配置是:

resolve: {
  mainFiles: ["index"] // 你可以添加其他默认使用的文件名
}
1
2
3
  • resolve.resolveLoader

这个字段resolve.resolveLoader用于配置解析 loader 配置,原本 resolve 的配置项在这个字段下基本都有。我们看下默认的配置:

resolveL{
  resolveLoader:{
    extensions:['.js','.json'],
    mainFields:['loader','main']
  }
}
1
2
3
4
5
6