webpack
在网页中会引用那些常见的静态资源
- js
- .js .jsx
- css
- .css .scss .less
- image
- .png .jpg .gif .jpeg .svg
- fonts
- .ttf .woff .eot
网页中引入得静态资源多了以后有什么问题??
- 网页加载速度慢,因为我们要发起很多得二次请求
- 要处理错综复杂得依赖关系
如何解决上述两个问题
- 合并、压缩、雪碧图、图片的base64编码
- 可以使用之前学过的requireJs,也可以使用webpack解决各个包之间的复杂依赖关系
什么是webpack
webpack是前端的一个项目构建工具,它是基于Node.js开发出来的一个前端工具,可以使用nodejs的内置模块(path, fs, url, querystring, http)
如何完美实现上述的2中解决方案
- 使用Gulp,是基于 task 任务的,小巧灵活
- 使用webpack, 是基于整个项目进行构建的
webpack安装的两种方式
- 运行
npm i webpack -g
全局安装webpack,这样就能在全局使用webpack的命令 - 在项目根目录中运行
npm i webpack --save-dev
安装到项目依赖中
快速了解几个概念
环境(mode)
- development 开发环境
- production 生产环境
入口文件(entry)
入口文件,指示webpack应该使用哪个模块,来作为构建内部依赖的开始,进入入口文件后,webpack会找到有哪些模块和库是入口文件所依赖的(直接或间接)
可以在webpack的配置文件中配置入口,配置节点位entry,当然可以配置一个入口,也可以配置多个
输出(output)
output属性告诉webpack在哪里输出文件,以及如何命名这些文件
loader
loader让webpack能过够去处理那些非js文件(webpack自身只理解javascript)。loader可以将所有类型的文件转换为webpack能够处理的有效模块
插件(plugins)
loader被用来转换某些类型的模块,而插件可以用于执行范围更广的任务
常用配置
- 处理css
- 这里会使用到style-loader,是将css以js文本注入的方式注入到style标签内,还会使用到css-loader,是让webpack可以识别以.css为后缀的模块
module.exports = {
...
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'] // 从右向左
}
]
}
}
- 处理sass文件
- sass-loader 让webpack可以识别以.scss为后缀的模块,此模块依赖与node-sass,所以也需要下载
module.exports = {
...
module: {
rules: [
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'] // 从右向左
}
]
}
}
- 将样式抽离为css文件
- mini-css-extract-plugin 使用此插件将样式不再以注入style的形式显示,而是将样式抽离出一个css文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module: {
...
rules: [
{
test: /\.(sc|c|sa)ss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader'
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css'
})
]
- 压缩html并将编译的css和js自动引入到html内
- html-webpack-plugin
plugins: [
new HtmlWebpackPlugin({
title: "这是标题",
filename: 'main.html', // 默认为index.html 生成的文件名
template: path.join(__dirname, 'src/main.html'), // 被编译压缩的html文件
minify: {
collapseWhitespace: true, //去空格
removeComments: true, // 去注释
removeAttributeQuotes: true, // 去属性的双引号
removeEmptyAttributes: true // 去空属性
}
})
],
- 处理图片
- file-loader 处理文件的导入
module: {
rules: [
{
test: /\.(jpg|png|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'img/'
}
}
]
}
]
},
- 更进一步处理图片成base64
- url-loader 功能类似于file-loader,可以把url地址对应的文件打包成base64格式,提供访问效率
module: {
rules: [
{
test: /\.(jpg|png|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 100000 // 小于多少B就转换成base64
}
}
]
},
{
test: /\.html$/,
use: ['html-loader'] // 处理html内的img
}
]
},
- es6转es5 babel-loader @babel/core @babel/preset-env
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
"babel-loader"
]
}
]
}
需要在根目录创建一个.babelrc 文件
{
"presets": [
"@babel/preset-env"
]
}
- 每次清除输出的dist目录
- clean-webpack-plugin
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
plugins: [
new CleanWebpackPlugin()
]
- 创建服务器,自动更新,代理
- webpack-dev-server 需要全局安装一次
module.exports = {
...
devServer: {
hot: true, // 启用webpack的模块热替换特性,需要配合webpack.HotModuleReplacePlugin插件
contentBase: path.join(__dirname, '../dist'),
port: 8080,
host: 'localhost', // 默认为localhost本机访问,如果设置成0.0.0.0则服务器外部可以访问
open: true, // 是否自动打开浏览器
before(app) {
app.get(接口名, (req, res) => {
res.send()
})
},
// publicPath: '/', // 此路径下的打包文件可在浏览器中访问
proxy: {
"/api": {
target: "http://localhost:3000",
pathRewrite: {"^api": "/api/getlist"}
}
// /api/getlist => http://localhost:3000/mock/api/getlist
}
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
}