朋友们,美好的一天!
我为您呈现了泰勒·麦金尼斯(Tyler McGinnis)撰写的文章“ Webpack:简要介绍”的译文。
在探索新技术之前,请问自己两个问题:
- 为什么需要此工具?
- 它执行什么任务?
如果您无法回答这些问题,则可能不需要您正在研究的技术。让我们尝试回答有关Webpack的这些问题。
为什么需要Webpack?
Webpack是一个模块构建器。它解析应用程序的模块,创建依赖关系图,然后以正确的顺序将模块组装成一个或多个捆绑包,这些捆绑包可以由“ index.html”文件引用。
App.js -> |
Dashboard.js -> | Bundler | -> bundle.js
About.js -> |
webpack解决什么问题?
通常,在创建JavaScript应用程序时,代码会分为几个部分(模块)。然后,在“ index.html”文件中,必须指定每个脚本的链接。
<body>
...
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="libs/react.min.js"></script>
<script src='src/admin.js'></script>
<script src='src/dashboard.js'></script>
<script src='src/api.js'></script>
<script src='src/auth.js'></script>
<script src='src/rickastley.js'></script>
</body>
这不仅繁琐,而且容易出错。重要的是不仅要忘记任何脚本,而且要以正确的顺序排列它们。如果在加载React本身之前加载依赖于React的脚本,则您的应用程序将中断。Webpack解决了这些问题。您不必担心会依次包含所有脚本。
<body>
...
<script src='dist/bundle.js'></script>
</body>
我们将很快学习到,收集模块只是webpack工作方式的一个方面。如有必要,您可以强制webpack在将其添加到捆绑包之前进行一些模块转换。例如,对于较旧的浏览器,将SASS / LESS转换为常规CSS,或将现代JavaScript转换为ES5。
安装Webpack
使用npm初始化项目后,要使webpack正常工作,您需要安装两个软件包-
webpack
和webpack-cli
。
npm i webpack webpack-cli -D
webpack.config.js
安装这些软件包后,需要配置webpack。为此,将创建
webpack.config.js
一个导出对象的文件。该对象包含webpack设置。
module.exports = {}
Webpack的主要任务是分析模块,有选择地转换它们并将它们智能地组合成一个或多个捆绑包,因此Webpack需要了解三件事:
- 应用程序入口点
- 要执行的转换
- 将生成的包放在何处
入口点
无论一个应用程序包含多少个模块,总会有一个入口。该模块包括其余部分。通常,此文件为index.js。它可能看起来像这样:
index.js
imports about.js
imports dashboard.js
imports graph.js
imports auth.js
imports api.js
如果我们告诉webpack该文件的路径,它将使用它来创建应用程序的依赖关系图。为此,您需要
entry
在webpack设置中添加一个属性,其中包含主文件路径的值:
module.exports = {
entry: './app/index.js'
}
装载机转换
添加入口点后,需要在生成捆绑包之前通知Webpack有关需要执行的转换。为此,使用了装载机。
默认情况下,当生成基于运算符的依存关系图时,
import / require()
Webpack仅能够处理JavaScript和JSON文件。
import auth from './api/auth' //
import config from './utils/config.json' //
import './styles.css' // ️
import logo from './assets/logo.svg' // ️
您几乎不敢将自己局限于应用程序中的JS和JSON文件,很可能还需要样式,SVG,图像等。那就是装载机进来的地方。顾名思义,加载程序的主要任务是为webpack提供不仅可以处理JS和JSON文件的功能。
第一步是安装加载程序。由于我们要加载SVG,因此请使用npm安装svg-loader。
npm i svg-inline-loader -D
接下来,将其添加到webpack设置。所有装载程序都包含在一系列对象中
module.rules
:
module.exports = {
entry: './app/index.js',
module: {
rules: []
}
}
加载程序信息包括两部分。首先是要处理的文件类型(
.svg
在我们的示例中)。第二个是用于处理此类文件的加载程序(svg-inline-loader
在我们的示例中)。
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' }
]
}
}
现在,我们可以导入SVG文件。但是我们的CSS文件呢?对于使用的样式
css-loader
。
npm i css-loader -D
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: 'css-loader' }
]
}
}
现在,我们可以导入SVG和CSS文件。但是,为了使样式正确工作,我们需要添加另一个加载器。多亏了,
css-loader
我们可以导入CSS文件。但这并不意味着它们将包含在DOM中。我们不仅要导入此类文件,而且还希望将其放置在标签中,<style>
以便将其应用于DOM元素。为此,您需要style-loader
。
npm i style-loader -D
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }
]
}
}
请注意,由于使用了两个加载程序来处理CSS文件,因此属性值
use
是一个数组。另外要注意的装载机的顺序,第一style-loader
,然后css-loader
。这很重要。Webpack将以相反的顺序应用它们。它首先css-loader
用于导入'./styles.css'
,然后style-loader
用于将样式注入DOM。
加载程序不仅可以用于导入文件,还可以用于转换文件。最受欢迎的是使用Babel将下一代JavaScript转换为现代JavaScript。它用于此
babel-loader
。
npm i babel-loader -D
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
}
}
几乎所有类型的文件都有加载程序。
出口点
现在,webpack知道了入口点和加载器。下一步是指定捆绑包的目录。为此,您需要向
output
Webpack设置添加属性。
const path = require('path')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
}
}
整个过程如下所示:
- Webpack接收位于以下位置的入口点
./app/index.js
- 它解析语句
import / require
并创建依赖关系图 - Webpack通过使用适当的加载器转换代码来开始构建包
- 他收集了一个捆并将其放入
dist/index_bundle.js
外挂程式
我们已经看到了如何在生成包之前或期间使用加载程序来处理单个文件。与加载程序不同,插件使您可以在构建捆绑包后执行任务。这些任务可能与包本身以及其他代码有关。您可以将插件视为功能更强大,限制更少的加载程序。
让我们举个例子。
HtmlWebpackPlugin
webpack的主要任务是生成一个可在中引用的包
index.html
。在带有捆绑软件的目录中
HtmlWebpackPlugin
创建index.html
,并自动在其中添加到捆绑软件的链接。
我们命名捆绑包
index_bundle.js
并将其放入dist
。HtmlWebpackPlugin
会index.html
在目录中创建一个新文件,dist
并在其中添加捆绑的链接<script src='index_bundle.js'></script>
。很好,不是吗?由于它是index.html
生成的HtmlWebpackPlugin
,因此即使我们更改出口点或包的名称,它也HtmlWebpackPlugin
将接收此信息并更改内容index.html
。
我们如何使用这个插件?与往常一样,您需要先安装它。
npm i html-webpack-plugin -D
接下来,将属性添加到webpack设置
plugins
。
const path = require('path')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
},
plugins: []
}
我们
HtmlWebpackPlugin
在数组中创建一个实例plugins
。
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin()
]
}
环境插件
如果您使用的是React,则需要在部署应用程序之前将其设置
process.env.NODE_ENV
为一个值production
。这将允许React通过删除开发工具(例如警告)来构建生产环境。Webpack允许您通过插件执行此操作EnvironmentPlugin
。它是webpack的一部分,因此您无需安装它。
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin(),
new webpack.EnvironmentPlugin({
'NODE_ENV': 'production'
})
]
}
现在,在我们应用程序中的任何地方,我们都可以使用设置生产模式
process.env.NODE_ENV
。
HtmlWebpackPlugin
并且EnvironmentPlugin
只是webpack插件系统的一小部分。
模式(mode)
在准备用于生产的应用程序的过程中,需要执行几个步骤。我们只介绍了其中之一-
process.env.NODE_ENV
重视价值production
。另一个操作是最小化代码并删除注释以减小包的大小。
有一些特殊的插件可以解决这些任务,但是有一种更简单的方法。在webpack设置中,可以将其设置
mode
为development
或production
取决于开发环境。
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'production'
}
请注意,我们已将其删除
EnvironmentPlugin
。事实是,在设置mode
值之后,production
Webpack会自动分配该process.env.NODE_ENV
值production
。这也可以减少代码并删除警告。
启动一个webpack
目前,我们知道Webpack的工作方式以及如何配置它,但它仍然可以运行。
我们有一个
package.json
可以创建script
运行的文件webpack
。
"scripts": {
"build": "webpack"
}
现在,当您
npm run build
在终端中运行命令时,将启动一个Webpack,它将创建一个优化的包index_bundle.js
并将其放在中dist
。
开发生产方式
总而言之,我们已经完成了webpack。最后,让我们看一下如何在模式之间切换。
在进行生产时,我们希望尽可能优化所有内容。在开发模式下,情况相反。
要在模式之间切换,您需要在中创建两个脚本
package.json
。
npm run build
将建立生产捆绑包。
npm run start
将启动开发服务器并监视文件更改。
请记住,我们在webpack设置中将其设置
mode
为一个值production
。但是,我们现在不需要它。我们希望环境变量根据执行的命令具有适当的值。让我们改变剧本build
在package.json
。
"scripts": {
"build": "NODE_ENV='production' webpack",
}
如果您使用Windows,则命令为:
"SET NODE_ENV='production' && webpack"
。
现在,在webpack设置中,我们可以
mode
根据更改值process.env.NODE_ENV
。
...
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development'
}
要为我们的应用程序构建现成的捆绑包,我们只需
npm run build
在终端中运行它即可。目录dist
文件已创建index.html
并index_bunlde.js
。
开发服务器
在开发应用程序时,速度至关重要。我们不想重新启动Webpack并等待每一次更改的新版本。这是包裹派上用场的地方
webpack-dev-server
。
顾名思义,这是用于开发的Webpack服务器。
dist
它没有创建目录,而是将数据存储在内存中并在本地服务器上进行处理。更重要的是,它支持实时重启。这意味着任何更改都将webpack-dev-server
重建文件并重新启动浏览器。
安装软件包。
npm i webpack-dev-server -D
剩下要做的就是将脚本添加
start
到中package.json
。
"scripts": {
"build": "NODE_ENV='production' webpack",
"start": "webpack-dev-server"
}
现在,我们有两个命令:一个用于启动开发服务器,另一个用于构建完成的包。
希望本文对您有所帮助。感谢您的关注。