从webpack2开始,webpack在打包node应用时,默认优先解析的是package.json中module字段指定的文件,module字段指定的文件是采用es模块方案的包的入口文件。由于某些特殊原因(什么原因,后面会提到),我们希望webpack在打包时还是默认解析package.json中main字段指定的文件,那么我们该如何配置webpack呢?这时我们可以使用webpack的resolve.mainFields配置。
resolve.mainFields介绍
我们看下webpack官方文档关于这个配置的介绍:
当从 npm 包中导入模块时(例如,
import * as D3 from "d3"
),此选项将决定在package.json
中使用哪个字段导入模块。根据webpack
配置中指定的target
不同,默认值也会有所不同。
当target
属性设置为webworker
,web
或者没有指定,默认值为:mainFields: ["browser", "module", "main"]
对于其他任意的
target
(包括node
),默认值为:mainFields: ["module", "main"]
例如,
D3
的package.json
含有这些字段:{ ... main: 'build/d3.Node.js', browser: 'build/d3.js', module: 'index', ... }
这意味着当我们
import * as D3 from "d3"
,实际从browser
属性解析文件。在这里browser
属性是最优先选择的,因为它是mainFields
的第一项。同时,由webpack
打包的Node.js
应用程序默认会从module
字段中解析文件。
因此,我们只需要这样配置该字段即可解决我们的问题:
mainFields: ["main"]
何时这样配置
讲这个问题之前,我们需要先了解下package.json
中module字段的含义和作用,推荐一篇文章,关于这个字段讲的十分的详细:package.json 中的 Module 字段是干嘛的
为了方便我们在babel
中进行js文件转换的时候,放心大胆的屏蔽掉node_modules
中的js文件以增快编译的速度,一般建议mdule字段指向的采用es模块方案的js文件,在编码语法上使用es5的语法。但是有的包并没有这样做,比如Three.js
,module指向的文件采用es的模块化方案,并且编码也是采用的es6的语法。这样我们在babel中就不能屏蔽掉编译node_modules
里面的js文件,减慢了编译的速度。
为了解决这种问题,我们用到文章标题中提到的方案问题,那就是:在webpack的配置中配置默认解析main字段指向的js文件,这样我们在babel
配置中,可以继续屏蔽掉node_modules
文件夹里面的js文件。