网易首页 > 网易号 > 正文 申请入驻

10分钟学习webpack

0
分享至

什么是 webpack?

webpack 是一款为现代 JavaScript 应用设计的静态资源打包工具。

作为 JavaScript 工程师,我们知道模块是什么,但是在 webpack 中稍微有些不同。它们可以是:

● ES 模块 - import 语句

● Common JS 模块 - require() 语句

● AMD 模块 - define 和 require 语句

● CSS 文件 - 在 css/sass/less 文件中的 @import 语句

● 图片 URL - url(...) 或

webpack 把这些不同的模块进行了统一处理,可以把它们导入到 JavaScript 代码里。

我应该学习 webpack 吗?

现在大多数应用是用 React/Vue 或其他框架编写的。它们提供了命令行工具(如 create-react-app,@vue/cli)来创建应用。这些命令行工具简化了大部分的配置,提供了默认的配置。但是我们作为开发者,理解它的工作原理是必要的,因为我们早晚都需要修改一些默认的配置。

开始学习

我们会创建一个简单的应用来展示 webpack 的用法。首先新建一个目录并初始化一个 npm 项目。假设你进入了新建的目录,在命令行中执行:

现在安装所需的webpack包:

打开 package.json 文件,删除其中的 test 脚本命令,然后增加一个新的脚本命令 dev 以在开发模式下运行 webpack。我们在本地开发测试时需要用到这个命令。现在你的 package.json 文件看起来如下:

如果现在你运行 npm run dev,会遇到一个烦人的报错:Entry module not found。这是因为默认情况,webpack 会使用 src/index.js 这个文件作为入口。此外,webpack 在默认情况下把打包后的文件输出到名为 dist 的目录里。

好了,现在我们创建一个目录 src 并在里面新建一个文件 index.js。现在我们暂时在这个文件里只写一句 console.log(‘hello’)。这样我们就可以解决这个报错。

现在再运行 npm run dev,这次不会遇到错误,同时你会发现打包后的文件 main.js 出现在了名为 dist 的目录里。

配置 webpack

要配置 webpack,你需要在项目的根目录里含有一个名为 webpack.config.js 的配置文件。在此文件中,我们需要导出一个配置对象。

一些最常用到的术语有:

● Entry point - 指定 webpack 的入口,从此入口找到的所有模块依赖都会收集起来。这些依赖关系构成了依赖图谱。

● Output - 用于指定输出的 JS 和静态文件存放的位置。

● Loaders - 帮助 webpack 处理各种文件后缀的第三方扩展。它们会把非 JS 文件转化为模块。

● Plugins - 可以修改 webpack 行为的第三方扩展。

● Mode - 用于指定两种模式,开发模式和线上模式。默认是线上模式。

现在我们配置一下入口和输出的目录。

修改入口

如果我们想让 webpack 以 source/index.js 作为入口,而不是默认的 src/index.js 文件。需要在导出的对象里增加一个名为 entry 的属性。

也可以这样写:

修改输出的目录

假设我们想把打包的文件输出到另一个名为 build 的目录里,而不是默认的 dist 目录。我们这样设置 output 属性如下:

在 HTM 文件里引入打包后的文件

在每个 web 应用里,至少有一个 HTML 文件。要实现这个目标,我们需要用到一个名为 html-webpack-plugin 的插件。首先执行如下命令安装插件:

这个插件究竟是干什么的?

它会加载我们的 HTML 文件,然后把打包的文件注入到 HTML 页面里。

我们先新建一个简单的 HTML 文件 index.html 放在 source 目录中,在里面填写一些简单的示例代码。现在修改我们的 webpack 配置如下:

这样文件已经就绪了,我们需要一个服务器来展示这个页面。现在可以用 webpack-dev-server 来启动服务器,我们已经在之前的步骤中安装好了。

Webpack dev server

要配置 webpack-dev-server,我们需要打开 package.json 文件,然后增加一个新的脚本命令来启动服务器。例如,我们增加一个名为 start 的命令如下:

现在在命令行执行这个命令:

