前言

为什么要使用构建工具?

1.转换ES6语法(很多老版本的浏览器不支持新语法) 2.转换JSX  3.CSS前缀补全/预处理器  4.压缩混淆(将代码逻辑尽可能地隐藏起来)  5.图片压缩  6. ....

为什么选择webpack?

  1. 社区生态丰富
  2. 配置灵活、插件化扩展
  3. 官方更新迭代速度快

基础概念

默认的配置文件是weback.config.js,在package.json中配置脚本可以通过webpack --config来指定构建使用的配置文件。

初始化

创建并进入新的目录,执行如下命令,初始化package.json文件,这是一个模块的描述文件,-y的意思是所有配置都是yes

npm init -y

安装webpack

npm install webpack webpack-cli --save-dev

核心概念

先看一下一份最简单的webpack配置是什么样的

const path = require('path');

module.exports = {
entry: './src/index.js', // 打包的入口文件
output: { // 打包后的输出
filename: "bundle.js",
path: path.join(__dirname, "/dist")
},
mode: 'development', // 所处环境
module: {
rules: [
{
test: /\.js$/,
use: "babel-loader"
},
......
]
},
plugins: [
new HtmlWebpackPlugin(),
]
};

entry

打包的入口文件

单入口:

entry: "./src/index.js"

多入口(适用于多页面场景):

entry: {
app: "./src/app.js",
adminApp: "./src/adminApp.js",
}

output

打包之后的输出

单输出:

output: {
filename: "bundle.js",
path: __dirname + "/dist"
}

多输出:

output: {
filename: "[name].js", // 占位符[name]代表entry中的key
path: __dirname + "/dist"
}

Loaders

webpack只支持JS和JSON两种文件类型,要想支持其他文件类型且转化成有效的模块,需要通过Loaders。Loaders本身是一个函数,接收源文件做参数,返回转换的结果。

常见的Loaders

babel-loader   转换ES6/ES7等语法
css-loader 支持.css文件的加载和解析
less-loader 将less文件转换成css
ts-loader 将TS转换成js
file-loader 将图片、字体等的打包
raw-loader 将文件以字符串的形式导入
thread-loader 多线程打包JS和CSS

Plugins

插件用于打包文件的优化,资源管理和环境变量注入,作用于整个构建过程。也可以理解为Loaders无法完成的事情都可以用Plugins完成。

常见的Plugins:

CommonsChunkPlugin        常用于多页面打包情况下,将多个页面公用的js代码块提取成公共js
CleanWebpackPlugin 清理构建目录
ExtractTextWebpackPlugin 将CSS从bundle文件里提取成一个独立的CSS文件
CopyWebpackPlugin 将文件或文件夹拷贝到够贱的输出目录
HtmlWebpackPlugin 创建html文件去承载输出的bundle。这个非常有用,不需要我们手动去创建html文件
UglifyjsWebpackPlugin 压缩JS
ZipWebpackPlugin 将打包的资源生成一个zip包

mode

用来指定当前的构建环境,值有 production 、development 、none,默认是production。通过mode可以使用webpack内置的函数和功能:

developement

开启 NamedChunksPlugin 和 NamedModulesPlugin 在代码热更新阶段,打印哪个模块发生了更新

production

开启 FlagDependencyUsagePlugin , FlagIncludedChunksPlugin , ModuleConcatenationPlugin , NoEmitOnErrorsPlugin,OccurrenceOrderPlugin , SideEffectsFlagPlugin 和 TerserPlugin

none

不开启任何优化

webpack基础功能

解析ES6

使用babel-loader, babel的配置文件是.babelrc, 增加ES6的babel preset配置

1.安装包

npm install @babel/core @babel/preset-env babel-loader -D

2.创建.babelrc文件,并添加配置

{
"presets": [
"@babel/preset-react",
"@babel/preset-env"
]
}

3.webpack.config.js配置

module: {
rules: [
{
test: /\.js$/,
use: "babel-loader", // 用来解析ES6
},
]
},

解析JSX

增加babel preset配置:

"@babel/preset-react"

要在React中使用箭头函数,需要安装插件

npm i @babel/plugin-proposal-class-properties
// .babelrc
"plugins": [
"@babel/plugin-proposal-class-properties"
]

解析CSS/CSS预处理/前缀补全

