webpack 使用外部的库_浅谈webpack工程化

04613bad49b7762eee32b943e6e0b54d.png

商业的本质是面向利益的,软件和技术又是为商业服务的,所以没有永恒的技术只有永恒的利益。

声明:由于代码部分属于公司财产,所以此文章着重介绍理念与技术,不会展示代码,请取你所需也欢迎一起讨论

工程组件介绍

编译框架:webpack => 用于整个项目的打包发布

loader:bable(ts、react、es)=>用于识别并转化ts、react和es语法

react:用于主流业务页面的开发

fetch+promise:用于接口的访问与资源的获取

其他loader:url-loader(编译图片),css-loader(编译css样式),less(编译less文件)

系统结构介绍

工程目录

----src
  |----commonChuk
     |----mainLogic.ts
     |----sourceLogic.ts
     |----sourceBean.ts
  |----pageChunk
     |----page1
        |----page1.jsx
        |----page1.less
  |----elementChunk
     |----element1
        |----element1.jsx
        |----element1.less
  |----3rdlib
  |----source
     |----I18n
     |----image
     |----style
----static

框架理念

1、核心理念:组件化开发,整个项目是一个大应用,这个大应用被拆分为四大部分:

    • commonChunk:用于提供公共方法与公共机制,使用ts开发
    • pageChunk:页面部分,整个系统被认为是由一个一个页面组成的,每个pageChunk会被单独打包成js文件
    • elementChunk:组件部分,页面是由组件组成的,组件会被编译到pageChunk内部不会单独打包
    • 三方件:会直接copy到编译后目录的对应位置
    • source部分:图片资源、国际化资源、样式资源

2、答疑:

你可能会问的一些问题,

为什么只有commonChunk用ts编写其他的用jsx编写?

虽然ts是js的超集,他的好处是有类型检查,而且安全性与稳定性相对较好。但是他的缺点也是存在的,比如学习成本、使用成本、定位成本等,所以框架部分我选择了ts,这部分代码要求精度高、效率好、结构性好,而且一般是有经验的代码高手来编写。

为什么pageChunk要单独打包?如何做到单独打包的?

webpack有个配置叫splitChunks,大家可以去官网学习一下,另外webpack还有一个打包可视化的plugin,叫 webpack-bundle-analyzer 也许会帮助你更好的查看打包效果。为什么pageChunk要单独打包呢?因为我们是一款pc端应用,而且是那种非常庞大的管理系统,我们希望用户使用的时候能尽快获得他想要的页面,放在一起打包的好处毋庸置疑:节省用户流浪,代码资源不需要重复打包,第一次慢一点后面基本不需要耗费太大流量。但是在庞大的系统中,加载一个文件会导致第一次加载非常的慢(跨国部署场景与海外地区劣势明显),所以我选择了分包加载,每个页面为一个粒度,他的好处是:每次加载都是均衡的,虽然组件会重复编译,但是页面的粒度,按需渲染,每次渲染带来的体验差距是一致的(每个页面加载组件的数目不会有太大差异)

为什么三方件不直接用webpack编译?

一些三方件会写不兼容的代码,比如三方件内部的文件间引用,很有可能基于相对目录,而且我们涉及微服务集成,你永远无法控制你集成的微服务会使用什么代码,最后,按需加载,共同使用。一些三方件你可能不会刚上来就用,但是可能有多个模块一起使用,所以一些三方件拆分开来会一定程度优化加载速度并且增加资源利用率。

使用到的技术

1、如何获取接口的:

使用的是fetch方法,为什么不用axios呢?

最重要原因,他是第三方库,我是不喜欢用第三方库的,不是因为我喜欢造轮子,而是因为其一,第三方库定位成本比原生代码高;其二,第三方库的代码掌握在别人手里,对于一些定制化的需求很难处理;其三,fetch足以满足我们的日常使用,而且版本已有规格不支持ie等老旧浏览器,不需要考虑兼容性问题(即使需要考虑也可以用webpack的兼容性编译解决)

剩下的原因嘛,也是第三方库带来的,比如会加大代码量啊、新的学习成本啊,而且由于需要解决一些安全问题(csrf攻击、会话超时机制等)我们会对请求头进行封装,所以即使使用第三方库也需要封装公共方法,倒不如直接基于原生方法封装。

2、异步处理:

sourceManager是一个单例类(框架部分的代码基本都是单例),用于帮助其他页面获取接口、获取国际化等资源,继承于sourceBean(用于js获取颜色库、样式库、数据库等),但是使用的时候遇到一个问题,sourceManager提供的方法需要从一个接口获取数据,当时想到的方案有几种:

1、在外部初始化sourceManager的时候使用await等待接口返回之后再初始化

2、在sourceManager单例实例化的时候使用await获取数据并传入构造函数

结果以上两个方法我都没有用,原因是其一,我希望功能是聚合的,sourceManager用到的东西就应该在他的类内部,其二,我不希望把他弄成同步的而阻塞后面的页面渲染。

所以用了一个讨巧的方式,首先给这个类声明了两个内部变量,一个是锁,另一个是等待队列。当外部调用了sourceManager内部必须等待接口返回才能进行的操作时,会判断锁有没有打开,如果没打开,将自己的函数句柄和参数放到等待队列里。然后在sourceManager接口获取到返回结果时,开锁并清空等待队列,这里介绍一种结构的写法:

let a = (p1,p2,p3)=>{
    console.log(p1 + "," + p2 + "," + p3);
}
let pDatas = [3, 6, "哈哈"];
b = {
    handler: a,
    data: pDatas,
}
b.handler(...b.data);

结构写法有很多妙用,比如交换两个变量的值,感兴趣的同学可以去搜一下

3、less的使用

其实现在chrome的css是支持变量的写法的,而且他是动态运行的,动态运行的好处是:假如你需要换肤功能,只需要重新请求声明变量的css即可(less有叫做modifyVar的属性,不过没用过,暂时不做深究),而我最终选择了less的主要原因如下:首先less是css的超集,而且css结构相对简单,定位起来没那么麻烦。然后less的结构性写法真的很舒服

#a{
    #b{}
    .c{}
}

它可以很直观的反应你的dom层级与css属性继承关系

4、javaScript中类的继承

为啥使用类的继承呢?在sourceManager这个类里面,我主要封装了一些资源获取的逻辑,比如国际化和接口等,但是js会使用到颜色库,那这个颜色库的获取与存放也需要写在sourceManager里的,严格来说这个颜色库就是返回一个map表然后根据id去查,并没有什么逻辑,所以我想直接把这些库写在一个文件里而不是通过json去获取,在不加长调用链且不想在sourceManager的基础上扩展的情况下,我用sourceBean提供基础的get/set方法并且让manager来继承这个类从而实现了一些静态数据的存取

5、三方件引用

之前我说了,我是用webpack的一个plugin将3rdlib文件夹直接复制到了static内部,在调用上,本质是创建一个script标签,src是文件路径,onload后面调用回调接口。

结语

由于以上所有技术都是一个星期内研究出来的,技术栈切换比较快(从原始的angular1.0+jq+seajs+ebt切换到现在的技术栈),所以个人在技术研究和使用上可能有一些不足,欢迎各位同僚们互相切磋讨论~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值