打开浏览器访问 localhost:8080,你会看到我们的 index.html 文件,打开浏览器的开发者工具可以看到打包后的 main.js 已经嵌入到了此文件中。

使用 webpack 加载器

如前所述,webpack中的加载器是处理各种其他文件后缀的第三方扩展。webpack有很多加载器可供使用。

让我们继续在webpack配置文件中配置加载器。 module 字段里有一个 rules 的属性,它是一个由加载器组成的数组。对于想要作为模块处理的文件,我们需要把它们作为对象放在 rules 数组里。每个对象由两个属性组成:test 定义文件的类型,use 是一个由加载器组成的数组。需要注意的是在 use 数组里的加载器是从右向左加载的。定义加载器时的顺序很重要。建议使用加载器前阅读对应的文档。

在配置文件中加载器的配置句法类似于这样:

处理 CSS

为了能在 webpack 中处理 CSS,我们需要两个加载器:css-loader 和 style-loader。首先在命令行中安装它们:

我们在 source 目录中新建一个 styles.css 文件,然后添加一些样式,在构建完成后会应用到 index.html 中。接下来我们要在 index.js 文件中引入它,而不是在 index.html 中。所以现在 index.js 看起来如下:

还有最后一步要做,那就是在 webpack.config.js 中配置加载器。我们的配置文件如下:

css-loader 用于加载 CSS 文件,而 style-loader 用于在 DOM 中加载样式。

重新运行 npm start,可以在浏览器中看到变化:

处理 SASS 文件

要处理 SASS(.scss) 文件,我们需要三个加载器:sass-loader,css-loader 和 style-loader,此外还需要一个 NPM 包 sass。这里的 sass-loader 用于导入 SASS 文件。由于另外两个加载器已安装,现在只需安装其他包即可。

我们在 source 目录下新建 styles.scss 文件,然后增加如下代码。

接下来修改 index.js 文件,在文件的开头使用 import ‘./styles.scss’ 导入此文件。

现在 webpack.config.js 中增加加载器。我们的加载器看起来如下:

重启服务器,检查一下页面是否发生了变化。

处理现代 JavaScript 句法

Webpack 自身不知道如何把现代 JavaScript 句法转成所有浏览器支持的格式。所以它使用了 Babel 来解决这个问题。我们需要安装如下包:@babel/core,它是实际的处理引擎;babel-loader,是webpack使用的加载器;@babel-preset-env 用于把 JavaScript 代码转成 ES5。我们运行如下命令安装依赖包:

下一步是配置 Babel,我们需要在项目根目录新增一个文件 babel.config.json。在这里,我们配置 Babel 使用刚安装的 preset-env:

然后在 webpack.config.js 文件里增加我们刚安装的加载器。

现在我们的 JS 代码中使用 ES6 句法,然后运行 npm run dev 重新构建,可以在生成的 main.js 里看到已经自动转换成了浏览器支持的 ES5 代码。

在 webpack 里指定模式

在 webpack 里有两种模式:开发模式和线上模式。

在开发模式下,不会执行代码压缩。webpack 只是把我们编写的 JS 直接加载入浏览器中,所以在浏览器中刷新应用很快。

在线上模式下,webpack 会做很多优化。它会自动使用 terser-webpack-plugin 来压缩代码减少打包后文件的体积。还会设置 process.env.NODE_ENV 为 production。这个环境变量很有用,我们可以根据不同的执行环境切换不同的任务。

要在线上模式下使用 webpack,让我们增加另外一个脚本命令到 package.json 文件里,我们把它命名为 build。现在脚本命令看起来如下:

优化 - 代码分拆

代码分拆或延迟加载是一项优化技术,用来避免包文件体积过大,也可以避免依赖重复打包。采用此机制后,我们可以按需加载代码,例如当用户点击一个按钮时,路由变化时。代码片段也称之为 chunk。

在 webpack 中如果打包后文件体积超过 244KB 可能会出现警告信息。有三种方式可以在 webpack 中实现代码分拆:

1. 配置多个入口文件

2. 使用 optimization.splitChunks

3. 动态导入

