本文首发于
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),实际上论述的就是一套完全的多页运用框架(或称架构)。这套框架划定了全部运用的各个方面,举几个例子:
固然,这只是我的框架,我愿望你们能够看懂了,然后依据自身的需求来调解,变成你们的框架。以至说,我自身在做差别范例的项目时,团体架构也都邑有不少的变化。
数月前,我找同事要了一个他自身写的区域挑选器,拉回来一看各处都是ESLint的报错(他担任的项目没有效ESLint,比较随便),我此人有强迫症的怎样看得过眼,卷起袖子就最先改,改好也就一般运用了。过了一段时间,来了新需求,同事在他那改好了区域挑选器又发了一份给我,我一看头都大了,又是满地报错,这不是又要我再改一遍吗?当时我就懵了,只好按着他的思绪,对我的版本做了修正。今后,也确立了我们公司会有两份表面功用都一致,然则完成却不一样的区域挑选器。
很坑爹是吧?
上面说的是组件级的,下面我们来讲架构级别的。
我在公司重要担任的项目有两个,在我的不懈努力下,已做到跟我的脚手架项目Array-Huang/webpack-seed大体上同构了。但保持同构显然是要付出代价的,我在脚手架项目实验过的革新,小至改个目次途径,大至引入个plugin啊loader啊什么的,都要分别在公司的两个项目里各做一遍,超烦哒(厌弃脸
试想只是两个项目就已如许了,假如是三个、四个,以至六个、七个呢?堪忧啊堪忧啊!
不晓得你们有无如许子的履历:接到新项目时,心血来潮“这不就是我的XX项目吗?”,然后赶忙搬出XX项目标源码,然后删掉营业逻辑,保存可复用的基本设施。
或许你会说,这不已比从零最先要好多了吗?总体上来讲,是吧,但还不够好:
以上这些题目,你每建立一个新项目都要阅历一遍,我问你怕了没有。
是的没错,脚手架自身就算是一整套基本设施了,但依旧有以下题目:
在之前的文章里,我运用的一向都是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
末了总结一下,是哪些资本被抽离出来了:
上传上来今后发明图被压小了,请到这里看原图
https://segmentfault.com/a/1190000006843916
https://segmentfault.com/a/1190000006863968
https://segmentfault.com/a/1190000006871991
https://segmentfault.com/a/1190000006887523
https://segmentfault.com/a/1190000006897458
https://segmentfault.com/a/1190000006907701
https://segmentfault.com/a/1190000006952432
https://segmentfault.com/a/1190000006992218
https://segmentfault.com/a/1190000007030775
https://segmentfault.com/a/1190000007043716
https://segmentfault.com/a/1190000007104372
https://segmentfault.com/a/1190000007126268
https://segmentfault.com/a/1190000007159115
https://segmentfault.com/a/1190000007301770
本文首发于
Array_Huang的手艺博客——
有效至上
,非经作者赞同,请勿转载。原文地点:
https://segmentfault.com/a/1190000007301770
假如您对本系列文章感兴趣,迎接关注定阅这里:
https://segmentfault.com/blog/array_huang