介绍
您可能已经使用了创建React App或Angular-CLI来生成应用程序的样板。即使这些工具在引擎盖下使用webpack,它们也为您抽象了大部分配置。
,但有时,根据要求,您可能必须从头开始创建自定义配置或自定义现有配置。在这里了解WebPack或任何其他类似工具有帮助。因此,让我们尝试创建WebPack应用程序并了解其概念。
本文是WebPack系列的一部分。在这方面,我们介绍了基本的WebPack概念。在下一个中,我们将介绍一些高级概念,例如代码分解,多个配置,源地图配置等。
本文的第一部分涵盖了基本的WebPack概念。在第二部分中,我们将构建一个简单的应用程序。
什么是webpack?
WebPack是用于JavaScript应用程序的模块捆绑包。用普通的英语,WebPack创建所有文件的依赖关系图(使用导入/需要语句,插件,加载程序等)。使用生成的依赖关系图,WebPack输出捆绑的代码。
WebPack将每个文件或资产视为模块。开箱即用,WebPack仅支持JavaScript文件(ES模块,CONCORJS模块,AMD模块)。
,但我们可以借助加载程序和插件将其扩展到其他文件类型,例如CSS,图像等。我们将在本文的稍后研究。
核心概念
使用WebPack构建应用程序时很有帮助的关键概念
- 条目
- 输出
- 装载机
- 插件
- Mode
入口
入口点是一个JavaScript文件,它是WebPack收集应用程序使用以构建依赖关系图的所有依赖项的起点。依赖项是库,例如React,jQuery等或静态资产,例如图像,CSS文件等。
从webpack> = 4,开箱即用,src/index.js
用作入口点。
但是您可以使用配置文件中的entry
属性配置入口点并具有多个入口点。
module.exports = {
entry: 'src/app.js', //Custom entry point
};
输出
输出是WebPack将所有依赖关系和您的应用程序代码捆绑到单个或多个文件的路径。
从webpack> = 4,盒子dist/main.js
用作输出路径。
您还可以使用输出属性等输出属性来配置输出。
module.exports = {
entry: 'src/app.js', //Custom entry point,
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'build'), //custom output point
},
};
装载机
加载程序是扩展程序,可帮助WebPack处理其他类型的文件,例如CSS,图像,Markdown Files等。
加载程序将这些文件转换为JavaScript模块。这些转换后的模块将由WebPack使用。
例如,在ts-loader的帮助下,您可以转移打字稿文件。
module: {
rules: [
{
test: /\.ts$/i,
use: ["ts-loader"],
},
],
},
加载程序有两个属性:
-
test
-用于识别需要转换为JavaScript模块的文件类型。 -
Use
-用于确定在此文件类型上使用的加载程序。
如果要在单个文件类型上使用多个加载程序,则可以通过
use
属性Array['loader-1', 'loader-2']
。
但请记住,将从右至左> 中应用装载机,以便首先应用Loader-2,然后使用Loader-1。
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
在上述代码中,css-loader
将首先应用,然后是style-loader
。
-
css-loader
-将直接导入CSS文件的支持添加到JavaScript文件中。 -
style-loader
-用来注入从css-loader
生成的样式中。
插件
虽然装载机可以转换JS以外的特定模块,但插件可以执行各种任务,例如捆绑优化,资产管理等。
webpack本身是由插件组成的。
要保持简单,让我们看看HtmlWebpackPlugin.
htmlwebpackplugin将创建一个HTML模板并添加脚本标签,该标签指向捆绑的JS。
。您可以使用NPM安装。
npm install html-webpack-plugin --save-dev
并使用plugins
属性添加配置。
{
...,
plugins: [
new HtmlWebpackPlugin({
title: 'My App',
template: path.resolve(__dirname, 'src', 'index.html'),
}),
],
...,
}
模式
模式允许WebPack使用基于环境的内置优化。例如,如果将模式设置为production
,则将更改输出代码。您可以将模式设置为
- 生产(默认)
- 开发
- 无
{
...,
mode: "development"
...,
}
示例应用程序
让我们构建一个计算年龄的简单应用程序。
创建一个带有任何名称的文件夹。在这里,我称之为年龄计算器 - webpack 。
mkdir age-calculator-webpack
cd age-calculator-webpack
之后,运行npm init -y
来初始化项目。
现在让我们安装webpack。
npm install webpack webpack-cli --save-dev
另外,安装CSS和HTML
的插件
npm install css-loader style-loader html-webpack-plugin
让我们创建文件。
touch webpack.config.js
mkdir src # creates the src folder
cd src
touch app.js
目录结构看起来像这样
├── src
│ ├── app.js
├── README.md
├── package-lock.json
├── package.json
└── webpack.config.js
基本设置
现在让我们使用webpack.config.js
配置webpack
const path = require('path');
module.exports = {
entry: path.resolve(__dirname, 'src/app.js'),
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'build'),
},
mode: "development"
};
在package.json
中添加webpack
命令以捆绑代码。
...
"scripts": {
"build": "webpack",
},
...
我们现在可以通过在src/app.js
中添加简单的控制台语句来测试配置
console.log('Hello from webpack!');
现在运行npm run build
,您将看到一个名为build
的文件夹。
添加插件
现在创建一个html文件src/index.html
并粘贴以下内容。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Age calculation with webpack</title>
</head>
<body>
<h1>Age calculator</h1>
<form id="form">
<label for="dob">Your date of birth</label>
<input type="date" name="dob" id="dob">
<button type="submit" id="submit">Calculate my age</button>
</form>
<br>
<br>
<div id="result"></div>
</body>
</html>
现在,在WebPack配置中添加HtmlWebpackPlugin
插件。然后我们可以浏览src/index.html
文件的内容。
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'src/app.js'),
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'build'),
},
plugins: [
new HtmlWebpackPlugin({
title: 'My App',
template: path.resolve(__dirname, 'src','index.html'),
}),
],
mode: "development"
};
我们将两个选项传递给HtmlWebpackPlugin
-
title
-模板的名称 -
template
-模板的路径
现在重新运行NPM Run Build。如果您在build
目录中观察到,则创建了两个文件。
build
├── index.html
└── main.js
打开浏览器中的build/index.html
文件并打开控制台。您会看到此消息。
添加WebPack开发服务器以进行更快的开发
每当更改代码非常乏味时,运行npm run build
。因此,为了加快开发的速度,我们可以使用webpack dev server。 WebPack Dev服务器是静态服务器(基于Express.js),并支持实时重新加载。
通过运行
安装WebPack Dev服务器
npm install webpack-dev-server --save-dev
现在,使用devServer
属性添加webpack.config.js
中的webpack dev服务器。
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'src/app.js'),
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'build'),
},
plugins: [
new HtmlWebpackPlugin({
title: 'My App',
template: path.resolve(__dirname, 'src', 'index.html'),
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
devServer: {
static: path.join(__dirname, 'build'),
port: 3000,
},
mode: "development"
};
在这里我们通过
-
static
-静态文件的路径,即捆绑的JavaScript,HTML和其他资产 -
port
-开发服务器的端口号
添加命令以说明package.json
中的开发服务器
webpack serve
在端口号3000上启动了开发服务器(在配置中定义)
{
"name": "webpack-5-tutorial",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"start": "webpack serve"
},
"repository": {
"type": "git",
"url": "git+https://github.com/bgopikrishna/webpack-5-tutorial.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/bgopikrishna/webpack-5-tutorial/issues"
},
"homepage": "https://github.com/bgopikrishna/webpack-5-tutorial#readme",
"devDependencies": {
"html-webpack-plugin": "^5.5.0",
"webpack": "^5.72.1",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.9.3"
},
}
现在运行npm start
并转到localhost:3000.
添加加载程序
让我们通过在应用程序中添加一些样式来查看正在行动中的加载程序。
创建一个文件名styles.css
并粘贴以下内容。
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
background: linear-gradient(to right bottom, #285de5 50%, #4a546f 50%); min-height: 500px;
min-height: 100vh;
color: white;
}
input {
border-radius: 8px;
padding: 4px 8px;
}
button {
background: #00d2ff;
padding: 8px 16px;
border-radius: 8px;
border: none;
cursor: pointer;
}
现在要将CSS文件导入我们的应用程序,我们可以使用style-loader
和css-loader
通过运行
安装它们
npm install --save-dev style-loader css-loader
将它们添加到webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'src/app.js'),
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'build'),
},
plugins: [
new HtmlWebpackPlugin({
title: 'My App',
template: path.resolve(__dirname, 'src', 'index.html'),
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
devServer: {
static: path.join(__dirname, 'build'),
port: 9000,
},
mode: "development"
};
如前所述,
-
css-loader
-将直接导入CSS文件的支持添加到JavaScript文件中。 -
style-loader
-用来注入从css-loader
生成的样式中。
现在在src/app.js
中导入CSS文件
import './styles.css'
console.log('Hello from webpack')
如果您重新加载应用程序,则应使用样式的样式看起来像这样。
最终应用
将年龄计算逻辑添加到应用程序。
在src/app.js
中
import './styles.css'
const dateInputEl = document.getElementById('dob');
const formEl = document.getElementById('form');
const resultEl = document.getElementById('result');
formEl.addEventListener('submit', (event) => {
event.preventDefault();
const dob = dateInputEl.value;
const calculatedAge = calcAge(dob);
resultEl.innerText = `Your age is ${calculatedAge}`;
})
function calcAge(dob) {
const todayDate = new Date();
const userDob = new Date(dob);
const diffTime = Math.abs(todayDate - userDob);
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
const result = `${diffDays} Days`
return result;
}
我们不会详细介绍每个功能以保持简单。
我们有一个与submit
类型的事件侦听器的表格。每当用户以他的出生日期提交表格时,我们都会使用calcAge
计算年龄。并在带有ID的div
中渲染结果。 result
。
看起来像这样。
使用第三方库和模块
现在,让我们将calcAge
函数移动到一个名为src/utils.js
的新文件中,以便我们可以在其他地方重复使用。
export function calcAge(dob) {
const todayDate = new Date();
const userDob = new Date(dob);
const diffTime = Math.abs(todayDate - userDob);
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return diffDays;
}
将其导入src/app.js
import { calcAge } from './utils';
import './styles.css'
const dateInputEl = document.getElementById('dob');
const formEl = document.getElementById('form');
const resultEl = document.getElementById('result');
formEl.addEventListener('submit', (event) => {
event.preventDefault();
const dob = dateInputEl.value;
const calculatedAge = calcAge(dob);
resultEl.innerText = `Your age is ${calculatedAge}`;
})
目前,我们在唯一的天数中显示出年龄。为了获得更好的可读性,让我们使用date-fns库中的功能。要安装它,运行。
npm run install date-fns --save
现在在src/utils.js,
中,用从date-fns
库导入的函数替换逻辑。
import { formatDuration, intervalToDuration } from 'date-fns';
export function calcAge(dob) {
const duration = intervalToDuration({
start: new Date(dob),
end: new Date()
})
return formatDuration(duration)
}
结果现在看起来像这样。
结论
到目前为止,我们已经看到了如何使用插件,加载程序和第三方库配置基本的WebPack应用程序。在即将发表的文章中,我们将尝试涵盖一些高级概念并使用WebPack设置React应用程序。
github repo -https://github.com/bgopikrishna/webpack-tutorial/tree/v5/part-1