第一种方法对于小型项目很合适,但是对于复杂项目不够灵活。在 webpack 的配置文件中指定多个入口即可。

使用 optimization.splitChunks

有时候我们需要在web应用里用到很多依赖。例如,我们要使用一个流行的日期库 Moment。我选择这个库是因为它有点大。让我们安装它然后在 index.js 中导入它,然后运行 build 命令。

Moment 会成功安装。现在 index.js 中导入这个库。

现在运行 build 命令。

你会在终端看到这个警告信息:

我们该怎么解决这个问题呢?很简单。让我们在 webpack 配置文件中增加一个 optimization 以及另一个名为 splitChunks 的属性:

你会发现入口文件的体积极大得缩小了。

动态导入

动态导入用于按条件加载代码。这种方式广泛用于 React 和 Vue 项目里。我们可以基于用户操作或者路由改变加载代码。

为了演示这种方式,我们在页面上增加一个按钮,点击后会查询获得一个帖子列表。用于查询的代码放在另一个单独的文件里,然后在 index.js 中动态导入它。

在 source 目录下新建一个 api.js 文件,在里面使用 fetch API 查询帖子列表。在这个文件中,我们导出一个函数,这个函数调用后返回一个 promise。

我们在 index.html 中增加一个按钮,设置它的 id 为 btn。

在 index.js 文件里,使用一个函数来动态导入 api.js 文件。

此外,在 index.js 的结尾增加这段逻辑记录获取的数据。

这段代码调用 getTodos 函数,会导入这个文件。在导入之后,我们从中解构出 fetchTodos 属性,调用此函数,然后成功后记录响应值。

我们编译文件,运行服务器,确保开发者工具是开启的并切换到其中的 Network 面板。你会发现点击后这个新建的 JS文件被动态加载了。

图片中的 0.main.js 就是那个被动态加载的文件。如果你想让这个文件名更可读,只需要在动态加载时增加一个注释即可:

现在再次重复这个过程,浏览器会加载名为 postAPI.js 的文件,而不是 0.main.js。

结语

这只是 webpack 的一个简单的介绍。就像我们之前说的,这篇文章主要是写给开始学习 webpack 的初中级 web 开发工程师的。当然了,在 webpack 中有许多可以学习的知识点。我们只是过了一下最基础的部分。如果你对 webpack 感兴趣,想学习更多内容,请参考 webpack 官方文档。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
1923年国民党警察厅长帮毛主席脱险,后进京谋职,主席安排真罕见

1923年国民党警察厅长帮毛主席脱险,后进京谋职,主席安排真罕见

野史日记
2024-06-07 17:42:08
突发!全国多家档口集体跑路,警方查封,受害人维权曝内幕!

突发!全国多家档口集体跑路,警方查封,受害人维权曝内幕!

古希腊掌管松饼的神
2024-06-07 17:52:01
2024年高考数学难度:现场的学生直呼简单,120分以上轻而易举!

2024年高考数学难度:现场的学生直呼简单,120分以上轻而易举!

智学园
2024-06-07 23:35:06
刘纪鹏:它是兴风作浪的“妖精” 掠夺民财的“害人精” 谁敢进?

刘纪鹏:它是兴风作浪的“妖精” 掠夺民财的“害人精” 谁敢进?

鲁八两
2024-06-07 13:39:06
乌以反目成仇!泽连斯基承认巴勒斯坦是国家:将全力制止以色列

乌以反目成仇!泽连斯基承认巴勒斯坦是国家:将全力制止以色列

兵说
2024-06-06 23:37:35
军火巨头纷纷入台,赖清德态度大变,下死命令,不愿再对大陆手软

军火巨头纷纷入台,赖清德态度大变,下死命令,不愿再对大陆手软

千里持剑
2024-06-04 15:29:05
惨不忍睹!直击江西车祸现场,孕妇和孩子双亡,司机身份曝光。

惨不忍睹!直击江西车祸现场,孕妇和孩子双亡,司机身份曝光。

小毅讲历史
2024-06-07 19:33:50
笑不活了!老板看王心凌演唱会发了8条朋友圈,被笑话了两天!

