前端工程化与webpack简单使用
1.前端工程化
1.1实际的前端开发
- 模块化
js
的模块化,css
的模块化,资源的模块化 - 组件化 复用现有的
UI
结构,样式,行为 - 规范化 目录结构的划分,编码的规范化,接口的规范化,文档规范化,Git 分支管理
- 自动化 自动化构建,自动化部署,自动化测试
1.2什么是前端工程化
前端工程化指的是:在企业级的前端项目开发中,把前端开发所需的工具,技术,流程,经验等进行规范化,标准化。
1.3前端工程化的解决方案
早期
- grunt
- gulp
目前主流
- webpack
- parcel
2.webpack
的基本使用
2.1什么是 webpack
概念:webpack 是
前端工程化的具体解决方案
主要功能:提供友好的
前端模块化开发
支持,以及代码压缩混淆
,处理浏览器端Javascript 的兼容性
,性能优化
等强大的功能.
2.2隔行变色案例
-
初始化项目
npm init -y
-
创建
src
源代码目录 -
新建
index.html
和index.js
-
安装
jquery
-
-S
的含义与--save
相同 将版本放在package.json
文件的dependencies
中 -
dependencies
:开发和上线过程都要用到
npm i jquery -S
-
-
通过
es6
语法导入jQuery
,实现列表隔行变色效果
2.3安装webpack
npm install webpack@5.42.1 webpack-cli@4.7.2 -D
-
-D
是--save-dev
的简写,将版本号记录到package.json
文件的devDependencies
下 -
devDependencies
:只在开发阶段会被用到 -
--save
或者--save-dev
可以根据查官方文档来确定
2.4配置webpack
2.4.1基本配置
-
在项目根目录中,创建名为
webpack.config.js
的webpack
配置文件,并初始化配置:module.exports = { mode: 'development' //mode 用来指定构建模式 //development 开发阶段 production 发布使用阶段 }
-
在
package.json
的script
节点下新增 dev 脚本
:script 节点下的脚本 可以通过 npm run xxx 来运行
"scripts": { "dev": "webpack" }
-
在终端运行
npm run dev
,启动webpack
进行项目的打包构建
会在在根目录下生成一个dist目录,目录下有main.js
解决了兼容性问题
2.4.2压缩
-
将
development
改成production
再重新npm run dev
-
可将
main.js
压缩 -
development 打包时间段 体积大 适合开发阶段
-
production 打包时间长 体积小 适合上线阶段
-
在 run 的时候会读取
webpack
配置文件 ,根据配置文件再去运行
2.4.3webpack
中的默认约定
在webpack 4.x
和 5.x
的版本中,有如下的默认约定:
- 默认的打包入口文件为
src -> index,js
- 默认的输出文件路径为
dist -> main.js
可以在 webpack.config.js
中修改打包的默认约定
2.4.4自定义打包的入口出口
在 webpack.config.js
配置文件中,通过 entry 节点
指定打包的入口。通过 output节点
指定打包的出口:
const path = require('path')
module.exports = {
mode: 'production',
// entry 处理的文件路径
entry: path.join(__dirname , './src/index.js'),
output: {
// 导出的文件目录
path: path.join(__dirname , './dist'),
//导出的文件名
filename: 'index.js'
}
}
3.webpack
中的插件
3.1 webpack-dev-server
3.1.1简介
- 官方使用介绍: https://www.npmjs.com/package/webpack-dev-server
- 类似于
node.js
用到的nodemon
工具 - 每当修改源代码,
webpack
会自动进行项目的打包和构建
3.1.2安装
npm install webpack-dev-server@3.11.2 -D
3.1.3配置
-
修改
package.json -> script
中的dev
命令:注意后面是serve哦,不是server
"scripts": { "dev": "webpack serve" }
-
再次运行
npm run dev
命令,重新进行项目的打包但是!!!如果你和我一样,发现运行后报下面的错:
[webpack-cli] Unable to load '@webpack-cli/serve' command
[webpack-cli] TypeError: options.forEach is not a function
那就运行一下下面的命令就 ok ~
npm install webpack-cli --save-dev
之后再运行
npm run dev
就可以了 -
在浏览器访问 http://locslhost:8080 地址,查看自动打包效果
-
将引用文件路径改为
/xxx
-
通过浏览器访问 http://127.0.0.1:8080/src/ 来查看样式的改变
访问
src
文件夹默认展示其中的index.html
文件
webpack-dev-server
会启动一个实时打包的http
服务器,每次修改代码或者保存代码都会被这个插件监听到,插件会将最新的导出文件放在根目录下,储存在内存中,但是看不见,可以在浏览器中通过8080端口的/xxx来访问。
3.2 html-webpack-plugin
3.2.1简介
Plugin that simplifies creation of HTML files to serve your bundles
这个插件简化了HTML文件的创建,以服务于你的bundle
官方使用介绍:https://www.npmjs.com/package/html-webpack-plugin
3.2.2安装
npm i --save-dev html-webpack-plugin
3.2.3配置
修改 webpack.config.js
文件:
const path = require('path')
const HtmlPlugin = require('html-webpack-plugin')
const htmlPlugin = new HtmlPlugin({
template: './src/index.html', //指定原文件的存放路径
filename: './index.html' // 指定生成文件的存放路径
})
module.exports = {
mode: 'development',
// entry 处理的文件路径
entry: path.join(__dirname , './src/index.js'),
output: {
path: path.join(__dirname , './dist'),
filename: 'index.js'
},
// 插件的数组 将来 webpack 在运行的时候 会调用这些插件
// 通过 plugins节点 使得 htmlPlugin 插件生效
plugins: [htmlPlugin]
}
修改了之后我们可以直接访问 http://127.0.0.1:8080 来访问最新页面,因为生成了index.html文件在项目根目录下,储存在了内存里。如果访问不到就保存一下刚刚修改的配置文件。
3.2.4特性
html-webpack-plugin
插件的神奇之处:
- 通过 HTML 插件复制到项目根目录中的
index.html
页面,也被放到内存中 - HTML 插件在生成的
index.html
页面,自动注入了打包的index.js
文件
3.3 devServer 节点
在 webpack.config.js 配置文件中,可以通过 devServer 节点对webpack-dev-server 插件进行更多的配置:
devServer: {
// 首次打包成功后 自动打开浏览器
open: true,
// 在 http 协议后 如果端口号是 80 则可以被省略
port: 80,
// 指定运行的主机机制
host: '127.0.0.1'
}
注意
:凡是修改了 webpack.config.js
配置文件,或修改了 package.json
配置文件,必须重启实时打包的服务器
,否则最新的配置文件无法生效!
4.webpack
中的loader
4.1 loader 简介
在实际的开发中,webpack 默认只能打包处理以 .js 后缀名结尾的模块。其他非 .js 后缀名结尾的模块, webpack 默认处理不了,需要调用 loader 加载器才可以正常打包,否则会报错!
loader 加载器的作用:协助 webpack 打包处理待定的文件模块。比如:
css-loader
可以打包处理.css
相关的文件less-loader
可以打包处理.less
相关的文件babel-loader
可以打包处理webpack
无法处理的高级JS
语法
4.2 打包处理 CSS 文件
-
运行
npm i style-loader css-loader -D
,安装处理 css 文件的 loader -
在
webpack.config.js
的module -> rules
数组中,添加 loader 规则其中,test 表示匹配的文件类型, use 表示对应调用的 loader
// 所有第三方文件模块的匹配规则 module: { // 文件后缀名的匹配规则 rules: [ { test: /\.css$/, use: ['style-loader','css-loader'] } ] }
注意:
use
数组指定的 loader顺序是固定的
- 多个loader的调用顺序:
从前往后调用
4.3 打包处理 less 文件
-
运行
npm i less-loader less -D
命令这个后面的 less 是内部依赖项,也就是 less-loader 的依赖项
-
在
webpack.config.js
的module -> rules
中,添加loader
规则如下:module: { // 文件后缀名的匹配规则 rules: [ // 定义不同模块对应的 loader { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] } ] }
4.4 打包处理样式表中与 url 路径相关的文件
-
运行
npm i url-loader file-loader -D
命令其中的
file-loader
是url-loader
的依赖项 -
在
webpack.config.js
的module -> rules
数组中,添加 loader 规则如下:module: { // 文件后缀名的匹配规则 // 定义不同模块对应的 loader rules: [ // css { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, // less { test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] }, // 图片类型的文件 { test: /\.jpg|png|gif|jpeg$/, // 如果需要调用的loader只有一个 写一个字符串即可 多个写数组 use: 'url-loader?limit=22229' } ] }
其中
?
之后的是 loader 的参数项:limit
用来指定图片的大小,单位是字节
- 只有
≤ limit
大小的图片,才会被转为base64
格式的图片 - 如果 > limit 大小的图片,会转为地址,如
http://127.0.0.1/b0090f87c0a274a44f805395509bf598.png
4.5打包处理 js 文件中的高级语法
4.5.1 引入
webpack 只能打包处理一部分高级的 js 语法。对于那些 webpack 无法处理的高级 js 语法,需要借助于 babel-loader 进行打包处理。例如:
// 定义一个装饰器函数
function info(target){
target.info = 'Person info'
}
// 定义一个普通的类
@info
class Person {}
console.log(Person.info)
4.5.2 安装 babel-loader
Babel 官网:Babel
-
运行如下的命令安装对应的依赖包:
注意后面两个包名前有
@
哦npm i babel-loader @babel/core @babel/plugin-proposal-decorators -D
-
在
webpack.config.js
的module -> rules
数组中,添加loader
规则:module: { // 定义不同模块对应的 loader rules: [ // 使用 babel-loader 处理高级 JS 语法 { test: /\.js$/, use: 'babel-loader', exclude: '/node_modules/' // exclude 指定排除项 因为 node_modules 目录下的第三方包不需要被打包 } ] }
4.5.3 配置babel-loader
官方文档:https://babeljs.io/docs/en/babel-plugin-proposal-decorators
在项目根目录下,创建名为 babel.config.js 的配置文件,定义 Babel 的配置项:
- 声明 Babel可用的插件
- webpack 在调用 babel-loader 的时候,会先加载 plugins 插件来使用
module.exports = {
plugins: [
['@babel/plugin-proposal-decorators' , { legacy: true}]
]
}
5.打包发布
5.1 配置 webpack 的打包发布
在 package.json
文件的 script
节点下,新增 build
命令:
"scripts": {
"dev": "webpack serve",
"build": "webpack --mode production"
}
注意点:
--mode
是一个参数项,用来指定 webpack 的运行模式
。production 代表生产环境,会对打包生成的文件进行代码压缩
和性能优化
。- 通过
--mode
指定的参数项,会覆盖webpack.config.js
中的mode
选项
5.2 将 Javascript 文件统一生成到 js 目录中
在 webpack.config.js 配置文件的 output 节点中,进行如下配置
output: {
path: path.join(__dirname , './dist'),
// 明确告诉 webpack 把生成的 index.js 文件放在 dist 目录下的 js子目录中
filename: 'js/index.js'
}
5.3 将图片统一生成到 images 目录中
修改 webpack.config.js 中的module -> rules 中图片对应的配置:
// 图片类型的文件
{
test: /\.jpg|png|gif|jpeg$/,
// 如果需要调用的loader只有一个 写一个字符串即可 多个写数组
use: 'url-loader?limit=4000&outputPath=images'
}
5.4 配置和使用 clean-webpack-plugin 插件自动删除 dist 目录
为了在每次打包发布时自动清理 dist 目录中的旧文件,可以安装并配置 clean-webpack-plugin 插件
官方使用说明: https://www.npmjs.com/package/clean-webpack-plugin
-
安装
npm i clean-webpack-plugin -D
-
在 webpack.config.js 中配置
const { CleanWebpackPlugin } = require('clean-webpack-plugin') //... plugins:[ new CleanWebpackPlugin() ]
5.5 总结发布主要流程
- 配置
build
命令 - js 文件与图片放置到相关文件夹
- 安装自动清理 dist 目录的插件
6. Source Map
6.1 简介
Source Map 是一个信息文件,以
.map
结尾,里面储存着位置信息。也就是说,Source Map 文件中储存着压缩混淆后的代码所对应的转换前的位置。有了它,出错的时候,出错工具将直接显示原始代码,而不是转换后的代码,能够极大的方便后期的调试。
6.2 Source Map 的默认问题:
开发环境下的默认生成的 Source Map ,记录的是生成后的代码的位置。会导致运行时报错的行数与源代码的行数不一致的问题。
6.3 解决Source Map 的默认问题:
开发模式下:
在 webpack.config.js 中添加如下配置,即可保证运行时报错的行数与源代码的行数保持一致
// 在开发调试阶段 建议将 devtool 设置为 eval-source-map
devtool: 'eval-source-map',
mode: 'development',
6.4 在发布项目的时候处于安全性建议关闭 Souce Map
在生产环境下,如果省略了 devtool 选项,则最终的生成文件中不包含 Souce Map。这能够防止原始代码通过 Souce Map 的形式暴露给有所图之人。
只定位行数不暴露源码
在生产环境下,如果只想定位报错的具体行数。此时可以将 devtool
的值设置为 nosource-sources-map
定位行数且暴露源码(不要这样干!)
将 devtool
的值设置为 sources-map
6.5 最佳实践
- 开发环境下:
- 建议将
devtool
设置为eval-source-map
- 好处:精准定位具体的错误行
- 建议将
- 生产环境下:
- 建议关闭 Source Map 或将
devtool
设置为nosource-sources-map
- 好处:防止源码泄漏,提高网站安全性
- 建议关闭 Source Map 或将
7. 拓展
7.1 webpack 中 @ 的原理和好处
建议使用 @
表示 src
源代码目录,从里往外找;不要使用 ../
从外往里找
在 webpack.config.js 中配置一下:
resolve: {
alias:{
// 告诉 webpack @ 符号 表示 src 这一层目录
'@': path.join(__dirname,'./src/')
}
}
7.2 在 Chrome 浏览器安装 vue-devtools 调试工具
- 安装 :浏览器右上角三个点 -> 更多工具 -> 扩展程序 -> 打开右上角开发者模式 ->
Vue.js devtools
-> 添加至扩展程序 -> 关闭开发者模式 - 配置:点开
Vue.js devtools
的详情 -> 打开允许访问文件网址