# webpack基础
# 初识webpack
代码
src/index.js
function add(x,y) {
return x + y
}
add(1,2)
运行指令
- 开发环境:webpack ./src/indexjs -o ./build/build.js --mode=development;
- 生产环境:webpack ./src/indexjs -o ./build/build.js --mode=production;
webpack会以 ./src/index.js 为入口文件开始打包,打包后输出到 ./build/build.js
结论
- webpack能处理js/json资源,不能处理css/img等资源;
- 生产环境和开发环境将ES6代码编译成浏览器能识别的代码;
- 生产环境比开发环境多一个js代码压缩;
# webpack五个核心
创建webpack.config.js
- entry 入口目录
- output 输出目录
- loader
- plugins 插件
- mode 模式
/**
* webpack.config.js webpack的配置文件
* */
const { resolve } = require('path')
module.exports = {
// 入口起点
entry: './src/index',
output: {
// 输出文件名
filename: "build.js",
// 输出路径
/**
* __dirname nodejs的变量, 代表当前文件的目录的绝对路径
*/
path: resolve(__dirname,'build')
},
// loader的配置
module: {
rules: [
// 详细的loader配置
]
},
// plugins的配置
plugins: [
],
// 模式 development / production
mode: "development"
}
# 注意:
loader: 1. 下载 2. 使用(配置loader)
plugins: 1 下载 2. 引入 3. 使用
# 打包样式资源
1. 打包样式资源需要配置loader
2. 需要 style-loader 、css-loader
3. 代码配置
// loader的配置
module: {
rules: [
// 详细的loader配置
{
// 匹配哪些文件
test: /\.css$/,
// 使用哪些loader
use: [
// use数组中loader执行顺序:从右到左, 从下到上 依次执行
// 创建style标签,将js中的样式资源插入进行,添加到head中生效
'style-loader',
// 将css文件变成一个commonjs模块加载到js中,里面内容是样式字符串
'css-loader'
]
},
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}
]
}
# 打包HTML资源
1. 安装 html-webpack-plugin
2. 使用
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
/**
* 功能:默认会创建一个空的Html文件,引入打包输出的所有资源(JS/CSS)
*/
new HtmlWebpackPlugin({
// 复制 "./src/index.html" 文件, 并自动引入打包输出的所有资源
template: "./src/index.html",
})
]
# 打包图片资源
// loader的配置
module: {
rules: [
{
// 问题:处理不了html img标签图片 只能处理css background-image
test: /\.(jpg|png|gif)$/,
// url-loader 依赖于 file-loader
loader: 'url-loader',
options: {
// 当图片大小小于8kb,就会被base64处理
// 优点: 减少请求数量(减轻服务器压力)
// 缺点: 图片体积会更大(文件请求速度更慢)
limit: 8 * 1024,
// 问题:因为url-loader默认es6模块化解析,而html-loader引入图片是commonjs
// 解析时会出现问题:[object Module]
// 解决:关闭url-loader的es6模块,使用commonjs解析
esModule: false,
// 给图片重命名
// [hash:10] 取图片的hash的前10位
// [ext] 取文件原来的扩展名
name: '[hash:10].[ext]'
}
},
{
test: /\.html$/,
// 处理html文件的img图片(负责引入img,从而能被url-loader处理)
loader: 'html-loader'
}
]
}
# 打包其他资源
// loader的配置
module: {
rules: [
// 打包其他资源(除了html/js/css资源以外的资源)
{
// 排除html/js/css资源
exclude: /\.(css|js|html)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
}
]
}
# devServer
module.exports = {
// 开发服务器 devServer: 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
// 特点:只会在内存中编译打包,不会有任何输出
// 启动devServer指令为:npx webpack-dev-server(需要下载 npm i webpack-dev-server)
devServer: {
contentBase: resolve(__dirname,'build'),
// 启动gzip压缩
compress: true,
// 端口号
port: 3000,
// 自动打开浏览器
open: true
}
}
# 提取单独的css文件
之前的css文件打包后会在js文件里面,但有另一种方法可以提取单独的css文件
使用mini-css-extract-plugin
const {resolve} = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
// 取代style-loader 作用: 提取js中的css成单独文件
MiniCssExtractPlugin.loader,
'css-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
// 对输出的css文件重命名
filename: 'css/built.css'
})
],
mode: 'development'
}
# css兼容性处理和压缩
css兼容性处理:postcss
- 需要
npm i postcss-loader postcss-prset-env -D
- 帮
postcss
找到package.json
中browserslist
里面的配置,通过配置加载指定的css兼容性样式
//package.json
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
browserslist
默认production
,如需使用development
则需要设置node环境变量:process.env.NODE_ENV = development
loader
的配置
{
loader: "postcss-loader",
options: {
ident: "postcss",
plugins: () => [
// postcss的插件
require('postcss-preset-env')()
]
}
}
- css压缩需要下载插件
npm i optimize-css-assets-webpack-plugin -D
- 完整配置
const {resolve} = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsWebpackplugin = require("optimize-css-assets-webpack-plugin");
// 设置nodejs环境变量
// process.env.NODE_ENV = "development";
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
// 取代style-loader 作用: 提取js中的css成单独文件
MiniCssExtractPlugin.loader,
'css-loader',
// 第一种:使用loader的默认配置
{
loader: "postcss-loader",
options: {
ident: 'postcss',
plugins: () => [
// postcss的插件
require('postcss-preset-env')()
]
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
// 对输出的css文件重命名
filename: 'css/built.css'
}),
// 压缩css
new OptimizeCssAssetsWebpackplugin()
],
mode: 'development'
}
# js语法检查eslint
- 语法检查需要两个插件
npm i eslint-loader eslint -D
- 注意:只检查自己写的源代码,第三方的库是不用检查的
- 设置检查规则:
package.json中eslintConfig
中设置
"eslintConfig": {
"extends": "airbnb-base"
}
- 推荐airbnb检查规则,需要安装
npm i eslint-config-airbnb-base eslint-plugin-import -D
- loader配置
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/, // 排除
loader: 'eslint-loader',
options: {
fix: true, // 自动修复eslint的错误
}
}
]
}
# js兼容性处理
js兼容处理:babel-loader @babel/preset-env @babel/core
1. 基本的js兼容性处理 --> @babel/preset-env
问题:只能转换基本语法,如promise高级语法不能转换
2. 全部js兼容性处理 --> @babel/polyfill
问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了~
3. 需要做兼容性问题的就做:按需加载 core-js
4. 一共需要安装 npm i babel-loader @babel/preset-env @babel/core @babel/polyfill core-js -D
# loader配置
{
test: /\.js$/,
exclude: /node_modules/, // 排除
loader: 'babel-loader',
options: {
// 预设:指示babel做怎样的兼容处理
presets: [
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core-js版本
corejs: {
version: 3
},
// 指定兼容性做到哪个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
}
}
# html和js压缩
# html压缩
在HtmlWebpackPlugin配置
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true, // 移除空格
removeComments: true // 移除注释
}
})
# js压缩
将mode设置为生产环境production,而production会执行UglifJsPlugin进而压缩js代码