现代前端常用工具

使用工具前,必须要理解为什么需要这些工具,这些工具解决了什么问题。本文,先带大家看下前端发展主流方向,然后基于此介绍常见工具的作用和使用。

前端发展主流方向

前后端分离

现在前端小年轻一提就是前后端分离,到底什么是前后端分离,为什么需要前后端分离。深入理解这个,会发现现代前端也是一步步演变过来的。

服务端负责分离

经历过html 4.0/jquery/php时代的程序员应该清楚,如下,最开始的想法很朴素:前端工程师负责前端页面html+js+css的编写,然后把需要填充的页面位置换成模板语法(比如文字/图片等);后端工程师负责生成对应的填充元素对应的值,调用模板引擎渲染替换对应模板中的值,生成的网页返回给前端展示;核心就是服务端按照模板替换真实的值,分工明确而且相对可控,各司其职。
服务端分离

这时候常见的模板引擎比如php的smarty,java的FreeMarker,C#的razor等。那时候php很流行,因为非常匹配这种用法。比如,一个典型的smarty模板如下

<!DOCTYPE html>
<html>
<head>
<meta charset="gb2312">
<title><{$title}></title>
</head>
<body>
你好,<{$name}>
</body>
</html>

php中调用渲染代码,如下

<?php 
require './Smarty/smarty.class.php';

$smarty=new smarty();
...

//给变量赋值
$smarty->assign('title','demo');
$smarty->assign('name','tom');

//渲染模板文件返回
$smarty->display('demo.html');

但这样也存在明显的缺点:
1.无法实现前端的灵活控制,灵活性取决于服务端和模板引擎,无法实现复杂应用
2.每次都返回html,流量消耗大且交互体验差
当然现在这种方式在很多地方也有应用,特别不是很复杂的应用和后台管理类,仍然有用武之地

前端负责分离

实际上前端分离的技术底座ajax出现很早,最开始大家只是用它做表单异步验证,jQuery然后到Angular的出现推动了完全前端分离的思想,如下,也就是整个页面展示交互的逻辑完全由前端控制,后端只是负责提供数据和后台逻辑,双方职责彻底划分开。

q前端分离

当前前端负责分离是主流,基于此,react/vue等开始把mvvm 组件化等概念进一步推进,前端彻底拥有自主权才出现现在的前端大爆发,各种复杂前端应用才成为可能。

模块化和组件化

模块化和组件化也是现代化前端常提的概念。

模块化(modules)

前面讲到模块化是现代前端的一个特点,为什么需要模块?
对比其他语言,就可以看到模块的重要性了,传统的前端依赖script标签引入js,大多数是一锅烩,一个超大文件写满js,也不考虑复用性。模块化的诞生,让前端得以像大多数后端语言一样使用,比如CommonJS规范如下
exports和require即可。

// 定义模块math.js
var total = 10;
function add(a, b) {
  return a + b;
}
// 需要向外暴露的函数、变量
module.exports = {
  add: add,
  total: total
}
/** 必须加./路径,不加的话只会去node_modules文件找 **/
// 引用自定义的模块时,参数包含路径,可省略.js
var math = require('./math');
math.add(2, 5);

// 引用核心模块时,不需要带路径
var http = require('http');
http.createService(...).listen(3000);

模块化带来的好处是
1.标准化,大功能可以拆成很多小功能,按照标准独立实现,适合团队合作,也能快速整合
2.复用性,大量标准库基于此实现,最典型是nodejs的CommonJS规范推动了nodejs扩展库的发展

基于模块化,复杂前端应用的管理才得以实现。前面提到模块化规范,发展进程上出现很多模块化规范,可以参考这篇文章《前端模块化——彻底搞懂AMD、CMD、UMD、ESM和CommonJS》。对于我们普通开发着来说目前事实上的规范就是nodejs的CommonJS和ES6的标准module,学会遵守规范使用即可。

组件化(components)

