谈谈webpack对npm模块导入的解析

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 问题描述 在一次运营后台的常规更新时,发现有一个外部依赖包不能正常工作。经排查发现,react-split-pane在前几天发了一个新版0.1.81,该版本同时提供commonjs和es module两种包导入方式:   原来我们采用的CMD写法 const ReactSplitPane = require('react-split-pane') 失效了。 

问题描述

在一次运营后台的常规更新时,发现有一个外部依赖包不能正常工作。经排查发现,react-split-pane在前几天发了一个新版0.1.81,该版本同时提供commonjses module两种包导入方式:
 
原来我们采用的CMD写法 const ReactSplitPane = require('react-split-pane') 失效了。 
 

原因分析

 
翻查webpack官方文档后,发现webpack会对包导入会进行解析,不管是采用CMD方式还是ES6 import方式。 解析的依据是配文件的 resolve.mainFields 属性, 该属性用于配置采用package.json的哪个字段作为模块的入口文件。
 
以react-split-pane 模块为例,当 resolve.mainFields = ['browser', 'module', 'main'] 时 , webpack在解析 如 const ReactSplitPane = require('react-split-pane')
import ReactSplitPane from 'react-split-pane' 的时候,会优先使用 dist/index.esm.js 。 由于采用
export default 导出的模块必须使用 import x from 'xx' 的方式(或 使用 const x = require('x').default的方式) 导入, 否则导入后的模块会引用不正确.
 
如果 resolve.mainFiels 没有显式指定,则根据webpack的 target 的取值来决定其默认值
 
  • 当 target的值为 webworkerweb 或者没有指定时,mainFields = ['browser', 'module', 'main']
  • 当 target 为其他任意值(包括node), mainFields = ['module', 'main']
 

后续

 
随着ES6的普及,相信会有越来越多的第三方模块提供 es module 版本,而mainFields的默认值中, module 总是排在 main之前 ,因此类似的问题还会发生。要从根本上解决这个问题,有以下的办法
 
  • 借助 js-codemod等工具,将所有对第三方模块的导入方式 从commonjs 方式改成 ES6 import方式。 因为采用module.exports= .. 导出的包均可以使用import x from '...' 的方式导入,但export default x 导出的包不能直接用require('x')导入.
  • 显式指定mainFields , 把main的优先级提高 或干脆不使用es module。但这种做法无法利用webpack提供的tree shaking 能力减少构建后bundle的体积, 也无法用上一些浏览器已支持的es6特性
  • 利用npm shrinkwrap锁定包版本,缺点是无法及时享受依赖bugfix更新
目录
相关文章
|
29天前
|
SQL 关系型数据库 MySQL
数据库导入SQL文件:全面解析与操作指南
在数据库管理中,将SQL文件导入数据库是一个常见且重要的操作。无论是迁移数据、恢复备份,还是测试和开发环境搭建,掌握如何正确导入SQL文件都至关重要。本文将详细介绍数据库导入SQL文件的全过程,包括准备工作、操作步骤以及常见问题解决方案,旨在为数据库管理员和开发者提供全面的操作指南。一、准备工作在导
141 0
|
1月前
|
XML 数据格式 开发者
解析数据的Beautiful Soup 模块(一)
解析数据的Beautiful Soup 模块(一)
|
1月前
|
前端开发 Python
解析数据的Beautiful Soup 模块(二)
解析数据的Beautiful Soup 模块(二)
|
2月前
|
编解码 开发工具 UED
QT Widgets模块源码解析与实践
【9月更文挑战第20天】Qt Widgets 模块是 Qt 开发中至关重要的部分,提供了丰富的 GUI 组件,如按钮、文本框等,并支持布局管理、事件处理和窗口管理。这些组件基于信号与槽机制,实现灵活交互。通过对源码的解析及实践应用,可深入了解其类结构、布局管理和事件处理机制,掌握创建复杂 UI 界面的方法,提升开发效率和用户体验。
147 12
|
18天前
|
JSON 前端开发 JavaScript
前端模块打包器的深度解析
【10月更文挑战第13天】前端模块打包器的深度解析
|
18天前
|
缓存 前端开发 JavaScript
Webpack技术深度解析:模块打包与性能优化
【10月更文挑战第13天】Webpack技术深度解析:模块打包与性能优化
|
19天前
|
缓存 资源调度 JavaScript
npx与npm的差异解析,以及包管理器yarn与Node版本管理工具nvm的使用方法详解
npx与npm的差异解析,以及包管理器yarn与Node版本管理工具nvm的使用方法详解
25 0
|
1月前
|
JSON API 开发者
深入解析Python网络编程与Web开发:urllib、requests和http模块的功能、用法及在构建现代网络应用中的关键作用
深入解析Python网络编程与Web开发:urllib、requests和http模块的功能、用法及在构建现代网络应用中的关键作用
15 0
|
1月前
|
移动开发 网络协议 C语言
详解 httptools 模块,一个 HTTP 解析器
详解 httptools 模块,一个 HTTP 解析器
22 0
|
3月前
|
图形学 C#
超实用!深度解析Unity引擎,手把手教你从零开始构建精美的2D平面冒险游戏,涵盖资源导入、角色控制与动画、碰撞检测等核心技巧,打造沉浸式游戏体验完全指南
【8月更文挑战第31天】本文是 Unity 2D 游戏开发的全面指南,手把手教你从零开始构建精美的平面冒险游戏。首先,通过 Unity Hub 创建 2D 项目并导入游戏资源。接着,编写 `PlayerController` 脚本来实现角色移动,并添加动画以增强视觉效果。最后,通过 Collider 2D 组件实现碰撞检测等游戏机制。每一步均展示 Unity 在 2D 游戏开发中的强大功能。
150 6

推荐镜像

更多