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


推荐阅读
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • 秒建一个后台管理系统?用这5个开源免费的Java项目就够了
    秒建一个后台管理系统?用这5个开源免费的Java项目就够了 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 在JavaWeb开发中,文件上传是一个常见的需求。无论是通过表单还是其他方式上传文件,都必须使用POST请求。前端部分通常采用HTML表单来实现文件选择和提交功能。后端则利用Apache Commons FileUpload库来处理上传的文件,该库提供了强大的文件解析和存储能力,能够高效地处理各种文件类型。此外,为了提高系统的安全性和稳定性,还需要对上传文件的大小、格式等进行严格的校验和限制。 ... [详细]
  • 浏览器作为我们日常不可或缺的软件工具,其背后的运作机制却鲜为人知。本文将深入探讨浏览器内核及其版本的演变历程,帮助读者更好地理解这一关键技术组件,揭示其内部运作的奥秘。 ... [详细]
  • 利用 JavaScript 和 Node.js 验证时间的有效性
    本文探讨了如何使用 JavaScript 和 Node.js 验证时间的有效性。通过编写一个 `isTime` 函数,我们可以确保输入的时间格式正确且有效。该函数利用正则表达式匹配时间字符串,检查其是否符合常见的日期时间格式,如 `YYYY-MM-DD` 或 `HH:MM:SS`。此外,我们还介绍了如何处理不同时间格式的转换和验证,以提高代码的健壮性和可靠性。 ... [详细]
  • 在 Android 开发中,`android:exported` 属性用于控制组件(如 Activity、Service、BroadcastReceiver 和 ContentProvider)是否可以被其他应用组件访问或与其交互。若将此属性设为 `true`,则允许外部应用调用或与之交互;反之,若设为 `false`,则仅限于同一应用内的组件进行访问。这一属性对于确保应用的安全性和隐私保护至关重要。 ... [详细]
  • 线程能否先以安全方式获取对象,再进行非安全发布? ... [详细]
  • 为开发者提供了一系列实用的参考网站和资源链接,包括HTML速查手册( 和 ),帮助开发者快速查找和学习相关技术知识。此外,还涵盖了其他重要的开发工具和文档,为编程工作提供全面支持。 ... [详细]
  • 本文探讨了如何利用 jQuery 的 JSONP 技术实现跨域调用外部 Web 服务。通过详细解析 JSONP 的工作原理及其在 jQuery 中的应用,本文提供了实用的代码示例和最佳实践,帮助开发者解决跨域请求中的常见问题。 ... [详细]
  • 在JavaWeb项目架构中,NFS(网络文件系统)的实现与优化是关键环节。NFS允许不同主机系统通过局域网共享文件和目录,提高资源利用率和数据访问效率。本文详细探讨了NFS在JavaWeb项目中的应用,包括配置、性能优化及常见问题的解决方案,旨在为开发者提供实用的技术参考。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 本文深入解析了 jQuery 中用于扩展功能的三个关键方法:`$.extend()`、`$.fn` 和 `$.fn.extend()`。其中,`$.extend()` 用于扩展 jQuery 对象本身,而 `$.fn.extend()` 则用于扩展 jQuery 的原型对象,使自定义方法能够作为 jQuery 实例的方法使用。通过这些方法,开发者可以轻松地创建和集成自定义插件,增强 jQuery 的功能。文章详细介绍了每个方法的用法、参数及实际应用场景,帮助读者更好地理解和运用这些强大的工具。 ... [详细]
  • 本文探讨了使用JavaScript在不同页面间传递参数的技术方法。具体而言,从a.html页面跳转至b.html时,如何携带参数并使b.html替代当前页面显示,而非新开窗口。文中详细介绍了实现这一功能的代码及注释,帮助开发者更好地理解和应用该技术。 ... [详细]
  • 在使用 jQuery 的 `html()` 方法时,我发现了一个奇怪的现象:该方法无法完整地插入指定的字符串内容。具体来说,当尝试插入较长或包含特殊字符的字符串时,部分内容可能会被截断或丢失。这一问题可能与 jQuery 对字符串的处理方式有关,建议在实际应用中进行充分测试以确保数据完整性。 ... [详细]
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社区 版权所有