为什么需要组件化,这个也有类比,看桌面编程,特别是做过VB编程的,应该知道每个按钮/每个文本框都有自己的样式/方法/可以独立定义点击响应和行为,甚至可以实现自定义的COM组件;再看后端编程,特别是微服务相关,各司其职,负责路由/配置/认证的都是单独的微服务(组件)。
严格来说组件化就是业务模块化。意思就是组件相当于按照业务需求拆分的更精细的模块。参考《深入探讨前端组件化开发 》,按照刚才的类比可以看到,包括两方面
1.功能的组件
负责独立的功能,比如vue中的路由组件 vue-router/状态存储组件vuex
2.界面的组件
参考 《搞懂什么是前端“组件化”开发》,传统开发中,项目的目录结构一般是把HTML文件放在最外层,把CSS文件、JavaScript文件放在单独的目录中,如下图所示:
非组件化代码

这样一整个html声明结构,包括一大块css声明样式,还有一大块js描述逻辑,以整体为中心,这样的代价是每个相同的逻辑块(比如按钮/文本/页脚)都是独有的,别的项目要用只能拷贝不能重建。
组件化的目的就是每个组件都有自己的结构、样式和代码。 参考如下vue工程,每块当作一个组件,每个组件都可封装在一个vue文件中,独立使用html/css/js描述,整个页面的编写就是各个组件的灵活组合。
组件化代码

这样带来的好处自然也是明显的
1.标准化 可以定义组件标准化,分工更加精细明确,上手也快,便于扩展
2.复用性 定义标准组件,大大提升开发效率

工具

根据如上描述,我们可以分析下现代前端所需的工具特征
1.类似别的编程语言的独立运行时和标准库——nodejs
2.基于模块的库管理工具——npm/cnpm/yarn
3.将引入的模块/组件等打包成前端部署文件——webpack

nodejs和nvm

官网 https://nodejs.org/zh-cn/
简单的说 Node.js 就是运行在服务端的 JavaScript,基于chrome V8改造而成。
node执行程序简单,和一般解释类型程序语言,比如server.js文件,如下执行

node server.js

建议使用nvm(Node Version Manager) ,nvm是 Nodejs 版本管理器,它让我们方便的对切换Nodejs 版本。
nvm的详细安装以及使用可以访问以下链接:

MAC 上安装使用 brew install nvm

常用nvm命令如下

nvm ls-remote 查看远程库中有哪些node版本可以安装
nvm list 查看当前已安装所有的node 版本
nvm install v10.13.0 安装指定的版本,安装多版本
nvm use —delete-prefix 10.13.0 使用nvm use切换到指定的版本
nvm current 查看当前node版本
nvm which v10.13.0 查看当前版本的安装目录

npm/cnpm/yarn

官网 https://npmmirror.com/
npm是随同NodeJS一起安装的包(模块)管理工具,用于管理包依赖和打包发布。
npm -v查看npm版本

依赖管理文件

  • package.json

npm使用package.json用来记录模块信息,一个典型的文件如下,其中dependencies指明生产环境依赖的包,devDependencies指明开发环境下依赖的包。

{
  "name": "webpack-demo",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0"
  },
  "dependencies": {
    "lodash": "^4.17.21"
  }
}

这里^是版本指定语法

  1. ~ 会匹配最近的小版本依赖包,比如~1.2.3会匹配所有1.2.x版本,但是不包括1.3.0
  2. ^ 会匹配最新的大版本依赖包,比如^1.2.3会匹配所有1.x.x的包,包括1.3.0,但是不包括2.0.0
  3. *这意味着安装最新版本的依赖包

自己创建一个新模块时,可以如下生成默认的package.json

# 需要根据提示手动输入项目的信息
npm init

# 使用默认值创建,不用根据提示手动输入项目的信息,但是当前文件夹名不能是中文
npm init -y

另外很多开源项目,下载后默认只有package.json描述依赖,那么和后端语言maven/pip等一样,可以如下一键下载相关依赖

