webpack
webpack 是一个JavaScript应用的静态模块化打包工具
打包
webpack就是将各种资源模块进行打包合并成为一个或者多个包(bundle),并且在打包过程中还可以多资源进行处理(压缩,转换等)
安装webpack
webpack 需要依赖node,在安装webpack之间应该先安装node
- 先全局安装webpack工具:
npm install webpack -g
- 局部安装webpack模块 和 webpack的脚手架:
npm install webpack webpack-cli --save-dev
webpack配置的基本结构
- dist文件夹:用于存放打包之后的文件(不需要创建,打包自动生成)
- public 文件夹:用于存放静态资源(不需要编译打包,比如HTML页面,和引用别人的插件,或者直接卸载结构中的图片)
- src文件夹:用于存放我们写的源文件
- index.js 入口文件
- webpack.config.js 文件 :用于写webpack的配置
webpack工具执行命令
webpack 按照默认的模式去打包
webpack --mode = development 开发环境 打包出来的文件未经过压缩;
webpack --mode = production 生产环境 打包出来的文件是经过压缩的。
使用npm 工具执行webpack
将webpack命令映射到 npm run
在package.json 文件中配置 script
"scripts": {
"dev": "cross-env NODE_ENV=development webpack serve --open --config config/webpack.dev.js",
"build": "cross-env NODE_ENV=production webpack --config config/webpack.prod.js"
},
npm run dev ====>webpack server 开启服务
npm run build ====>webpack 构建打包
webpack 配置
1.入口配置 entry
-
单入口:
entry:'./src/app.js'
-
多入口:
entry: { home: './src/views/home/index.js', about: './src/views/about/index.js' },
2.出口配置 output
output:{
filename: "js/[name].bundle.js", // 打包压缩导出之后的文件名称
path: resolveApp("./dist"), // 导出的路径 基本都是写在dist文件夹下面
clean: true, // 每次打包之后是否需要 清楚缓存
publicPath: 'http://www.baidu.com' // 上线之后的服务 ,打包的时候回自动的添加都所有路径的前面
}
3.模式配置 mode
- 开发环境配置:
mode='development'
- 生成环境配置:
mode='production'
4.module 模块
配置各种loader的属性
让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)
module: {
rules: [
{
test: /\.(scss|sass)$/, // 表示编译后缀名为 scss sass 的文件
include: [], // 指定需要处理的文件或者 文件夹中符合test指定的类型的文件
use:[] , // 写需要使用到的loader
}
]
}
5.plugin 插件
插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务
6.服务 devServer
需要先安装webpack的服务 npm install -D webpack-dev-server
devServer: {
static: {
directory: resolveApp("./public"), // 启动服务默认打开的文件
},
port: 8888, // 服务端口
hot: true, // 热刷新,不用手动刷新浏览器,代码更改 浏览器自动刷新
open:true, // 自动打开服务器
proxy: {
//定义一个标记,如以后api开头的请求都走代理的设置
'/api': {
// 要请求的真实服务端基地址 相当于被/api替代了
target: 'https://...',
//把api重写为空,因为别人没有 /api
pathRewrite: {"^/api":""},
//发送请求头中host会设置成target
changeOrigin: true
}
}
},
7.cache
webpack 5.0版本新增的,如果只有小改动的时候 值压缩小改动发的部分,没有更改的部分全部用之前的缓存的
cache: {
type: 'filesystem'
},
8.resolve
resolve: {
// 配置哪些文件可以省略后缀名
extensions: ['.tsx', '.ts', '.js', '.jsx'],
// 路径别名
alias: {
'@': paths.appSrc, // 用@符号来代替 src文件夹 路径
}
},
9.devtool
devtool: "eval-cheap-module-source-map", // 报错打印能定位到源代码对应的位置
常用的loader和插件
1.处理js代码的loader
-
babel-loader
: 在 webpack 里面利用 babel 解析 ES6 的桥梁;
@babel/core
: babel 的核心模块;
@babel/preset-env
: babel预设,一组 babel 插件的组合,省的我们自己安装插件了。{ test: /\.js$/, include: ['./src'], use: { loader: 'babel-loader', // *引入babel-loader options: { presets: ['@babel/preset-env'] // *引入预设 } } }
-
esbuild-loader
esbuild
是基于Golang
开发的一款打包工具,其主要目的是为了提升构建速度,相比传统打包工具速度可快 10 ~ 100 倍esbuild-loader
是一个构建在esbuild
上的webpack loader
,且可以替代babel-loader
或ts-loader
来提高构建速度。{ test: /\.(js|ts|jsx|tsx)$/, include: paths.appSrc, use: [{ loader: 'esbuild-loader', options: { loader: 'tsx', target: 'es2015' } }] }
2.处理css相关代码的loader
**注意:**当存在使用多个loader的时候,loader执行顺序是从右往左执行,也就是先执行后面的loader,在执行前面的loader
-
style-loader
: 编译css代码 -
css-loader
识别css代码 -
postcss
必须安装postcss-loader
需要依赖改 模块 -
postcss-loader
javaScript转换样式的工具,这个工具能处理css兼容问题 -
postcss-preset-evn
做css更强大的兼容,会自动给浏览器添加前缀之类 -
sass
必须安装,sass-loader
需要依赖的模块 -
sass-loader
处理sass 并编译为css的loader -
less-loader
处理less 并编译为css的loader{ test: /\.css$/, use: [ 'style-loader', 'css-loader', //添加postcss-loader { loader:'postcss-loader', //配置参数 options:{ postcssOptions:{ plugins:['postcss-preset-env'] } } }, 'sass-loader', 'less-loader' ] }
3.处理图片的loader
处理 在js中引用的图片
-
file-loader
{ test: /\.(png|svg|gif|jpe?g)$/, use: { loader:'file-loader', options:{ name: '[name].[contenthash].[ext]', // 处理之后图片名称 outputPath: 'img' // 图片存储的位置 } } }
-
url-loader
url-loader可以将图片转为base64字符串,能更快的加载图片(适用图片文件较少情况,过大的话还是用file-loader)。file-loader相对于拷贝,速度较慢
{ test: /\.(png|svg|gif|jpe?g)$/, use: { loader:'url-loader', options:{ name: 'img/[name].[contenthash].[ext]', limit: 20*1024; // 文件呢大小超过20k,就执行file-loader 存储图片,小于20kb的,会转换为base64编码显示图片 } } } //【ext】扩展名,【name】文件名,【contenthash】表示内容。
-
asset
webpack5之后可以直接使用asset处理图片,不必再配置file-loader或url-loader。能更好的简化使用。且它是webpack5内置模块,不必额外进行安装其它东西。
- 简单配置 (默认是把图片拷贝大dist目录下)
{ test: /\.(png|svg|gif|jpe?g)$/, type: 'asset/resource' }
- 指定路径配置
指定图片打包后位置,放到dist下的img文件夹里,新增generator属性
{ test: /\.(png|svg|gif|jpe?g)$/, type: 'asset/resource', generator:{ filename:'img/[name].[contenthash][ext]' } }
- 转化为base64 配置
{ test: /\.(png|svg|gif|jpe?g)$/, type: 'asset/inline', }
- 根据文件大小来确定是是图片资源还是base64编码
{ test: /\.(png|svg|gif|jpe?g)$/, type: 'asset', generator:{ filename:'img/[name].[contenthash][ext]' }, parser:{ dataUrlCondition: { maxSize: 30*1024 // 操过20kb 就使用图片资源,小于20kb就使用base64编码 } } }
常用插件
每个插件都是一个类(构造函数),直接new就行,可以查看对应插件的官网,了解传的参数对应什么功能。
1.clean-webpack-plugin
清楚缓存
把dist目录自动清空
webpack5 之后不需要用该插件了,直接配置 cache即可
2.html-webpack-plugin
设置文件模板
打包后在目录生成一个HTML,可以设置HTML文件模板
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({
template: './public/home.html', // 模板文件
chunks: ['home'], // 自动引入的js文件名称
inject: 'body', // 注入到body中,表示代码执行完成才会执行js文件
minify: process.env.NODE_ENV === 'production', // 如果是生产环境则 会自动压缩这个文件,否则不压缩
filename: 'home.html'
})
]
// process.env.NODE_ENV :node中的一个全局变量,不要定义 直接获取 ,表示环境变量的
3.copy-webpack-plugin
复制文件
把静态资源中不需要压缩处理的一些文件复制到 dist中
const CopyWebpackPlugin = require("copy-webpack-plugin");
plugins: [
new CopyWebpackPlugin({
patterns: [{
from: paths.resolveApp('./public'), // 复制哪里的文件
to: paths.resolveApp('./dist'), // 复制到哪里去
globOptions: {
ignore: ['**/*.html'] // 忽略不需要 复制的文件
}
}, ],
}),
]
4.mini-css-extract-plugin
css抽离
这个插件是基于webpack5构建的 只能在webpack5环境下才行
- 导入
- 在插件中初始化
- 在module中调用loader
// 引入抽离css的插件
const MinCssExtractPlugin = require('mini-css-extract-plugin');
plugins:[
new MinCssExtractPlugin({
filename:'style/[contenthash].css', //设置输出的css文件名
})
], //设置插件
module:{ //设置模块
rules:[ //设置loader
{
test:/\.(css|less)$/,
use:[
// style-loader不需要了 我们要用link的方式引入css 所以替换掉
MinCssExtractPlugin.loader, //抽离css的loader
'css-loader', //将css转换成js
]
}
]
}
5.progress-bar-webpack-plugin
进度在终端显示进度条
const chalk = require('chalk'); // webpack 内置存在的,不需要安装
const ProgressBarWebpackPlugin = require('progress-bar-webpack-plugin'); //进度条
plugins:[
new ProgressBarWebpackPlugin({
format: ` build [:bar] ${chalk.green.bold(':percent')}(:elapsed seconds)`
})
]
loader了解
loader 概述
在实际开发过程中,webpack 默认只能打包处理以 .js 后缀名结尾的模块。其他非 .js 后缀名结尾的模块,webpack 默认处理不了,需要调用 loader 加载器才可以正常打包,否则会报错!
loader 加载器的作用:协助 webpack 打包处理特定的文件模块
对配置文件进行模块化设置
- config 文件夹 (存放webpack配置文件的)
- webpack.common.js 公共配置文件(把一些一样的配置写在改文件中)
- webpack.dev.js 开发环境中单独的配置
- webpack.prod.js 生产环境的配置
注意 还需要配合 package.json文件中的script脚本设置
// package.json中配置
"scripts": {
"dev": "cross-env NODE_ENV=development webpack serve --open --config config/webpack.dev.js",
"build": "cross-env NODE_ENV=production webpack --config config/webpack.prod.js"
},
// 当执行 npm run dev 的时候,环境变量配置为 NODE_ENV=development 并且执行cinfig下面的 webpack.dev.js文件
// 当执行 npm run build 的时候,环境变量配置为 NODE_ENV=production 并且执行 cinfig下面的 webpack.prod.js文件
// 环境变量就是 通过 process.env.NODE_ENV 来获取的
扩展node中的模块
merge
- 合并对象,深度合并
- Object.assign() 浅合并 merge() 深度合并
const {merge} = require("merge");
module.exports = merge(common, {})
cross-env
运行跨平台设置和使用环境变量的脚本,安装之后直接使用
NODE_ENV =production, 来设置环境变量时,大多数Windows命令提示将会阻塞(报错),所以用cross-env 来做平台的兼容设置