webpack 概述
webpack 是一个现代JavaScript应用程序的静态模块打包器(module bundler)
当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
webpack 做了什么
- 语法转换
- less/sass转换成css
- ES6转换成ES5
- typescript转换成js
- html/css/js 代码的压缩与合并(打包)
- webpack可以在开发期间提供一个开发环境
- 自动开启浏览器
- 自动监视文件变化
- 自动刷新浏览器
说明:项目一般都需要经过webpack打包之后才上线。webpack是开发阶段使用的,项目上线后是不用的。
核心概念
webpack 配置文件: webpack.config.js
/*
webpack.config.js 文件是webpack默认会读取的配置文件,文件名固定。
webpack 是运行在nodejs环境下的,在webpack.config.js中可以使用nodejs的语法
*/
// 引入path模块
const path = require('path')
module.exports={
// 入口: 你要对哪个文件进行打包
entry: './path/to/my/entry/file.js',
// 出口: 你要把文件打包到哪里去
output: {
path: path.join(__dirname,'dist'),
filename: 'bundle.js'
},
// 模式: 打包的模式,development,production
mode: 'development',
// 配置webpack的插件
plugins: []
}
入口(entry)
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
每个依赖项随即被处理,最后输出到称之为 bundles 的文件中。
出口(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。
loader
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
注意,loader 能够 import 导入任何类型的模块(例如 .css 文件),这是 webpack 特有的功能
在 webpack 的配置中 loader 有两个目标:
test
属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。use
属性,表示进行转换时,应该使用哪个 loader。
插件(plugins)
loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中
模式
通过选择 development 或 production 之中的一个,来设置 mode 参数
webpack 打包
基本步骤
- 初始化一个项目
npm init -y
- 安装依赖包
npm install webpack@5.69.1 webpack-cli --save-dev
- 在package.json文件中配置一条scripts
"scripts": {
"build": "webpack"
}
在package.json 中的scripts 中,可以配置一些自己的命令
运行方式: npm run xx
特殊的命令: start stop 运行的时候可以省略runscripts 的作用:
- 可以配置一些命令,简化运行时的输入
- 更好的可阅读性
- 配置webpack.config.js 文件
const path = require('path')
module.exports={
// 入口: 你要对哪个文件进行打包
entry: './src/main.js',
// 出口: 你要把文件打包到哪里去
output: {
path: path.join(__dirname,'dist'),
filename: 'bundle.js'
},
// 模式: 打包的模式,development,production
mode: 'production'
}
- 运行命令进行打包
npm run build
打包js文件
准备两个js文件
src/ext.js
:
console.log('ext.js..................')
src/main.js
:
// 引入一个js模块
require('./ext')
console.log('main.js.................')
运行打包命令
# npm run build
> webpack-demo@1.0.0 build C:\workspaces_web\webpack-demo
> webpack
asset bundle.js 2.73 KiB [emitted] (name: main)
./src/main.js 304 bytes [built] [code generated]
./src/ext.js 35 bytes [built] [code generated]
webpack 5.69.1 compiled successfully in 135 ms
打包后,可见在dist目录下,生成一个bundle.js
文件,通过其内容可知ext.js
和main.js
两个模块打包合并到了bundle.js
中。
打包html文件: html-webpack-plugin
- 准备一个html文件:
src/index.html
<!DOCTYPE html>
<html>
<head>
<title>js与html</title>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</body>
</html>
- 安装插件:HtmlWebpackPlugin
npm install --save-dev html-webpack-plugin
- 在webpack.config.js中配置插件HtmlWebpackPlugin
/*
webpack.config.js 文件是webpack默认会读取的配置文件,文件名固定。
webpack 是运行在nodejs环境下的,在webpack.config.js中可以使用nodejs的语法
*/
// 引入html-webpack-plugin模块
var HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')
module.exports={
// 入口: 你要对哪个文件进行打包
entry: './src/main.js',
// 出口: 你要把文件打包到哪里去
output: {
path: path.join(__dirname,'dist'),
filename: 'bundle.js'
},
// 模式: 打包的模式,development,production
mode: 'development',
// 配置webpack的插件
plugins: [
// html-webpack-plugin 插件
new HtmlWebpackPlugin({template: './src/index.html'})]
}
- 运行命令进行打包
# npm run build
> webpack-demo@1.0.0 build C:\workspaces_web\webpack-demo
> webpack
asset bundle.js 2.74 KiB [emitted] (name: main)
asset index.html 221 bytes [emitted]
./src/main.js 306 bytes [built] [code generated]
./src/ext.js 35 bytes [built] [code generated]
webpack 5.69.1 compiled successfully in 234 ms
经过打包后,dist目录下,生成一个index.html文件,并且内容中自动引入了bundle.js
,如下:
<!DOCTYPE html>
<html>
<head>
<title>js与html</title>
<script defer src="bundle.js"></script></head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</body>
</html>
案例:基于webpack实现li隔行变色
- 安装jquery
npm install jquery
- 修改前面例子中的
main.js
如下:
// 引入一个js模块
require('./ext')
console.log('main.js.................')
// 引入jquery,注意:引入前需先安装 npm install jquery
const $ = require('jquery')
$(function(){
// 实现隔行变色
$('li:odd').css('color','red')
$('li:even').css('color','green')
})
- 运行命令进行打包
npm run build
浏览器打开dist目录下的index.html,如下:
打包css文件: style-loader与css-loader
- 安装loader:css-loader,style-loader
npm install css-loader --save-dev
npm install style-loader --save-dev
- 配置webpack.config.js
// 配置loader
module: {
// 规则
rules: [
// 处理css文件的规则
{
// 用于匹配对应的文件
test: /\.css$/,
// 匹配到的文件用什么loader来处理
use: [
// css-loader 只能把css文件进行处理,不能让样式生效
// style-loader 把css-loader处理的结果添加到页面中
{loader: "style-loader"},
{loader: "css-loader"}
]
}
]
}
- 准备css文件
src/css/base.css
后,导入到main.js
中
// 引入样式模块,将css样式也打包到bundle.js 中。
require('./css/base.css')
- 运行命令进行打包
C:\workspaces_web\webpack-demo>npm run build
> webpack-demo@1.0.0 build C:\workspaces_web\webpack-demo
> webpack
asset bundle.js 343 KiB [emitted] (name: main)
asset index.html 221 bytes [compared for emit]
runtime modules 937 bytes 4 modules
modules by path ./node_modules/ 290 KiB
modules by path ./node_modules/style-loader/dist/runtime/*.js 5.75 KiB 6 modules
modules by path ./node_modules/css-loader/dist/runtime/*.js 2.33 KiB
./node_modules/css-loader/dist/runtime/noSourceMaps.js 64 bytes [built] [code generated]
./node_modules/css-loader/dist/runtime/api.js 2.26 KiB [built] [code generated]
./node_modules/jquery/dist/jquery.js 282 KiB [built] [code generated]
modules by path ./src/ 2.04 KiB
modules by path ./src/*.js 430 bytes
./src/main.js 391 bytes [built] [code generated]
./src/ext.js 39 bytes [built] [code generated]
modules by path ./src/css/*.css 1.63 KiB
./src/css/base.css 1.13 KiB [built] [code generated]
./node_modules/css-loader/dist/cjs.js!./src/css/base.css 502 bytes [built] [code generated]
webpack 5.69.1 compiled successfully in 998 ms
打包less文件: less-loader
- 安装loader:less-loader
npm install --save-dev less-loader less
- 配置webpack.config.js
// 配置loader
module: {
// 规则
rules: [
// ...
// 配置处理less文件的规则
{
test: /\.less$/,
use: ['style-loader','css-loader','less-loader']
}
]
}
- 准备css文件
src/less/index.less
后,导入到main.js
中
// 引入less样式模块
require('./less/index.less')
- 运行命令进行打包
npm run build
打包图片,字体,图标: asset
- 配置webpack.config.js
module: {
// 规则
rules: [
// ...
// 配置处理图片文件的规则 webpack5 新用法:https://webpack.js.org/guides/asset-modules/
{
test: /\.(png|jp?g|gif)$/,
type: 'asset',
// 默认8kb,小于8kb打包成base64,大于8kb,返回图片url。可以自行设置大小
parser: {
dataUrlCondition: {
maxSize: 10 * 1024 // 4kb
}
}
}
]
}
处理高版本javascript: babel-loader
- 安装loader: babel-loader
npm install -D babel-loader @babel/core @babel/preset-env
- 配置webpack.config.js
// 配置loader
module: {
// 规则
rules: [
// ...
// 配置babel处理高版本的js语法
{
test: /\.m?js$/,
// 排除
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
// 预设:配置哪些版本的js代码需要被babel出来,表示es6以上的语法都需要被处理
presets: ['@babel/preset-env']
}
}
}
]
}
webpack-dev-server 的使用
在开发期间,我们可以用webpack的一个辅助包: webpack-dev-server
来提高开发效率
- 自动开启http服务
- 自动打开浏览器
- 自动监视文件的变化
解决的问题: 每次修改代码,调试的时候不需要重新打包
安装 webpack-dev-server
npm install webpack-dev-server --save-dev
配置 webpack-dev-server
- 在
package.json
中添加scripts
:
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server"
}
- 启动服务
npm run dev
- 在
webpack.config.js
中添加运行设置项[可选]https://www.webpackjs.com/configuration/dev-server/#devserver-hot
// devServer 选项设置
devServer:{
open: true,// 自动打开浏览器
port: 3000, // 服务端口
hot: true // 热更新
}
webpack 打包基本配置参考
package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.17.5",
"@babel/preset-env": "^7.16.11",
"babel-loader": "^8.2.3",
"css-loader": "^6.6.0",
"html-webpack-plugin": "^5.5.0",
"less": "^4.1.2",
"less-loader": "^10.2.0",
"style-loader": "^3.3.1",
"webpack": "^5.69.1",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4"
},
"dependencies": {
"jquery": "^3.6.0"
}
}
webpack.config.js
/*
webpack.config.js 文件是webpack默认会读取的配置文件,文件名固定。
webpack 是运行在nodejs环境下的,在webpack.config.js中可以使用nodejs的语法
*/
// 引入html-webpack-plugin模块
var HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')
module.exports = {
// 入口: 你要对哪个文件进行打包
entry: './src/main.js',
// 出口: 你要把文件打包到哪里去
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
},
// 模式: 打包的模式,development,production
mode: 'development',
// 配置webpack的插件
plugins: [
// html-webpack-plugin 插件
new HtmlWebpackPlugin({template: './src/index.html'})],
// 配置loader
module: {
// 规则
rules: [
// 处理css文件的规则
{
// 用于匹配对应的文件
test: /\.css$/,
// 匹配到的文件用什么loader来处理
use: [
// css-loader 只能把css文件进行处理,不能让样式生效
// style-loader 把css-loader处理的结果添加到页面中
// 处理顺序: 从后往前
{loader: "style-loader"},
{loader: "css-loader"}
]
},
// 配置处理less文件的规则
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
},
// 配置处理图片文件的规则 webpack5 新用法:https://webpack.js.org/guides/asset-modules/
{
test: /\.(png|jp?g|gif)$/,
type: 'asset',
// 默认8kb,小于8kb打包成base64,大于8kb,返回图片url。可以自行设置大小
parser: {
dataUrlCondition: {
maxSize: 10 * 1024 // 4kb
}
}
},
// 配置babel处理高版本的js语法
{
test: /\.m?js$/,
// 排除
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
// 预设:配置哪些版本的js代码需要被babel出来,表示es6以上的语法都需要被处理
presets: ['@babel/preset-env']
}
}
}
]
},
// devServer 选项设置
devServer:{
open: true,// 自动打开浏览器
port: 3000, // 服务端口
hot: true // 热更新
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。