webpack入门教程
2023-09-11 14:19:18 时间
webpack相关
1. webpack相关配置
- 详情 点击
2. 安装
- 新建一个文件夹
webpack_demo
- 初始化package.json
npm init -y
- 安装webpack
npm install --save-dev webpack webpack-cli
//如果是使用的webpack版文为4x需要安装CLI,如果不是,反之
- 安装之后,就会多一个
webpack
,运行webpack -v
查看是否安装成功,如果是局部安装需要进入到\node_modules\.bin
下进行输入
可能会遇到的问题
- 在运行安装命令的时候也可能会遇到一下报错
Refusing to install package with name "webpack" under a package
,这是因为 点击 - 当输入命令之后,可能会出现报错:
无法将“webpack”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
- 解决措施:
- 全局安装
webpack
- 如果不想全局安装,打开
package.json
,找到scripts
输入以下代码,然后运行npm run dev
- 全局安装
"scripts": {
"dev": "webpack"
},
- 解决问题的原因
- 当我们运行
scripts
中的命令的时候,他寻找包的流程为:从当前项目的node_modules
目录下寻找,如果找不到,则去全局寻找 - 如果没有运行
scripts
中的命令,直接运行包暴露出的命令,他会直接到全局寻找
- 当我们运行
3. 基本使用
- 打包的方式有两种 详情 点击
- 不使用配置文件
- 使用配置文件
3.1 不使用配置文件打包
- 命令
webpack <entry> [<entry>] -o <output>
- entry : 表示入口文件(目前可以理解成我们要打包的文件),可以是
文件名
或者文件的路径
- output : 表示我们最终的打包的文件名称,可以是
文件名
或者文件的路径
- 中括号表示可以指定多个入口
- entry : 表示入口文件(目前可以理解成我们要打包的文件),可以是
- 让我们在
webpack_demo
的根目录下新建index.js
文件,在文件中写上如下代码
index.js
//index.js
function helloWorld() {
console.log('Hello World')
}
helloWorld()
在 终端
输入下面的命令
webpack index.js -o index.bundle.js
bundle
没有什么特别的含义,相当于一个标识,表示打包后的文件- 如果报错的同学,进行了
scripts
配置,需要修改为下面代码,运行npm run dev
"scripts": {
"dev": "webpack index.js -o index.bundle.js"
},
- 打包完成后在我们的根目录下就会多出文件
index.bundle.js
,打开之后就可以看到被打包后的压缩后的代码
指定打包模式
- 命令
webpack <entry> [<entry>] --mode development -o <output>
- 默认生产模式(压缩代码)
--mode
用来修改打包的模式,详情 点击- 运行之后你就会,打开被打包的文件,没有被压缩
3.2 使用配置文件打包
- webpack 默认的配置文件为
webpack.config.js
,我们所有的配置都可以在这个文件中写,且这个文件最好放在根目录下- 我们也可以运行命令
webpack [--config webpack.config.js]
来修改配置文件名称 - 配置文件的结构,请查看
- 我们也可以运行命令
- 我们在根目录下新建
webpack.config.js
文件,写上如下代码
const path = require("path")
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, "dist"),
filename:"bundle.js"
}
}
- 直接运行命令
webpack
,或者npm run dev
(已经配置过scripts
的同学) - 你会发现在根目录下多出了
dist
文件夹,里面有已经为我们打包好的文件bundle.js
对于文件中的一些代码的说明
- entry 入口文件,他后面可以跟
字符串
,对象
,数组
,可以查看配置结构 - output 输出文件路径与文件名(第二个参数)
path
指定文件输出的路径filename
输出的文件名- 可以传递参数,形式为
"[name].js"
,他只能与入口文件的对象
形式配合使用,对象的key
也就是属性名,对传递到参数中,将[name]
替换,演示请看下面的代码
- 可以传递参数,形式为
__dirname
获取当前文件所在的绝对路径resolve
进行路径的拼接 ,详情点击
const path = require("path")
module.exports = {
entry: {
index:'./index.js'
},
output: {
path: path.resolve(__dirname, "dist"),
filename:"[name].bundle.js"
}
}
//打包后的文件名为 index.bundle.js
4. mode
- 当我们进行打包的时候,会发现命令行终端会给我们一些警告
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
- 他的意思是我们进行打包的模式(环境)还没有指定
4.1 打包环境指定
-
mode
种类production
development
none
-
我们可以配置文件中添加
module.exports = {
mode:'development'
}
- 当我们再次运行命令打包的时候,警告就不会出现了,并且打包出来的代码是没有经过压缩的
5. loader
loader的作用
- 首先要明白
webpack
只认识js
,先让他处理其他的文件,如.png
,.less
等,根本不可能啊,因为他只认识js
- 所以
loader
就横空出世了,他就负责将其他文件格式转化为js
,然后webpack
就可以处理他们了
5.1 url-loader
url-loader的作用
- 主要用来对各种图片格式进行处理,如
.jpeg
,.png
等 - 将图片打包成 base64
格式
file-loader
的功能与url-loader
的功能差不多,都是对图片进行处理的loader- 当打包超过限制的时候,
url-loader
会自动调用file-loader
5.1.1 url-loader安装
npm install --save-dev url-loader
- 详情 点击
5.1.2 url-loader配置
- 在
webpack.config.js
中写上如下代码
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 1024*50
}
}
]
}
]
}
}
说明
对于webpack.config.js
我们做了如下的改动
- 新增
moudle
对象,对象里面有一个rules
的数组,数组中包含的是一个对象 test
后面跟的是一个正则表达式,表示的是我们要对那些格式的文件做处理use
表示使用那些loader
对test
的文件做处理loader
具体使用的loaderoptions
:配置选项limit
:对于图片的限制,以字节B
为单位,1024B=1KB
,所以我们采取了1024*50
的写法
5.1.2 url-loader实战
- 找到两个图片(大小差距大一些),在根目录新建
images
,并把两张图片放到文件夹中,这里用了两张图片并分别重命名img_big.png
(95KB),img_small.jpg
(9KB),配置中我们的限制为50KB
2.运行webpack
或者npm run dev
(配置scripts
的同学)
- 我们会发现命令行端口报错:较大的图片解析失败,原因:没有
file-loader
- 同时,我们也发现
dist
文件夹下已经打包出文件,我们进入文件- 按
Ctrl + F
,搜索img_small.jpg
- 按
- 我们会发现在限制内的图片已经被打包成
base64编码
图片了
- 为了解决报错,我们安装
file-loader
npm install file-loader -D
- 继续运行
webpack
- 打包之后没有报错,接着打开
dist
文件夹,发现超出限制的图片打包到了dist
文件夹下
5.2 babel-loader
babel-loader的作用
- babel最主要的作用是将ES6的代码转化成ES5的代码
- 当然,它还可以转换JSX语法
- 这些在babel的官网都有说明,详情 点击
5.2.1 babel-loader安装
- 在
webpack
官网有两行安装的代码,一个是安装babel6,一个是babel7,我们这里使用babel7
npm install babel-loader@8.0.0-beta.0 @babel/core @babel/preset-env webpack
@babel/core
babel的核心库,一般babel的库都已@开头@babel/preset-env
主要内置了一些转换的规则- 如果我们想识别JSX语法的话,还需要安装babel的插件,详情点击
- 还需要在
test
中添加对JSX语法的支持
npm install --save-dev @babel/plugin-transform-react-jsx
5.2.2 babel-loader配置
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: ["@babel/plugin-transform-react-jsx"]
}
}
}
]
}
exclude
表示排除对某些包的编译presets
表示规则文件plugins
功能扩展使用的插件
5.2.3 babel-loader实战
ES6转ES5
- 我们在根目录下新建
src
文件夹,并新建es6.js
,表示里面写的有es6的代码 - 在
es6.js
中写上如下代码,并在入口文件引入
const helloworld = async() => {
console.log('helloworld')
}
helloworld()
- 入口文件引入
import './src/es6'
- 为了观察转换效果,我们可以先把配置文件中的规则和插件注释掉进行打包,运行
webpack
/* presets: ['@babel/preset-env'],
plugins: ["@babel/plugin-transform-react-jsx"] */
- 打包完成后,打开打包文件,搜索
helloworld
,结果应该如下,我们发现代码原封不动的打包到了文件中
- 将注释掉的规则释放,再次打包,并查看
- 我们发现打包之后的
箭头函数
和async
都不见了踪影
转化JSX语法
- 想要使用JSX语法,我们需要下载
react
,react-dom
npm install react react-dom -S
- 写上如下代码,并在入口文件中引入
import React,{Component} from 'react'
export default class HelloWorld extends Component{
render() {
return (
<div>HelloWorld</div>
)
}
}
入口文件引入
import HelloWorld from './src/helloWorld.jsx'
- 此时我们将
webpack.config.js
插件配置注释掉
/* plugins: ["@babel/plugin-transform-react-jsx"] */
- 运行打包命令,你会发现他会报错,原因是不识别JSX语法
- 我们将注释清掉,再次运行打包命令,你就会发现他已经不报错了
5.3 less-loader
less-loader的作用
- 将
less
代码转化为css
代码 - 但是css代码webpack还不能处理,需要
css-loader
转化成js
style-loader
是用来将css代码注入到style
标签中- 所以我们需要下载的包有
less less-loader css-loader style-loader
- 详情点击
5.3.1 less-loaer安装
npm install --save-dev less-loader less css-loader style-loader
5.3.2 less-loaer配置
module.exports = {
module: {
rules: [{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
}]
}
};
5.3.3 less-loaer实战
- 在
src
文件夹下新建style.less
文件,写上如下代码
@color:red;
body{
background-color:@color;
}
- 运行打包命令,并打开打包后的文件,搜索
background
,你会发现变量已经被编译了
6.plugins
plugins的作用
plugins
的作用与loader
相反,将js代码转化成相应的格式- plugins还提供了一些功能扩展
6.1 mini-css-extract-plugin
作用
6.1.1 mini-css-extract-plugin安装
npm install --save-dev mini-css-extract-plugin
6.1.2 mini-css-extract-plugin配置
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.less$/,
use: [MiniCssExtractPlugin.loader, 'css-loader',"css-loader","less-loader"],
},
],
},
};
- 在配置文件引入插件,插件暴露出来的是一个构造函数
- 在配置对象中添加
plugins
选项,如图 - 在处理样式的配置中,使用插件的属性
loader
,在这里我们使用了另一种配置字符串
配置的方式,但是需要我们注意的而是- 要把配置的
style-loader
删去,因为style-loader
的作用是生成style
标签,而我们把它css提取出去,就不需要了。如果保留style-loader
他会报错
- 要把配置的
6.1.3 mini-css-extract-plugin实战
- 运行打包命令,我们就会发现在打包输出的
dist
文件夹下,多出了一个index.css
文件 - 当然我们还可以在
new MiniCssExtractPlugin()
参数中传递一些配置filename
打包输出的文件名,他可以是一个路径chunkFilename
打包输出的模块名,不常用
- 再次运行打包,你会发现打包输出的文件名就是配置的名字
6.2 html-webpack-plugin
作用
- 为html文件中引入的外部资源如script、link动态添加每次compile后的hash,防止引用缓存的外部文件问题
- 可以生成创建html入口文件,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面入口
- 详情 点击
6.2.1 html-webpack-plugin安装
npm install --save-dev html-webpack-plugin
6.2.2 html-webpack-plugin配置
var HtmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
module.exports = {
plugins: [new HtmlWebpackPlugin()]
};
6.2.3 html-webpack-plugin实战
- 当我们写完上面的配置的时候,可以运行命令打包一下,他会给我们生成默认的配置
- 他在打包目录
dist
文件夹下自动生成了index.html
文件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack App</title>
<meta name="viewport" content="width=device-width, initial-scale=1"></head>
<body>
<script src="index.bundle.js"></script></body>
</html>
- 自动为我们注入了
js
脚本文件 - 自动生成的
title
为webpack app
但是这都我们我们想要的,我们需要我们自己可以定制title
,也可以随意引入其他依赖的库,这应该怎么做呢。
html-webpack-plugin高度配置
- 详情点击
- 我们可以在构造函数中传递配置选项
title
最终会被插入到title标签中filename
html的文件名字template
将配置的内容注入的模板,在这个模板中我们可以引入CDN,他后面可以跟一个路径
new HtmlWebpackPlugin({
title:'Hello webpack',
filename: 'main.html',
template:'template.html'
})
- 那么模板如何编写呢
title
的值需要用ejs的模板语法来实现- 想要引入其他CDN可以在模板中直接引入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ejs模板语法 -->
<title><%= htmlWebpackPlugin.options.title %></title>
<!-- 引入 jQuery的CDN -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
</head>
<body>
</body>
</html>
- 运行打包命令进行打包
- 在打包目录下就生成了我们想要的模板,其他配置也可点击查看
- 这个时候我们可以在
template.html
和index.js
中写上如下代码
index.js
import React from 'react'
import ReactDOM from 'react-dom'
ReactDOM.render(<HelloWorld/>,document.getElementById('root'))
template.html
<body>
<div id="root"></div>
</body>
- 再次运行进行打包
6.3 devServer
作用
- 当我们写完一个文件保存之后,他会自动编译,并更新浏览器
- 详情 点击
6.3.1 devServer安装
npm install webpack-dev-server -D
6.3.2 devServer配置
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 8080
},
contentBase
,对于那个目录开启devServer(我们要显示那个目录中的内容)compress
是否压缩,启用gzip 压缩port
运行端口号- 在
scripts
中配置一下命令
"start": "webpack-dev-server",
"build": "webpack"
注意
在webpack5中contentBase属性已经别删除,详情点击
6.3.2 devServer实战
- 运行
npm start
- 当我们在
helloWorld.jsx
中写上一些代码时,打开浏览器或者终端,我们会发现他会自动更新 - 当我们运行
npm run build
,他就会在打包 - 这时我们会发现我们差不多可以搭建一个React的脚手架了
7. webpack性能优化
7.1 打包分析
详情点击
下载
npm install --save-dev webpack-bundle-analyzer
配置
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
}
然后我们可以修改package.json
命令为
"build": "webpack --profile --json > stats.json"
他的意思是将打包过程的描述放在stats.json
文件中
- 然后我们运行命令
npm run build
,等待打包完成,当打包完成之后他会出现以下图片
- 而我们打包出来文件的目录是这个样子的
- 而图片便是的就是一个包围结构,上面的包围着下面的,图片的大小代表的包的体积的大小
github源码地址:https://github.com/whynot-todo/webpack_demo.git
相关文章
- [Webpack] Analyze a Production JavaScript Bundle with webpack-bundle-analyzer
- [React] Asynchronously Load webpack Bundles through Code-splitting and React Suspense
- [Webpack] Detect Unused Code with Webpack and unused-files-webpack-plugin
- webpack CommonsChunkPlugin详细教程
- webpack开发小总结
- webpack的安装与基本使用
- Web前端 -- Webpack
- [Webpack] Externalize Dependencies to be Loaded via CDN with webpack
- [WASM] Create a New Rust/Webpack Project using the rust-webpack Template
- Vue + webpack 项目实践
- 一小时包教会 —— webpack 入门指南
- es6学习笔记(gulp、babel、webpack、express)
- 笔记:webpack 打包参数 mode development