一、前端工程化
1、什么是前端工程化?
前端工程化是指将前端开发的流程规范化、标准化,包括开发流程、技术选型、代码规范、构建发布等,用于提升前端工程师的开发效率和代码质量。
2、为什么要前端工程化?
复杂度高:前端项目的多功能、多页面、多状态、多系统
规模大:团队开发、多人协作,代码质量管理
要求高:页面性能优化(CDN/异步加载/请求合并),CSS兼容性、单页面应用、服务端渲染...
3、怎么做前端工程化?
从业务着手
简单的单页面应用,使用gulp打包+同步工具实现全流程开发
从复杂度考虑
jenkins、git/gilab、webpack、React/Vue/Angular
从已知向未知扩展
不同的技术有不同的适应场景,选择合适的才是最好的
二、前端构建工具
1、webpack
1.1 安装
#环境确认
nvm install/use v12.16.1 node -v npm -v
#快速创建nodejs项目
npm init -y
#安装webpack webpack-cli
#项目安装 cnpm install webpack webpack-cli -D 或 yarn add webpack webpack-cli -D #全局安装 cnpm install webpack webpack-cli -g 或 yarn add webpack webpack-cli -g
#查看webpack是否安装成功
npx webpack --version
./node_modules/.bin/webpack --version
#webpack使用1
npx webpack XXXX
或
./node_modules/.bin/webpack XXX
#webpack使用2 #构建修改package.json下面scripts/build
{ "name": "resource", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "webpack" }, "author": "", "license": "ISC", "devDependencies": { "webpack": "^5.4.0", "webpack-cli": "^4.2.0" } }
然后控制台直接执行:
npm run build
1.2五大核心概念
(1)入口-entry
单入口webpack配置文件:webpack.config.js
(2)输出-output
path使用绝对路径,可以使用path.join拼接路径,nodejs全局变量__dirname(当前目录的绝对路径)
使用require引入,webstorm需要配置node core
(3)加载器-loader
(3.1)转化css文件
#安装样式loader cnpm install css-loader style-loader -D 或yarn add css-loader style-loader -D
安装完成后,package.json下面的devDependencies会多出两个依赖:
{ "name": "resource", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "webpack" }, "author": "", "license": "ISC", "devDependencies": { "css-loader": "^5.0.1", "style-loader": "^2.0.0", "webpack": "^5.4.0", "webpack-cli": "^4.2.0" } }
#配置使用样式loader打包
const path=require("path") //输出当前目录绝对路径 console.log(path.resolve()) //输出当前目录拼接disk的绝对路径 console.log(path.join(__dirname,'./dist')) const config ={ entry:"./src/index.js", output:{ filename:'bundle.js',//打包后的文件 path:path.join(__dirname,'./dist') }, module:{ rules:[ { test: /\.css$/, use: ['style-loader', 'css-loader'] //执行顺序从右到左 } ] } }; module.exports=config
#编写样式src/index.css
body{
background: red;
}
#index.js引入css
require('./index.scss') console.log("hello webpack!!")
#打包
npm run build
#使用样式 新建./dist/index.html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> hello cac2020 <script src="bundle.js"></script> </body> </html>
#查看结果
(3.2)一般工程里不会直接编写css样式,而是使用sass、scss预编译css:
#安装sass-loader node-loader
yarn add sass-loader node-sass -D
#webpack设置
const path=require("path") //输出当前目录绝对路径 console.log(path.resolve()) //输出当前目录拼接disk的绝对路径 console.log(path.join(__dirname,'./dist')) const config ={ entry:"./src/index.js", output:{ filename:'bundle.js',//打包后的文件 path:path.join(__dirname,'./dist') }, module:{ rules:[ { test: /\.(scss|sass)$/, use: ['style-loader', 'css-loader','sass-loader'] //执行顺序从右到左 } ] } }; module.exports=config
注意一点:loader执行顺序,从右往左
(4)插件-plugins,提供扩展能力
支柱功能,解决loader无法实现的其他事情。
#插件使用示例 HtmlWebpackPlugin(简单创建 HTML 文件,用于服务器访问)
#安装插件
yarn add html-webpack-plugin -D
#配置中引入
const path=require("path") const Htmlwebpackplugin = require("html-webpack-plugin") const config ={ entry:"./src/index.js", output:{ filename:'bundle.js',//打包后的文件 path:path.join(__dirname,'./dist') }, module:{ rules:[ { test: /\.(scss|sass)$/,//test用来匹配文件 use: ['style-loader', 'css-loader','sass-loader'] //执行顺序从右到左 } ] }, plugins:[ new Htmlwebpackplugin({ filename:"index.html",//生成html的名字 template:'template.html'//使用模板html生成html } )//参数为空 会默认在dist下生成一个普通的index.html ] }; module.exports=config
#打包
npm run build
#效果 自动生成dist/index.html,里面会自动引入bundle.js依赖
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title></head> <body>hello cac2020 <script src="bundle.js"></script> </body> </html>
#代码热编译
方式一:热编译:监控自动触发编译
#修改package.json 监视js是否有变化
{ "name": "resource", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "webpack", "watch": "webpack --watch" }, "author": "", "license": "ISC", "devDependencies": { "css-loader": "^5.0.1", "html-webpack-plugin": "^4.5.0", "node-sass": "^5.0.0", "sass-loader": "^10.1.0", "style-loader": "^2.0.0", "webpack": "^5.4.0", "webpack-cli": "^4.2.0" } }
#执行监控
npm run watch
#修改index.js保存 在控制台会看到自动执行编译日志
... [webpack-cli] watching files for updates... [webpack-cli] Compilation starting... [webpack-cli] Compilation finished ...
#手工刷新页面查看 就会看到更新内容
方式二:热编译+热刷新
使用HMR,模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面。
#安装webpack-dev-server,提供开发运行时环境,当有变化时自动刷新浏览器
yarn add webpack-dev-server -D
#配置package.json
{ "name": "resource", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "webpack", "watch": "webpack --watch", "hot": "webpack-dev-server" }, "author": "", "license": "ISC", "devDependencies": { "css-loader": "^5.0.1", "node-sass": "^5.0.0", "sass-loader": "^10.1.0", "style-loader": "^2.0.0", "webpack": "^5.4.0", "webpack-cli": "^4.2.0", "webpack-dev-server": "^3.11.0" } }
#配置webpack.config.js
const path=require("path") const htmlwebpackplugin = require("html-webpack-plugin") const webpack = require('webpack') const config ={ entry:"./src/index.js", output:{ filename:'bundle.js',//打包后的文件 path:path.join(__dirname,'./dist') }, module:{ rules:[ { test: /\.(scss|sass)$/, use: ['style-loader', 'css-loader','sass-loader'] //执行顺序从右到左 } ] }, devServer:{ hot: true }, plugins:[ new htmlwebpackplugin({ filename:"index.html",//生成html的名字 template:'template.html'//使用模板html生成html }),//参数为空 会默认在dist下生成一个普通的index.html new webpack.HotModuleReplacementPlugin()//初始化HMR ] }; module.exports=config
#启动webpack-dev-server
npm run hot
E:\webapp\demo1\resource>npm run hot > resource@1.0.0 hot E:\webapp\demo1\resource > webpack-dev-server i 「wds」: Project is running at http://localhost:8080/ i 「wds」: webpack output is served from / i 「wds」: Content not from webpack is served from E:\webapp\demo1\resource i 「wdm」: Hash: fb2be21415c83bcbde26 Version: webpack 4.35.2 Time: 727ms Built at: 2020-11-12 1:24:03 PM Asset Size Chunks Chunk Names bundle.js 406 KiB main [emitted] main index.html 182 bytes [emitted] Entrypoint main = bundle.js [0] multi (webpack)-dev-server/client?http://localhost (webpack)/hot/dev-server.js ./src/index.js 52 bytes {main} [built] [./node_modules/strip-ansi/index.js] 161 bytes {main} [built] [./node_modules/webpack-dev-server/client/index.js?http://localhost] (webpack)-dev-server/client?http://localhost 4.29 KiB {main} [built] [./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.51 KiB {main} [built] [./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.53 KiB {main} [built] [./node_modules/webpack-dev-server/client/utils/createSocketUrl.js] (webpack)-dev-server/client/utils/createSocketUrl.js 2. 77 KiB {main} [built] [./node_modules/webpack-dev-server/client/utils/log.js] (webpack)-dev-server/client/utils/log.js 964 bytes {main} [built] [./node_modules/webpack-dev-server/client/utils/reloadApp.js] (webpack)-dev-server/client/utils/reloadApp.js 1.63 KiB {main } [built] [./node_modules/webpack-dev-server/client/utils/sendMessage.js] (webpack)-dev-server/client/utils/sendMessage.js 402 bytes {main} [built] [./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built] [./node_modules/webpack/hot/dev-server.js] (webpack)/hot/dev-server.js 1.59 KiB {main} [built] [./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 75 bytes {main} [built] [./node_modules/webpack/hot/log-apply-result.js] (webpack)/hot/log-apply-result.js 1.27 KiB {main} [built] [./node_modules/webpack/hot/log.js] (webpack)/hot/log.js 1.34 KiB {main} [built] [./src/index.js] 58 bytes {main} [built] + 24 hidden modules Child HtmlWebpackCompiler: 1 asset Entrypoint HtmlWebpackPlugin_0 = __child-HtmlWebpackPlugin_0 [./node_modules/html-webpack-plugin/lib/loader.js!./template.html] 403 bytes {HtmlWebpackPlugin_0} [built] i 「wdm」: Compiled successfully.