爱前端 2018react 技术分享一 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
aiqianduan
V2EX    React

爱前端 2018react 技术分享一

  •  
  •   aiqianduan 2018-06-27 15:12:53 +08:00 2014 次点击
    这是一个创建于 2745 天前的主题,其中的信息可能已经有所发展或是发生改变。

    特点 1:这种项目几乎都是单页面应用( SPA,single page application ),整个项目就是一个 html 页面。 注意下面的两个页面的 URL 网址,只有#后面的内容在变化,而#之前的内容没有变化。

    也就是说,网页没有发生跳转,而是 DOM 的整体上树、下树。这样的好处是,让本地变量可以在本地持久的时间变长。

    特点 2,都是组件化的。 比如我们找到了两个页面上都用了这样的一个日期组件:

    也就是说,这些日历,不管是 HTML、CSS 还是 JS 交互,都能复用的。

    特点 3:所有的 DOM 元素都是动态上树的,页面上没有了 HTML 清单,所有的部件,都是组件,组件套组件,集体被 js 上树。 我们可以查看源代码,发现没有任何 DOM:

    所以 React 和 Vue 包括已经过时的 Angular 是什么: 提供组件化开发的、单页面应用的、动态上树的模块化开发的框架。

    二、webpack 基本使用 2.1 复习一下传统的前端开发多个 js 文件的关系 比如 yuan.js 中定义了一个函数: function mianji(r){ return 3.14 * r * r; } 然后 main.js 文件中调用了这个函数: alert(mianji(10));

    在页面上引入(按顺序引入)这两个 js 文件:

    <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" cOntent="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" cOntent="ie=edge"> <title>Document</title> </head> <body> <script src="yuan.js"></script> <script src="main.js"></script> </body> </html> 能够弹出计算后的值:

    yaun.js 中定义的函数,实际上是 window 对象的属性,因为这个函数是全局的函数。所以 main.js 中当然能够访问同一个 window 对象的函数。但是我们说,这两个 js 文件之间,没有“强的引入”关系。

    如果两个 js 文件之间,能够像 nodejs 的多个 js 文件之间,有暴露、有引入那该多好? exports.mianji = mianji;

    var yuan= require("./yuan.js");

    我们试着写了 exports、require(),但是浏览器报错:

    不认识这两个词语。

    在 ES6 中新增了 js 文件的暴露和引入的新的写法(重点): W3C 那些老头想,我曹,Rynl Dahl 那个小孩子挺牛逼的啊,发明了 exports 和 require()挺好用的!我们也指定一个标准吧!于是研究出了这样的语法: 暴露: 引入:

    W3C 的新的发明的词语,export 和 import 也不被浏览器支持。

    搞毛啊????? 没事,webpack 解决了这一切!

    小知识:实际上在 2005 年(比 nodejs 还早),就有美国的程序员发明了 commonjs,中国程序员阿里巴巴玉伯发明了 seajs,都解决了 export 和 require 的识别问题。因为这个规范是 commonjs 提出的,所以叫做 CMD 规范,common module definition,通用模块定义。即 nodejs 也遵循 CMD 规范,即 nodejs 并不是 CMD 规范的发明人。

    2.2 webpack 的安装 在 2 月 26 日 webpack 除了 4 代,我们学习 4 代,基本变化不大。

    webpack 是 nodejs 工作流工具,所以要通过-g 安装。安装之前,电脑中要有 nodejs 环境。 npm install -g webpack npm install -g webpack-cli

    安装完毕之后,就要用 webpack -v 来确认安装成功

    2.3 webpack 的基本使用(重点,也是分水岭) 项目是这样的:

    其中两个 js 文件的代码符合 CMD 规范: main.js: yuan.js:

    此时在这个文件夹中,打开命令行窗口,键入命令: webpack main.js -o all.js

    我们的 index.html 要引入:

    <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" cOntent="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" cOntent="ie=edge"> <title>Document</title> </head> <body> <script src="all.js"></script> </body> </html>

    此时打开浏览器,即可看见结果:

    我们看一下 all.js 的源程序:

    也就是说,webpack 进行了 3 个事情: 第一,从 main.js 出发,顺着 import 链儿寻找每一个 js 文件 第二,将每一个 js 文件智能打包。比如一个 export 暴露的函数没有被使用,将不会被打包; 第三,去 import、export 化,也就是说,all.js ,是 IE8 兼容的。

    webpack 是一个构建工具。

    2.4 使用 webpack.config.js 文件来指导 webpack 的工作(分水岭) 我们要在项目的根,创建一个 webpack.config.js 文件,就能指导 webpack 工作。

    不要求背诵,但是要求能够根据 API 文档,写出来。

    https://doc.webpack-china.org/configuration/ 加入收藏夹。

    根据这个网页的中文说明,截取我们需要的配置: 最简单的配置如下(谁被谁没出席,谁直接用老师的,更没出息),必须自己会去官网配:

    const path = require('path');

    module.exports = { entry: "./app/main.js", //入口文件 output: { //出口文件 path: path.resolve(__dirname, "dist"), //打包到哪个文件夹中 filename: "bundle.js" //打包到哪个文件 } } 这个 webpack.config.js 文件,已经拥有了这个配置文件的最小要素:入口、出口。

    文件架构:

    有了 webpack.config.js 文件之后,我们现在要打包 js 文件,此时只需要运行 webpack 即可。

    为了实时监控文件的变化,此时我们必须,加上一个 watch:true const path = require('path');

    module.exports = { entry: "./app/main.js", //入口文件 output: { //出口文件 path: path.resolve(__dirname, "dist"), //打包到哪个文件夹中 filename: "bundle.js" //打包到哪个文件 }, watch : true , mode: "development" //要求写的,表示当前正在开发模式 } 此时就能够实时的监控文件变化,自动打包。 那个自动打包的 CMD 不能关闭!!

    三、学习 ES6 中的暴露和导出 文件结构:

    3.1 最简单的暴露和接收

    如果想暴露多个函数,必须使用 export const 这样的词语配合: export const mianji = (r) => { return 3.14 * r * r; }

    export const zhouchang = (r) => { return 2 * 3.14 * r; }

    导入一个函数的时候,此时要使用 import {罗列,罗列} from "./文件名"的写法。

    import {mianji,zhouchang} from "./yuan.js";

    这里注意两个问题: 1 )接收的函数名字,必须等于暴露的名字。比如,暴露的是 mianji,此时必须用 mianji 来接收;而不能用 mj 来接收。 2 )路径必须./开头。

    3.2 命名空间 比如我们增加一个 fang.js ,也向外暴露两个函数,叫做 mianji 和 zhouchang: export const mainji = (a) => { return a * a; }

    export const zhouchang = (a) => { return 4 * a; }

    此时主文件如果一成不变: import {mianji,zhouchang} from "./yuan.js"; import {mianji,zhouchang} from "./fang.js";

    document.getElementById("box1").innerHTML = mianji(10); document.getElementById("box2").innerHTML = zhouchang(10); 会报错,因为函数的名字重复了:

    解决的办法就是命名空间: import * as yuan from "./yuan.js"; import * as fang from "./fang.js";

    alert(yuan.mianji(10)) alert(fang.mianji(10)) 此时我们的函数必须通过 yuan 继续打点,或者 fang 继续打点来调用,此时叫做命名空间。

    也就是说,import * as 命名空间 from "./文件"的语法,可以有效避免函数的名字冲突。

    注意,import * as 的这个名字,必须和文件名相同。

    3.3 默认暴露 如果一个 js 文件是一个类,此时我们不希望有命名空间,此时要用 export default 来暴露。

    比如我们写一个文件叫做 People.js 文件,这个文件仅仅向外暴露一个类,所以要用 export default 来进行暴露。 export default class People{ constructor(name,age,sex){ this.name = name; this.age = age; this.sex = sex; } changge(){ alert(啦啦啦啦啦,我是卖报的${this.name},我今年${this.age}岁啦!); } }

    在主文件,就可以不用{}来引入这个类: import * as yuan from "./yuan.js"; import * as fang from "./fang.js"; import People from "./People.js";

    alert(yuan.mianji(10)) alert(fang.mianji(10))

    var xiaoming = new People("小明" , 12 , "男"); xiaoming.changge();

    上午的知识自查,必须会以下的内容: 1 )后面学习什么知识? dashboard 是什么?有什么特点? 2 ) webpack 是干什么的,解决了什么问题? 3 ) webpack 如何安装到电脑里面? 4 ) webpack 如何启动? 5) webpack 用什么文件来指导它的工作,文件的名字是什么,里面大致有哪些属性?从哪个网页上去看这个配置。 6 )如何配置 webpack 的自动的监控文件,如何让 webpack 可以在文件变化的时候自动打包? 7 ) ES6 中的暴露和接收,有三种引入方法,有两种暴露方法,分别是什么?

    四、webpack 高级使用(难点) 4.1 babel-loader 我们之前学习过 babel,babel 用来翻译高级语法。babel 是-g 安装的工具,需要用.babelrc 文件进行指导。 我们今天 webpack 打包之后的 dist/bundle.js 文件是没有进行翻译的:

    所以,现在的任务是,在 webpack 打包过程中,对每一个.js 文件用 babel 进行翻译。 捎带脚儿 我们 webpack 提供了叫做 loader (加载器)的东西,可以让 webpack 在打包的时候捎带脚进行某些操作,比如 babel 的翻译。这个 loader 叫做 babel-loader。 babel-loader 三装一配: 安装依赖: cnpm install --save-dev babel-core cnpm install --save-dev babel-loader cnpm install --save-dev babel-preset-env babel-core:表示 babel 核心, babel-loader 表示 babel 的加载器 babel-preset-env 表示 babel 的预处理器,让 babel 对 ecmascript new version 进行翻译。

    之前我们写.babelrc 文件,现在 webpack 在自己的 webpack.config.js 文件中提供了配置的位置: 配置 webpack.config.js:

    下面的代码不需要背诵,但是也不能直接用老师的,而应该自己去 webpack 官方网站找配置: const path = require('path');

    module.exports = { entry: "./app/main.js", //入口文件 output: { //出口文件 path: path.resolve(__dirname, "dist"), //打包到哪个文件夹中 filename: "bundle.js" //打包到哪个文件 }, watch : true, mode: "development", module : { rules: [ { test: /.js$/, //以.js 结尾的文件 include: [ path.resolve(__dirname, "app") //包括什么文件夹 ], exclude: [ path.resolve(__dirname, "node_modules") //不包括 ], loader: "babel-loader", options: { presets: ["env"] } } ] } }

    module 是模块的意思,表示我们需要运行哪些外置的模块,也就是说 babel-loader 属于外置模块。 rules 表示规则,我们测试( test )所有以.js 文件结尾的文件,include、exclude 表示包括哪些文件夹、不包括哪些文件夹。 使用 babel-loader、选线格式 presets:["env"] 

    再次运行 webpack,此时就发现 ES6 的语法进行了翻译,我们的程序能够兼容到 IE8 了。

    我们今天让 webpack 在打包的时候捎带脚儿翻译 js 文件,用的是 babel-loader 在 react 基础课第 5 天左右,我们要学习 css-loader、style-loader、less-loader,他们都是让 webpack 在打包的过程中捎带脚儿做的事情。

    4.2 webpack-dev-server (重点) 这个东西不好讲,所以我们直接采用生猛教学法,告诉你怎么做,做完再回味。

    在机器的全局,安装 webpack-dev-server cnpm install -g webpack-dev-server 字面叫做“ webpack 开发服务器”。

    安装完毕可以用 webpack-dev-server --version 来查看版本号:

    我们将项目的 app 文件夹和 index.html 文件放入 www 文件夹中,整个项目的结构:

    改变 webpack.config.js 文件的一些配置: const path = require('path');

    module.exports = { entry: "./www/app/main.js", //入口文件 output: { //出口文件 path: path.resolve(__dirname, "www/dist"), //打包到哪个文件夹中 filename: "bundle.js", //打包到哪个文件 publicPath : "/xuni" }, watch : true, mode: "development", module : { rules: [ { test: /.js$/, //以.js 结尾的文件 include: [ path.resolve(__dirname, "www/app") //包括什么文件夹 ], exclude: [ path.resolve(__dirname, "node_modules") //不包括 ], loader: "babel-loader", options: { presets: ["env"] } } ] } }

    然后启动项目 webpack-dev-server --content-base ./www --port 8080 --content-base 表示以 www 文件夹作为一个根目录 --port 表示端口号。

    启动项目的时候:

    webpack-dev-server 在进行两个事情: 1 )在打包 js 文件(就是上午学习的 webpack 的事情) 2 )静态化 www 文件夹,说白了,就是说帮我们写了一个 app.use(express.static("www"));

    注意!!我们的 index.html 文件,要改变 script 的 src:

    <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" cOntent="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" cOntent="ie=edge"> <title>Document</title> </head> <body>
    <script src="xuni/bundle.js"></script> 
    </body> </html>

    项目中物理磁盘上没有 xuni 文件夹!!但是 webpack-dev-server 将 /xuni/bundle.js 文件路由到了打包的文件,不毁硬盘!!

    我们以后起项目,都要 webpack-dev-server --content-base ./www --port 8080

    此时我们可以在 package.json (身份证)文件中,进行配置: { "name": "test", "version": "1.0.0", "description": "", "main": "webpack.config.js", "scripts": { "dev" : "webpack-dev-server --content-base ./www --port 8080" }, "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.4", "babel-preset-env": "^1.6.1" } }

    以后起项目,就直接使用 npm run dev

    以后看项目,就直接在 8080 端口的 URL 下看。不要直接双击打开 index.html 页面了。

    五、React 配置和起步 React 需要建立在 webpack + babel-loader 上, 然后补充安装 npm install --save react npm install --save react-dom npm install --save-dev babel-preset-react

    改变 webpack.config.js 文件,加一个 babel 的 preset,就是 babel 的预处理器: const path = require('path');

    module.exports = { entry: "./www/app/main.js", //入口文件 output: { //出口文件 path: path.resolve(__dirname, "www/dist"), //打包到哪个文件夹中 filename: "bundle.js", //打包到哪个文件 publicPath : "/xuni" }, watch : true, mode: "development", module : { rules: [ { test: /.js$/, //以.js 结尾的文件 include: [ path.resolve(__dirname, "www/app") //包括什么文件夹 ], exclude: [ path.resolve(__dirname, "node_modules") //不包括 ], loader: "babel-loader", options: { presets: ["env" , "react"] } } ] } }

    然后,写 main.js(其他的 JS 文件可以删除了):

    import React from "react"; import ReactDOM from "react-dom";

    ReactDOM.render(

    你好!我是 React !

    你好!我是 React !

    你好!我是 React !

    , document.getElementById("app") )

    改变 index.html:

    <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" cOntent="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" cOntent="ie=edge"> <title>Document</title> </head> <body>
    <script src="xuni/bundle.js"></script> </body> </html>

    npm run dev 打开 8080 端口,即可看见项目:

    我们的项目的身份证,react 需要 6 个依赖(最少 6 个依赖)就可以运行: { "name": "test", "version": "1.0.0", "description": "", "main": "webpack.config.js", "scripts": { "dev": "webpack-dev-server --content-base ./www --port 8080" }, "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.4", "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.24.1" }, "dependencies": { "react": "^16.2.0", "react-dom": "^16.2.0" } }

    家也可以加群实时技术交流:137503198

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2293 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 02:09 PVG 10:09 LAX 18:09 JFK 21:09
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86