文章目录
- [1. 什么是webpack?](#1. 什么是webpack?)
- [2. webpack使用](#2. webpack使用)
-
- [2.2. 前置知识](#2.2. 前置知识)
- [2.1. 创建一个项目](#2.1. 创建一个项目)
- [3. webpack打包](#3. webpack打包)
-
- [3.1. 创建一个webpack.config.js文件](#3.1. 创建一个webpack.config.js文件)
- [3.2. 入口(entry)](#3.2. 入口(entry))
-
- [3.2.1. webpack.config.js](#3.2.1. webpack.config.js)
- [3.2.2. src/index.js](#3.2.2. src/index.js)
- [3.2.3. package.json](#3.2.3. package.json)
- [3.3. 输出(output)](#3.3. 输出(output))
-
- [3.3.1. webpack.config.js](#3.3.1. webpack.config.js)
- [3.4. 加载器(loader)](#3.4. 加载器(loader))
-
- [3.4.1. src/index.js](#3.4.1. src/index.js)
- [3.4.2. src/index.css](#3.4.2. src/index.css)
- [3.4.3. webpack.config.js](#3.4.3. webpack.config.js)
- [3.5. 插件(plugin)](#3.5. 插件(plugin))
- [3.6. devServer](#3.6. devServer)
-
- [3.6.1. webpack.config.js](#3.6.1. webpack.config.js)
- [3.6.2. package.json](#3.6.2. package.json)
1. 什么是webpack?
Webpack
是一个现代 JavaScript
应用程序的静态模块打包器 。它是一个用于将代码编译成浏览器可识别的格式的工具。
webpack
可以实现以下的功能:
- 代码转换:
TypeScript
编译成JavaScript
、SCSS
、less
编译成CSS
等。 - 文件优化:压缩
JavaScript
、CSS
、HTML
代码,压缩合并图片等。 - 代码分割:提取 多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载。
- 模块合并:在采用模块化的项目里会有很多个模块和文件,需要构建功能把模块分类合并成一个文件。
- 自动刷新:监听本地源代码的变化,自动重新构建 、刷新浏览器。
- 代码校验:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过。
- 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。
- 依赖管理:通过分析模块之间的依赖关系,自动加载所需的依赖模块。
- 插件扩展:通过插件扩展功能,满足不同项目的需求。
构建其实是工程化 、自动化 思想在前端开发中的体现,把一系列流程用代码去实现,让代码自动化地执行这一系列复杂的流程。 构建给前端开发注入了更大的活力,解放了我们的生产力。
Webpack
的工作原理是从一个入口文件开始,递归地解析 出所有的依赖 ,然后将这些依赖打包 成一个或多个输出文件 。Webpack 支持多种模块化规范,包括CommonJS
、AMD
、ES6
模块等。
2. webpack使用
2.2. 前置知识
- node基础
- 包的理解
- 模块化思想
2.1. 创建一个项目
-
创建一个文件夹
-
创建一个package.json文件
bashnpm init -y
-
安装依赖
bashnpm install webpack webpack-cli webpack-dev-server style-loader css-loader html-webpack-plugin cross-env mini-css-extract-plugin less less-loader postcss postcss-loader autoprefixer @babel/core @babel/preset-env babel-loader typescript ts-loader @babel/preset-typescript eslint eslint-webpack-plugin eslint-config-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node @typescript-eslint/eslint-plugin --save
3. webpack打包
3.1. 创建一个webpack.config.js文件
3.2. 入口(entry)
entry
选项用于指定Webpack
打包的入口文件,即告诉Webpack
从哪个文件开始打包
3.2.1. webpack.config.js
js
module.exports = {
entry: "./src/index.js",
};
3.2.2. src/index.js
js
let a = 1;
console.log(a);
3.2.3. package.json
json
"scripts": {
"build": "webpack"
},
运行 npm run build 查看结果:
默认生成了一个dist文件,这就是打包后的代码。
3.3. 输出(output)
output
选项用于指定Webpack
打包后输出的文件和路径,即告诉Webpack
打包后的文件应该放在哪个目录下以及如何命名output
通常配置为一个对象 ,包含了多个属性path
指定了打包文件的输出路径 ,必须是一个绝对路径filename
指定了打包后的文件名 ,可以包含路径信息
3.3.1. webpack.config.js
js
const path = require("path"); // nodeJs 的 path 模块
module.exports = {
// entry:默认的路径是src/index.js,也可以自定义
entry: "./src/index.js",
output: {
// 打包文件的输出位置
path: path.resolve(__dirname, "dist"),
// 打包后的文件名
filename: "index.js",
},
};
运行 npm run build 之后的效果:
- 根文件下生成了一个 dist 文件夹,作为打包后输出文件
- dist 中生成了一个 index.js 文件。由默认的 main.js 文件变成了我们自定义的 index.js 文件,其他内容没有变化。
3.4. 加载器(loader)
loader
是Webpack
的一个关键功能,它可以处理 各种各样的文件类型。Webpack
将一切文件视为模块,但只有JS
模块才能被直接运行和使用Loader
可以将非JS
模块(如CSS、图片等)转换为Webpack
可以处理的有效模块loader
是在"webpack.config.js"
文件中使用"module"
属性指定的。每个loader
都定义为一个对象,该对象具有指定loader
应处理哪些文件的"test"
属性和指定要使用的加载程序的"use"
属性。
例如,loader可以用于将Sass或Less文件转换为CSS,或者将ES6代码转换为可以由旧浏览器执行的ES5代码。
3.4.1. src/index.js
js
import "./index.css";
console.log(123);
3.4.2. src/index.css
css
body {
background-color: red;
color: blue;
}
注意:此时运行npm run build 会报错,由于浏览器只认识js代码,因此在webpack中需要将其他的代码进行处理,此时需要使用style-loader、css-loader来处理我们的css代码。
3.4.3. webpack.config.js
- 每个
Loader
规则由两部分组成:匹配条件 和处理方式 - 匹配条件 通常使用正则表达式 ,用于匹配 需要被转换的文件
- 处理方式 则是具体的转换操作
test
属性指定了匹配的文件类型use
属性指定了转换方式exclude
用于指定哪些文件或目录不应该被 loader 处理css-loader
作用是将CSS代码转换为JavaScript代码css-loader
可以识别@import
和url()
等语句,实现 CSS 模块的引用和解析style-loader
用于将css-loader
转换后的JavaScript
对象,以style
标签的形式动态插入到 HTML 文件中(动态创建style标签,然后放到head标签中)
js
module.exports = {
// ......
module: {
rules: [
{
test: /\.css$/, // 匹配以 .css 结尾的文件
use: ["style-loader", "css-loader"], // 注意:loader执行顺序是从后往前执行,顺序不能改变
},
]
},
};
可以看到,此时运行 npm run build 已经打包成功了:
测试:在dist目录下创建一个html文件,测试一下样式是否生效:
可以看到,此时样式已经生效了:
例子:css代码通过loader转换成浏览器可识别代码的模拟过程(伪代码):
js
/**
* 模拟 css 样式大概转换过程
*/
// 1. webpack 将css读取出来
let cssCode = `body {
background-color: red;
color: blue;
}`;
// 2. css-loader将css代码转换成js代码
let cssModule = `
module.exports = "
body {
background-color: red;
color: blue;
}
"
`;
// 3. style-loader将css-loader转换的内容经过处理。放到动态创建的style标签中,变成浏览器能读取的代码
let style = document.createComment("style");
style.innerHTML = cssModule;
document.head.appendChild(style);
3.5. 插件(plugin)
Webpack
插件是用于扩展 Webpack
功能的 JavaScript 对象。它们可以用于各种用途,例如打包输出优化 、资源管理 和代码压缩 等。以下是一些常见的 Webpack
插件及其功能:
UglifyJSPlugin
:用于压缩 JavaScript 代码,减少文件大小并提高页面加载速度。HtmlWebpackPlugin
:用于生成 HTML 文件,并将打包后的 JavaScript 和 CSS 文件自动添加到 HTML 文件中。ExtractTextWebpackPlugin
:用于将 CSS 代码从 JavaScript 文件中提取出来,并将其保存为单独的 CSS 文件。CleanWebpackPlugin
:用于在打包之前清除之前的打包文件。CopyWebpackPlugin
:用于将文件或文件夹从源目录复制到输出目录。ProvidePlugin
:用于自动加载模块,而不必使用 import 或 require 语句。
例子:通过 HtmlWebpackPlugin
插件生成 HTML
文件,并将打包后的 JavaScript
和 CSS
文件自动添加到 HTML
文件中
- 创建模板文件
src/index.html
html
<!DOCTYPE html>
<html lang="zh-CN">
<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>模板文件</title>
</head>
<body>
模板文件
</body>
</html>
- webpack.config.js
js
const HtmlWebpackPlugin = require("html-webpack-plugin"); // 生成html的插件,并自动将打包后的 JS、CSS 文件引入 HTML 文件中
module.exports = {
// ......
module: {
// ......
},
plugins: [
// 插件使用时,像构造函数一样直接 new 即可
// template:模板文件的路径
// filename:打包后生成的文件名
// chunk:代码块
new HtmlWebpackPlugin({ template: "./src/index.html" }),
],
};
- 运行
npm run build
,查看打包后的dist
文件,此时已经生成了index.html
文件
3.6. devServer
webpack-dev-server
是一个基于Express
的Web 服务器
,它可以为Webpack
打包后的代码提供一个本地开发环境,支持实时刷新 、热替换 和自动构建 等功能,大大提高了开发效率static
:静态资源目录的路径,设置该参数可以在服务器中访问这些静态资源compress
:启用 gzip 压缩,默认是关闭的port
:服务器端口,默认是 8080host
:服务器主机名,默认是 localhostopen
:是否自动在浏览器中打开页面,默认是关闭的hot
:启用模块热替换功能,默认是关闭的watchFiles
:需要监听的文件列表,当这些文件发生变化时,自动重启服务器historyApiFallback
:参数用于设置是否启用HTML5
历史记录API
,用于处理单页应用的路由问题。默认情况下,当使用浏览器的前进/后退按钮时,devServer
会尝试根据 URL 路径查找对应的静态资源,如果找不到就返回404
。如果启用了historyApiFallback
,则会将这些请求重定向到index.html
,然后交给前端路由来处理
- 在命令行中运行
webpack-dev-server
命令后,webpack-dev-server
将会启动一个本地Web
服务器,并监听我们定义的端口。我们可以在浏览器中访问http://localhost:9000
,即可预览打包后的页面,并实现实时刷新 和热替换功能
3.6.1. webpack.config.js
js
devServer: {
static: path.join(__dirname, "public"), // 静态资源路径
compress: true, // 是否开始gzip压缩
host: "localhost", // 服务器主机名
port: 80, // 服务器端口名
open: true, //启动项目后是否自动打开浏览器
hot: true, // 是否启动模块热替功能
historyApiFallback: true, // 处理单页应用的路由问题
watchFiles: ["src/**/*.js", "src/**/*.css"], // 需要监听的文件列表,当这些文件发生变化时,自动重启服务器
},
3.6.2. package.json
json
"scripts": {
"dev": "webpack serve",
"build": "webpack"
},
运行 npm run dev,可以发现此时项目已经启动了: