源码地址:https://gitee.com/cyp926/webpack-project.git

"webpack": "^5.46.0",

"webpack-cli": "^4.7.2",

目录

1、webpack介绍,

2、webpack中的常用术语chunk

3、五个核心模块

4、打包html

5、开发服务器devserver,

6、打包css

6.1、打包sass及less,

6.2、抽离css文件,

6.3、css3兼容处理(编译成各个浏览器支持的---前缀--),

6.4、压缩css,

6.5、css去掉无用的代吗,

7、webpack打包资源,

8、背景图打包,

9、eslint代码规范,

10、js兼容处理,

11、树摇tree-shaking,

12、entry多入口实现分割,

13、optimization配置实现分割,

14、路径别名与导入后缀省略


一、webpack

1.1 webpack是什么

webpack是一种前端资源构建工具,一个静态模块打包器.在webpack看来,前端的所有资源文件(js/json/css/image/less/sass...)都会作为模块处理。它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源

配置文件: webpack.config.js

1.2 五个核心内容

  • entry:入口。webpack是基于模块的,使用webpack首先需要指定模块解析入口(entry),webpack从入口开始根据模块间依赖关系递归解析和处理所有资源文件。
  • output:输出。源代码经过webpack处理之后的最终产物。
  • loader:模块转换器。本质就是一个函数,在该函数中对接收到的内容进行转换,返回转换后的结果。因为 Webpack 只认识 JavaScript,所以 Loader 就成了翻译官,对其他类型的资源进行转译的预处理工作。
  • plugin:扩展插件。基于事件流框架 Tapable,插件可以扩展 Webpack 的功能,在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
  • mode 模式。通过选择 development 或 production 之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化

1.3 下载webpack的插件

npm init -y

npm i -D webpack webpack-cli

1.4 基本使用

const path = require('path')
module.exports = {
// https://webpack.docschina.org/configuration/mode/
// 打包模式 development | production
mode: 'development',
// 项目入口
entry: './src/index.js',
// 项目出口
output: {
path: path.resolve(path.dirname(__dirname), 'dist'),
// js/打包的位置, [name]默认的名称为main ,-[hash:8] 拼接hash
filename: 'js/[name]-[hash:8].js'
}
}

运行打包命令行

  • npx webpack
  • npx webpack --mode development (不写配置情况下)
  • npx webpack 需要打包的文件 -o 打包的文件位置与名称 --mode development (不写配置情况下)

快捷配置

我们可以直接在package.json中配置:"build":"webpack"

1.5 打包html

  • 安装:html-webpack-plugin
1)引入
const HtmlWebpackPlugin = require('html-webpack-plugin') 2)打包压缩html(打包多个,就实例化new多个)
plugins: [
new HtmlWebpackPlugin({
title: '欢迎来到Webpack',打包设置标题 (可选项)
template:'./src/index.html', //打包的文件
filename:'demo.html', //打包后的名称 (可选项)
chunks:[], //指定html中使用的js文件 (可选项)
minify:{ //压缩 (可选项)
// 移除空格
collapseWhitespace:true,
// 移除注释
removeComments:true,
}
}),
] 3)模板中使用定义的title
<title><%= htmlWebpackPlugin.options.title %></title>

1.6 开发服务器 devServer

  • npm i -D webpack-dev-server@3 (注意这里我们用到的是3版本的)
  • 命令 npx webpack serve
 // 在webpack5 需要加上这个选项才会自动刷新页面
target:"web"

配置devServer

 devServer:{

        contentBase: path.resolve(__dirname, '../dist'),// 运行代码目录(可选)
port:3001, //端口号
compress:true,//自动更新 (可选)
open:true//自动打开浏览器 (可选)
watchOptions: { ignored: /node_modules/}, // 忽略文件 (可选)
host: 'localhost', // 域名(可选) 默认就是localhost
clientLogLevel: 'none', // 不要显示启动服务器的日志信息
overlay: false, // 如果出错,不要全屏提示
// 服务器代理 --> 解决开发环境跨域问题
proxy: {
// 一旦devServer服务器接受到 /api开头的请求,就会把请求转发到另一个服务器
'/api': {
target: 'http://localhost:3000',
// 发送请求时,请求路径重写: 将/api 去除
pathRewrite: {
'^/api': ''
}
}
}
}

