0

0

在Webpack中有关优化配置问题

亚连

亚连

发布时间:2018-06-15 15:37:38

|

2054人浏览过

|

来源于php中文网

原创

这篇文章主要介绍了webpack优化-缩小文件搜索范围的相关知识,文中较详细的给大家介绍了可以优化的途径,需要的朋友可以参考下

Webpack 启动后会从配置的 Entry 出发,解析出文件中的导入语句,再递归的解析。

在遇到导入语句时 Webpack 会做两件事情:

1.根据导入语句去寻找对应的要导入的文件。例如 require('react') 导入语句对应的文件是 ./node_modules/react/react.js , require('./util') 对应的文件是 ./util.js 。

2.根据找到的要导入文件的后缀,使用配置中的 Loader 去处理文件。例如使用 ES6 开发的 JavaScript 文件需要使用 babel-loader 去处理。

以上两件事情虽然对于处理一个文件非常快,但是当项目大了以后文件量会变的非常多,这时候构建速度慢的问题就会暴露出来。

虽然以上两件事情无法避免,但需要尽量减少以上两件事情的发生,以提高速度。

接下来一一介绍可以优化它们的途径。

优化 loader 配置

由于 Loader 对文件的转换操作很耗时,需要让尽可能少的文件被 Loader 处理。

在 2-3 Module 中介绍过在使用 Loader 时可以通过 test 、 include 、 exclude 三个配置项来命中 Loader 要应用规则的文件。

为了尽可能少的让文件被 Loader 处理,可以通过 include 去命中只有哪些文件需要被处理。

以采用 ES6 的项目为例,在配置 babel-loader 时,可以这样:

module.exports = {
 module: {
  rules: [
   {
    // 如果项目源码中只有 js 文件就不要写成 /\.jsx?$/,提升正则表达式性能
    test: /\.js$/,
    // babel-loader 支持缓存转换出的结果,通过 cacheDirectory 选项开启
    use: ['babel-loader?cacheDirectory'],
    // 只对项目根目录下的 src 目录中的文件采用 babel-loader
    include: path.resolve(__dirname, 'src'),
   },
  ]
 },
};

你可以适当的调整项目的目录结构,以方便在配置 Loader 时通过 include 去缩小命中范围。

优化 resolve.modules 配置

在 2-4 Resolve 中介绍过 resolve.modules 用于配置 Webpack 去哪些目录下寻找第三方模块。

resolve.modules 的默认值是 ['node_modules'] ,含义是先去当前目录下的 ./node_modules 目录下去找想找的模块,如果没找到就去上一级目录 ../node_modules 中找,再没有就去 ../../node_modules 中找,以此类推,这和 Node.js 的模块寻找机制很相似。

当安装的第三方模块都放在项目根目录下的 ./node_modules 目录下时,没有必要按照默认的方式去一层层的寻找,可以指明存放第三方模块的绝对路径,以减少寻找,配置如下:

module.exports = {
 resolve: {
  // 使用绝对路径指明第三方模块存放的位置,以减少搜索步骤
  // 其中 __dirname 表示当前工作目录,也就是项目根目录
  modules: [path.resolve(__dirname, 'node_modules')]
 },
};

优化 resolve.mainFields 配置

在 2-4 Resolve 中介绍过 resolve.mainFields 用于配置第三方模块使用哪个入口文件。

安装的第三方模块中都会有一个 package.json 文件用于描述这个模块的属性,其中有些字段用于描述入口文件在哪里, resolve.mainFields 用于配置采用哪个字段作为入口文件的描述。

可以存在多个字段描述入口文件的原因是因为有些模块可以同时用在多个环境中,准对不同的运行环境需要使用不同的代码。

以 isomorphic-fetch 为例,它是 fetch API 的一个实现,但可同时用于浏览器和 Node.js 环境。

它的 package.json 中就有2个入口文件描述字段:

{
 "browser": "fetch-npm-browserify.js",
 "main": "fetch-npm-node.js"
}

isomorphic-fetch 在不同的运行环境下使用不同的代码是因为 fetch API 的实现机制不一样,在浏览器中通过原生的 fetch 或者 XMLHttpRequest 实现,在 Node.js 中通过 http 模块实现。

resolve.mainFields 的默认值和当前的 target 配置有关系,对应关系如下:

  • 当 target 为 web 或者 webworker 时,值是 ["browser", "module", "main"]

  • 当 target 为其它情况时,值是 ["module", "main"]

以 target 等于 web 为例,Webpack 会先采用第三方模块中的 browser 字段去寻找模块的入口文件,如果不存在就采用 module 字段,以此类推。

为了减少搜索步骤,在你明确第三方模块的入口文件描述字段时,你可以把它设置的尽量少。

由于大多数第三方模块都采用 main 字段去描述入口文件的位置,可以这样配置 Webpack:

module.exports = {
 resolve: {
  // 只采用 main 字段作为入口文件描述字段,以减少搜索步骤
  mainFields: ['main'],
 },
};

使用本方法优化时,你需要考虑到所有运行时依赖的第三方模块的入口文件描述字段,就算有一个模块搞错了都可能会造成构建出的代码无法正常运行。

优化 resolve.alias 配置

在 2-4 Resolve 中介绍过 resolve.alias 配置项通过别名来把原导入路径映射成一个新的导入路径。

在实战项目中经常会依赖一些庞大的第三方模块,以 React 库为例,安装到 node_modules 目录下的 React 库的目录结构如下:

行业贸易网站管理系统 2007 Beta 1
行业贸易网站管理系统 2007 Beta 1

