目录
提取css成单独文件(MiniCssExtractPlugin)
压缩css(OptimizeCssAssetsWebpackPlugin)
webpack实现js兼容性处理(babel-loader)
webpack是什么?
webpack是一个模块打包机,它做的事情是分析你的项目结构,找到js模块以及其它的一些浏览器不能直接运行语言(Scss、less、ts),并将其打包为合适的格式以供浏览器使用。
webpack解决什么问题?
进行重新加载编译。实际就是将浏览器不认识的语法编译成浏览器认识的语法。比如less编译成css,ES6 语法 转成 ES5等等。
减少io请求。通常我们在请求后,会返回一个html到浏览器。这时,我们如果打开控制台,就会发现在html页面通过script,link等标签引用的静态资源, 浏览器会再次发出请求去获取这些资源。但是webpack的打包,将所有的静态资源都合并好了,减少了io请求
理解:
- webpack能处理js/json资源,不能处理css/img等其他资源
- 生产环境和开发环境将es6模块化编译成浏览器能识别的模块化
- 生产环境比开发环境多了一个压缩js代码,所以体积会小一点
webpack打包样式资源
webpack的配置文件:
指示webpack干哪些活,当运行webpack指令时,会加载里面的配置。所有的构建工具都是基于nodejs平台运行的,模块化默认采用commonJS。
配置loader在module.rules里面进行配置,loader是有执行顺序的,从右到左,从下到上 依次执行
loader配置: 不同文件必须配置不同loader处理
使用多个loader用use,单个loader,用loader
// 配置多个loader
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}
// 配置单个loader
{
test: /\.(jpg|png|gif)$/,
loader: 'url-loader'
}
基本配置:
配置less文件先用less-loader编译为css文件,在用css-loader处理加载css到js文件中,然后最后用style-loader实现创建style标签插入head中
module: {
rules: [
// 详细loader配置
{
test: /\.css$/, // 匹配那些文件
// use数组中的执行顺序:从右往左,从下到上 依次执行
use: [
'style-loader', // 创建style便签,将js中的样式资源插入进去,添加到head中生效
'css-loader', // 将css文件变成commonJS模块加载到js中,里面的内容是样式字符串
] // 使用哪些loader
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader', // 将less文件编译成css文件
]
}
]
}
webpack打包html资源
// 下载
npm install html-webpack-plugin -D
// 引用
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 配置
module.exports = {
plugins: [
// 默认会创建一个空的html文件,自动引入打包输出的所有资源
new HtmlWebpackPlugin({
// 复制这个目录下的文件,并自动引入打包输出的所有资源
template: './src/index.html'
})
]
}
webpack打包图片资源
url-loader:处理图片资源,url-loader依赖file-loader,所以还得下载file-loader
file-loader:打包的资源会给每个资源都生成一个随机的hash值作为资源的名称
html-loader:处理html文件中img标签引入的图片(负责引入img,从而能被url-loader能够处理)
url-loader和file-loader有什么不同?
url-loader是基于file-loader封装的一个新的库,可以说是url-loader在file-loader的基础上做了小小的优化,实现功能实际都差不多,无非是url-loader多了一个limit属性设置图片过小转换为base64格式
当webpack发现用了同一个图片,他不会重复打包,会引用打包好的文件
module.exports = {
module: {
rules: [{
// 处理不了html文件中img标签中引入的图片
test: /\.(jpg|png|gif)$/,
loader: 'url-loader', // 处理图片资源 url-loader依赖file-loader,所以还得下载file-loader
options: {
/*
图片大小 < limit设置值,就会被base64处理(base64字符串)
优点:减少请求数量,减轻服务器压力
缺点:图片体积会更大,文件请求速度慢一点
*/
limit: 2 * 1024, // 8KB
/*
产生问题:url-loader默认使用es6模块化解析,而html-loader引入图片是commonJS,解析时会出问题:[object Module]?
解决:关闭url-loader的es6模块化,使用commonJS解析
*/
esModule: false,
// 给图片重命名 [hash:10]取图片hash值的前十位 [ext]取文件原来后缀名
name: '[hash:10].[ext]'
}
},
{
// 处理html文件中img标签引入的图片(负责引入img,从而能被url-loader能够处理)
test: /\.html$/,
loader: 'html-loader'
}]
}
}
webpack打包其他资源(字体、图标)
module.exports = {
module: {
rules: [
{
// 打包其他资源(除了html/js/css/less以外的其他资源)
// 排除指定资源不处理
exclude: /\.(css|js|html|less)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
}
]
}
}
devServer(自动打包)
开发服务器 devserver:用来自动化(自动编译、自动打开浏览器、自动刷新浏览器)
特点:只会在内存中编译打包,不会有任何输出
启动指令:npx webpack-dev-server
运行项目指令:
(1) webpack指令会严格按照流程输出内容
(2) npx webpack-dev-server指令只会在内存中编译打包,一旦停止运行,内存中的内容又会被删除,所以不会输出内容
比如:把dist文件夹删掉然后运行 npx webpack-dev-server,那么项目目录是不会自动生成dist文件夹的。
只要代码发生变化,会自动编译代码,浏览器自动刷新
module.exports = {
devServer: {
contentBase: resolve(__dirname, 'dist'), // 项目构建后路径
compress: true, // 是否开启gzip压缩,让我们的代码提体积更小,优化
port: 3001, // 端口号
open: true, // 自动打开浏览器
}
}
构建环境介绍
开发环境:能让代码本地调试运行的环境源代码 => webpack => bundle
生产环境:能让代码优化上线运行的环境需要做哪些事情呢??
- css代码通过css-loader加载到js文件中,会让js文件体积变的很大,因为它会先加载js才会创建style便签插入到head中,所以会出现闪屏现象。那么这个时候就要做把css文件从js中提取出来;
- 代码统一进行压缩处理;
- 样式代码和一些部分js代码是有兼容性问题,例如css3,需要做样式和js的兼容;
- 代码能够更快更强,性能更好,能够在浏览器中平稳的运行。
提取css成单独文件(MiniCssExtractPlugin)
MiniCssExtractPlugin.loader:这个loader取代style-loader。作用:提取js文件中的css代码成单独文件
// 安装插件
npm install mini-css-extract-plugin --dev-save
// 引入
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// 基本配置
module.exports = {
module: {
rules: [
{
test: /\.css$/,
// use数组中的执行顺序:从右往左,从下到上 依次执行
use: [
// 创建style便签,将js中的样式资源插入进去,添加到head中生效
// 'style-loader',
// 这个loader取代style-loader。作用:提取js文件中的css代码成单独文件
MiniCssExtractPlugin.loader,
// 将css文件变成commonJS模块加载到js文件中,里面的内容是样式字符串
'css-loader',
],
},
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/build.css', // 对输出的css文件进行重命名
})
]
}
css兼容性处理(postcss-loader)
css兼容性处理:postcss => postcss-loader、postcss-preset-env
postcss-preset-env:帮postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式。
- package.json中增加browserslist配置:
"browserslist": {
// 开发环境 => 要想取开发环境的设置,需要webpack.config.js中设置node环境变量:process.env.NODE_ENV = 'development'
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
// 生产环境 => 默认是生产环境,跟设置mode没关系
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
- 安装:
npm install postcss-loader postcss-preset-env --dev-save
- 有两种配置方式:
// 方式一:使用loader的默认配置,但是一般都得配置
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
'postcss-loader'
]
}
]
}
// 方式二:修改loader配置,写成一个对象的形式
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
ident: 'postcss',
plugins: () => [
require('postcss-preset-env')()
]
}
}
}
]
}
]
}
压缩css(OptimizeCssAssetsWebpackPlugin)
// 下载
npm install optimize-css-assets-webpack-plugin --dev-save
// 引入
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
// 使用
plugins: [
new OptimizeCssAssetsWebpackPlugin()
]
js语法检查(eslint)
语法检查:代码规范,语法问题 eslint-loader eslint
注意:只检查自己写的源代码,第三方库是不检查的
(1)设置检查规则:package.json中eslintConfig中设置
"eslintConfig": {
"extends": "airbnb-base"
}
(2)airbnb(js风格指南) => eslint-config-airbnb-base依赖于两个库eslint、eslint-plugin-import
{
test: /\.js$/,
exclude: /(node_modules|dist)/,
loader: 'eslint-loader',
options: {
// 自动修复
fix: true
}
}
webpack实现js兼容性处理(babel-loader)
ie浏览器等一些低版本浏览器可能不支持es6及以上的语法处理,所以要做兼容处理,将es6语法的代码编译为es5浏览器识别的语言
所用插件简单了解:
- babel-loader:es6语法转换为es5语法(负责es6语法转换)
- @babel/core:babel核心包
- @babel/preset-env:只能转换基本语法,promise不能转换。告诉balbel使用哪种转码规则进行文件处理
- @babel/polyfill:全部兼容性处理,将所有的兼容性代码全部引入,体积太大。使用只要引入即可,在index.js文件中 import '@babel/polyfill'
- core-js:需要做兼容性处理就做按需加载
方案一:基本语法兼容处理,但是像promise这些,处理不了
// 安装
npm install babel-loader @babel/preset-env @babel/core --save
// 配置:
module: {
rules: [
{
test: /\.js$/,
enclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'] // 预设:指示babel做哪些的兼容性处理
}
}
]
}
方案二:全部兼容处理
安装:npm install @babel/polyfill --save
使用:在index.js入口文件中import引入:import '@babel/polyfill'
缺点:将所有的兼容性代码全部引入,打包后文件体积会大,加载速度慢,性能不好。
方案三:core-js兼容按需加载
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage', // 按需加载
corejs: { // 指定corejs版本
version: 3
},
targets: { // 指定兼容性做到哪个版本浏览器
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
}
]
}
webpack压缩html和js
js压缩:
生产环境会自动加载好多个插件自动实现压缩文件,所以只要将mode设置为porduction即可。
html压缩:
plugins: [
new HtmlWebpackPlugin({
// 复制这个目录下的文件,并自动引入打包输出的所有资源
template: './src/index.html',
minify: {
// 移除空格
collapseWhitespace: true,
// 移除注释
removeComments: true
}
}),
]