less-loader   将less转化成css
css-loader 让webpack解析css文件,并转换成commonjs对象,插入到JS里(因为webpack本身只支持js和json)
style-loader 将样式通过<style>标签插入到<head>中

CSS前缀常见的有: -ms -moz -webkit -o 需要安装autoprefixer 和 postcss-loader

npm i autoprefixer postcss-loader

配置:

{
test: /\.less$/,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
plugins: () => [
require('autoprefixer')({
overrideBrowserslist: ['last 2 version', '>1%', 'ios 7'] // 指定所需要兼容浏览器的版本
})
]
}
},
"less-loader",
]
},
执行顺序:less-loader -> postcss-loader -> css-loader -> style-loader

解析图片、字体

file-loader 用于处理文件

js文件中:

import logo from './images/geektime.png'
const MyComponent = () => {
retrun <img alt="" src={logo} />
}

webpack.config.js配置:

{
test: /.(png|jpg|gif|jpeg)$/i,
use: {
loader: "file-loader",
options: {
name: '[name][hash:8].[ext]' // 重命名打包后的文件
}
}
}

很多时候,前端的图片请求路径需要从后端接口获取,不适用此场景。另外,即使不从后端获取,静态资源也可以用传统的相对路径引用,此时存在一个问题,就是打包后的文件夹,与打包前源文件位置不同,相对静态文件的相对路径也不同,造成打包后路径失效,无法引入的情况。我们需要将静态文件夹整体复制到打包后的文件目录内,手工做太麻烦,可以借助插件实现。

npm i copy-webpack-plugin

webpack.config.js配置:

const CopyWebpackPlugin = require('copy-webpack-plugin');
plugins: [
new CopyWebpackPlugin([
{
from: './src/static',
to: __dirname + './dist/static'
}
])
]

资源解析

url-loader 也可以处理图片和字体,可以设置较小资源自动 base64。

webpack.config.js配置:

{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: "url-loader",
options: {
limit: 1024*5, // 当文件小于1024*n字节,webpack将该资源自动转化成base64编码在js文件中
}
}
]
}

文件监听

文件监听指在发现源代码发生变化时,自动重新构建出新的输出文件。需要手动刷新浏览器。

webpack开启监听模式有两种方式:

  • 命令打包时带上 --watch参数(可以在package.json中配置脚本)
  • 配置webpack.config.js中设置 watch: true

webapck配置:

watch: true,
watchOptions: {
ignored: /node_modules/, // 不监听的文件或文件夹,默认为空。正则匹配/字符串都可
aggregateTimeout: 300, // 监听到变化发生后,延迟300ms再去执行,默认300ms
poll: 1000 // 轮询频率,默认每秒1000次
},

监听原理:轮询判断文件的最后编辑时间是否发生变化。某个文件发生了变化,并不会立即告诉监听者,而是先缓存起来,等aggregateTimeout时间过后再构建。

热更新

需要安装webpack-dev-server,适用于开发环境,不输出文件,将构建后的内容保存在内存中。

在package.json中编写脚本:

"dev": "webpack-dev-server --open"   // open指自动打开浏览器

webpack配置:

devServer: {
contentBase: './dist', // 必需
port: 8080, // 默认8080
hot: true // 默认true
},

当然,如果使用html-webpack-plugin,则不需要contentBase属性。

文件指纹策略

作用:

  1. 做版本管理。当文件发生修改时,只需要更新发生变化的文件
  2. 浏览器缓存。文件名发生变化时,浏览器会重新请求该文件,而其它未改变的文件则直接从缓存中拿就行。

三种hash:

  • Hash:和整个项目的构建相关,只要项目文件有修改,整个项目构建的hash值就会改变
  • Chunkhash:和webpack打包的chunk有关,不同的entry会生成不同的chunkhash值,只能在生产环境中使用
  • Contenthash:根据文本内容来定义hash,文件内容不变,则contenthash不变

使用:

entry: {
app: './src/app.js',
search: './src/search.js',
},
output: {
filename: '[name][chunkhash:8].js',
path: __dirname + '/dist'
}

CSS由于style-loader的存在,被内联在html中,可以用插件将其独立出一个css文件。

