webpack是一个模块打包工具,能够递归构建一个js模块的依赖关系,将模块最终打包成一个或多个文件.
安装
yarn add webpack webpack-cli
零配置
webpack可以进行零配置,只是此时打包功能比较弱.执行:
npx webpack
进行打包. 执行npx webpack默认查找node_modules---bin文件夹--webpack.cmd--执行../webpack/bin/webpack.js
手动配置
简单配置
let path = require('path');
module.exports = {
mode: 'development', //模式:打包后的文件是否可见production/development
entry: './src/index.js', // 入口,可以是相对路径
output: { // 出口
filename: 'bundle.[hash:8].js', // 打包后的文件名:+哈希(打包生成新的文件), :8指定哈希长度
path: path.join(__dirname, 'build'), // 打包后的文件路径:必须是绝对路径
}
};
默认配置文件名为webapck.config.js
webpack-cli文件夹下的config-yarg.js文件指定,配置文件名为webpack.config.js 或 webpackfile.js
修改配置文件名
- 方法一:
npx webpack --config webpack.config.name.js
- 方法二: 在package.json文件中配置脚本进行打包, 同时修改配置文件名
"scripts": {
"build": "webpack --config webpack.config.my.js"
}
// 执行 npm run webpack进行打包
当仅在package.json文件中配置脚本进行打包, 在执行命令中修改配置文件名时:
"scripts": {
"build": "webpack"
}
// 执行npm run build -- --config webpack.config.my.js 打包,注意两个--进行传参
html文件处理
启动静态服务-webpack-dev-server
webpack-dev-server:启动了一个使用express的Http服务器
// webpack.config.js文件
devServer: { // 开发服务器配置,实现静态服务
port: 3000, // 服务器启动端口
progress: true, // 打包进度条
contentBase: path.join(__dirname, './build'), // 指定静态服务目录
compress: true, // 是否压缩
}
// package.json文件
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server"
}
// 执行npm run dev运行静态服务,通过http://localhost:3000在浏览器中访问
html-webpack-plugin
html-webpack-plugin:将打包后的js文件放在html中,将结果放在build目录下
// webpack.config.js文件
let HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html', // html模板文件
filename: 'index.html', // 打包后的文件名称
hash: true, // 添加哈希,避免缓存
minify: { // 对html也进行压缩
removeAttributeQuotes: true, // 删除双引号
collapseWhitespace: true, // 折叠为一行
}
}),
],
css文件处理
在html中不能直接引入css文件,因为上文提到html文件只是一个模板;所以,一般是在js文件中引入css文件,引入时需要通过loader进行解析
文件解析
module: {
rules: [{
// css文件
test: /\.css$/,
use: [{
loader: 'style-loader',
options: {
insertAt: 'top', // 将css插入到自定义css的顶部
},
}, 'css-loader'],
}, {
// less文件
test: /\.less$/,
use: [style-loader, 'css-loader', 'less-loader'],
}],
}
- loader特点:功能专一,所以需要多个loader,loader顺序: 从右向左 从上往下执行
- css-loader:处理css文件,如解析@import语法等
- style-loader:以style标签形式将css代码插入在html页面的head标签,默认插入在head标签的底部;可以通过
- less-loader: 将less转为css, yarn add less less-loader
css样式抽离:mini-css-extract-plugin
将所有的css放在head标签中,如果内容过多,导致页面加载阻塞,根据需要将css抽离到单独的文件中.
let MiniCssExtractPlugin = require('mini-css-extract-plugin');
plugins: [
new MiniCssExtractPlugin({
filename: 'main.css', // 抽离出的css文件名
}),
],
module: {
rules: [{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader, // 使用此loader将抽离后的css文件路径放在link标签中
'css-loader',
'postcss-loader',
],
}, {
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'less-loader'
],
}],
},
css添加前缀: autoprefixer postcss-loader
// 新增postcss.config.js文件
module.exports = {
plugins: [require('autoprefixer')],
};
// webpack.config.js
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader', // 添加前缀
'less-loader'
],
打包css文件: optimize-css-assets-webpack-plugin
使用此插件会对css进行压缩时,必须使用uglifyjs-webpack-plugin,否则js文件不会压缩
let OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
let UglifyJsPlugin = require('uglifyjs-webpack-plugin');
optimization: { // 优化项
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true,
}),
new OptimizeCssAssetsPlugin()
]
}
js文件处理
安装babel-loader、@babel/core、@babel/preset-env(es6语法)、@babel/plugin-proposal-class-properties@7.5.5(es7语法)、@babel/plugin-proposal-decorators(装饰器)、@babel/plugin-transform-runtime(修改内置方法或高级语法时使用,抽离部分公共方法)、@babel/runtime(不定)、@babel/polyfill(解析includes方法解析等es7语法) 、eslint(js语句校验规则)
module: {
rules: [{
test: /\.js$/,
use: {
loader: 'eslint-loader',
options: {
enforce: 'pre', // 强制在普通loader之前执行 post在普通loader之后执行
}
},
exclude: /node_modules/,
}, {
test: /\.js$/,
use: {
loader: 'babel-loader', // 转化es6语法
options: {
presets: [
'@babel/preset-env',
],
plugins: [ // 转化es7语法 注意顺序
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose" : true }],
"@babel/plugin-transform-runtime"
],
},
},
exclude: /node_modules/, // 默认会查找所有文件
include: path.resolve(__dirname, 'src'),
}],
},
eslint校验规则: 在eslint.org/demo中配置需要的e…
将jquery注入到每个模块中
通过内联espose-loader将$暴露到window上
import $ from 'expose-loader?$!jquery';
console.log(window.$);
或者
module: {
rules: [{
test: require.resolve('jquery'),
use: 'expose-loader?$',
}]
}
给每个模块提供$
let webpack = require('webpack');
plugins: [
new webpack.ProvidePlugin({
$: 'jquery', // 在每个模块中注入$
}),
],
此时,不能通过window.$获取
可以直接引入jquery cdn
<script src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script> // 直接引入不打包
此时,通过import $ from 'jquery'时,需要配置externals避免jquery被重新打包.
externals: {
jquery: '$',
}
图片使用和打包
js文件中使用图片
file-loader: 生成一张图片到build目录下并返回新的图片地址
import img from './640.jpeg'; // 引入图片,返回的结果是一个新的图片地址
let image = new Image();
image.src = img;
document.body.appendChild(image);
// webpack.config.js
module: {
module: {
rules: [{
test: /\.(png|jpg|jpeg|gif)$/,
use: {
loader: 'file-loader',
},
}]
}
css文件中使用图片
background: url('./huaer.jpeg');
可以直接引入,css-loader会对其转为require方式引入
html文件中使用图片
在html文件中直接引入图片时,通过html-withimg-loader对图片文件进行处理
<img src='./huaer.jpeg' />
// webpack.config.js
module: {
rules: [{
test: /\.html$/,
use: 'html-withimg-loader',
}]
}
url-loader
通过url-loader可以将图片转为base64,减少http请求次数.缺点是文件变大
module: {
rules: [{
test: /\.(png|jpg|jpeg|gif)$/,
use: {
loader: 'url-loader',
options: {
limit: 1, // 当图片小于n k时 用base64转换
outputPath: '/img/', // 输出路径,实现对静态文件分类
publicPath: 'http://guazi.com', // 当通过cdn方式引入文件时,配置引入路径
}
},
}]
}