以前花了篇文章讲述怎么从零开始搭建起一个基础的webpack4+React的脚手架,而后由于有些小项目不须要用到这么复杂的打包器去构建,这里分享一款项目中使用的简单配置的脚手架.javascript
webpack4从零开始构建(一)
webpack4+React16项目构建(二)
webpack4功能配置划分细化(三)
webpack4引入Ant Design和Typescript(四)
webpack4代码去重,简化信息和构建优化(五)
webpack4配置Vue版脚手架(六)php
FIS3 是面向前端的工程构建工具。解决前端工程中性能优化、资源加载(异步、同步、按需、预加载、依赖管理、合并、内嵌)、模块化开发、自动化工具、开发规范、代码部署等问题。css
可是好像开发团队都散了,如今已是弃置的样子,好几年没有消息,特别是Nodejs支持版本只到@6,因此若是对这方面有要求的话不建议使用,简单了解下便可.html
由于这里摘抄了fis3构建流程和官网一些经常使用语法,更详细能够直接看官网,知道的就直接往下拉到配置部分前端
由于Fis3的Node版本要求 0.8.x,0.10.x, 0.12.x,4.x,6.x
,不在此列表中的版本不予支持node
咱们能够安装一个版本管理器,根据需求切换.
nvm-windowsreact
安装版本jquery
nvm install <version> [arch]
移除版本webpack
nvm uninstall <version>
查看已安装版本
nvm ls
切换版本
nvm use [version] [arch]
咱们选择系列最新的@6.14.4
版本安装
一些具体的包管理器等能够参考我以前的章节,这里不复述了.
npm install -g fis3
安装完成后执行 fis3 -v 判断是否安装成功
fis3 -v
命令行提供了如下功能
[INFO] Currently running fis3 (C:\Users\msi\AppData\Roaming\npm\node_modules\.fis3_npminstall\node_modules\.3.4.40@fis3\) Usage: fis3 <command> Commands: init scaffold with specifed template. install install components release [media name] build and deploy your project server <command> [options] launch a server inspect [media name] inspect the result of fis.match Options: -h, --help print this help message -v, --version print product version and exit -r, --root <path> specify project root -f, --file <filename> specify the file path of `fis-conf.js` --no-color disable colored output --verbose enable verbose mode
FIS3 在执行编译的过程当中,会扫描这些编译标记,从而创建一张 静态资源关系表,资源关系表详细记录了项目内的静态资源id、发布后的线上路径、资源类型以及 依赖关系 和 资源打包 等信息。使用 FIS3 做为编译工具的项目,能够将这张表提交给后端或者前端框架去运行时,根据组件使用状况来 按需加载资源或者资源所在的包,从而提高前端页面运行性能。
FIS3 是基于文件对象进行构建的,每一个进入 FIS3 的文件都会实例化成一个 File 对象,整个构建过程都对这个对象进行操做完成构建任务。
整个 FIS3 的构建流程大致归纳分为三个阶段。
1, 扫描项目目录拿到文件并初始化出一个文件对象列表
2, 对文件对象中每个文件进行单文件编译
3, 获取用户设置的 package 插件,进行打包处理(包括合并图片)
lint:代码校验检查,比较特殊,因此须要 release 命令命令行添加 -l 参数
parser:预处理阶段,好比 less、sass、es六、react 前端模板等都在此处预编译处理
preprocessor:标准化前处理插件
standard:标准化插件,处理内置语法
postprocessor:标准化后处理插件
prepackager 打包前处理插件扩展点
packager 打包插件扩展点,经过此插件收集文件依赖信息、合并信息产出静态资源映射表
spriter 图片合并扩展点,如 csssprites
postpackager 打包后处理插件扩展点
文件指纹,惟一标识一个文件。在开启强缓存的状况下,若是文件的 URL 不发生变化,没法刷新浏览器缓存。通常都须要经过一些手段来强刷缓存,一种方式是添加时间戳,每次上线更新文件,给这个资源文件的 URL 添加上时间戳。
而 FIS3 选择的是添加 MD5 戳
,直接修改文件的 URL,而不是在其后添加 query
。
<!--源码: <img title="百度logo" src="images/logo.gif"/> 编译后--> <img title="百度logo" src="/static/pic/logo_74e5229.gif"/>
定位资源能力,能够有效地分离开发路径与部署路径之间的关系,工程师再也不关心资源部署到线上以后去了哪里,变成了什么名字,这些均可以经过配置来指定。而工程师只须要使用相对路径来定位本身的开发资源便可。这样的好处是:资源能够发布到任何静态资源服务器的任何路径上而不用担忧线上运行时找不到它们,并且代码具备很强的可移植性,甚至能够从一个产品线移植到另外一个产品线而不用担忧线上部署不一致的问题。
FIS3 支持对html中的script、link、style、video、audio、embed
等标签的src或href属性进行分析,一旦这些标签的资源定位属性能够命中已存在文件,则把命中文件的url路径替换到属性中,同时可保留原来url中的query查询信息。
相关配置
fis.match('*.{js,css,png,gif}', { useHash: true // 开启 md5 戳 }); // 全部的 js fis.match('**.js', { //发布到/static/js/xxx目录下 release : '/static/js$0' }); // 全部的 css fis.match('**.css', { //发布到/static/css/xxx目录下 release : '/static/css$0' }); // 全部image目录下的.png,.gif文件 fis.match('/images/(*.{png,gif})', { //发布到/static/pic/xxx目录下 release: '/static/pic/$1$2' });
实际结果
<!--源码: <img title="百度logo" src="images/logo.gif"/> 编译后--> <img title="百度logo" src="/static/pic/logo_74e5229.gif"/> <!--源码: <link rel="stylesheet" type="text/css" href="demo.css"> 编译后--> <link rel="stylesheet" type="text/css" href="/static/css/demo_7defa41.css"> <!--源码: <script type="text/javascript" src="demo.js"></script> 编译后--> <script type="text/javascript" src="/static/js/demo_33c5143.js"></script>
js语言中,可使用编译函数 __uri(path)
来定位资源,fis分析js文件或 html中的script标签内内容 时会替换该函数所指向文件的线上url路径。
<!--源码: var img = __uri('images/logo.gif'); 编译后--> var img = '/images/logo_74e5229.gif'; <!--源码: var css = __uri('demo.css'); 编译后--> var css = '/demo_7defa41.css'; <!--源码: var js = __uri('demo.js'); 编译后--> var js = '/demo_33c5143.js';
<!--源码: @import url('demo.css'); 编译后--> @import url('/demo_7defa41.css'); <!--源码: .style { background: url('images/body-bg.png'); } 编译后--> .style { background: url('/images/body-bg_1b8c3e0.png'); } <!--源码: .style { _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/body-bg.png'); } 编译后--> .style { _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/body-bg_1b8c3e0.png'); }
嵌入资源即内容嵌入,能够为工程师提供诸如图片base64
嵌入到css、js里,前端模板编译到js文件中,将js、css、html拆分红几个文件最后合并到一块儿的能力。有了这项能力,能够有效的减小http请求数,提高工程的可维护性。
在html中能够嵌入其余文件内容或者base64编码值,能够在资源定位的基础上,给资源加 ?__inline
参数来标记资源嵌入需求。
html中嵌入图片base64
<img title="百度logo" src="images/logo.gif?__inline"/> -----------------------------输出-------------------------------- <img title="百度logo" src="data:image/gif;base64,R0lGODlhDgGBALMAAGBn6eYxLvvy9PnKyfO...Jzna6853wjKc850nPeoYgAgA7"/>
html中嵌入样式文件
<link rel="stylesheet" type="text/css" href="demo.css?__inline"> -----------------------------输出-------------------------------- <style>img { border: 5px solid #ccc; }</style>
html中嵌入脚本资源
<script type="text/javascript" src="demo.js?__inline"></script> -----------------------------输出-------------------------------- <script type="text/javascript">console.log('inline file');</script>
html中嵌入页面文件
<link rel="import" href="demo.html?__inline"> -----------------------------输出-------------------------------- <h1>demo.html content</h1>
在js中,使用编译函数 __inline()
来提供内容嵌入能力。能够利用这个函数嵌入图片的base64编码、嵌入其余js或者前端模板文件的编译内容, 这些处理对html中script标签里的内容一样有效。
在js中嵌入js文件
__inline('demo.js'); -----------------------------输出-------------------------------- console.log('demo.js content');
在js中嵌入图片base64
var img = __inline('images/logo.gif'); -----------------------------输出-------------------------------- var img = 'data:image/gif;base64,R0lGODlhDgGBALMAAGBn6eYxLvvy9PnKyfO...Jzna6853wjKc850nPeoYgAgA7';
在js中嵌入其余文本文件
var css = __inline('a.css'); -----------------------------输出-------------------------------- var css = "body \n{ color: red;\n}";
与html相似,凡是命中了资源定位能力的编译标记, 除了src="xxx"以外,均可以经过添加 ?__inline
编译标记均可以把文件内容嵌入进来。src="xxx"被用在ie浏览器支持的filter内,该属性不支持base64字符串,所以未作处理。
在css文件中嵌入其余css文件
@import url('demo.css?__inline'); -----------------------------输出-------------------------------- img { border: 5px solid #ccc; };
在css中嵌入图片的base64
.style { background: url(images/logo.gif?__inline); } -----------------------------输出-------------------------------- .style { background: url(data:image/gif;base64,R0lGODlhDgGBALMAAGBn6eYxLvvy9PnKyfO...Jzna6853wjKc850nPeoYgAgA7); }
当咱们开发项目后,须要发布到测试机(联调机),通常能够经过如 SMB、FTP 等上传代码。FIS3 默认支持使用 HTTP 上传代码,首先须要在测试机部署上传接收脚本(或者服务),这个脚本很是简单,如今给出了 php 的实现版本,能够把它放到测试机上某个 Web 服务根目录,而且配置一个 url 能访问到便可。
假定这个 URL 是:http://cq.01.p.p.baidu.com:8888/receiver.php
那么咱们只须要在配置文件配置
fis.match('*', { deploy: fis.plugin('http-push', { receiver: 'http://cq.01.p.p.baidu.com:8888/receiver.php', to: '/home/work/htdocs' // 注意这个是指的是测试机器的路径,而非本地机器 }) })
从上面就知道FIS3 是基于文件对象进行构建的,首先咱们要定义好文件目录
. │───README.md // 说明 │───node_modules // 依赖 │───dist // 打包目录 │───.editorconfig // 格式化代码设置 │───.eslintrc.json // 代码风格设置 │───.gitignore // 提交文件过滤 │───package.json // 说明 │───fis-conf.js // fis3配置文件 │───dev.cmd // 执行开发命令 │───prod.cmd // 执行生产命令 └───assets │ │───style // 公用scss和css │ │───img // 公用图片 │ └───utils // 公用工具代码 │ └───static │ │───plugins // 公用插件 │ │ └───文件夹 // 可能包含插件图片样式等 │ └───libs // 公用库 │ └───page // 页面部分
切记: 配置文件是具体针对项目文件夹路径打包,不能随意改动
. └───dist │───img // 项目打包图片 │───index.html // 项目打包入口 └───pkg // 打包后的项目文件夹 │───all.css // 项目打包样式 │───libs.js // 项目打包库 └───page.js // 项目打包业务代码
时间关系直接附上,先安装完以后再讲解
package.json
{ "name": "fis3_demo", "version": "1.0.0", "scripts": { "dev": "fis3 release dev -wL", "prod": "fis3 release prod -c", "lint": "eslint --fix", "clean": "rimraf dist/" }, "dependencies": { "cross-env": "^5.2.0", "eslint": "^5.9.0", "fis-optimizer-clean-css": "^0.0.12", "fis-optimizer-html-compress": "^0.0.7", "fis-optimizer-png-compressor": "^0.2.0", "fis-optimizer-uglify-js": "^0.2.3", "fis-parser-babel-6.x": "^6.24.1", "fis-parser-node-sass": "^1.0.4", "fis3-optimizer-img-compressor": "^0.1.3", "fis3-packager-deps-pack": "^0.1.2", "fis3-packager-map": "^1.1.3", "fis3-parser-typescript": "^1.2.2", "fis3-postpackager-loader": "^2.1.11", "fis3-preprocessor-autoprefixer": "^0.1.1", "fis3-preprocessor-js-require-css": "^0.1.3", "fis3-preprocessor-js-require-file": "^0.1.3" }, "devDependencies": { "fis-postpackager-map": "^0.0.2" } }
里面有两个命令分别执行开发环境和生产环境
"dev": "fis3 release dev -wL", // 监听文件实时更新 "prod": "fis3 release prod -c", // 清除缓存
参数回顾上面介绍命令行功能便可.为了方便使用不用每次打开终端,咱们写两个执行文件
dev.cmd
npm run dev
prod.cmd
npm run prod
双击文件便可自动打开终端执行
根目录新建fis-conf.js
,每次执行命令都会读取这里的配置去构建
由于fis3是根据文件打包,不像webpack4根据依赖解析,因此咱们须要声明哪些文件不被加入构建队列中
fis.set('project.ignore', [ '/dist/**', '/node_modules/**', '/fis-conf.js', '/package.json', '/*.cmd', '/doc/**', '/yarn*', '*.md', '*.zip' ]);
指向样式目录覆盖全部文件
fis.match('/assets/style/(**)', { rExt: '.css', // 支持 sass/scss 编译成 css parser: fis.plugin('node-sass', { // options... }), // 自动给 css 属性添加前缀,让标准的 css3 支持更多的浏览器. preprocessor: fis.plugin('autoprefixer', { browsers: ['Android >= 2.1', 'iOS >= 4', 'ie >= 8', 'firefox >= 15'], cascade: true }) })
fis.match('/assets/(js)/(**).js', { // rExt: 'js', // 支持 es六、es7 或者 jsx 编译成 es5 parser: fis.plugin('babel-6.x'), /* 容许你在 js 中直接 require 文件。好比图片,json, 其余静态文件。 require 部分将会替换成部署后的 url。 同时还支持,若是文件小于 20K 直接替换成 base64 字符串。 */ preprocessor: [ fis.plugin('js-require-file'), fis.plugin('js-require-css', { mode: 'dependency' }) ] })
fis.match('/assets/img/(**)', { // 资源相对输出路径打包 release: './img/$1' }) .match('/pages/(**)', { release: './$1' })
先不作处理,单纯输出指定位置
这个是打包的关键配置,能够直接使用打包相关依赖的文件,若是对打包顺序有要求的话须要本身控制.固然还有不少插件帮你更好处理.这是最基础的用法.当下以个人本地测试代码设置
fis.match('::package', { postpackager: fis.plugin('loader'), packager: fis.plugin('deps-pack', { 'pkg/libs.js': ['static/libs/jquery-1.11.0.min.js'], 'pkg/home/all.css': ['assets/style/reset.css', 'assets/style/style.scss'], 'pkg/home/page.js': [ 'assets/js/index.js' ] }) })
首先须要指定打包路径,咱们根据不一样环境配置一下,到时候代码里全部相关路径都会被转成绝对路径.
const baseDir = './dist', // 项目打包路径 devDir = '../dist', // 开发资源路径 prodDir = '../dist'; // 线上资源路径
开发环境打包配置
// dev fis.media('dev').match('*', { domain: devDir, deploy: fis.plugin('local-deliver', { to: baseDir }) });
意思就是将代码打包到baseDir
路径,里面的资源地址所有转成绝对路径devDir
+url
生产环境咱们能够进行更多针对性操做
// prod fis .media('prod') .match('*.{js,css,png}', { useHash: true // 添加hash缓存 }) .match('/assets/js/(**)', { // fis-optimizer-uglify-js 插件进行压缩,已内置 optimizer: fis.plugin('uglify-js') }) .match('/pages/(**):js', { // 针对html内js作压缩 optimizer: fis.plugin('uglify-js') }) .match('/assets/style/(**)', { // fis-optimizer-clean-css 插件进行压缩,已内置 optimizer: fis.plugin('clean-css') }) .match('/pages/(**):{css,inline-style,scss}', { // 针对html内css作压缩 optimizer: fis.plugin('clean-css') }) .match('/assets/img/(**)', { // 图片压缩 optimizer: fis.plugin('img-compressor') }) .match('*', { domain: prodDir, deploy: fis.plugin('local-deliver', { to: baseDir }) });
基本配置到此就完成了,咱们能够测试效果看看
新建pages/index.html
<!DOCTYPE html> <html> <head> <meta charset='utf-8'> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Page Title</title> <link rel="stylesheet" type="text/css" media="screen" href="../assets/style/style.scss" /> </head> <body> <div class="container"> <img src="../assets/img/banner.jpg"> </div> </div> <!-- JS --> <script src="../static/libs/jquery-1.11.0.min"></script> <script src="../assets/js/index.js"></script> </body> </html>
而后根据里面对应的位置加上些资源执行命令便可,最终输出以下
. └───dist │───static // 源文件处理后的资源,已经被打包入pkg的libs.js中,可忽略 │───assets // 源文件处理后的资源,已经被打包入pkg的对应文件中,可忽略 │───img // 项目打包图片 │───index.html // 入口 └───pkg // 打包后的项目文件夹 │───all.css // 项目打包样式 │───libs.js // 项目打包库 └───page.js // 项目打包业务代码
最终咱们获得的输出资源如上.至于被合并的资源应该有办法忽略不让输出,可是我没去找
还有当前项目没有引入模块插件,只是单纯讲解打包,有须要自行研究.