1.修正BUG站用资源问题,优化程序2.增加关键词搜索3.修改报价4.修正BUG 水印问题5.修改上传方式6.彻底整合论坛,实现一站通7.彻底解决群发垃圾信息问题。注册会员等发垃圾邮件7.彻底解决数据库安全9.修改交易方式.增加网站担保,和直接交易两中10.全站可选生成html.和单独新闻生成html(需要装组建)11. 网站有10中颜色选择适合不同的行业不同的颜色12.修改竞价格排名方式13.修

下载

├── dist
│   ├── react.js
│   └── react.min.js
├── lib
│   ... 还有几十个文件被忽略
│   ├── LinkedStateMixin.js
│   ├── createClass.js
│   └── React.js
├── package.json
└── react.js

可以看到发布出去的 React 库中包含两套代码:

  • 一套是采用 CommonJS 规范的模块化代码,这些文件都放在 lib 目录下,以 package.json 中指定的入口文件 react.js 为模块的入口。

  • 一套是把 React 所有相关的代码打包好的完整代码放到一个单独的文件中,这些代码没有采用模块化可以直接执行。其中 dist/react.js 是用于开发环境,里面包含检查和警告的代码。 dist/react.min.js 是用于线上环境,被最小化了。

默认情况下 Webpack 会从入口文件 ./node_modules/react/react.js 开始递归的解析和处理依赖的几十个文件,这会时一个耗时的操作。

通过配置 resolve.alias 可以让 Webpack 在处理 React 库时,直接使用单独完整的 react.min.js 文件,从而跳过耗时的递归解析操作。

相关 Webpack 配置如下:

module.exports = {
 resolve: {
  // 使用 alias 把导入 react 的语句换成直接使用单独完整的 react.min.js 文件,
  // 减少耗时的递归解析操作
  alias: {
   'react': path.resolve(__dirname, './node_modules/react/dist/react.min.js'),
  }
 },
};

除了 React 库外,大多数库发布到 Npm 仓库中时都会包含打包好的完整文件,对于这些库你也可以对它们配置 alias。
但是对于有些库使用本优化方法后会影响到后面要讲的 使用 Tree-Shaking 去除无效代码 的优化,因为打包好的完整文件中有部分代码你的项目可能永远用不上。

一般对整体性比较强的库采用本方法优化,因为完整文件中的代码是一个整体,每一行都是不可或缺的。

但是对于一些工具类的库,例如 lodash ,你的项目可能只用到了其中几个工具函数,你就不能使用本方法去优化,因为这会导致你的输出代码中包含很多永远不会执行的代码。

优化 resolve.extensions 配置

在导入语句没带文件后缀时,Webpack 会自动带上后缀后去尝试询问文件是否存在。

在 2-4 Resolve 中介绍过 resolve.extensions 用于配置在尝试过程中用到的后缀列表,默认是:

extensions: ['.js', '.json']

也就是说当遇到 require('./data') 这样的导入语句时,Webpack 会先去寻找 ./data.js 文件,如果该文件不存在就去寻找 ./data.json 文件,如果还是找不到就报错。

如果这个列表越长,或者正确的后缀在越后面,就会造成尝试的次数越多,所以 resolve.extensions 的配置也会影响到构建的性能。

在配置 resolve.extensions 时你需要遵守以下几点,以做到尽可能的优化构建性能:

  • 后缀尝试列表要尽可能的小,不要把项目中不可能存在的情况写到后缀尝试列表中。

  • 频率出现最高的文件后缀要优先放在最前面,以做到尽快的退出寻找过程。

  • 在源码中写导入语句时,要尽可能的带上后缀,从而可以避免寻找过程。例如在你确定的情况下把 require('./data') 写成 require('./data.json') 。

相关 Webpack 配置如下:

module.exports = {
 resolve: {
  // 尽可能的减少后缀尝试的可能性
  extensions: ['js'],
 },
};

优化 module.noParse 配置

在 2-3 Module 中介绍过 module.noParse 配置项可以让 Webpack 忽略对部分没采用模块化的文件的递归解析处理,这样做的好处是能提高构建性能。

原因是一些库,例如 jQuery 、ChartJS, 它们庞大又没有采用模块化标准,让 Webpack 去解析这些文件耗时又没有意义。

在上面的 优化 resolve.alias 配置 中讲到单独完整的 react.min.js 文件就没有采用模块化,让我们来通过配置 module.noParse 忽略对 react.min.js 文件的递归解析处理,

相关 Webpack 配置如下:

const path = require('path');
module.exports = {
 module: {
  // 独完整的 `react.min.js` 文件就没有采用模块化,忽略对 `react.min.js` 文件的递归解析处理
  noParse: [/react\.min\.js$/],
 },
};

注意被忽略掉的文件里不应该包含 import 、 require 、 define 等模块化语句,不然会导致构建出的代码中包含无法在浏览器环境下执行的模块化语句。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在微信小程序中如何获取用户信息(详细教程)

使用百度地图如何去掉marker覆盖物具体该如何解决

在微信小程序中如何实现animation动画

在微信小程序中如何才能获取图片信息

使用百度地图api如何清除指定覆盖物Overlay具体怎么做?

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

15

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

23

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

75

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

95

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

218

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

420

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

168

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

221

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

33

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Webpack4.x---十天技能课堂
Webpack4.x---十天技能课堂

共20课时 | 1.5万人学习

两小时学会 Webpack
两小时学会 Webpack

共14课时 | 1.7万人学习

Node.js-前端工程化必学
Node.js-前端工程化必学

共19课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号