Webpack初学者指南

    Ivaylo Gerchev
    分享

    如今,我们被迫使用许多辅助工具来促进、加速和优化我们的web开发工作流程。但是,这类工具通常会在堆栈中增加额外的复杂性。因此,我们需要利用额外的时间和精力来正确地学习、理解和使用这些工具。同样适用于webpack

    第一次使用webpack时,可能很难理解它是如何工作的以及应该如何使用它。尽管它有很好的文档,但对于新手来说可能会令人生畏,而且它有一个陡峭的学习曲线。然而,webpack是值得学习的,从长远来看可以节省大量的时间和精力。在本教程中,我将介绍所有的核心概念来帮助您入门。

    注意:在本教程中,我使用的是webpack 5.9.0。

    什么是Webpack?

    webpack的核心是一个静态模块捆绑器。在一个特定的项目中,webpack将所有文件和资产视为模块。在底层,它依赖于一个依赖关系图。依赖关系图描述了模块如何使用引用(需要而且进口语句)之间的文件。通过这种方式,webpack静态地遍历所有模块来构建图形,并使用它来生成一个包(或几个包)——一个JavaScript文件,其中包含所有模块以正确顺序组合的代码。“静态”的意思是,当webpack构建它的依赖关系图时,它不执行源代码,而是将模块和它们的依赖关系拼接成一个包。然后可以将其包含在HTML文件中。

    现在,为了扩展上述粗略的概述,让我们来探索webpack使用的主要概念。

    Webpack主要概念

    Webpack有一些主要的概念,在深入研究它的实际实现之前,我们需要清楚地了解这些概念。让我们来逐一分析一下:

    • 条目:入口点是webpack用来开始构建内部依赖关系图的模块。从那里,它确定入口点(直接或间接)依赖于哪些其他模块和库,并将它们包含在图中,直到没有依赖关系。默认情况下,条目属性设置为/ src / index.js,但是我们可以在webpack配置文件中指定一个不同的模块(甚至多个模块)。
    • 输出: output属性指示webpack在哪里发出bundle,以及为文件使用什么名称。此属性的默认值为/ dist / main.js对于主包和/ dist。对于其他生成的文件,例如图像。当然,我们可以根据需要在配置中指定不同的值。
    • 加载器:默认情况下,webpack只理解JavaScript和JSON文件。为了处理其他类型的文件并将它们转换为有效的模块,webpack使用了加载器。加载器转换非javascript模块的源代码,允许我们在将这些文件添加到依赖关系图之前对它们进行预处理。例如,加载器可以将文件从CoffeeScript语言转换为JavaScript,或将内联图像转换为数据url。使用加载器,我们甚至可以直接从JavaScript模块导入CSS文件。
    • 插件:插件用于加载器不能做的任何其他任务。他们为我们提供了关于资产管理、捆绑包最小化和优化等广泛的解决方案。
    • 模式:通常,当我们开发应用程序时,我们使用两种类型的源代码——一种用于开发版本,另一种用于生产版本。Webpack允许我们通过改变mode参数来设置我们想要生产哪一个发展生产没有一个.这允许webpack使用相应于每个环境的内置优化。默认值为生产.的没有一个模式意味着不使用默认优化选项。以了解更多关于webpack在发展而且生产模式,访问模式配置页面

    Webpack如何工作

    在本节中,我们将研究webpack是如何工作的。即使是一个简单的项目也包含HTML、CSS和JavaScript文件。此外,它还可以包含字体、图像等资产。所以,一个典型的webpack工作流将包括设置一个index . html文件和适当的CSS和JS链接,以及必要的资产。此外,如果你有许多相互依赖的CSS和JS模块,它们需要被优化并适当地组合在一个单元中,以便生产。

    要做到这一切,webpack依赖于配置。从版本4及以上开始,webpack提供了合理的开箱即用的默认值,因此不需要创建配置文件。然而,对于任何重要的项目,你需要提供一个特殊的webpack.config.js文件,它描述了应该如何转换文件和资产,以及应该生成什么样的输出。这个文件很快就会变成一个整体,这使得你很难理解webpack是如何工作的,除非你知道它工作背后的主要概念。

    基于提供的配置,webpack从入口点开始,解析它在构建依赖关系图时遇到的每个模块。如果模块包含依赖项,则对每个依赖项递归执行该过程,直到遍历完成。然后webpack将项目的所有模块捆绑成少量的包——通常只有一个——由浏览器加载。

    Webpack 5有什么新功能

    webpack 5发行版是在2020年10月宣布的.这篇文章很长,探讨了webpack的所有变化。不可能提到所有的变化,对于这样的初学者指南来说,这是不必要的。相反,我将试着列出一个小列表,其中有一些一般的亮点:

    • 使用持久缓存可以提高构建性能。开发人员现在可以启用基于文件系统的缓存,这将加快开发构建的速度。
    • 长期缓存也得到了改进。在webpack 5中,对不影响最小化bundle版本(注释,变量名)的代码所做的更改不会导致缓存失效。此外,还添加了新的算法,以确定的方式将短数字id分配给模块和块,并将短名称分配给导出。在webpack 5中,它们在生产模式下默认启用。
    • 改进了包的大小,这要归功于更好的摇树和代码生成。多亏了新的嵌套摇树特性,webpack现在能够跟踪对导出的嵌套属性的访问。CommonJs树摇动允许我们消除未使用的CommonJs导出。
    • 支持的Node.js最低版本从6增加到10.13.0 (LTS)。
    • 代码库被清理。所有在webpack 4中标记为弃用的项目都被移除。
    • 自动Node.js填充被移除。之前版本的webpack包含了本地Node.js库的腻子加密.在许多情况下,它们是不必要的,并且会极大地增加包的大小。这就是为什么webpack 5不再自动填充这些核心模块,而是专注于前端兼容模块。
    • 作为开发的一个改进,webpack 5允许我们传递一个目标列表,也支持目标的版本。它提供了公共路径的自动确定。此外,它提供了自动的、唯一的命名,这可以防止多个webpack运行时使用相同的全局变量进行块加载之间的冲突。
    • webpack-dev-server命令就是现在webpack服务
    • 资产模块分别介绍一下,哪些替代的用途file-loaderraw-loader,url-loader

    请打开上面的公告链接,以查找有关所有更新的更完整和详细信息。

    最后,如果你来自webpack 4,这里是迁移向导

    开始

    注意:您可以在GitHub回购

    既然我们有了坚实的理论基础,我们就把它付诸实践吧。

    首先,我们将创建一个新目录并切换到它。然后我们将初始化一个新项目:

    mkdirlearn-webpackcdlearn-webpacknpminit - y

    接下来,我们需要在本地安装webpack和webpack CLI(命令行接口):

    npm安装Webpack -cli—save-dev

    现在,内容生成了package.json应类似于以下内容:

    “名称”“learn-webpack”“版本”“1.0.0”“描述”""“主要”“index.js”“脚本”“测试”"echo \"错误:没有指定测试\" && exit 1"“关键词”“作者”""“许可证”“ISC”“devDependencies”“webpack”“^ 5.9.0”“webpack-cli”“^ 4.2.0”

    除了作为一个包装经理,npm可以用作简单的任务运行器。创建webpack任务的方法是在脚本部份package.json文件。让我们现在试试这个。开放package.json然后改变脚本反对以下内容:

    “脚本”“测试”"echo \"错误:没有指定测试\" && exit 1"“开发”webpack模式开发“构建”webpack模式生产

    脚本财产,npm允许我们通过名称引用本地安装的Node.js包。我们用它和——模式要定义的标志dev而且构建任务,将在开发中运行webpack (运行开发)和生产(NPM运行构建)模式。

    在测试刚刚创建的任务之前,让我们先创建一个src目录,并将index.js文件,以便它包含console.log(“你好,Webpack !”);.现在我们已经可以运行dev以开发模式启动webpack的任务:

    npm运行开发>learn-webpack@1.0.0 dev C:WEBDEVlearn-webpack>Webpack模式开发webpack-cli编译完成的资产main.js874字节发出名称:主要/ src / index.js31字节生成的代码webpack5.9.0编译成功122女士

    正如我前面提到的,webpack将默认入口点设置为/ src / index.js和默认输出到/ dist / main.js.webpack在运行dev任务是获取源代码index.js文件并将最终代码打包到main.js文件。

    太棒了!它像预期的那样工作。但是为了验证我们得到了正确的输出,我们需要在浏览器中显示结果。要做到这一点,让我们创建一个index . html经销目录:

    <!文档类型超文本标记语言><超文本标记语言><><标题>Webpack入门标题>><身体><脚本srcmain.js>脚本>身体>超文本标记语言>

    现在,如果我们在浏览器中打开该文件,我们应该会看到你好,Webpack !消息。

    显示Webpack控制台消息"loading=

    到目前为止,一切顺利。但是写我们index . html手动文件在某些情况下可能会有问题。例如,如果我们改变了入口点的名称,生成的bundle将被重命名,但是我们的index . html文件仍将引用旧名称。因此,每次重命名入口点或添加新入口点时,我们都需要手动更新HTML文件。幸运的是,我们可以使用html-webpack-plugin.让我们现在安装它:

    npm安装html-webpack-plugin@next——save-dev

    注意:注意我已经输入了html-webpack-plugin@next而不仅仅是html-webpack-plugin.在撰写本文时,前者是webpack 5的合适版本,后者是webpack 4的合适版本。这在将来可能会更改,因此对于实际版本,请检查html-webpack-plugin回购

    此时,要激活插件,我们需要创建一个webpack.config.js根目录下的文件,内容如下:

    常量HtmlWebpackPlugin需要“html-webpack-plugin”常量路径需要“路径”模块出口插件HtmlWebpackPlugin标题“Webpack输出”

    如您所见,要激活webpack插件,我们需要将其包含在文件中,然后将其添加到插件数组中。如果需要,我们还将选项传递给插件。看到html-webpack-plugin回购的所有可用选项还有能力编写并使用自己的模板

    现在让我们运行webpack看看会发生什么:

    npm运行开发>learn-webpack@1.0.0 dev C:WEBDEVlearn-webpack>Webpack模式开发webpack-cli编译完成的资产main.js874字节相比发出名称:主要资产index . html234字节发出/ src / index.js31字节生成的代码webpack5.9.0编译成功151女士

    让我们打开index . html.正如我们所看到的,插件自动创建了一个updatedindex . html文件,它使用标题选项从配置:

    <!文档类型超文本标记语言><超文本标记语言><><字符集utf - 8><标题>Webpack输出标题><的名字视窗内容宽度=设备宽度,初始= 1><脚本推迟srcmain.js>脚本>><身体>身体>超文本标记语言>

    对象的自定义名称条目而且输出属性。在webpack.config.js的前面添加了以下内容插件属性:

    条目主要路径解决__dirname“/ src / app.js。”输出文件名“[名字].bundle.js”路径路径解决__dirname“部署”

    在这里,我们将条目文件更改为app.js和输出文件夹到部署.我们还稍微调整了一下生成的包文件的名称。现在,它将以条目的名称(“main”)开头,后面跟着单词“bundle”和. js文件扩展名。

    现在,我们要创建一个src / component.js文件:

    出口默认的文本“你好,Webpack !”= >常量元素文档createElement“标题”元素innerHTML文本返回元素

    接下来,我们重命名index.jsapp.js为反映我们的变化,将其内容替换为以下内容:

    进口组件”。/组件的文档身体列表末尾组件

    现在,让我们再次运行webpack:

    npm运行开发>learn-webpack@1.0.0 dev C:WEBDEVlearn-webpack>Webpack模式开发webpack-cli编译完成的资产main.bundle.js4.67简约发出名称:主要资产index . html241字节发出运行时模块668字节3.可缓存模块230字节。/ src / app.js79字节生成的代码/ src / component.js151字节生成的代码webpack5.9.0编译成功194女士

    让我们检查并澄清来自webpack输出的信息。在“编译完成”消息之后,您可以看到在部署目录(main.bundle.js而且index . html).在它们下面,您可以看到源文件:app.js)及其依赖项(component.js).

    现在,在部署文件夹中,我们有新生成的bundle文件main.bundle.js.如果我们打开index . html文件在浏览器中,我们应该看到你好,Webpack !显示在页面中。

    显示Webpack浏览器消息"loading=

    还有,如果我们查一下来源index . html的值src的财产脚本标签被更新为main.bundle.js

    此时,我们可以删除经销文件夹,webpack最初生成的,因为我们不再需要它了。

    将现代JavaScript翻译到ES5

    在本节中,我们将了解如何将ES6转换为兼容es5的代码,并在所有浏览器中都能运行。让我们首先运行以下命令:

    npm执行命令dev -- --devtool inline-source-map

    这里,我运行webpackdevtool选项设置为inline-source-map为了使代码更具可读性。这样我可以更清楚地演示从ES6到ES5的代码转换。

    接下来,让我们打开main.bundle.js

    / * * * /”。/ src / component.js ": /*!**************************!*** ./src/component.js ***!\**************************// * !命名空间导出*// * !导出默认[已提供][无使用信息][缺少使用信息防止重命名]*// * !其他导出[未提供][无使用信息]*// * !运行时要求:__webpack_exports__, __webpack_require__。r, __webpack_require__。d, __webpack_require__。* * //***/ ((__ unused_webpack_module __webpack_exports__ __webpack_require__) = >__webpack_require__.r (__webpack_exports__);/* harmony export */__webpack_require__d__webpack_exports__/* harmony export */“默认”= >__WEBPACK_DEFAULT_EXPORT__/* harmony export *//* harmony默认输出*/常量__WEBPACK_DEFAULT_EXPORT__文本“你好,Webpack !”= >常量元素文档createElement“标题”元素innerHTML文本返回元素/ * * * /

    如您所见,现代ES6特性(箭头函数和常量声明)component.js模块默认情况下不会转换为符合es5的代码。为了让我们的代码在旧的浏览器中工作,我们必须添加Babel加载器:

    npm安装babel loader @babel/core @babel/preset-env——save-dev

    然后,在webpack.config.js添加模块输出属性:

    模块规则测验/美元\ . js/排除/node_modules/使用加载程序“babel-loader”选项预设“@babel / preset-env”

    当我们为webpack加载器定义规则时,通常需要定义三个主要属性:

    • 测验,它描述了应该转换什么类型的文件。
    • 排除,它定义了不应该从加载器处理的文件(如果我们有的话)。
    • 使用,它告诉应该对匹配的模块使用哪个加载器。在这里,我们还可以设置加载器选项,就像我们刚刚对预设选择。

    重新执行如下命令:

    npm执行命令dev -- --devtool inline-source-map

    这一次,代码在main.bundle.js编译:

    / * * * /”。/ src / component.js ": /*!**************************!*** ./src/component.js ***!\**************************// * !命名空间导出*// * !导出默认[已提供][无使用信息][缺少使用信息防止重命名]*// * !其他导出[未提供][无使用信息]*// * !运行时要求:__webpack_exports__, __webpack_require__。r, __webpack_require__。d, __webpack_require__。* * //***/ ((__ unused_webpack_module __webpack_exports__ __webpack_require__) = >__webpack_require__.r (__webpack_exports__);/* harmony export */__webpack_require__d__webpack_exports__/* harmony export */“默认”= >__WEBPACK_DEFAULT_EXPORT__/* harmony export *//* harmony默认输出*/常量__WEBPACK_DEFAULT_EXPORT__函数var文本参数长度>0& &参数0= = !未定义的?参数0“你好,Webpack !”var元素文档createElement“标题”元素innerHTML文本返回元素/ * * * /

    完美的。现在我们可以使用现代的JS特性,webpack将转换我们的代码,以便它可以在旧的浏览器上执行。

    使用样式

    在本节中,我们将看到如何向项目添加一些样式。要做到这一点,我们需要安装两个加载器:

    npm安装Css-loader style-loader——save-dev
    • css-loader将CSS解析为JavaScript并解析任何依赖项
    • style-loader输出我们的CSS到<时尚>标签在HTML文档中。

    让我们添加必要的配置webpack.config.js

    模块规则...测验/美元\ . css/使用“style-loader”“css-loader”

    这里,装载机的顺序很重要。它们以相反的顺序计算——即从右到左,从下到上。在我们的例子中css-loader首先计算,然后是style-loader

    现在,让我们创建一个文件src / style.css

    h1颜色红色的

    然后我们把它导入app.js

    进口”。/ style.css '

    当我们运行webpack (运行开发),然后打开index . html,我们应该看看你好,Webpack !红色的信息。

    应用样式的Webpack浏览器消息"loading=

    资产管理

    大多数情况下,您的项目将包含图像、字体等资产。在webpack 4中,要使用资产,我们必须安装一个或多个以下加载器:file-loaderraw-loader,url-loader.在webpack 5中,正如我们前面看到的,这不再需要了,因为新版本带有内置的资产模块

    在这里,我们将探讨一个带有图像的示例。中添加新规则webpack.config.js

    模块规则...测验/gif \。(?:ico | | png | jpg | jpeg)美元/类型“资产/资源”

    这里是类型资产/资源用来代替file-loader

    现在,为了测试加载器,我们将创建一个image-component.js文件,在src目录,内容如下:

    进口图像”。/ image.png”常量img文档createElement“img”imgsrc图像文档身体列表末尾img

    在这里,我们将图像作为模块导入,并使用它创建一个< img / >标签。要使上面的代码工作,您需要下载图片然后重命名为image.png然后把它放在src目录中。

    下一步是导入我们的图像组件app.js

    进口“。/图片组件”

    瞧。现在,当我们运行webpack (运行开发),然后打开页面,我们应该会看到上图你好,Webpack !消息。

    显示Webpack映像组件"loading=

    如果你看一下部署文件夹现在,你会发现其中生成了三个文件:a1af828b4e65d37668e1.pngmain.bundle.js,index.js.下面是webpack在幕后所做的工作:将图像添加到部署文件夹,并分配了唯一的散列,然后是图像扩展名。然后将图像包含在新生成的图像中main.bundle.js文件作为模块。最后,一个index . html的引用生成文件main.bundle.js文件。

    加速开发过程webpack-dev-server

    目前,每次进行更改时,我们都需要重新构建代码。幸运的是,webpack提供了一个实时重新加载的web服务器,可以自动构建和刷新页面。要安装它,请执行以下命令:

    npm安装webpack-dev-server——save-dev

    我们需要更新我们的dev脚本,在package.json,以使用该服务器:

    “开发”webpack服务模式开发

    现在让我们配置服务器webpack.config.js属性之后添加以下属性输出

    devServercontentBase”。/部署的开放真正的

    这告诉webpack-dev-server来提供文件部署目录,并自动打开入口页面。

    现在,如果运行webpack (运行开发),便可看到网页如何在浏览器上自动打开http://localhost:8080

    注意:运行webpack-dev-server后,您将在部署文件夹(它将为空),因为服务器在编译后不写入任何输出文件。相反,它将包文件保存在内存中,并将它们作为挂载在服务器根路径上的真实文件提供服务。看到webpack开发指南获取更多信息。但是,当您运行构建命令,部署文件夹将按预期填充生成的文件。

    如果我们现在更改任何源文件并保存它们,web服务器将在代码编译后自动重新加载页面。例如,尝试将CSS文件中的color属性更改为绿色,您应该会看到页面中的颜色是如何适当更新的。

    Webpack开发服务器在行动"loading=

    清理输出

    随着我们项目的进展,部署文件夹可能会变得非常混乱。在每次构建时,webpack都会生成包并将它们放在部署文件夹,但它不能跟踪项目实际使用的文件。所以这是一个很好的练习部署文件夹,以便只生成正在使用的文件。为此,我们需要安装和配置clean-webpack-plugin

    npm安装clean-webpack-plugin——save-dev

    webpack.config.js

    常量CleanWebpackPlugin需要“clean-webpack-plugin”...插件...CleanWebpackPlugin

    现在,运行webpack (NPM运行构建),并检查部署文件夹中。您现在应该只看到从构建生成的文件,而没有旧的和未使用的文件。要测试它,请创建一个项目中未使用的简单文本文件,并运行构建脚本了。编译后文件将被删除。

    结论

    Webpack是一个有用而强大的工具。本教程只介绍了核心概念,但是webpack提供了更多的特性、插件和不同的技术来应用它们,随着知识的增长,你可以采用它们。下面是我建议进一步探索webpack功能的资源列表:

    • 官方webpack文档.该文档提供了关于webpack的主要概念和配置的结构化信息,以及您可以在项目中使用的插件和加载器,以及基本指南和API参考。
    • Webpack 5:从学徒到大师.一个完整的手册,深入每个webpack方面。作者:Juho Vepsäläinen, webpack的核心开发者。
    • Webpack:核心概念.webpack的维护者之一Sean Larkin的一个很好的入门视频课程。
    学习正则表达式:初学者指南"></a>
         <div class= 学习正则表达式:初学者指南 迈克尔Wanyoike
    必威西盟体育网页登录SitePoint Premium新发布:Webpack, TensorFlow, Swift & Parcel"></a>
         <div class= 必威西盟体育网页登录SitePoint Premium新发布:Webpack, TensorFlow, Swift & Parcel 乔尔驯鹰人
    介绍FuseBox -一个更快,更简单的webpack替代方案"></a>
         <div class= 介绍FuseBox -一个更快,更简单的webpack替代方案 得到Khoursheed
    使用Babel和webpack创建ES6项目"></a>
         <div class= 使用Babel和webpack创建ES6项目 克里斯·佩里
    观看:使用Webpack转换JSX"></a>
         <div class= 观看:使用Webpack转换JSX 迈克尔•陈
    Baidu