摘要:引發(fā)此篇文章是看到了阮一峰的在掘金上的轉(zhuǎn)載的作者創(chuàng)建的利用字符串標(biāo)簽?zāi)0鎸?shí)現(xiàn)的類(lèi)的庫(kù),可以將標(biāo)簽?zāi)0娴念?lèi)字符串轉(zhuǎn)化成類(lèi)或函數(shù)用來(lái)創(chuàng)建對(duì)象的函數(shù)字符串介紹重點(diǎn)閱讀模版字符串和標(biāo)簽?zāi)0鎯晒?jié)瀏覽器級(jí)別將字符串解析成對(duì)象原始的思考原文如下
引發(fā)此篇文章是看到了阮一峰的twitter在掘金上的轉(zhuǎn)載:?https://juejin.im/pin/5bf6463...
Preact 的作者創(chuàng)建的利用字符串標(biāo)簽?zāi)0鎸?shí)現(xiàn)的類(lèi)JSX的庫(kù),可以將標(biāo)簽?zāi)0娴念?lèi)JSX字符串轉(zhuǎn)化成類(lèi)React.createElement或h函數(shù)(用來(lái)創(chuàng)建?virtual DOM對(duì)象的函數(shù)):?https://github.com/developit/htm
ES6字符串介紹(重點(diǎn)閱讀模版字符串和標(biāo)簽?zāi)0鎯晒?jié)):http://es6.ruanyifeng.com/#do...
瀏覽器級(jí)別API將字符串解析成DOM對(duì)象:https://developer.mozilla.org...
原始的思考原文如下:
JSX Quasi-Literal
I"ve been struggling to get the JSX transpiler playing nicely with the?traceur compiler, specifically the flags hidden behind?--experimental.The problem is that the since both the JSX transpiler and the traceur compiler are actually parsing the full javascript AST, they would have to mutually agree on the syntax extensions you use: traceur can"t parse the faux-xml syntax JSX adds, and JSX can"t parse the?async?or?await?keywords, for example, or generator functions.
This proof-of-concept is a potential solution: instead of using an external JSX transpiler, we"ll parse the faux-xml ourselves, using an ES6 feature called?quasi-literals.
Example
define(function(require) { ? ?var React ? = require("react"); ? ?var jsx ? ? = require("lib/jsxquasi"); ? ?var EchoComponent = React.createClass({ ? ? ? ?getInitialState: function() { ? ? ? ? ? ?return { value: "" }; ? ? ? }, ? ? ? ?handleChange: function() { ? ? ? ? ? ?this.setState({ value: this.refs.input.getDOMNode().value }); ? ? ? }, ? ? ? ?render: function() { ? ? ? ? ? ?return jsx` ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?${this.state.value} ? ? ? ? ? ? ? ?? ? ? ? ? ?`; ? ? ? } ? }) ? ?return function() { ? ? ? ?var comp = jsx`<${EchoComponent} />`; ? ? ? ?React.renderComponent(comp, document.body); ? }; });
A couple of things to notice:
This is valid javascript! Or harmony or es6 or whatever, but importantly, it"s not happening outside the js environment. This also allows us to use our standard tooling: the traceur compiler knows how to turn?jsx
This is not exactly the same as JSX according to the spec: it includes quotes around the attributes, etc. This is because this parser is based on?DOMParser, and hence needs to be valid XML. It would be straighforward though to change it so it matched exactly, or to remove the browser dependency (so it could run on the server, eg.)
index.js
define(function(require) { ? ?var React = require("react"); ? ?var paramRegex ?= /__(d)+/; ? ?var parser ? ? ?= new DOMParser(); ? ?var errorDoc ? ?= parser.parseFromString("INVALID", "text/xml"); ? ?var errorNs ? ? = errorDoc.getElementsByTagName("parsererror")[0].namespaceURI; ? ?// turns the array of string parts into a DOM ? ?// throws if the result is an invalid XML document. ? ?function quasiToDom(parts) { ? ? ? ? ? ?// turn ["Hi"] ? ? ? ?// into "Hi" ? ? ? ?var xmlstr = parts.reduce((xmlstr, part, i) => { ? ? ? ? ? ?xmlstr += part; ? ? ? ? ? ?if (i != parts.length - 1) { // the last part has no ending param ? ? ? ? ? ? ? ?xmlstr += `__${i}`; ? ? ? ? ? } ? ? ? ? ? ?return xmlstr; ? ? ? }, ""); ? ? ? // parse into DOM, check for a parse error ? ? ? // browser"s DOMParser is neat, but error handling is awful ? ? ? var doc ? ? ?= parser.parseFromString(xmlstr, "text/xml"); ? ? ? var errors ? = doc.getElementsByTagNameNS(errorNs, "parsererror"); ? ? ? var error ? ?= ""; ? ? ? if (errors.length > 0) { ? ? ? ? ? error = errors[0].textContent.split(" ")[0]; ? ? ? ? ? throw `invalid jsx: ${error} ${xmlstr}`; ? ? ? } ? ? ? return doc; ? } ? ?// turn a document into a tree of react components ? ?// replaces tags, attribute values and text nodes that look like the param ? ?// placeholder we add above, with the values from the parameters array. ? ?function domToReact(node, params) { ? ? ? ?var match; ? ? ? ? ? ? ? ?// text node, comment, etc ? ? ? ?if (node.nodeValue) { ? ? ? ? ? ?var value = node.nodeValue.trim(); ? ? ? ? ? ?if (value.length === 0) { ? ? ? ? ? ? ? ?return undefined; ? ? ? ? ? } ? ? ? ? ? ?match = value.match(paramRegex); ? ? ? ? ? ?return match ? params[parseInt(match[1])] : value; ? ? ? } ? ? ? ?// node to get react for ? ? ? ?// if the node name is a placeholder, assume the param is a component class ? ? ? ?var reactNode; ? ? ? ?match = node.localName.match(paramRegex) ? ? ? ?reactNode = match ? params[parseInt(match[1])] : React.DOM[node.localName]; ? ? ? ? ? ? ? ? ? ?// if we don"t have a component, give a better error message ? ? ? ?if (reactNode === undefined) { ? ? ? ? ? ?throw `Unknown React component: ${node.localName}, bailing.`; ? ? ? } ? ? ? ?// attributes of the node ? ? ? ?var reactAttrs = {}; ? ? ? ?for (var i = node.attributes.length - 1; i >= 0; i--) { ? ? ? ? ? ?var attr = node.attributes[i]; ? ? ? ? ? ?reactAttrs[attr.name] = attr.value; ? ? ? ? ? ?match = attr.value.match(paramRegex); ? ? ? ? ? ?if (match) { ? ? ? ? ? ? ? ?reactAttrs[attr.name] = params[parseInt(match[1])]; ? ? ? ? ? } ? ? ? } ? ? ? ?// recursively turn children into react components ? ? ? ?var reactChildren = []; ? ? ? ?for (var i = 0; i < node.childNodes.length; i++) { ? ? ? ? ? ?var child = node.childNodes[i]; ? ? ? ? ? ?var reactChild = domToReact(child, params); ? ? ? ? ? ?if (reactChild) { ? ? ? ? ? ? ? ?reactChildren.push(reactChild); ? ? ? ? ? } ? ? ? } ? ? ? ?return reactNode(reactAttrs, reactChildren); ? } ? ?return function jsx(parts, ...params) { ? ? ? ?var doc ? ? = quasiToDom(parts); ? ? ? ?var react ? = domToReact(doc.firstChild, params); ? ? ? ?return react; ? } });
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/99392.html
摘要:和類(lèi)似的預(yù)處理器還有等。的用處非常多,包括給自動(dòng)加前綴使用下一代語(yǔ)法等,目前越來(lái)越多的人開(kāi)始用它,它很可能會(huì)成為預(yù)處理器的最終贏家。 webpack實(shí)戰(zhàn) 查看所有文檔頁(yè)面:全棧開(kāi)發(fā),獲取更多信息。快馬加鞭,加班加點(diǎn),終于把這個(gè)文檔整理出來(lái)了,順便深入地學(xué)習(xí)一番,鞏固知識(shí),就是太累人,影響睡眠時(shí)間和質(zhì)量。極客就是想要把事情做到極致,開(kāi)始了就必須到達(dá)終點(diǎn)。 原文鏈接:webpack實(shí)戰(zhàn),原...
摘要:有沒(méi)有辦法實(shí)現(xiàn)就局部刷新呢當(dāng)然是有第十步執(zhí)行為了實(shí)現(xiàn)局部熱加載,我們需要添加插件。 前言 用了3個(gè)多月的vue自認(rèn)為已經(jīng)是一名合格的vue框架api搬運(yùn)工,對(duì)于vue的api使用到達(dá)了一定瓶頸,無(wú)奈水平有限,每每深入底層觀賞源碼時(shí)候都迷失了自己。 遂決定再找個(gè)框架學(xué)習(xí)學(xué)習(xí)看看能否突破思維局限,加上本人早已對(duì)React、RN技術(shù)垂涎已久,于是決定找找教程來(lái)學(xué)習(xí)。無(wú)奈第一步就卡在了環(huán)境搭...
摘要:但是,的本質(zhì)仍然是函數(shù),是構(gòu)造函數(shù)的另外一種寫(xiě)法。報(bào)錯(cuò)原生構(gòu)造函數(shù)的繼承對(duì)于一些原生的構(gòu)造函數(shù),比如,,,等,在是無(wú)法通過(guò)方法實(shí)現(xiàn)原生函數(shù)的內(nèi)部屬性,原生函數(shù)內(nèi)部的無(wú)法綁定,內(nèi)部屬性獲得不了。 在沒(méi)有學(xué)習(xí) ES6 之前,學(xué)習(xí) React,真的是一件非常痛苦的事情。即使之前你對(duì) ES5 有著很好的基礎(chǔ),包括閉包、函數(shù)、原型鏈和繼承,但是 React 中已經(jīng)普遍使用 ES6 的語(yǔ)法,包括 ...
摘要:一基礎(chǔ)配置項(xiàng)目安裝安裝并新建文件,并初始化文件入口出口配置插件安裝配置用來(lái)解析文件轉(zhuǎn)譯成瀏覽器可以識(shí)別的文件。以形式在頁(yè)面中插入代碼加載文件是否開(kāi)啟代碼壓縮。 一.基礎(chǔ)配置 1.init項(xiàng)目 mkdir react-webpack-demo cd react-webpack-demo mkdir src mkdir dist npm init -y 2.安裝webpack 安裝webp...
摘要:面對(duì)越來(lái)越火的,我們公司今年也逐漸開(kāi)始擁抱。綜上所述,我個(gè)人覺(jué)得是要?jiǎng)h除相關(guān)的東西,降低項(xiàng)目復(fù)雜度。但是有一個(gè)例外情況。這個(gè)配置項(xiàng)有三個(gè)值可選擇,分別是和。模式會(huì)生成,在使用前不需要再進(jìn)行轉(zhuǎn)換操作了,輸出文件的擴(kuò)展名為。 拋轉(zhuǎn)引用 現(xiàn)在越來(lái)越多的項(xiàng)目放棄了javascript,而選擇擁抱了typescript,就比如我們熟知的ant-design就是其中之一。面對(duì)越來(lái)越火的typesc...
閱讀 2187·2021-11-18 10:02
閱讀 3289·2021-11-11 16:55
閱讀 2694·2021-09-14 18:02
閱讀 2426·2021-09-04 16:41
閱讀 2056·2021-09-04 16:40
閱讀 1165·2019-08-30 15:56
閱讀 2213·2019-08-30 15:54
閱讀 3161·2019-08-30 14:15