<p><code></p> <h3 id="articleHeader0">数据分析平台-实践系列一</h3> <blockquote><p>项目创建于2018年1月底,到现在已经接近半年,在此写下半年来项目的实践过程以及自己对前端的学习与体悟。</p></blockquote> <h4>技术选型</h4> <p>框架: <code><a href="http://www.js-code.com/tag/react" title="React" target="_blank">React</a></code></p> <p>路由: <code><a href="http://www.js-code.com/tag/react" title="React" target="_blank">React</a>-Router 4</code></p> <p>状态管理: <code>Redux</code></p> <p>UI组件库: <code>Ant Design</code></p> <h4>搭建工程</h4> <p>因为平台的前端技术选型,因此挑选了<code><a href="http://www.js-code.com/tag/react" title="浏览关于“React”的文章" target="_blank" class="tag_link">React</a></code>为技术框架。并使用<code>create-react-app</code>快速搭建工程。<code>create-react-app</code>为fackbook官方出品的快速搭建<code>React</code>工程的命令行工具,可以减少写各种配置的过程,似于<code>vue</code>的<code>vue-cli</code>和<code>angular</code>的<code>angular-cli</code>。</p> <p>而在使用<code>create-react-app</code>,需要使用<code>eject</code>暴露所有配置项,好自定义个人的<code>Webpack</code>配置。</p> <p>首先我们并不打算将<code>React</code>让<code>Webpack</code>打包,而使用第三方的CDN,直接在<code><a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a></code>文件以<code>script</code>标签引入。在此我们选用用友的<a href="http://www.tinper.org/dist/cdn/index.html" rel="nofollow noreferrer" target="_blank">tinper公共静态资源库</a>。</p> <p>改动<code>Webpack</code>配置文件</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="externals: { 'react': 'React', 'react-dom': 'ReactDOM', 'react-router-dom': 'ReactRouterDOM', 'redux': 'Redux', 'react-redux': 'ReactRedux' }" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs groovy"><code><span class="hljs-string">externals:</span> { <span class="hljs-string">'react'</span>: <span class="hljs-string">'React'</span>, <span class="hljs-string">'react-dom'</span>: <span class="hljs-string">'React<a href="http://www.js-code.com/tag/dom" title="浏览关于“DOM”的文章" target="_blank" class="tag_link">DOM</a>'</span>, <span class="hljs-string">'react-router-dom'</span>: <span class="hljs-string">'ReactRouterDOM'</span>, <span class="hljs-string">'redux'</span>: <span class="hljs-string">'Redux'</span>, <span class="hljs-string">'react-redux'</span>: <span class="hljs-string">'ReactRedux'</span> }</code></pre> <p>而若引入第三方CDN,需要分引入为生产环境还是开发环境的代码。<br />如在生产环境下要引入<code>//design.yonyoucloud.com/static/react/16.0.0/umd/react.production.min.js</code><br />而在开发环境引入<code>//design.yonyoucloud.com/static/react/16.2.0/umd/react.development.js</code>。</p> <p>选用<code>ejs-compiled-loader</code>,这样另我们可以在<code><a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a></code>文件使用<code>ejs</code>模板引擎。</p> <p>继续改动<code>Webpack</code>配置文件</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="new HtmlWebpackPlugin({ inject: true, template: `!!ejs-compiled-loader!${paths.appHtml}`, })," title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs typescript"><code><span class="hljs-keyword">new</span> HtmlWebpackPlugin({ inject: <span class="hljs-literal">true</span>, template: <span class="hljs-string">`!!ejs-compiled-loader!<span class="hljs-subst">${paths.appHtml}</span>`</span>, }),</code></pre> <p>在<code><a href="http://www.js-code.com/tag/html" title="浏览关于“HTML”的文章" target="_blank" class="tag_link">HTML</a></code>使用模板引擎</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" <% if (process.env.NODE_ENV === 'production') { %><br /> <script src=&quot;//design.yonyoucloud.com/static/react/16.0.0/umd/react.production.min.js&quot;></script><br /> <script src=&quot;//design.yonyoucloud.com/static/react-dom/16.0.0/umd/react-dom.production.min.js&quot;></script><br /> <% } %><br /> <% if (process.env.NODE_ENV === 'development') { %><br /> <script src=&quot;//design.yonyoucloud.com/static/react/16.2.0/umd/react.development.js&quot;></script><br /> <script src=&quot;//design.yonyoucloud.com/static/react-dom/16.2.0/umd/react-dom.development.js&quot;></script><br /> <% } %>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="xml hljs"><code class="html"> <span class="hljs-tag">&lt;<span class="hljs-name">%</span> <span class="hljs-attr">if</span> (<span class="hljs-attr">process.env.NODE_ENV</span> === <span class="hljs-string">'production'</span>) { %&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"//design.yonyoucloud.com/static/react/16.0.0/umd/react.production.min.js"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"//design.yonyoucloud.com/static/react-dom/16.0.0/umd/react-dom.production.min.js"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">%</span> } %&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">%</span> <span class="hljs-attr">if</span> (<span class="hljs-attr">process.env.NODE_ENV</span> === <span class="hljs-string">'development'</span>) { %&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"//design.yonyoucloud.com/static/react/16.2.0/umd/react.development.js"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"//design.yonyoucloud.com/static/react-dom/16.2.0/umd/react-dom.development.js"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">%</span> } %&gt;</span></code></pre> <p>最后,设置<code>Webpack</code>的别名,让后续引用的地方减少路径的复杂度。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="alias: { 'root': path.resolve(__dirname, '../src'), '@': path.resolve(__dirname, '..') }," title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs lua"><code>alias: { <span class="hljs-string">'root'</span>: <span class="hljs-built_in">path</span>.resolve(__dirname, <span class="hljs-string">'../src'</span>), <span class="hljs-string">'@'</span>: <span class="hljs-built_in">path</span>.resolve(__dirname, <span class="hljs-string">'..'</span>) },</code></pre> <p>如在<code>src</code>文件夹下有两个文件夹<code>a</code>和<code>b</code>,倘若<code>b</code>下的<code>m.js</code>需要引用<code>a</code>下的<code>n.js</code>,需要<code>import X from ‘../a/n.js’</code>,设置别名后可写为<code>root/a/n.js</code>。</p> <h4>前后端分离</h4> <p><span class="img-wrap"><img data-src="/img/bVbbYaO?w=700&amp;h=262" src="https://cdn.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="clipboard.png" title="clipboard.png" style="cursor: pointer;"></span></p> <p>在知乎上面找了张图片,前后端分离,简单的说,就是前端负责页面交互,显示后台提供的数据,而后端负责数据的处理,提供给前台数据。</p> <p>可以看出前后端是有很强的耦合关系,后端需要依赖前端请求,前端需要依赖后端响应。不过此处后端是可以轻松模拟前端请求,如<code>POSTMAN</code>等。剩下的解决要点为如何给前端模拟数据。因此,我们在设计接口约定数据后构建另一个简单的<code>Server</code>,这个<code>Server</code>会简单的响应前端请求,根据约定返回模拟的数据。我们将这个<code>Server</code>成为<code>Mock Server</code>。</p> <p>其中<code>Mock Server</code>可分成本地及远程。</p> <p>本地的<code>Mock Server</code>需要每个前端在自己电脑上部署服务器,且若后台改动<a href="http://www.js-code.com/tag/api" title="API" target="_blank">API</a>,后台无法同步维护<code>Mock Server</code>与<code>Real Server</code>。</p> <p>因此打算建立远程的<code>Mock Server</code>(其实还有个关键是我使用用友配的电脑开发,在本地部署的话电脑配置。。。)不过此步骤我们也可以省略了,用友的大前端技术团队提供了<a href="https://mock.yonyoucloud.com" rel="nofollow noreferrer" target="_blank">Mock平台</a>。<span class="img-wrap"><img data-src="/img/bVbbYaS?w=1265&amp;h=594" src="https://cdn.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="clipboard.png" title="clipboard.png" style="cursor: pointer;"></span></p> <p>他的功能十分齐全,具备权限管理,Mock Server,数据导入等等的功能。</p> <p></code></p>

本文固定链接: http://www.js-code.com/react/react_43445.html