Webpack5核心原理与应用实践(基础用法)一
前言
记录Webpack基本配置规则;根据场景、技术栈运用具体方法、工具与技巧。
主要有:搭建完善的JavaScript、CSS开发环境;搭建微前端、NPM包、桌面应用等。
一、Webpack配置项
1.Webpack编译流程
Webpak原生配置项数不胜数,最终都会作用于不同阶段
大致编译流程可分为四个流程:
输入—>模块处理—>后处理—>输出
- 输入:从文件系统读入代码文件
- 模块递归处理:调用 Loader 转译 Module(模块) 内容,并将结果转换为 AST(抽象语法树),从中分析出模块依赖关系,进一步递归调用模块处理过程,直到所有依赖文件都处理完毕;
- 后处理:所有模块递归处理完毕后开始执行后处理,包括模块合并、注入运行时、产物优化等,最终输出 Chunk (按照某种规则的模块集合)集合;
- 输出:将Chunk写出到外部文件系统;
2.Webpack配置
Webpack配置项可分为两大类
- 流程类:作用于打包流程某个或若干个环节,直接影响编译打包效果的配置项
- 工具类:打包主流程之外,提供更多工程化工具的配置项
(1)流程类配置
与流程类配置强相关配置有:
- 输入输出:
entry
:用于定义项目入口文件,Webpack 会从这些入口文件开始按图索骥找出所有项目文件;context
:项目执行上下文路径;output
:配置产物输出路径、名称等;
- 模块处理:
resolve
:用于配置模块路径解析规则,可用于帮助 Webpack 更精确、高效地找到指定模块module
:用于配置模块加载规则,例如针对什么类型的资源需要使用哪些 Loader 进行处理externals
:用于声明外部资源,Webpack 会直接忽略这部分资源,跳过这些资源的解析、打包操作
- 后处理:
optimization
:用于控制如何优化产物包体积,内置 Dead Code Elimination、Scope Hoisting、代码混淆、代码压缩等功能target
:用于配置编译产物的目标运行环境,支持 web、node、electron 等值,不同值最终产物会有所差异mode
:编译模式短语,支持 development、production 等值,可以理解为一种声明环境的短语
Webpack 首先需要根据输入配置(
entry/context
) 找到项目入口文件;之后根据按模块处理(module/resolve/externals
等) 所配置的规则逐一处理模块文件,处理过程包括转译、依赖分析等;模块处理完毕后,最后再根据后处理相关配置项(optimization/target
等)合并模块资源、注入运行时依赖、优化产物结构等。
(2)工具类配置
除了核心的打包功能之外,Webpack 还提供了一系列用于提升研发效率的工具,大体上可划分为:
- 开发效率类:
watch
:用于配置持续监听文件变化,持续构建devtool
:用于配置产物 Sourcemap(储存代码转换前后的对应位置信息) 生成规则devServer
:用于配置与 HMR(模块热更新) 强相关的开发服务器功能
- 开发效率类:
cache
:Webpack 5 之后,该项用于控制如何缓存编译过程信息与编译结果performance
:用于配置当产物大小超过阈值时,如何通知开发者
- 日志类:
stats
:用于精确地控制编译过程的日志内容,在做比较细致的性能调试时非常有用infrastructureLogging
:用于控制日志输出方式,例如可以通过该配置将日志输出到磁盘文件
3.配置逻辑
文件结构如下:
.
├── src
| └── index.js
└── webpack.config.js
其中,
src/index.js
为项目入口文件,webpack.config.js
为 Webpack 配置文件。在配置文件中,首先我们需要声明项目入口:
// webpack.config.js
module.exports = {entry: "./src/index"
};
声明产物输出路径:
// webpack.config.js
const path = require("path");module.exports = {entry: "./src/index",output: {filename: "[name].js",path: path.join(__dirname, "./dist"),}
};
在前端项目中经常需要处理 JS 之外的其它资源,包括 css、ts、图片等,此时需要为这些资源配置适当的加载器:
// webpack.config.js
const path = require("path");module.exports = {entry: "./src/index",output: {filename: "[name].js",path: path.join(__dirname, "./dist"),},module: {rules: [{test: /\.less$/i,include: {and: [path.join(__dirname, './src/')]},use: ["style-loader","css-loader",// "./loader",{loader: "less-loader",},],}],},
};
二、脚手架工具
对于项目的推进,配置管理将十分困难。所以社区提供了对应的脚手架工具来管理配置。
- Vue CLI:用于帮助用户快速创建、运行 Vue.js 项目脚手架的命令行工具;
- create-react-app:用于创建 React 项目脚手架的命令行工具;
- @angular/cli:用于创建 angular 项目的命令行工具;
- webpack-cli:Webpack 官方提供的命令行工具,提供了一套交互式生成配置文件的指令集,以及项目编译、开发、迁移等功能;
- Neutrino:用于快速创建、运行现代 JavaScript 应用的工具,同时支持 React、Preact、Vue、Web、Node.js、Library 等场景;
- react-starter-kit:用于创建 React + Relay + GraphQL 应用的脚手架工具,内置 SSR 支持。
1. Vue CLI 搭建项目脚手架
Vue CLI 底层调用 Webpack 实现针对 .vue 等资源的编译打包功能;调用 webpack-dev-server 实现包含 HMR 功能的开发服务器功能;还能通过插件方式整合 ESLint、Babal、Less 等工具。
安装依赖:(安装完成后 可以使用 vue -V 测试是否安装成功)
npm install -g @vue/cli# 或者使用 yarn
yarn global add @vue/cli
创建项目:
vue create
命令 (可使用vue create --help
命令查看 create 的参数列表仅限于 vue3中使用
)
vue create 项目名
执行 create 命令后,CLI 会进一步询问使用何种脚手架方案:
通常使用第三种自定义
Vue CLI v4.5.15
? Please pick a preset: (Use arrow keys)
❯ Default ([Vue 2] babel, eslint)Default (Vue 3) ([Vue 3] babel, eslint)Manually select features
vue2使用
vue init webpack 项目名
来构建项目
基本回车就行倒数四项根据自身需求来
Project name webpack5-dispose
? Project description A Vue.js project
? Author xxx <邮箱>
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? No
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) yarn
Vue CLI 底层依赖于 Webpack 实现编译打包等工程化能力,开发者可通过
configureWebpack
与chainWebpack
配置项修改 Webpack 配置信息。
// vue.config.js
module.exports = {configureWebpack: {plugins: [new MyAwesomeWebpackPlugin()]}
}
configureWebpack 的配置规则与 Webpack 一致,同样支持 plugins/module/resolve 等配置项。实际上,Vue CLI 内部最终会调用 webpack-merge 将 configureWebpack 值与其它上下文配置合并,生成最终的 Webpack 配置信息。
// vue.config.js
module.exports = {chainWebpack: config => {config.module.rule('vue').use('vue-loader').tap(options => {// modify the options...return options})}
}
使用 inspect 命令生成完整的 Webpack 配置信息:
vue inspect > output.js
2. CRA 搭建项目脚手架
使用如下代码可使用CRA创建一个react项目,webStrom创建react项目时可选CRA创建项目
npx create-react-app [项目名称]
默认规则创建的脚手架包含如下工程能力:
- JSX、ES6、TypeScript、Flow 语法支持
- CSS 自动添加 --webkit-- 前缀
- 基于 Jest 的自动化测试能力
- 支持 HMR 的开发服务器
- 等等
必要时,也可以通过
npm run eject
命令导出完整的项目配置结构:
注意:可能有未被管理的文件需要先提交在使用该命令
会生成对应的配置:
导出配置后,直接修改
webpack.config.js
等相关配置文件即可控制各项功能行为。
三、如何借助 Babel+TS+ESLint 构建现代 JS 工程环境
1.使用Babel
作用:用于将代码向后兼容,在旧版本JS引擎中运行
因为ES6提供了许多JS新特性,这就会导致旧版本的JS和Node等产生兼容性问题,Babel就是解决这个问题,它会将代码转译成旧版本的代码,使得旧版本引擎能正常使用。
// 使用 Babel 转译前
arr.map(item => item + 1)// 转译后
arr.map(function (item){return item + 1;
})
Webpack 场景下,只需使用
babel-loader
即可接入 Babel 转译功能:
- 安装依赖
npm i -D @babel/core @babel/preset-env babel-loader
- 添加模块处理规则
module.exports = {/* ... */module: {rules: [{test: /\.js$/, // 规则 表示所有.js后缀文件use: ['babel-loader'], // 使用babel-loader处理},],},
};
- 执行编译命令
npx webpack
- 可以使用 .babelrc 文件或 rule.options 属性配置 Babel 功能逻辑
// 预先安装 @babel/preset-env
// npm i -D @babel/preset-env
module.exports = {/* ... */module: {rules: [{test: /\.js$/,use: [{loader: 'babel-loader',options: {presets: ['@babel/preset-env'],},},],},],},
};
@babel/preset-env是Babel预设规则集----Preset,可以使用各种Preset资源:
babel-preset-react
:包含 React 常用插件的规则集,支持preset-flow
、syntax-jsx
、transform-react-jsx
等;@babel/preset-typescript
:用于转译 TypeScript 代码的规则集@babel/preset-flow
:用于转译 Flow 代码的规则集
vue-cli
在文件
build/webpack.base.conf.js
中脚手架已经配置了相关的配置项,但我们依然可以在
webpack.config.js中修改一些配置
entry`入口文件
entry: {app: './src/main.js'},
output
编译产物的目标位置
output: {path: config.build.assetsRoot,filename: '[name].js',publicPath: process.env.NODE_ENV === 'production'// 判断是什么环境? config.build.assetsPublicPath: config.dev.assetsPublicPath},
resolve
解析规则
resolve: {extensions: ['.js', '.vue', '.json'],//文件扩展名alias: {// 别名'vue$': 'vue/dist/vue.esm.js','@': resolve('src'),}},
modele
解析模块
module: {rules: [{test: /\.vue$/, // 规则过滤条件,这里表示对所有 .vue 后缀文件loader: 'vue-loader',// vue-loader处理options: vueLoaderConfig},{test: /\.js$/,loader: 'babel-loader',include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]},{test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,loader: 'url-loader',options: {limit: 10000,name: utils.assetsPath('img/[name].[hash:7].[ext]')}},{test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,loader: 'url-loader',options: {limit: 10000,name: utils.assetsPath('media/[name].[hash:7].[ext]')}},{test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,loader: 'url-loader',options: {limit: 10000,name: utils.assetsPath('fonts/[name].[hash:7].[ext]')}}]},
CRA
在
config/webpack.config.js
中已经有脚手架给我门配置的一些
module: {rules: [{test: /\.js$/,// 声明该规则过滤文件,只有路径和文件类型对应才会生效,此处为所有的 .js 后缀的文件生效loader: 'babel-loader',// 所有命中文件传入Loader序列做转译include: [resolve('src'), resolve('test'), //包内容路径 这里时src和test下的文件 resolve('node_modules/webpack-dev-server/client')]// 以及node_modules中自己的包}]}
不光配置了程序内的文件,还配置了文件外
{test: /\.(js|mjs)$/,exclude: /@babel(?:\/|\\{1,2})runtime/,loader: require.resolve('babel-loader'),options: {babelrc: false,configFile: false,compact: false,presets: [[require.resolve('babel-preset-react-app/dependencies'),{ helpers: true },],],cacheDirectory: true,// See #6846 for context on why cacheCompression is disabledcacheCompression: false,// Babel sourcemaps are needed for debugging into node_modules// code. Without the options below, debuggers like VSCode// show incorrect code and set breakpoints on the wrong lines.sourceMaps: shouldUseSourceMap,inputSourceMap: shouldUseSourceMap,},},
2.使用 TypeScript
作用:提供了一系列类型约束,能更早的发现错误,确保运行阶段的类型安全性,适合在多人协作的项目中使用。
Webpack 有很多种接入 TypeScript 的方法,包括
ts-loader
、awesome-ts-loader
、babel-loader
。通常可使用ts-loader
构建 TypeScript 代码:
Vue CLi和 CRA均使用
babel-loader
引入TypeScript
- 安装依赖
npm i -D @babel/preset-typescript
- 配置 Webpack
// 预先安装 @babel/preset-env
// npm i -D @babel/preset-env
module.exports = {/* ... */module: {rules: [{test: /\.js$/,use: [{loader: 'babel-loader',options: {presets: ['@babel/preset-typescript'],},},],},],},
};
@babel/preset-typescript
只是做了简单的代码转换,未做类型检查等,可以使用其它Preset
3.使用 ESLint
js作为一种灵活、弱类型脚本语言,对于一些开发过程中产生的语法、类型导致影响稳定的错误,这对开发效率和质量造成影响,ESLint就是为了解决这些问题。
作用:JS代码风格检查器,能将违反规则的代码修复。
Webpack 下,可以使用
eslint-webpack-plugin
接入 ESLint 工具,步骤:
- 安装依赖
# 安装 webpack 依赖
yarn add -D webpack webpack-cli# 安装 eslint
yarn add -D eslint eslint-webpack-plugin# 简单起见,这里直接使用 standard 规范
yarn add -D eslint-config-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node
- 在项目根目录添加 .
eslintrc
配置文件,内容:
// .eslintrc
{"extends": "standard"
}
- 添加
webpack.config.js
配置文件,补充eslint-webpack-plugin
配置:
// webpack.config.js
const path = require('path')
const ESLintPlugin = require('eslint-webpack-plugin')module.exports = {entry: './src/index',mode: 'development',devtool: false,output: {filename: '[name].js',path: path.resolve(__dirname, 'dist')},// 添加 eslint-webpack-plugin 插件实例plugins: [new ESLintPlugin()]
}
- 执行编译命令
npx webpack
也可以使用第三方扩展来进行特殊的代码风格检测
eslint-config-airbnb
:Airbnb 提供的代码风格规则集,算得上 ESLint 生态第一个成名的规则集合eslint-config-standard
:Standard.js 代码风格规则集,史上最便捷的统一代码风格的方式eslint-plugin-vue
:实现对 Vue SFC 文件的代码风格检查eslint-plugin-react
:实现对 React 代码风格检查@typescript-eslint/eslint-plugin
:实现对 TypeScript 代码风格检查eslint-plugin-sonarjs
:基于 Sonar 的代码质量检查工具,提供圈复杂度、代码重复率等检测功能
总结
本文主要记录了Webpack配置底层逻辑结构以及如何借助Babel、TS、ESLint构建JS环境
Webpack5核心原理与应用实践(基础用法)一相关推荐
- clickhouse原理解析与应用实践_编程好书推荐《Redis 深度历险:核心原理与应用实践》...
今天看到一本书,叫<Redis 深度历险:核心原理与应用实践>,作者叫钱文品(老钱),目前在掌阅科技出任资深开发工程师,这本书对redis的剖析还是挺深入的 对redis感兴趣的朋友可以买 ...
- Redis 深度历险:核心原理与应用实践
Redis 是互联网技术架构在存储系统中使用最为广泛的中间件,它也是中高级后端工程师技术面试中面试官最喜欢问的工程技能之一,特别是那些优秀的.竞争激烈的大型互联网公司(比如 Twitter.新浪微博. ...
- 赠书:Redis 深度历险:核心原理与应用实践
Redis 是互联网技术架构在存储系统中使用得最为广泛的中间件,它也是中高级后端工程师技术面试中面试官最喜欢问的工程技能之一,特别是那些优秀的.竞争激烈的大型互联网公司(比如 Twitter.新浪微博 ...
- redis深度历险:核心原理与应用实践_送你一份Redis书单,以后使用缓存的问题不用再问我啦!...
点击蓝色"程序员书单"关注我哟 加个"星标",每天带你读好书! 经过了10多年的发展,Java Web从开发框架到社区都已经非常成熟,很多程序员都可以通过使 ...
- Redis核心原理与应用实践
Redis核心原理与应用实践 在很多场景下都会使用Redis,但是到了深层次的时候就了解的不是那么深刻,以至于在面试的时候经常会遇到卡壳的现象,学习知识要做到系统和深入,不要把Redis想象的过于复杂 ...
- rocketmq存储结构_阿里专家分享内部绝密RocketMQ核心原理与最佳实践笔记
本文源码以RocketMQ 4.2.0 和 RocketMQ 4.3.0 为 基 础 , 从RocketMQ的实际使用到RocketMQ的源码分析,再到RocketMQ企业落地实践方案,逐步讲解.使读 ...
- clickhouse原理解析与应用实践 pdf_阿里专家分享内部绝密RocketMQ核心原理与最佳实践PDF...
前言 本文源码以RocketMQ 4.2.0 和 RocketMQ 4.3.0 为 基 础 , 从RocketMQ的实际使用到RocketMQ的源码分析,再到RocketMQ企业落地实践方案,逐步讲解 ...
- 重磅!Redis 深度历险:核心原理和应用实践,GitHub标星65k!
前言 授人以鱼不若授人以渔-- Redis 可以用来做什么? Redis 是互联网技术领域使用最为广泛的存储中间件,它是「Remote Dictionary Service」的首字母缩写,也就是「远程 ...
- 知其然也知其所以然,Redis笔记总结:核心原理与应用实践
所谓「授人以鱼不如授人以渔」这份笔记的初衷和目标就是帮助后端开发者较为深入的理解Redis背后的原理和实践经验,做到知其然也知其所以然,为未来进阶成长为架构师做好准备. 笔记内容介绍 : Redis基 ...
最新文章
- 在main()之前,IAR都做了啥?
- copy vs. uninitialized_copy
- -bash : xxx : command not found 新安装Linux后,安装一些必须软件(持续更新……)
- Windows 7 SID 修改
- python基础知识学习笔记(2)
- 不可错过的「持续集成」进阶指南
- html5 Ajax 访问.net WebApi获取视频流
- 鸿蒙os2.0电脑版,鸿蒙系统2.0PC版
- 番茄助手在VS2017中的设置
- 计算机考研各省份学校,想考研究生,哪个省份的高校更容易考上?
- TCC(新加坡太一国际数字交易所):升值万倍的数字资产 成就多少亿万豪
- xbox360能玩java我的世界吗_xbox360我的世界完整版god
- win8 android 跑分,Windows 10和win8.1性能跑分测试结果曝光
- oracle12免安装版配置,配置免安装版Oracle客户端
- javadoc 创建html,javadoc html标签
- PMOS和NMOS引脚及封装
- 【POI2005】SZA-Template(KMP)
- LocalDate的用法与String互转
- Eagle PCB软件
- 流量复制导流工具研究
热门文章
- java中的CountDownLatch(共享锁)与ReentrantLock(排他锁)
- html不用css超链接去掉下划线,div css之去掉a超链接下划线样式
- 编制计算机程序解决问题的5个步骤,4.1.4剖析编制计算机程序解决问题的过程
- java swing 植物大战僵尸精品游戏432 功能完善 完整代码 下载即可以运行
- matlab根号图像,求助高手,用matlab求两幅图像平方和再开根号公式怎样表达?
- 梦想是一个天真的词,实现梦想是一个残酷的词。
- ORB特征提取和匹配
- 史上最牛B的FLASH广告——本田汽车
- 多臂高分子PEG试剂:4Arm PEG L-Lysine,四臂PEG L赖氨酸,4臂聚乙二醇衍生物
- Web技术是开发iOS和Android App