npm install mini-css-extract-plugin

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
plugins: [
new MiniCssExtractPlugin({ // 该插件会将css提取出来并在html中引入独立的文件,与style-loader互斥
filename: '[name][contenthash:8].css'
});
]

JS文件只能使用hash和ChunkHash,CSS建议使用ContentHash

占位符:
[ext] 后缀名
[name] 文件名称
[path] 文件的相对路径
[folder] 文件所在的文件夹
[contenthash] 文件的内容hash,默认是md5生成
[hash] 文件内容的hash,默认md5生成(注意这里的hash与前面的"hash"意义不一样)
[emoji] 一个随机的只带文件内容的emoji

文件压缩

主要是HTML、CSS、JS的压缩

JS压缩:

  webpack内置了uglifyjs-webpack-plugin,在生产环境自动实现了JS压缩

CSS压缩:

  使用optimize-css-assets-webpack-plugin 和 cssnano可以实现对CSS文件进行压缩,因为style-loader将CSS内联在html中,需要借助 mini-css-extract-plugin 插件将CSS分离成文件。

HTML压缩:

  html-webpack-plugin设置压缩参数minify,可以将空格、换行和注释干掉

npm install html-webpack-plugin optimize-css-assets-webpack-plugin cssnano mini-css-extract-plugin

const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
// 一个页面对应一个 html-webpack-plugin
module: {
rules: [
{
test: /\.less$/,
use: [
// "style-loader",
MiniCssExtractPlugin.loader, // 与style-loader互斥
"css-loader",
{
loader: "postcss-loader",
options: {
plugins: () => [
require('autoprefixer')({
overrideBrowserslist: ['last 2 version', '>1%', 'ios 7'] // 指定所需要兼容浏览器的版本
})
]
}
},
"less-loader",
]
},
]
},
new HtmlWebpackPlugin({
template: "./src/index.html", // 模板所在路径
filename: "index.html", // 指定打包后的文件名称
// chunks: [''], // 生成的html要链入哪些js文件。数组值对应的是entry中的键
// inject: true, // 将生成的css等文件自动注入到html内,默认开启
minify: {
html5: true,
collapseWhitespace: true, // 干掉空格
preserveLineBreaks: false, // 干掉换行
minifyCSS: true, // 压缩html内的css
minifyJS: true, // 压缩html内的js
removeComments: true, // 删除注释
},
}),
new MiniCssExtractPlugin({
filename: '[name][contenthash:8].css'
}),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'),
}),

自动清理构建目录

借助 clean-webpack-plugin 每次构建都会自动删除之前的构建目录。默认会删除output指定的输出目录。

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
new CleanWebpackPlugin(),

最新文章

  1. C. Shaass and Lights 组合数学
  2. 大型架构.net平台篇(WEB层均衡负载nginx)
  3. 排序+逆向思维 ACdream 1205 Disappeared Block
  4. C#生成软件注册码
  5. PostgreSQL的 initdb 源代码分析之十二
  6. Javascript中的函数(Function)与对象(Object)的关系
  7. Android ===smail语法总结
  8. html+css布局小练习w3cfuns
  9. Emgu学习笔记(一)安装及运行Sample
  10. html学习 - 自己主动跳转与自己主动刷新
  11. ibatis实战之OR映射
  12. Spark SQL原理及实战
  13. SQL Server AlwaysON从入门到进阶(3)——基础架构
  14. [CF893F] Subtree Minimum Query
  15. GitLab管理之 - Gitlab 用户管理
  16. 【BZOJ5250】[九省联考2018]秘密袭击(动态规划)
  17. Linux命令之lsof
  18. vue quill editor输入文字出现首字母的问题
  19. oracle锁表查询
  20. Restful的优势

热门文章

  1. 【JZOJ3301】家族
  2. CentOS7服务器中apache、php7以及mysql5.7的安装配置代码
  3. Serverless Kubernetes全面升级2.0架构:支持多命名空间、RBAC、CRD、PV/PVC等功能
  4. IDEA启动springboot项目一直build
  5. Android基础控件ScrollView滚动条的使用
  6. 从0开始学习ssh之岗位管理
  7. js格式化数字为金额
  8. Leetcode963. Minimum Area Rectangle II最小面积矩形2
  9. Leetcode240. Search a 2D Matrix II搜索二维矩阵2
  10. centos7.5安装公版mysql5.7.25