热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

webpack多页运用架构系列(十四):No复制粘贴!多项目共用基础设施

本文首发于Array_Huang的手艺博客——有效至上,非经作者赞同,请勿转载。原文地点:https:segmentfault.coma1190000007301770假如您对本系

本文首发于
Array_Huang的手艺博客——
有效至上,非经作者赞同,请勿转载。

原文地点:
https://segmentfault.com/a/1190000007301770

假如您对本系列文章感兴趣,迎接关注定阅这里:
https://segmentfault.com/blog/array_huang

媒介

本文引见如安在多项目间共用统一套基本设施,又或是某种条理的框架

基本设施是什么?

一个完全的网站,不可能只包含一个jQuery,或是某个MVVM框架,个中一定包含了很多处理方案,比方:怎样上传?怎样兼容IE?怎样跨域?怎样运用当地存储?怎样做用户信息反馈?又或许详细到怎样挑选日期?等等等等……这内里一定包含了UI框架、JS框架、各种小工具库,不论是第三方的照样自身团队研发的。而以上所述的各种,就构成了一套完全的处理方案,也称基本设施

基本设施有个重要的特性,那就是与营业逻辑无关,不论是OA照样CMS又或是CRM,只需团体产物形状相似,我们就能够运用统一套基本设施。

框架

框架这个观点很泛,泛得让民气生疑心,但笼统出来讲,框架就是一套定义代码在那里写、怎样写的划定规矩。不能说我们要怎样去框架,反倒是框架掌握我们怎样去代码。

本系列前面的十来篇文章,离开来看是差别的,但假如一切文章合起来,并连同示例项目(Array-Huang/webpack-seed),实际上论述的就是一套完全的多页运用框架(或称架构)。这套框架划定了全部运用的各个方面,举几个例子:

  • 每一个页面的文件放在哪一个目次?
  • 页面的HTML、进口文件、css、图片等等应当怎样放?
  • 编码范例(由ESLint来保证)。

固然,这只是我的框架,我愿望你们能够看懂了,然后依据自身的需求来调解,变成你们的框架。以至说,我自身在做差别范例的项目时,团体架构也都邑有不少的变化。

为何要共用基本设施/框架/架构?

缘起

数月前,我找同事要了一个他自身写的区域挑选器,拉回来一看各处都是ESLint的报错(他担任的项目没有效ESLint,比较随便),我此人有强迫症的怎样看得过眼,卷起袖子就最先改,改好也就一般运用了。过了一段时间,来了新需求,同事在他那改好了区域挑选器又发了一份给我,我一看头都大了,又是满地报错,这不是又要我再改一遍吗?当时我就懵了,只好按着他的思绪,对我的版本做了修正。今后,也确立了我们公司会有两份表面功用都一致,然则完成却不一样的区域挑选器。

很坑爹是吧?

多项目同享架构更改

上面说的是组件级的,下面我们来讲架构级别的。