npm install
npm i # 简写
npm ci # 精确安装
  • package.lock.json

现在也会看到同目录一般有package.lock.json,这是因为package.json本版本描述语法,保证了最大兼容性,但是在不同的用户电脑中,初始化的包的版本可能会出现不一样的情况,从而造成未可知的bug。
npm在5.0之后引入了package.lock.json文件,用来固定包的版本、包的源地址等信息,保证在不同的用户开发环境中加载的是相同的包。
一般使用精确安装语法 npm ci会强制限制从package.lock.json读取安装。

模块管理

# 当前项目依赖安装,在当前文件夹使用,安装的依赖放在 ./node_modules
npm install 模块名称
npm i 模块名称 # 简写

# 全局依赖安装,可以在任意文件夹使用,安装的依赖放在node 的安装目录
npm install --global 模块名称
npm i -g 模块名称 # 简写

npm i 模块名称@版本 # 下载指定的版本
npm install -g cnpm --registry=https://registry.npm.taobao.org #指定源安装

# 卸载模块
npm uninstall 模块名

#查看模块
npm ls

调试开发

  • 生产阶段的依赖

–save或-S
将加入安装包信息到package.json文件dependencies对象中,一般是项目运行正式需要的模块安装

npm install gulp --save 
npm install gulp -S
  • 开发阶段的依赖

–save-dev或-D
将加入安装包信息到package.json文件devDependencies对象中,参考如上文件,一般是开发阶段的辅助工具如webpack vue-cli等的安装

npm install gulp --save-dev 
npm install gulp -D

安装升级npm

默认npm随nodejs发布,可如下升级

npm install npm -g

npm默认的镜像比较慢,可如下配置阿里代理代理

npm get registry #查看当前
npm config set registry http://registry.npm.taobao.org/ #阿里代理
npm config set registry https://registry.npmjs.org/ # 设回官方

也可以设置别名安装,即常说的cnpm

npm install -g cnpm --registry=https://registry.npmmirror.com

另一个常见的包管理工具是yarn,核心就是改善并行下载,速度提升较多,但是现在新版npm也大大改善,用法都差不多,感兴趣的可以自行查阅相关资料。

webpack

官网 https://www.webpackjs.com/
如下,现代化前端包含诸多模块,webpack就相当于传统后端语言的编译器,输入的是各种模块,输出的是html+js+css+image组成的可在浏览器执行的前端打包产物
webpack

这个过程中,webpack通过定义rules中不同loader来辅助完成转换打包,参考如下
1.js转换和依赖精简,不同平台版本的ts/js转换保证跨平台运行,一般是babel-loader
2.css转换和兼容性,包括很多css的高级工具sass/less等提供更灵活的书写方式,可编译成原始css,一般是css-loader
3.image相关的转换/加载/切分等,一般是file-loader
4.其他组件处理,比如vue对应的vue-loader

配置文件

webpack.config.js描述配置,一个典型vue项目配置如下

var path = require('path')
var webpack = require('webpack')

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ],
      },      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
          }
          // other vue-loader options go here
        }
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.(png|jpg|gif|svg|eot|woff|woff2|ttf)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]'
        }
      }
    ]
}
...
}

require(‘path’),node自带的一个模块,用来处理路径
entry:入口函数,要处理文件
output:出口,输出文件的位置
resolve()拼接路径
rules指定用于转换处理的各种loader

常用命令

cnpm i -g webpack webpack-cli #全局安装
cnpm i webpack webpack-cli -D #本地调试依赖安装

webpack # 进到目录 运行打包

参考

深入使用已经有太多教程,推荐参考的快速学习文档如下,进一步学习参考官网
https://zhuanlan.zhihu.com/p/163267718
nodejs——https://www.runoob.com/nodejs/nodejs-tutorial.html
npm——https://blog.csdn.net/qq_45677671/article/details/114546577
webpack——https://blog.csdn.net/m0_63722685/article/details/125473926

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值