飞道的博客

大前端技术学习与核心整理(NodeJS/ES6/npm/babel/webpack)

281人阅读  评论(0)

前言

本文整理了学习过程中关于NodeJS、ES6标准的新特性、npm包管理工具、babel降级、webpack打包等大前端技术,学习的原因是几个月以后可能会用到。

NodeJS

Node 是一个让 JavaScript 运行在服务端的开发平台,它让 JavaScript 成为与PHP、Python、Perl、Ruby 等服务端语言平起平坐的脚本语言,实质是对Chrome V8引擎进行了封装(node安装自带npm,node -v查看版本)。

【案例1】用Node实现请求响应(类似flask)。创建server.js并执行node server.js

// 0.用require导包(类似python的import)
const http = require('http');

// 1.创建一个httpserver服务
http.createServer(function(request, response){
   
    // request用来接收参数, response用来返回内容
    // 告诉浏览器将以text/plain解析"hello server is running!"这个数据
    response.writeHead(200, {
   "Content-type":"text/plain"});
    // response.writeHead(200, {"Content-type":"text/html"}); //这样会以html的形式解析<h1></h1>
    // 给浏览器输出内容
    response.end("<h1>hello server is running!<h1>")
}).listen(8888);  
// 2.监听端口 比如8888
// 3.启动 node serverFileName.js
// 4.浏览器访问 http://127.0.0.1:8888
console.log("server已启动 端口为8888")

【案例2】用node操作mysql数据库。新建mysqltest.js,先在项目目录执行npm install mysql安装第三方库,此时生成了node_modules文件夹和package-lock.json文件。最后运行node mysqltest.js查看效果。

// 0.导入第三方模块mysql
var mysql = require('mysql');

// 1.创建mysql的Connection对象
// 2.配置连接
var connection = mysql.createConnection({
   
    host:"xxx.xxx.xxx.xxx",
    user:"root",
    port:3306,
    password:"xxxxx",
    database:"vaeh"
});

// 3.打开连接
connection.connect();

// 4.执行curd
connection.query("select count(*) from cityinfo", function(error, result, fields) {
   
    // 如果出错 抛出
    if(error) {
   
        throw error;
    }    
    console.log("result = ", result);
});

// 5.关闭连接
connection.end();

ES6标准新特性

ECMAScript是个用来指定JavaScript规范的组织 es6就是JavaScript的标准。

  • let定义变量,const定义常量。
<!-- 以下内容在vscode打了个叹号回车就生成了 -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 传统定义变量和常量都用var
        var name = "vae";
        var PI = Math.PI;
        console.log(name);
        console.log(PI);

        // ES6定义变量 (解决了变量穿透问题,比如for循环里定义的var = i, 循环完按说i不能再用了)
        let name_es6 = "vae"

        // ES6定义常量 (解决了常量修改问题,比如圆周率PI如果用const定义就不能修改了)
        const PI_es6 = Math.PI;
        
        console.log(name_es6);
        console.log(PI_es6);

    </script>