我在公司重要担任的项目有两个,在我的不懈努力下,已做到跟我的脚手架项目Array-Huang/webpack-seed大体上同构了。但保持同构显然是要付出代价的,我在脚手架项目实验过的革新,小至改个目次途径,大至引入个plugin啊loader啊什么的,都要分别在公司的两个项目里各做一遍,超烦哒(厌弃脸

试想只是两个项目就已如许了,假如是三个、四个,以至六个、七个呢?堪忧啊堪忧啊!

疾速建立新项目

不晓得你们有无如许子的履历:接到新项目时,心血来潮“这不就是我的XX项目吗?”,然后赶忙搬出XX项目标源码,然后删掉营业逻辑,保存可复用的基本设施。

或许你会说,这不已比从零最先要好多了吗?总体上来讲,是吧,但还不够好:

  • 你须要花时间重温全部项目标架构,搞清楚哪些要删、哪些要留。
  • 毕竟是快刀斩乱麻,清理好的架构比不上本来的思绪那末清楚。
  • 清理完代码想着跑跑看,效果一大堆报错,一个一个来调烦的要命,而且还很多是删错了什么了不起的东西,还要去本来额项目里搬回来。

以上这些题目,你每建立一个新项目都要阅历一遍,我问你怕了没有。

脚手架不是能够协助疾速建立新项目吗?

是的没错,脚手架自身就算是一整套基本设施了,但依旧有以下题目:

  • 保护一套脚手架你晓得有多贫苦吗?公司项目一忙起来,加班都做不完,哪顾得上脚手架啊。末了新建项目标时刻发明脚手架已落伍N多了,你究竟是用呢照样不必呢?
  • 甭跟我提Github上开源的脚手架,像我这么有特性的人,会直接用那些妖艳贱货吗?
  • 差别范例的项目手艺选型不一样,比方说:需不须要兼容低版本IE;是web版的照样Hybrid App的;是前台照样背景。每一套手艺选型就是一套脚手架,岂非你要保护这么多套脚手架吗?

上述题目,经由历程共用基本设施,都能处理

  • 既然共用了基本设施,要怎样改一定都是一切项目一同同享的了,不论是组件层面的照样架构自身。
  • 假定你每一个差别范例的项目都已预备好了与别的项目共用基本设施,那末,你基本不须要花费过剩的保护本钱,建立新项目标时刻看准了跟之前哪一个项目是属于统一范例的,凑一脚就好了呗,轻松。

怎样完成多项目共用一套基本设施呢?

示例项目

在之前的文章里,我运用的一向都是Array-Huang/webpack-seed这个脚手架项目作为示例,而为了实践多项目共用基本设施,我对该项目标架构做了较大幅度的调解,晋级为2.0.0版本。为免人人看前面的文章时发明示例项目货不对板,觉得疑心,我新开了一个repo来寄存调解后的脚手架:Array-Huang/webpack-seed-v2(https://github.com/Array-Huang/webpack-seed-v2),而且,我在两个项目标README里我都注清楚明了响应的内容,人人可不要殽杂了哈。

下面就以从Array-Huang/webpack-seed到Array-Huang/webpack-seed-v2的革新历程来引见怎样完成多项目共用基本设施。

革新思绪

革新思绪实在很简朴,就是把料想中多个项目都能用得上的部份从现有项目里抽离出来

怎样抽离

抽离的说法是针对原项目标,假如纯真从文件体系的角度来讲,只不过是挪动了某些文件和目次。

挪动到那里了呢?自然是挪动到与项目目次同级的处所,如许就轻易多个项目援用这个中心了。

假如你跟我一样,在原项目中定义了大批途径和alias的话,挪动这些文件/目次就只是个转变量的活了:

选自webpack-seed/webpack-config/base/dir-vars.config.js

var path = require('path');
var moduleExports = {};
// 源文件目次
moduleExports.staticRootDir = path.resolve(__dirname, '../../'); // 项目根目次
moduleExports.srcRootDir = path.resolve(moduleExports.staticRootDir, './src'); // 项目营业代码根目次
moduleExports.vendorDir = path.resolve(moduleExports.staticRootDir, './vendor'); // 寄存一切不能用npm治理的第三方库
moduleExports.dllDir = path.resolve(moduleExports.srcRootDir, './dll'); // 寄存由各种不常转变的js/css打包而来的dll
moduleExports.pagesDir = path.resolve(moduleExports.srcRootDir, './pages'); // 寄存各个页面独占的部份,如进口文件、只要该页面运用到的css、模板文件等
moduleExports.publicDir = path.resolve(moduleExports.srcRootDir, './public-resource'); // 寄存各个页面运用到的大众资本
moduleExports.logicDir = path.resolve(moduleExports.publicDir, './logic'); // 寄存公用的营业逻辑
moduleExports.libsDir = path.resolve(moduleExports.publicDir, './libs'); // 与营业逻辑无关的库都能够放到这里
moduleExports.cOnfigDir= path.resolve(moduleExports.publicDir, './config'); // 寄存各种设置文件
moduleExports.compOnentsDir= path.resolve(moduleExports.publicDir, './components'); // 寄存组件,能够是纯HTML,也能够包含js/css/image等,看自身须要
moduleExports.layoutDir = path.resolve(moduleExports.publicDir, './layout'); // 寄存UI规划,构造各个组件拼起来,因应须要能够有差别的规划套路
// 天生文件目次
moduleExports.buildDir = path.resolve(moduleExports.staticRootDir, './build'); // 寄存编译后天生的一切代码、资本(图片、字体等,虽然只是简朴的从源目次迁徙过来)
module.exports = moduleExports;

选自webpack-seed/webpack-config/resolve.config.js

var path = require('path');
var dirVars = require('./base/dir-vars.config.js');
module.exports = {
// 模块别号的设置,为了运用轻易,一般来讲一切模块都是要设置一下别号的
alias: {
/* 各种目次 */
iconfontDir: path.resolve(dirVars.publicDir, 'iconfont/'),
configDir: dirVars.configDir,
/* vendor */
/* bootstrap 相干 */
metisMenu: path.resolve(dirVars.vendorDir, 'metisMenu/'),
/* libs */
withoutJqueryModule: path.resolve(dirVars.libsDir, 'without-jquery.module'),
routerModule: path.resolve(dirVars.libsDir, 'router.module'),
libs: path.resolve(dirVars.libsDir, 'libs.module'),
/* less */
lessDir: path.resolve(dirVars.publicDir, 'less'),
/* components */
/* layout */
layout: path.resolve(dirVars.layoutDir, 'layout/html'),
'layout-without-nav': path.resolve(dirVars.layoutDir, 'layout-without-nav/html'),
/* logic */
cm: path.resolve(dirVars.logicDir, 'common.module'),
cp: path.resolve(dirVars.logicDir, 'common.page'),
/* config */
configModule: path.resolve(dirVars.configDir, 'common.config'),
bootstrapConfig: path.resolve(dirVars.configDir, 'bootstrap.config'),
},
// 当require的模块找不到时,尝试增加这些后缀后举行寻觅
extentions: ['', 'js'],
};

抽离对象

抽离的要领很简朴,那末症结就看究竟是哪些部份能够抽离、须要抽离了,这一点看我抽离后的效果就比较清楚了:

先来看根目次:

├─ core # 抽离出来的基本设施,或称“中心”
├─ example-admin-1 # 示例项目1,被抽离后剩下的
├─ example-admin-2 # 示例项目2,嗯,简朴起见,直接复制了example-admin-1,不过照样要做一点调解的,比方说设置
├─ npm-scripts # 没想到npm-scripts也能公用吧?
├─ vendor # 没法在npm上找到的第三方库
├─ .eslintrc # ESLint的设置文件
├─ package.json # 一切的npm库依靠发起都写到这里,不发起写到详细项目标package.json里

再来看看core目次

├─ _webpack.dev.config.js # 整理好公用的开辟环境webpack设置,以备继续
├─ _webpack.product.config.js # 整理好公用的临盆环境webpack设置,以备继续
├─ webpack-dll.config.js # 用来编译Dll文件用的webpack设置文件
├─ manifest.json # Dll文件的资本目次
├─ package.json # 没有什么本质内容,我这里就放了个编译Dll用的npm script
├─components # 各种UI组件
│ ├─footer
│ ├─header
│ ├─side-menu
│ └─top-nav
├─config # 大众设置,有些是提供给详细项目标设置来继续的,有些自身就有效(比方说“中心”部份自身须要的设置)
├─dll # 之前的文章里就说过,我发起把各种第三方库(包含npm库也包含非npm库)都打包成Dll来加快webpack编译历程,这部份显著就属于基本设施了
├─iconfont # 字体图标能不能公用,这点我也是比较犹疑的,看项目实际须要吧,不折腾的话照样引荐公用
├─layout # 规划,既然是同范例项目,规划一定是基本一样的
│ ├─layout
│ └─layout-without-nav
├─less # 款式基本,在我这项目里就是针对bootstrap的SB-Admin主题做了修正
│ ├─base-dir
│ └─components-dir
├─libs # 自身团队研发的一些大众的要领/库,又或是针对第三方库的适配器(比方说对alert库封装一层,背面要替换库的时刻就轻易了)
├─npm-scripts # 与根目次下的npm-scripts目次不一样,这里的不是用来公用的,而是“中心”运用到的script,比方我在这里就放了编译dll的npm script
└─webpack-config # 公用的webpack设置,尤其是关系到“中心”部份的设置,比方说各第三方库的alias。这里的设置是用来给详细项目来继续的,老实说我如今继续的要领也比较复杂,转头看看有无更简朴的要领。
├─base
├─inherit
└─vendor

末了总结一下,是哪些资本被抽离出来了:

  • webpack设置中属于架构的部份,比方说各种loader、plugin、“中心”部份的alias。
  • “中心”部份所需的设置,比方我这项目里为了定制bootstrap而建的设置。
  • 各种与UI相干的资本,比方UI框架/款式、UI组件、字体图标。
  • 第三方库,以Dll文件的情势存在。
  • 自研库/适配器。

结构图

上传上来今后发明图被压小了,请到这里看原图

《webpack多页运用架构系列(十四):No复制粘贴!多项目共用基础设施》

附系列文章目次(同步更新)

  • webpack多页运用架构系列(一):一步一步处理架构痛点:https://segmentfault.com/a/1190000006843916
  • webpack多页运用架构系列(二):webpack设置经常使用部份有哪些?:https://segmentfault.com/a/1190000006863968
  • webpack多页运用架构系列(三):怎样打包大众代码才防止反复?:https://segmentfault.com/a/1190000006871991
  • webpack多页运用架构系列(四):老式jQuery插件还不能丢,怎样兼容?:https://segmentfault.com/a/1190000006887523
  • webpack多页运用架构系列(五):据说webpack连less/css也能打包?:https://segmentfault.com/a/1190000006897458
  • webpack多页运用架构系列(六):据说webpack连图片和字体也能打包?:https://segmentfault.com/a/1190000006907701
  • webpack多页运用架构系列(七):开辟环境、临盆环境傻傻分不清楚?:https://segmentfault.com/a/1190000006952432
  • webpack多页运用架构系列(八):锻练我要写ES6!webpack怎样整合Babel?:https://segmentfault.com/a/1190000006992218
  • webpack多页运用架构系列(九):总有刁民想害朕!ESLint为你阻击渣滓代码:https://segmentfault.com/a/1190000007030775
  • webpack多页运用架构系列(十):怎样打造一个自定义的bootstrap:https://segmentfault.com/a/1190000007043716
  • webpack多页运用架构系列(十一):预打包Dll,完成webpack音速编译:https://segmentfault.com/a/1190000007104372
  • webpack多页运用架构系列(十二):应用webpack天生HTML一般网页&页面模板:https://segmentfault.com/a/1190000007126268
  • webpack多页运用架构系列(十三):构建一个简朴的模板规划体系:https://segmentfault.com/a/1190000007159115
  • webpack多页运用架构系列(十四):No复制粘贴!多项目共用基本设施:https://segmentfault.com/a/1190000007301770
  • webpack多页运用架构系列(十五):论前端如安在后端衬着开辟形式下夹缝生计
  • webpack多页运用架构系列(十六):善用浏览器缓存,该去则去,该留则留

本文首发于
Array_Huang的手艺博客——
有效至上,非经作者赞同,请勿转载。

原文地点:
https://segmentfault.com/a/1190000007301770

假如您对本系列文章感兴趣,迎接关注定阅这里:
https://segmentfault.com/blog/array_huang


推荐阅读
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 从零基础到精通的前台学习路线
    随着互联网的发展,前台开发工程师成为市场上非常抢手的人才。本文介绍了从零基础到精通前台开发的学习路线,包括学习HTML、CSS、JavaScript等基础知识和常用工具的使用。通过循序渐进的学习,可以掌握前台开发的基本技能,并有能力找到一份月薪8000以上的工作。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了如何使用vue-awesome-swiper组件,包括在main.js中引入和使用swiper和swiperSlide组件,以及设置options和ref属性。同时还介绍了如何在模板中使用swiper和swiperSlide组件,并展示了如何通过循环渲染swipes数组中的数据,并使用picUrl属性显示图片。最后还介绍了如何添加分页器。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
author-avatar
mobiledu2502853397
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有