张云龙
张云龙
fis本身设计的时候,是希望工程目录是纯粹的工程资源,没有“不需要发布却混在项目中的资源”。所以一般fis的正确用法是独立创建一个工程,然后用fis release -d xxx把项目构建之后再发布到其他目录下进行部署。如果做不到分离前端工程,一定要和其他资源混在一起的话,可以配置: ``` javascript fis.config.set('project.include', 'views/**'); ``` 让fis只读取views目录下的文件。 另外,roadmap.path配置的配规则并不是告诉fis去抓取这个文件,而是告诉fis所有工程文件中,服从这个reg匹配的文件对象应该标记哪些属性。所以配置了roadmap.path并不能影响fis对项目文件的读取,因为这个配置并不是定义了fis读取文件的过程。而是定义了读取到的所有文件对象要做什么分类。
@jackiealex 首先,fis的用法上确实不同于其他工具。 ## 关于问题1 fis的设计概念是这样的: > fis是一个前端构建工具,我们强烈建议用户只针对前端代码进行构建。 基于这个原则,假设你有一个nodejs的项目,目录大概是: ``` bash site ├─ public │ ├─ css │ ├─ img │ ├─ js │ └─ index.html ├─ views ├─ package.json ├─...
@jackiealex ## 关于问题2 如果做了上面解答问题1的处理,那么问题2自然也就没有了。但我还是要解答问题2中你对fis的一些理解和fis设计初始上的不一致的问题。 这里涉及到fis的第二个设计原则: > 解耦工程和部署,用最自然的方式写码。 举个例子,你说设置了静态资源发布规则,把static目录下的代码,都发布到了st目录下。然后试图在代码中这样引用资源: ``` html ``` 并发现fis不予处理路径。 这是因为,你的资源路径,写成了部署路径,而不是工程路径。 fis一直希望用户无论何时写的都是工程路径,这个例子中,很明显你的路径应该是: ``` html ``` static目录才是你工程里存在的。fis识别到一个路径的时候,会用这个路径直接找到具体的项目文件,然后通过匹配roadmap.path来判断应该把原来的位置替换成什么url,这是因为fis参考了其他语言的设计思路,在源码中提供`工程引用`,构建后替换为`部署引用`。 这样也同时做到了解耦开发和部署的关系。将来你们的部署怎么改变,只要修改fis的配置就好了,代码不用动,fis会给你做好所有的路径转换。也不用在开发的时候还要在脑海中想象一个文件部署后地址是什么,多费劲啊。 另外,源码中的路径引用也可以使用相对路径,假设写上面那句link标签的html也在static目录下,那么代码就可以写成: ``` html ``` 而最终构建的结果就如你所愿的变成了: ``` html ```
@dcy views里的html中资源引用是会加上md5戳啊
@xxapp BOM的危害很多,所以处理的时候自然就去掉了
@xxapp 可以说一下为什么要保留BOM么?我们这么辛苦才把它去掉的。。。
@ioriandy4  比如你有两个页面A和B,因为两个页面有不同的功能模块,我们可以继续假设: - A页面使用了资源:a.js, b.js, c.js, d.js - B页面使用了资源:a.js, b.js, e.js, f.js ## 问题一:将每个页面的资源都合并成一个请求就是性能最好的么?  当用户访问A页面时,需从服务器下载 a-b-c-d.js ,接下来又去访问B页面,由于B页面引用的资源的url和A页面不同,所以浏览器又从服务端下载了资源 a-b-e-f.js ,很明显,这一次资源加载中的a-b内容是冗余的,我们本来在访问A页面时就下载过同样内容了。  所以这种打包才更合理,多页面共享的资源合并在一起,页面独有的资源合并在一起,每个页面加2个资源,虽然请求多了,但整站的性能是更好的(不信你测试就知道了) ## 问题二:页面有冗余就性能差么? 还是这两个页面,假设绝大多数用户是通过直接访问A页面来到网站,然后走到B页面的,那么我们有充分理由要让A页面更快速的展现,因为它代表着用户对网站体验的第一印象,这很重要;同时,为了加快B页面的访问速度,需要让AB页面共享公共资源的浏览器缓存,一种可能的做法就是:  是的,对于B页面来说在a-b-c-d.js请求中加载了不需要的资源c-d,这种方案虽然有点违背直觉,但从统计的结果来看,它是合理的,因为我们前提假设了网站绝大多数入口请求访问的是A页面,而B页面的绝大多数访问请求会经由A页面到达。这种合并组合方案即优化了A页面的性能,也提升了B页面的性能。(不信你测一下就知道了) 你预期的 >...
@superddr 合并css只是一个典型案例,类似的还有资源内嵌,模板引用等等会改变相对路径关系的文件引用问题。所以将工程路径转换为绝对路径是保证代码独立可使用的基本前提,这也是fis最核心的设计理念。所以关闭路径转换,fis会退化为一般的压缩工具,这种情况下可能还不如grunt、gulp好用。 如果确实某些公司的部署有各种限制,使得在构建代码之前不能知道最终部署路径的话,有两种解决办法: 1. 在fis的roadmap.path配置中设置文件的useStandard属性为false,关闭fis对相对路径的绝对化处理,但这个配置也会同时关闭资源内嵌和依赖分析等功能,这些都是和绝对路径有关的。 2. 夺回部署方面的话语权,充分利用fis的功能,做真正的前端工程化实践。
@superddr 这么做,根本目的是为了更好的模块化开发。  一直以来,前端工程希望实现模块化开发,然而真正意义的模块化开发,可不是仅仅js实现了就可以的,模块应该具有独立性,因此,fis提倡的模块化,是能将一个模块所依赖的所有js、css、图片、模板等资源维护在一个目录下的开发模式。 如果你不认可这种模式,那么fis的很多功能对你来说可能意义不大,但这种开发方式给人的印象非常深刻,这也是fis一直致力倡导的。 接下来,为了保证模块的独立性、可移植性和可组装性,就要面临一个问题:相对路径 or 绝对路径。 如果采用相对路径,那么将大大降低模块的可组装性,一个模块中的资源都是相对路径,别的模块引用它的js或者css的时候,如果路径不处理,就可能引起相对路径定位错误的问题。包括模板合并、js中访问资源、css中访问资源等情况都会受到影响。 然后你觉得都写绝对路径就ok了是么?但这又会使得这个模块失去了可移植性,你在代码里把路径都写死了,别的项目还用不了?另外,写绝对路径还要考虑浏览器缓存更新问题,这个也是绝对路径书写时带上的么?它显然不适合人工维护。 所以,fis综合了所有前端工程问题中关于路径处理的诉求,决定: 1. 源码中使用相对路径 2. 构建后统一替换成绝对路径 3. 在替换绝对路径的过程中添加缓存更新戳 以最自然的方式编码(源码写相对路径),以最透明的方式优化(工具替换成绝对路径),保证模块的独立性、可移植性、可组合性。 这是fis的设计思想,如果你觉得现阶段用不到也没关系,因为随着工程的复杂度增加,人员和规模的扩张,上面图片展示的模块化开发方式会让你为之着迷,一旦你希望这么维护你的系统,一旦你希望以搭积木的方式开发应用,你就会遇到相对路径问题对源码使用的限制,你也就会理解fis为什么要这么做了。
@superddr 相对路径是在运行时发生的,你不知道一个模块被运行时用在了什么地方,所以相对路径是不安全的。 接下来,说一下tpl的问题。 tpl在我们这里上下文中有完全不同的含义。前面 @hefangshi 说的tpl,是服务端运行的模板,这种前端开发模型你可以理解为“前端工程师写好了html,后端工程师把它动态化成tpl”中的那个tpl。fis在研究这种开发模型的时候,发现可以在模板中实现一种类似requirejs的服务端静态资源管理框架,来管理前端资源,这个说起来比较复杂,以后可以展开论述,这里的问题并不关心它。 所以,你说“fis可以tpl组装也一起搞了”,但前文说的tpl是后端动态语言模板,fis是静态编译工具,所以不能直接处理动态模板,比如同一个页面(tpl),登陆用户展现一种样子,非登录用户展现另一种,只有运行起来才知道,线下构建是处理不了的。 而我也理解你所说的tpl,其实是前端模板,或者说是碎片化的html,这部分fis也有支持。如果是纯前端项目,fis支持把前端模板代码嵌入到js中使用,这样用户最终就使用js就好了,模板连请求都省了:  模板中的img、audio、video等资源标签所引用的url地址fis都能给你转成绝对路径,这样js把这段html插入到任何页面都是正确运行的了