</body>
</html>
  • 模版字符串(反引号做格式化or拼字符串:类似python的 f"名字是{name}的人"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 模版字符串 类似python的 f"名字是{name}的人"
        person = {
    name: "vae", id: 514, url: "xusong.com"};

        // 传统方式
        let res = person.name + "的id为" + person.id + ", 官网为" + person.url;
        console.log(res);

        // ES6 用 ` ${变量名} ` 就ok了
        let res_es6 = `${
      person.name}的id为${
      person.id}, 官网为${
      person.url}`;
        console.log(res_es6);
    </script>
</body>
</html>
  • 函数默认参数(函数参数默认是undefined,可手动指定)
<script>
    // 函数默认参数(默认是undefined)
    function sum(a=undefined,b=100){
    
        return a+b;
    }
    let res = sum(a=200);
    console.log(`res=${
      res}`);
</script>
  • 箭头函数(箭头函数=>简化函数表达,规律如下)
<script>
    // 箭头函数(重点。有lambda函数内味儿了,不过本质不一样) 小程序、uniapp、脚手架中大量使用
    
    // 传统方式:
    let sum0 = function(a,b){
    
        return a+b;
    };
    console.log(sum0(1,2));

    // 箭头函数 改进1 :
    let sum1 = (a,b)=>{
    
        return a+b;
    };

    // 箭头函数 改进2 :
    let sum2 = (a,b) => a+b;
    
    // 规律:
    // 1.去掉function 
    // 2.参数列表括号后加上 =>
    // 3.若逻辑代码仅return 可省略return和大括号
    // 4.若参数只有一个 可参数列表的省略小括号
    // 示例:数组的每个数都*2
    let arr = [1,2,3]
    let new_arr = arr.map(obj=>obj*2);
    console.log(new_arr)
</script>
  • 定义对象时的简写(key和value一致 or value是个函数)
<script>
    // 定义对象时的简写
    // 1.如果key和value变量名一致 只定义一次即可
    // 2.如果value是个函数 可删掉“function” 保留()即可

    // 传统写法
    let title = "About Vae+";
    let obj_example = {
    
        title: title,
        go: function(){
    
            console.log("test...");
        }
    };

    // ES6
    let title1 = "About Vae+";
    let obj_example1 = {
    
        title1,
        go(){
    
            console.log("test...");
        }
    };
    obj_example1.go();
</script>
  • 对象解构(3种获取对象中的属性/方法)
<script>
    // 1、通过 . 
    console.log(obj_example.title);
    obj_example.go();
    // 2、通过 []
    console.log(obj_example["title"]);
    obj_example["go"]();
    // 3、ES6的新方法 有点像python的 a,b=[1,2] 可以用冒号取小名:var {name,age,language:lan} = person;
    let {
    obj_title,go} = obj_example;
    go();
</script>
  • 对象传播操作符(…)把一个对象的属性传播到另外一个对象中
<script>
    // 对象传播操作符...
    let person = {
    
        name: "vae",
        id: 514,
        link: "xusong.com",
        address: "北京市朝阳区"
    }
    // ...linkAndAddr 来接收除了name和id的其他变量 并解构成一个obj
    let {
    name, id, ...linkAndAddr} = person;
    console.log(name);
    console.log(id);
    console.log(linkAndAddr);
</script>
  • map和reduce方法
    map方法可以将原数组中的所有元素通过一个函数进行处理,并放入到一个新数组中并返回该新数组。
    reduce(function(),初始值(可选)) :接收一个函数(必须)和一个初始值(可选),该函数接收两个参数:第一个参数是上一次reduce处理的结果,第二个参数是数组中要处理的下一个元素。reduce() 会从左到右依次把数组中的元素用reduce处理,并把处理的结果作为下次reduce的第一个参数。如果是 第一次,会把前两个元素作为计算参数,或者把用户指定的初始值作为起始参数。
<script>
    let arr = [1,2,3];

    // 【map(自带循环 并把处理值回填)】
    // 需求:对数组arr的每个元素乘以2 赋值给new_arr
    let new_arr = []
    // 传统方式:for循环
    for (let i=0;i<arr.length;i++){
    
        new_arr.push(arr[i]*2)
    };
    console.log(new_arr);
    // ES6的方式
    console.log(arr.map(num=>num*2));

    // 【reduce(接收俩参数,1.上一次reduce处理的结果 2.数组中要处理的下一个元素)】
    // 需求:对数组arr中每个元素相加
    add_res = arr.reduce(function(a,b){
    
        return a+b;
    });
    add_res = arr.reduce((a,b)=>a+b);  // 简写
    
    //(原理:辗转相加)
    // arr = [1,2,3]
    // i=1        j=2 
    // i=3(i+j)   j=3
    // i=6(i+j)

    console.log(add_res);
</script>
  • 模块化开发(模块的导入导出):常用的CommonJS模块化规范(导出用exports,导入用require)和ES6规范(导入用import,不过需要用babel降级到es2015)。目录结构和代码如下:

需要export的js文件(四则运算.js):

// 模块化规范(引入自己写的方法)
// commonjs(导出用exports,导入用require)

const sum = (a,b)=>a+b;
const sub = (a,b)=>a-b;
const mul = (a,b)=>a*b;
const div = (a,b)=>a/b;
// console.log(sum(1,2))

// 导出给别人(exports不是export)
module.exports = {
   
    sum, sub, mul, div
}

需要require的js文件(导入测试.js):

const cal = require('./四则运算');

console.log(cal.sum(3,4));
console.log(cal.sub(3,4));
console.log(cal.mul(3,4));
console.log(cal.div(3,4));

es6规范:
需要export的js文件(userApi.js):

// export function getList() {
   
//     // 真实业务是异步获取
//     console.log("获取数据列表");
// }

// export function save() {
   
//     // 真实业务是保存数据
//     console.log("保存数据");
// }

// 也可以这么写(常用)
export default {
   
    getList() {
   
        console.log("获取数据列表");
    },
    save() {
   
        console.log("保存数据");
    }
}

需要import的js文件(userTest.js):

import {
   getList,save} from './userApi.js'

getList();
save();
// 默认不支持es6语法 import 需要用babel降级到es2015

npm(Node Package Manager)

NPM(Node Package Manager)
node.js包管理工具(相当于pip),装node的时候就已经自带了
仓库官网:https://www.npmjs.com/
看安装版本:npm -v

npm的两个用途:

  • 快速构建nodejs工程,方法 npm init 根据提示输入后续内容(npm init -y默认都是yes), 最后在执行命令的目录生成一个package.json, 内容如下:
{
   
    "name": "npmproj", // 工程名
    "version": "1.0.0",
    "description": "this is a npm project created by muyaostudio.",
    "main": "index.js", // 入口js
    "scripts": {
   
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "muyao",
    "license": "ISC"
}
// 类似maven的pom.xml
  • 快速安装第三方依赖模块,比如 npm install mysqlnpm i mysql
    安装完后产生在执行install命令的目录下产生node_modules文件夹、package-lock.json文件。

    并在写入package.json的属性dependencies中:

    这个文件可以方便其他项目复用(类似python的requirement.txt):
    把本项目的package.json复制到新项目空白文件夹下 并执行npm install(不用init了 因为有package.json了)。为啥不直接复制node_modules文件夹呢?倒是可以,不过因为依赖错综复杂,不如重新下载来得方便。

下面是一些常用npm命令:

  • 导入模块:const mysql = require("mysql")
  • 执行js:node xx.js (.js可以省略为node xx)
  • 通过cnpm命令用镜像安装依赖:
    首先安装cnpm:npm install -g cnpm --registry:https://registry.npm.taobao.org (-g是全局安装)
    以后就能用了:cnpm install xxx
  • 下载多个包、指定版本号:npm install vue redis@1.1.x mysql
  • 卸载模块:npm uninstall vue mysql [-g]
  • 更新模块:npm update xxx

babel

es6某些高级语法在浏览器甚至nodejs环境里没法执行
于是,babel的作用:把es6代码降级为比如es5的代码

全局安装:npm install -g babel-cli
查看版本:babel --version

实战步骤:

  1. 新建node工程(npm init -y),新建./src/example.js 用es6语法写代码

  2. 新建.babelrc,配置好要转化到的版本,内容如下:

  3. 当前目录下安装es2015转化器:cnpm install --save-dev babel-preset-es2015。(--save-dev的原因是转化器就开发时用,--save发布的版本并不需要依赖这玩意)

  4. 执行 babel src -d dist 把src目录下的所有js 转化,存到dist目录下。
    也可以通过自定义脚本完成上述操作:改写package.json,执行 npm run fuckes6

Webpack

webpack:前端资源加载、打包工具。
把多种静态资源js css less转成一个静态文件 减少页面请求

全局安装:cnpm install -g webpack webpack-cli
看版本号:webpack -v

  • webpack合并js:

学习步骤:
1.创建nodejs项目 npm init -y
2.创建src目录 存两个需要合并的js:src/util.js和 src/common.js
3.准备一个入口文件 src/main.js 把模块集中引入(用来汇总相关的js等资源文件)
4.在根目录下定义webpack.config.js配置打包规则
5.在根目录下执行webpack命令 去dist文件夹查看效果
6.在dist文件夹里新建index.html引入生成的bundle.js 查看效果

补充:
webpack -w可以监听js改动并自动编译打包

目录结构如下:

  • webpack合并css

学习步骤:
1.安装依赖npm install --save-dev style-loader css-loader(因为webpack默认只支持js打包)
2.在根目录下定义webpack.config.js配置打包规则(module)
3.新建src/style.css,并在src/main.js 把css引入(require("./style.css");)
4.项目根目录执行命令webpack(也可以执行webpack -w 边改边打包) 就会把js和css一起打包到同一个bundle.js里!

其中:
配置打包规则webpack.config.js代码如下:

// 导入path模块
const path = require("path");
// 自己定义js打包规则
module.exports = {
   
    // 从入口函数开始编译打包
    entry: "./src/main.js",
    // 定义输出的目录 __dirname是当前项目根目录 产生dist文件夹 合并成bundle.js
    output: {
   
        path: path.resolve(__dirname, "./dist"),
        filename: "bundle.js"
    },
    // 定义css打包规则
    module: {
   
        rules:[{
   
            test:/\.css$/, // 把所有css结尾的文件打包
            use: ["style-loader", "css-loader"]
        }]
    }
}

入口文件main.js代码如下:

// 导入util和common
const util = require("./util");
const common = require("./common");

common.info(`Add result = ${
     util.add(3,4)}`);

// 导入css
require("./style.css");

其他文件:

生成上图所示压缩和混淆后的bundle.js,写个html,通过script引入测试一下:

<!DOCTYPE html>
<html lang="en">
<head>
    ...
</head>
<body>
    <script src="bundle.js"></script>
</body>
</html>
  • 补充
    webpack官网:https://webpack.docschina.org/
    当前 uniapp等框架或者脚手架已经内置了webpack,所以一般不用单独去用了。

参考资料
https://www.bilibili.com/video/BV1BU4y147pS
https://www.kuangstudy.com/bbs/1351463043300708353


转载:https://blog.csdn.net/muyao987/article/details/116170307
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场