我之前写前端的时候就三个技术(html、js、css),现在的前端技术一般使用vue.js+element-ui, 一个后端程序员感觉再看现在的前端完全看不懂,js语法也不认识了,css语法也不认识了,html中也出现了不认识的标签。为了弄懂现在的前端是怎么玩的就研究了一下,本文是一个后端服务器码农对现在的大前端技术的扫盲,因不是专业前端,不保证所写的都是正确的,如有错误请指出。
我们知道javascript代码只能在浏览器上运行,只有浏览器能够解析js代码,如果想要javascript代码能够在服务器端运行就必须提供一个Javascript的运行环境(runtime environment),这就是node.js。
node.js是对Chrome V8引擎进行了封装,是一个能让JavaScript运行在服务端的开发平台,它让JavaScript成为与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语言。
# 查看node的版本$ node -v$ cat helloworld.jsconsole.log("Hello Node.js");$ node helloworld.jsHello Node.js
// 1、加载http模块var http = require('http');// 2、创建一个http服务对象var server = http.createServer();// 3、监听用户的请求事件(request事件)// 回调函数中有两个参数// request 对象 包含用户请求报文中所有内容,通过request对象可以获取所有用户提交过来的数据// response 对象 用来向用户响应一些数据,当服务器要向客户端响应数据的时候必须使用response对象server.on('request', function (req, res) { res.setHeader('Content-Type', 'text/html; charset=utf-8'); var url = req.url; res.write('<h1> web http server <br/> request url :' + url + ' </h1>'); // 对于每一个请求,服务器必须结束响应,否则,客户端(浏览器)会一直等待服务器响应结束 res.end();});// 4、启动服务server.listen(8080, function () { console.log('服务器启动了,请访问:http://localhost:8080');});
$ node index.js
在传统的前端开发中我们会经常引入jquery、bootstrap、echarts等js插件,我们首先去插件的每个官网去下载下来,然后放到自己前端工程中static/js目录下,我们每引用一个插件都要去官网下载,然后将下载的插件拖到工程中来,美国的一个程序员Isaac Z. Schlueter就做够了这种机械运动,想简化这个流程,于是做了这样一件事:
这套思想和maven是完全一样的,熟悉maven或者gradle的也就自然理解npm了,只不过npm用于js,maven用于java,都是作者先将共享的代码放到某个公共的代码仓库,用户先在配置文件中配置好要使用的依赖,然后通过一个命令就能下载下来。
|仓库 | npm | maven |
|----------|:-------------:|:------:|
| 代码仓库 | registry | repository |
| 仓库地址 | http://registry.npmjs.org | https://mvnrepository.com |
| taobao镜像 |
https://registry.npm.taobao.org |
http://maven.aliyun.com/nexus/content/groups/public |
| 配置文件 | package.json"dependencies": {"vue": "^2.5.13"} | pom.xml<dependencies><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.6</version></dependency><dependencies>|
| 软件 | npm(node package manager) | apache-maven |
| 下载命令 | npm install | mvn install |
| 打包生成的目录 | dist | target |
npm: Node Package Manager, 一种用Node.js开发的工具用于发布插件到仓库和从插件仓库中下载插件的工具,一种用于共享JS代码的工具。
由于node.js当时也缺少一个包管理器,npm也是使用node.js开发的,这个工具使用的人较少,后来node.js的作者和npm的作者沟通一下将npm作为node.js包管理器,内置到node.js中,后来由于node.js大火,npm使用的人也越来越多,越来越多的JS插件通过npm被共享,现在几乎常用的插件都能在npm中找到,现在的npm已经发展成为前端共享代码的标准了。因为npm已经内置于node.js当中了,所以安装了node.js也就安装了npm, 可以通过node -v 和 npm -v 分别查看对应的版本。
npm init : 用于生成一个基础的package.json文件,里面包含名称、版本号、描述、主文件、作者、协议等
package.json
{ "name": "platform-webapp", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC"}
传统的前端一般会html、javascript、css这三样东西就够了。现代的前端发展迅猛,引入了TypeScript、SCSS、LESS、stylus(CSS预处理器)等技术,提供了更丰富的特性,提高了开发效率,但是引入的这些技术不能直接被浏览器解析,需要一个东西将浏览器不能解析的代码翻译成浏览器可以直接解析代码,这就是webpack的作用。
webpack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(TypeScript、SCSS等),并将其打包为合适的格式以供浏览器直接使用。随着webpack的发展,webpack支持ECMAScript6、ECMAScript7、ECMAScript8等。随着webpack的发展,webpack不仅仅用来编译(翻译)代码,也集成了更多的功能,比如:
webpack最终发展成为:前端项目的构建工具。
模块(module)化就是把复杂的应用程序细分为较小的文件,在webpack中一切都是模块,js、css、图片、字体等待都可称为模块。
webpack文档
webpack可以通过npm安装,安装后会生成一个node_modules目录
# npm初始化,直接回车即可,生成package.json文件npm init# npm全局(global)安装npm install -g webpack # 切换到项目根目录,安装到你的项目目录中, 生成node_modules目录和package-lock.json文件# 注意:全局安装的作用是可以在命令行中直接使用命令,效果类似于环境变量的作用# 全局安装后,仍然需要在自己的项目中再次安装# --save-dev 将依赖保存到package.json中的devDependencies中# --save 将依赖保存到package.json中的dependencies中npm install --save-dev webpack
# webpack 打包命令webpack <源文件> -o <目标文件>webpack src/index.js -o dist/index.bundle.js# 如果报错Error: Cannot find module 'webpack-cli',执行下面命令npm install webpack-cli -g
devtool: "eval-source-map" webpack打包后的文件可读性非常低,不利于调试,使用devtool可以生成对应的源码便于调试。使用eval打包源文件模块,在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。在开发阶段这是一个非常好的选项,在生产阶段则一定不要启用这个选项;
webpack-dev-server 是一个本地开发服务器,居于node.js实现的,使用npm run dev 后就可以使用默认的8080端口在浏览器上访问了,类似于apache的功能
loader可以让webpack有能力调用外部的脚本或工具,实现对不同格式的文件的处理,比如说分析转换scss为css,或者把下一代的JS文件(ES6,ES7)转换为现代浏览器兼容的JS文件
css-loader 和 style-loader 就是用来处理样式的。
Babel其实是一个编译JavaScript的平台,它可以编译代码帮你达到以下目的:
插件(Plugins)是用来拓展Webpack功能的,它们会在整个构建过程中生效,执行相关的任务。
Loaders和Plugins常常被弄混,但是他们其实是完全不同的东西,可以这么来说,loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less..),一次处理一个,插件并不直接操作单个文件,它直接对整个构建过程其作用。
Webpack有很多内置插件,同时也有很多第三方插件,可以让我们完成更加丰富的功能。
常用的插件:
页面上每个独立的可视或者可交互的区域均视为一个组件,每个组件对应一个工程目录(文件夹),组件所需要的各种资源尽可能的都放在这个目录下就近维护(即将模板、样式、js等都写在一个.vue文件中),组件可以嵌套自由组合,形成完整的页面。
# 1.安装vue-cli脚手架(用于初始化项目)$ npm install -g vue-cli$ 2. 创建项目$ vue init webpack <project name># 3. 安装cnpm(此步骤不是必须的)# 有些npm有些资源被屏蔽或者是国外资源的原因,经常会导致用npm安装依赖包的时候失败,所以还需要npm的国内镜像—cnpmnpm install -g cnpm –registry=http://registry.npm.taobao.org# 4. 安装依赖包$ cd <project name># cnpm 需要单独安装,如果没有cnpm可以使用npm来代替$ cnpm install# 5. 启动程序就可以在浏览器访问$ npm run dev# 6. 在浏览器访问localhost:8080
import Vue from 'vue'import Router from 'vue-router'import HelloWorld from '@/components/HelloWorld'Vue.use(Router)export default new Router({ routes: [ { path: '/helloworld', name: 'HelloWorld', component: HelloWorld } ]})
<template> <div class="hello"> <h1>{{ msg }}</h1> </div></template><script>export default { name: 'HelloWorld', data () { return { msg: 'HelloWorld.vue' } }}</script><!-- style 标签省略了 -->
<template> <div id="app"> <img src="./assets/logo.png"> <router-view/> </div></template><script>export default { name: 'App'}</script><!-- style 标签省略了 -->
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>platform-webapp</title> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> </body></html>
# 切换到项目根目录$ cd <project root dir># 安装element-ui, 安装后package.json中dependencies就会增加element-ui依赖$ cnpm i element-ui -S
在main.js中增加导入和让Vue使用ElementUI
import Vue from 'vue'import App from './App'import router from './router'// 导入element-uiimport ElementUI from 'element-ui'Vue.config.productionTip = false// Vue使用ElementUIVue.use(ElementUI)/* eslint-disable no-new */new Vue({ el: '#app', router, components: { App }, template: '<App/>'})
cnpm install
HelloWorld.vue
<template> <div class="hello"> <h1>{{ msg }}</h1> <el-button type="primary">主要按钮</el-button> <el-input-number v-model="num" :min="1" :max="10" @change="handleChange"></el-input-number> </div></template><script>export default { name: 'HelloWorld', data () { return { msg: 'HelloWorld.vue', num: 5 } }, methods: { handleChange(value) { console.log(value) } }}</script><!-- 样式省略 -->
npm run dev