热门标签 | 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


推荐阅读
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文内容为asp.net微信公众平台开发的目录汇总,包括数据库设计、多层架构框架搭建和入口实现、微信消息封装及反射赋值、关注事件、用户记录、回复文本消息、图文消息、服务搭建(接入)、自定义菜单等。同时提供了示例代码和相关的后台管理功能。内容涵盖了多个方面,适合综合运用。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
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社区 版权所有