【webpack】细化webpack的resolve配置项

当我们使用webpack进行构建前端项目的时候,会从配置的入口模块处出发找出所有依赖的模块,Resolve配置Webpack如何去找出模块所对应的文件。

由于Webpack 内置了 JavaScript 模块化语法解析功能,默认会采用模块化标准里约定好的规则去寻找,但你也可以通过Resolve字段根据自己的需要修改默认的规则。

// webpack.config.js
module.exports = {
  //...
  resolve: {
    // configuration options
  }
};

resolve.alias

作用:通过别名来把原导入路径映射成一个新的导入路径,例如:

// webpack.config.js
module.exports = {
  //...
  resolve: {
    alias: {
      '@Components': path.resolve(__dirname, 'src/components/'),
      '@Utils': path.resolve(__dirname, 'src/utils/')
    }
  }
};

先看下,我们传统模式导入一个组件是这样的:

import Button from '../../../componets/button'

现在,我们就可以这么使用别名了:

import Button from '@Components/button'

当然,我们还可以给定对象键后末尾添加$进行精确匹配

// webpack.config.js
module.exports = {
  //...
  resolve: {
    alias: {
      xyz$: path.resolve(__dirname, 'path/to/file.js')
    }
  }
};

import Test1 from 'xyz'; // 精确匹配,所以 path/to/file.js 被解析和导入
import Test2 from 'xyz/file.js'; // 非精确匹配,触发普通解析

resolve.mainFields

当从 npm 包中导入模块时(例如,import * as D3 from 'd3'),此选项将决定在 package.json 中使用哪个字段导入模块。根据 webpack 配置中指定的 target 不同,默认值也会有所不同。

当 target 属性设置为 webworker, web 或者没有指定,默认值为:

// webpack.config.js
module.exports = {
  //...
  resolve: {
    mainFields: ['browser', 'module', 'main']
  }
};

对于其他任意的 target(包括 node),默认值为:

// webpack.config.js
module.exports = {
  //...
  resolve: {
    mainFields: ['module', 'main']
  }
};

例如,考虑任意一个名为 upstream 的 library,其 package.json 包含以下字段:

{
  "browser": "build/upstream.js",
  "module": "index"
}

在我们 import * as Upstream from 'upstream' 时,这实际上会从 browser 属性解析文件。在这里 browser 属性是最优先选择的,因为它是 mainFields 的第一项。同时,由 webpack 打包的 Node.js 应用程序首先会尝试从 module 字段中解析文件。

resolve.extensions

自动解析确定的扩展。默认值为:

// webpack.config.js
module.exports = {
  //...
  resolve: {
    extensions: ['.wasm', '.mjs', '.js', '.json']
  }
};

能够使用户在引入模块时不带扩展:

import File from '../path/to/file';

resolve.modules

告诉 webpack 解析模块时应该搜索的目录。

绝对路径和相对路径都能使用,但是要知道它们之间有一点差异。

通过查看当前目录以及祖先路径(即 ./node_modules, ../node_modules 等等),相对路径将类似于 Node 查找 'node_modules' 的方式进行查找。

使用绝对路径,将只在给定目录中搜索。

// webpack.config.js
module.exports = {
  //...
  resolve: {
    modules: ['node_modules']
  }
};

如果你想要添加一个目录到模块搜索目录,此目录优先于 node_modules/ 搜索:

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

上述配置会导致webpack在查找模块时候,先去src目录下找,如果没有找到会去node_modules下查找

resolve.descriptionFiles

作用:描述第三方模块的文件名称,也就是 package.json 文件。默认如下:

descriptionFiles: ['package.json']
enforceExtension

resolve.enforceExtension

如果配置为 true 所有导入语句都必须要带文件后缀, 例如开启前 import './foo' 能正常工作,开启后就必须写成 import './foo.js'

resolve.enforceModuleExtension

enforceModuleExtensionenforceExtension 作用类似,但 enforceModuleExtension 只对 node_modules 下的模块生效。 enforceModuleExtension 通常搭配 enforceExtension 使用,在 enforceExtension:true 时,因为安装的第三方模块中大多数导入语句没带文件后缀, 所以这时通过配置 enforceModuleExtension:false 来兼容第三方模块。

更多关于resolve配置项

可自行查阅官方文档