笑不活了!老板看王心凌演唱会发了8条朋友圈,被笑话了两天!

有趣的羊驼
2024-06-06 14:25:48
董宇辉:我种地的父母长期被那些商家骚扰,直播这活我都想不干了

董宇辉:我种地的父母长期被那些商家骚扰,直播这活我都想不干了

映射生活的身影
2024-06-07 22:39:53
董军离开前,改变对台军称呼,岛内传出投降声,张亚中预测结局

董军离开前,改变对台军称呼,岛内传出投降声,张亚中预测结局

武事汇
2024-06-05 18:13:14
李妍瑾结婚10个月惊爆婚变,好友甄莉证实:已和老公分开

李妍瑾结婚10个月惊爆婚变,好友甄莉证实:已和老公分开

葫芦哥爱吐槽
2024-06-06 20:05:03
台湾省境内几乎不产石油,大量依赖进口,为何油价却那么低?

台湾省境内几乎不产石油,大量依赖进口,为何油价却那么低?

毒舌混知所
2024-05-29 07:10:13
多伦多大学研究发现,10年以上戒烟者死亡率与从未吸烟者相近

多伦多大学研究发现,10年以上戒烟者死亡率与从未吸烟者相近

米开朗基地
2024-06-06 16:27:31
若中美全面开打,中国在制裁封锁下,究竟能撑多久?

若中美全面开打,中国在制裁封锁下,究竟能撑多久?

兵国大事
2024-06-04 10:14:25
2008年,3岁男孩被拐3年,人群中一眼认出父亲,紧抱住父亲不松手

2008年,3岁男孩被拐3年,人群中一眼认出父亲,紧抱住父亲不松手

今天说故事
2024-04-22 17:22:03
大范围高温将启动,烫伤级地温确定跟随!专家分析:局部或超70度

大范围高温将启动,烫伤级地温确定跟随!专家分析:局部或超70度

中国气象爱好者
2024-06-07 19:23:33
具俊晔情绪难自抑,罕见发脾气!韩网友:说的难道不是事实?

具俊晔情绪难自抑,罕见发脾气!韩网友:说的难道不是事实?

麦香娱综艺
2024-06-06 14:49:21
黑龙江一男子血洗工作单位,暗暗下定决心:没报完仇不能死

黑龙江一男子血洗工作单位,暗暗下定决心:没报完仇不能死

一度历史观
2024-05-13 13:05:13
马步芳窜逃沙特后强娶侄女马月兰,还让马月兰把母亲和妹妹骗过来

马步芳窜逃沙特后强娶侄女马月兰,还让马月兰把母亲和妹妹骗过来

百态人间
2024-06-03 16:50:54
西藏古籍揭秘轮回真相?记载人死49天灵魂不灭,机会只有四次?

西藏古籍揭秘轮回真相?记载人死49天灵魂不灭,机会只有四次?

光头哥的头
2024-01-03 10:16:02
2024-06-08 04:52:49
小象Web开发
小象Web开发
专注于web开发领域
25文章数 910关注度
往期回顾 全部

科技要闻

6家大模型抢答高考作文,谁是你心中的Top1

头条要闻

云南省镇雄县一煤矿发生事故致1死3伤 还有2人失联

头条要闻

云南省镇雄县一煤矿发生事故致1死3伤 还有2人失联

体育要闻

优势在我?中国足球有自己的节奏

娱乐要闻

汤唯抵达巴黎将担任奥运火炬手

财经要闻

身陷退市股的投资者:我的钱瞬间没了

汽车要闻

2.0T混动售20.98万元起 福特蒙迪欧运动版上市

态度原创

家居
本地
时尚
公开课
军事航空

家居要闻

柔和婉转 让阳光洒满空间

本地新闻

我和我的家乡|踏浪营口,心动不止一夏!

接下来几个月,比看赛事更有意思的是......

公开课

近视只是视力差?小心并发症

军事要闻

普京刚说完考虑"不对称"回应西方 俄核潜艇就将抵古巴

无障碍浏览 进入关怀版