package.json中的scripts中配置命令

"serve": "webpack-dev-server --config ./config/webpack.config.js"

1.7 打包css,sass等样式

1.7.1 打包css

webpack默认只支持js的打包,不支持其它类型,为了让它支持样式的打包就需要加载一些loader

  • npm i -D css-loader style-loader
   /*
一个用 loader:css-loader
一个以上 use:[]
从右往左
*/
module:{
rules:[ {
test: /\.css$/,
use: ['style-loader','css-loader']
}
]
}

1.7.2 打包less或者sass

  • less npm i -D less-loader
 {
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
  • sass npm i -D node-sass sass-loader
 {
test: /\.sass$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
}

1.7.3 提取抽离css为单独文件

  • npm i -D mini-css-extract-plugin
const miniCssExtractPlugin = require('mini-css-extract-plugin')
module:{
rules:[
{
test: /\.css$/,
use: [
miniCssExtractPlugin.loader, //写在第一行
'css-loader']
},
{
test: /\.css$/,
use: [
miniCssExtractPlugin.loader, //写在第一行
'css-loader',
'sass-loader'
]
},
]
},
plugins:[
new miniCssExtractPlugin({filename:'demo.css'})
]

1.7.4css3兼容处理(变异成各个浏览器支持的---前缀--)

  • npm i -D postcss-loader postcss-preset-env
  1. package.json配置兼容浏览器
  "browserslist": [
">0.2%",
"last 2 version",
"not dead"
]
  1. 新建文件postcss.config.js
module.exports={
plugins:[
require('postcss-preset-env')()
]
}
  1. 引入loader
{
test: /\.css$/,
use: [
miniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
},

1.7.5 压缩css

  • npm i -D optimize-css-assets-webpack-plugin
plugins:[
new optimizeCssAssetsWebpackPlugin()
]

1.7.6 css去掉无用的代吗

  • npm i -D purgecss-webpack-plugin
new PurgecssWebpackPlugin({
paths:glob.sync(pattern:`${PATH.src}/**/*`,options:{nodir:true})
})

1.8 webpack打包资源

  • npm i -D url-loader file-loader html-loader

1.8.1 背景图打包

module: {
rules: [
{
test: /\.(png|jpeg|jpg|gif)$/,
loader: 'url-loader',
options: {
publicPath:'./images/',
outputPath: 'imgs/',
name:'[name][hash].[ext]',//命名hash+名称
limit:1024*8,//限制8k一下转base64
}
},
// 也可以这么写图片处理
{
test: /\.(png|jpeg|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
// 图片小于8kb,就会被base64处理
// 优点: 减少请求数量(减轻服务器压力)
// 缺点:图片体积会更大(文件请求速度更慢)
limit: 8 * 1024,
name: 'static/imgs/[name].[ext]',
publicPath: '/dist'
}
}
]
},
]
}

1.8.2 html图 html-loader

module: {
rules: [
{
test: /\.(html)$/,
loader: 'html-loader',
}
]
}

1.8.3 其他文件打包

像项目中字体资源是不需要进行打包处理的,可以直接的通过复制方式给打包到目标目录中

module: {
rules: [
{
// exclude 排查资源
exclude:/\.(js|json|html|css|less|scss|png|jpg)$/,
loader:'file-loader',
options:{
outputPath: 'font/', //打包位置
publicPath:'./font', //寻找位置
name:'[name][hasg].[ext]',//命名hash+名称
}
}
]
}
  • 也可以这样处理静态资源

    • npm i -D copy-webpack-plugin
    const CopyPlugin = require('copy-webpack-plugin')
    plugins: [
    new CopyPlugin({
    patterns: [
    {
    // 来源
    from: path.resolve(__dirname, '../src/iconfont/'),
    // 目标
    to: path.resolve(__dirname, '../dist/iconfont')
    },
    {
    // 来源
    from: path.resolve(__dirname, '../src/iconfont/'),
    // 目标
    to: path.resolve(__dirname, '../dist/iconfont')
    }
    ]
    })
    ]

1.9 eslint代码规范(airbnb)

  • npm i -D eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import
  1. package.json
 "eslintConfig":{
"extends":"airbnb-base"
}
  1. webpack.config.js
{
test: /\.js$/,
//只检查自己写的代码,不检查第三方的
exclude:/node_modules/,
loader:'eslint-loader'
},

1.10 js兼容处理

webpack在不需要引入任何loader可以对于js进行打包处理,但是它不会对于js兼容性进行任务的处理,而我们编写的项目是需要在不同的浏览器中运行的,此时就需要对于js的兼容性在打包过程中进行对应的处理。使用babel来完成对应的js兼容处理

  • npm i -D babel-loader @babel/core @babel/preset-env core-js@3
module: {
rules: [
// js兼容处理
{
test: /\.js$/,
// 排除
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
// 按需加载 inital enter uage
useBuiltIns: 'usage',
// 指定core-js版本
corejs: 3,
// 兼容性做到哪个版本的浏览器
targets: {
chrome: '80',
firefox: '50',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
}
]
}

环境优化

开发环境

- 打包构建速度
- 优化代码调试

生产优化(树摇)

- 代码运行性能

HMR模块热替换

 devServer:{
port:3001,
compress:true,//自动更新
open:true,//自动打开浏览器
hot:true//HMR模块热替换
}

树摇去掉没用到的js代码

  • tree-shaking webpack自帶
  1. es6 导出
  2. 必须是 production

可以:在package.json文件中添加了 "sideEffects": false 表示所有代码都没有副作用(所有代码都可以进行tree shaking)

问题:可能会把 css的@babel/polyfill (副作用)文件删除掉

解决:"sideEffects":["*.css"]

css去掉无用的代吗

  • npm i -D purgecss-webpack-plugin
new PurgecssWebpackPlugin({
paths:glob.sync(pattern:`${PATH.src}/**/*`,options:{nodir:true})
})

代码分割

entry多入口实现分割

entry: {
main: './src/js/index.js',
print: './src/js/print.js'
},
output: {
filename: "js/[name]-[contentHash].js",
path: path.resolve(__dirname, "dist")
}

optimization配置实现分割

  • 过大的js文件拆分成多个,实现并行加载,提高加载速度(把工具库jq,lodash和业务逻辑拆分开)

可以将node_modules中代码单独打包一个chunk最终输出

chunks: 表示显示块的范围,有三个可选值:initial(初始块 同步)、async(按需加载块)、all(全部块),默认为all;

optimization: {
splitChunks: {
chunks: 'all'
}
},

路径别名与导入后缀省略

  // 解析模块的规则
resolve: {
// 配置解析模块路径别名:优点简写路径,缺点路径没有提示
alias: {
// 定义一个@变量,可在import引入时使用
'@': path.resolve(__dirname, '../src')
'$css': path.resolve(__dirname, '../src/css')
},
// 配置省略文件路径的后缀名称 import '@/index'
// 如果省略,建议文件名称不要重名了
extensions: ['.js', '.json', '.vue']
}

二 代码

相关代码

webpack.config.js

// 采用commonjs
const path = require('path')
const htmlWebpackPlugin = require('html-webpack-plugin')
const miniCssExtractPlugin = require('mini-css-extract-plugin')
const optimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
module.exports = {
mode: 'production', //生产:development,开发:production
/*
1、entry:
1、单入口,字符串表示-----打包一个chunk,生成一个build
entry:'./src/index.js',
2、多入口,数组------打包成一个chunk,生成一个build
entry:['./src/index.js','./src/cc.js'],
3、对象的写法 -----有几个文件生成几个chunk,生成几个build
entry:{
one:'./src/one.js',
two:'./src/two.js'
}
*/
entry: './src/index.js',
output: {
filename: '[name].js',
// **对象多入口写法entry: filename:'[name].js',
path: path.resolve(__dirname, 'dist'),
},
// loader 处理非js资源 如html,css,img
module: {
rules: [
/*
一个用 loader:css-loader
一个以上 use:[]
从右往左
{
test: /\.css$/,
use: [
'style-loader',
'css-loader']
},
*/ {
test: /\.css$/,
use: [
miniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
},
{
test: /\.sass$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
},
{
test: /\.(png|jpg|jpeg)$/,
loader: 'url-loader',
options: {
publicPath:'./images/',
outputPath: 'imgs/',
name:'[name][hasg].[ext]',//命名hash+名称
limit:1024*8,//限制8k一下转base64
}
},
{
test: /\.(html)$/,
loader: 'html-loader',
},
{
// exclude 排查资源
exclude:/\.(js|json|html|css|less|scss|png|jpg)$/,
loader:'file-loader',
options:{
outputPath: 'font/', //大包位置
publicPath:'./font', //寻找位置
name:'[name][hasg].[ext]',//命名hash+名称 }
},
// eslint 只检查js
{
test: /\.js$/,
//只检查自己写的代码,不检查第三方的
exclude:/node_modules/,
loader:'eslint-loader',
options:{
fix:true,//自动修复
}
},
]
},
// plugin插件,执行范围更广的任务 打包到开发压缩
plugins: [
// 打包压缩html(打包多个就实例化new多个)
new htmlWebpackPlugin({
template: './src/index.html', //打包的文件
filename: 'demo.html', //打包后的名称
chunks: [], //指定使用的js文件
minify: { //压缩
// 移除空格
collapseWhitespace: true,
// 移除注释
removeComments: true,
}
}),
new miniCssExtractPlugin({ filename: 'demo.css' }),
new optimizeCssAssetsWebpackPlugin()
],
// 在webpack5 需要加上这个选项才会自动刷新页面
target:"web", devServer:{
port:3001,
compress:true,//自动更新
open:true,//自动打开浏览器
hot:true//HMR模块热替换
}
}

postcss.config.js

module.exports={
plugins:[
require('postcss-preset-env')()
]
}

相关依赖文件

package.json

{
"name": "webpack5s",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev":"webpack serve --mode development --port 3000",
"build":"webpack --mode production"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"css-loader": "^6.2.0",
"eslint": "^7.31.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.23.4",
"file-loader": "^6.2.0",
"html-loader": "^2.1.2",
"html-webpack-plugin": "^5.3.2",
"less": "^4.1.1",
"less-loader": "^10.0.1",
"mini-css-extract-plugin": "^2.1.0",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"post-loader": "^2.0.0",
"postcss-loader": "^6.1.1",
"postcss-preset-env": "^6.7.0",
"style-loader": "^3.2.1",
"url-loader": "^4.1.1",
"webpack": "^5.46.0",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2"
},
"browserslist": [
">0.2%",
"last 2 version",
"not dead"
],
"eslintConfig": {
"extends": "airbnb-base"
}
}

轻松搞定webpack5.x的更多相关文章

  1. 【转】轻松搞定FTP之FlashFxp全攻略

    转载网址:http://www.newhua.com/2008/0603/39163.shtml 轻松搞定FTP之FlashFxp全攻略 导读: FlashFXP是一款功能强大的FXP/FTP软件,融 ...

  2. 轻松搞定javascript变量(闭包,预解析机制,变量在内存的分配 )

    变量:  存储数据的容器     1.声明        var   2.作用域       全局变量. 局部变量. 闭包(相对的全局变量):   3.类型         a.基本类型(undefi ...

  3. Webcast / 技术小视频制作方法——自己动手录制video轻松搞定

    Webcast / 技术小视频制作方法——自己动手录制video轻松搞定 http://blog.sina.com.cn/s/blog_67d387490100wdnh.html 最近申请加入MSP的 ...

  4. 【微服务】之二:从零开始,轻松搞定SpringCloud微服务系列--注册中心(一)

    微服务体系,有效解决项目庞大.互相依赖的问题.目前SpringCloud体系有强大的一整套针对微服务的解决方案.本文中,重点对微服务体系中的服务发现注册中心进行详细说明.本篇中的注册中心,采用Netf ...

  5. 【微服务】之三:从零开始,轻松搞定SpringCloud微服务-配置中心

    在整个微服务体系中,除了注册中心具有非常重要的意义之外,还有一个注册中心.注册中心作为管理在整个项目群的配置文件及动态参数的重要载体服务.Spring Cloud体系的子项目中,Spring Clou ...

  6. 从零开始,轻松搞定SpringCloud微服务系列

    本系列博文目录 [微服务]之一:从零开始,轻松搞定SpringCloud微服务系列–开山篇(spring boot 小demo) [微服务]之二:从零开始,轻松搞定SpringCloud微服务系列–注 ...

  7. 【微服务】之四:轻松搞定SpringCloud微服务-负载均衡Ribbon

    对于任何一个高可用高负载的系统来说,负载均衡是一个必不可少的名称.在大型分布式计算体系中,某个服务在单例的情况下,很难应对各种突发情况.因此,负载均衡是为了让系统在性能出现瓶颈或者其中一些出现状态下可 ...

  8. 【微服务】之五:轻松搞定SpringCloud微服务-调用远程组件Feign

    上一篇文章讲到了负载均衡在Spring Cloud体系中的体现,其实Spring Cloud是提供了多种客户端调用的组件,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使 ...

  9. 【微服务】之六:轻松搞定SpringCloud微服务-API网关zuul

    通过前面几篇文章的介绍,我们可以轻松搭建起来微服务体系中比较重要的几个基础构建服务.那么,在本篇博文中,我们重点讲解一下,如何将所有微服务的API同意对外暴露,这个就设计API网关的概念. 本系列教程 ...

随机推荐

  1. HCNA Routing&Switching之OSPF度量值和基础配置命令总结

    前文我们了解了OSPF的网络类型,OSPF中的DR和BDR的选举规则.作用等相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15054938.html: ...

  2. visibility:hidden和display:none的区别

    一.相同点 disable:none和visibility:hidden都能把网页上的某元素隐藏起来 二.不同点 display:none--不为被隐藏的对象保留其物理空间,即该对象在页面上彻底消失. ...

  3. python读取数据写入excel的四种操作

    Python对Excel的读写主要有:xlrd.xlwt.xlutils.openpyxl.xlsxwriter几种 xlutils结合xlrd: 操作的是以xls后缀的excel,读取文件保留原格式 ...

  4. python 装饰函数2

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Tue May 5 21:40:49 2020 ...

  5. SetupDi系列函数

    SetupDiClassGuidsFromName WINSETUPAPI BOOL SetupDiClassGuidsFromNameA( PCSTR ClassName, LPGUID Class ...

  6. Docker run 命令参数及使用

    Docker run 命令参数及使用 Docker run :创建一个新的容器并运行一个命令 语法 docker run [OPTIONS] IMAGE [COMMAND] [ARG...] OPTI ...

  7. 深度掌握 Java Stream 流操作,让你的代码高出一个逼格!

    概念 Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选.排序.聚合等. Stream 的操作符大体上分为两种:中间操作符和终止操作符 中 ...

  8. 【动画消消乐 】仿ios、android中常见的一个loading动画 074

    前言 Hello!小伙伴! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出-   自我介绍 ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计 ...

  9. XSS靶机1

    参考文章https://blog.csdn.net/weixin_30897079/article/details/97314476 第一关 http://www.zixem.altervista.o ...

  10. C++通讯录管理系统(添加联系人,显示联系人,删除联系人,查找联系人,修改联系人,清空联系人,退出通讯录)

    1 /** 2 * ProjectNmae:通讯录管理系统 3 * 功能: 4 * 添加联系人:向通讯录添加新人 5 * 显示联系人:显示通讯录中的所有联系人信息 6 * 删除联系人:按照姓名进行删除 ...