├── .github └── FUNDING.yml ├── .gitignore ├── INTRO.md ├── LICENSE ├── README.md ├── README_NG.md ├── component.json ├── fis-conf-npm.js ├── fis-conf.js ├── img └── test.jpg ├── index.html ├── lib ├── es5-sham.js ├── es5-shim.js ├── html5-shim.js └── mod.js ├── map.json ├── modules ├── app │ ├── test-npm.es │ ├── test.es │ └── test.tmpl ├── css │ ├── _global.less │ ├── _layout.scss │ ├── _mixin.scss │ ├── common.scss │ ├── img │ │ └── index.jpg │ ├── index.scss │ ├── mixin │ │ ├── _clearfix.scss │ │ └── _size.scss │ └── test.less ├── html │ ├── footer │ │ ├── footer.html │ │ └── footer.scss │ └── header │ │ ├── header.html │ │ └── header.scss ├── lib │ ├── data.js │ │ └── data.js │ └── template │ │ └── template.js └── util │ └── template │ └── template.es ├── package-lock.json ├── package.json ├── pc.html ├── test-npm.html ├── test.html ├── test ├── dynamic.js ├── server.conf └── test.json └── wap.html /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['https://yanhaijing.com/mywallet/']# Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | components/* 3 | output 4 | -------------------------------------------------------------------------------- /INTRO.md: -------------------------------------------------------------------------------- 1 | # 文档 2 | 这里说明文档。依赖fis3,如果你不了解fis3,请移步[fis3官网](http://fis.baidu.com/)。 3 | 4 | ## 推荐环境 5 | 作者长期使用和测试的平台如下,对于没测试过的平台,可能会遇到一些问题,欢迎反馈哈 6 | 7 | - window7 node0.12.x 8 | - mac10.13 node8.9.x 9 | 10 | ## 依赖 11 | fis依赖node,了解node请看这里[nodejs.org](http://nodejs.org/)。 12 | 13 | **注意:windows平台,推荐node版本 0.12.x。** 14 | 15 | 第一步,用下面的命令安装fis3(安装失败,可以试试[淘宝镜像](http://yanhaijing.com/tool/2015/09/01/my-npm-note/)) 16 | 17 | ``` bash 18 | npm install -g fis3 19 | ``` 20 | 21 | 第二步,安装fis插件 22 | 23 | ``` bash 24 | # hook类 25 | npm install -g fis3-hook-commonjs 26 | 27 | # parser类 28 | ## 下面两个sass插件二选一,还需要更改fisconf里对应的插件 29 | npm install -g fis-parser-sass # node版本需 <= 0.12 30 | npm install -g fis-parser-node-sass # node >= 4 31 | 32 | npm install -g fis-parser-less 33 | npm install -g fis-parser-template 34 | npm install -g fis-parser-babel-5.x 35 | 36 | # preprocessor类 37 | npm install -g fis3-preprocessor-js-require-file 38 | npm install -g fis3-preprocessor-js-require-css 39 | 40 | # postprocessor类 41 | npm install -g fis-postprocessor-autoprefixer 42 | 43 | # postpackager类 44 | npm install -g fis3-postpackager-loader 45 | 46 | # optimizer类 47 | # npm install -g fis3-optimizer-html-compress # 此插件已废弃,可跳过 48 | 49 | # deploy类 50 | npm install -g fis3-deploy-skip-packed 51 | ``` 52 | 53 | 下面给出把上面插件一起安装的命令 54 | 55 | ``` bash 56 | npm install -g fis3-hook-commonjs fis-parser-node-sass fis-parser-less fis-parser-template fis-parser-babel-5.x fis3-preprocessor-js-require-file fis3-preprocessor-js-require-css fis-postprocessor-autoprefixer fis3-postpackager-loader fis3-optimizer-html-compress fis3-deploy-skip-packed 57 | ``` 58 | 59 | 更多插件可以看[fis3插件开发](http://fis.baidu.com/fis3/docs/api/dev-plugin.html)和[fis3常用插件列表](http://fis.baidu.com/fis3/docs/common-plugin.html)。 60 | 61 | 第三步,需要安装组件,此处需要区分使用npm,还是components 62 | 63 | 如果你是用的是npm(也就是使用fis-conf-npm.js),接下来需要安装npm依赖 64 | 65 | ``` bash 66 | npm install 67 | ``` 68 | 69 | 如果你使用fis-components(也就是使用fis-conf.js),接下来需要安装fis组件 70 | 71 | ``` bash 72 | fis3 install 73 | ``` 74 | 75 | 更多信息请看[fis用户文档](http://fis.baidu.com/fis3/docs/beginning/install.html)。 76 | 77 | 如果 78 | 79 | ## 如何运行 80 | 开启fis服务器 81 | 82 | ``` bash 83 | fis3 server start 84 | ``` 85 | 86 | 发布 87 | 88 | ``` bash 89 | fis3 release 90 | 91 | fis3 release prod-debug # 本地查看发布产品库状态 92 | fis3 release prod # 发布产品库 93 | 94 | fis3 release rd # 发布到指定机器 95 | fis3 release rd-debug # 发布到指定机器调试 96 | ``` 97 | 98 | 如果是想使用npm可以再release后面指定fis-conf文件 99 | 100 | ``` bash 101 | fis3 release -f fis-conf-npm.js 102 | ``` 103 | 104 | 更多命令请[查看这里](http://fis.baidu.com/fis3/docs/api/command.html)。 105 | 106 | ## 目录说明 107 | 项目的目录树如下: 108 | 109 | ``` 110 | ┌─components 111 | ├─img 112 | ├─lib 113 | ├─modules 114 | │ ├─app 115 | │ ├─css 116 | │ ├─lib 117 | │ ├─ui 118 | │ └─util 119 | └─test 120 | ``` 121 | 根目录下存放html文件。 122 | 123 | - components fis 组件的目录 124 | - img html中用到的图片 125 | - lib 存放一些不打包的js库 126 | - modules 项目的组件 127 | - app 项目用到的js 128 | - css 项目用到的css 129 | - lib 第三方js 130 | - ui UI 组件 131 | - util 工具组件 132 | - test 模拟测试数据 133 | 134 | ## fis components 135 | fis提供了大量组件,社区比较活跃的库一般都有组件存在,你可以在下面的链接查找对应组件。 136 | https://github.com/fis-components 137 | 138 | **注意:为了稳定性,建议把components也加入版本控制库。** 139 | 140 | ## 问题反馈 141 | 使用过程中的常见问题请见这里 [issue](https://github.com/yanhaijing/fis3-base/issues)。 142 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2015-2018 yanhaijing 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [fis3 base](https://github.com/yanhaijing/fis3-base) [![](https://img.shields.io/badge/Powered%20by-fis3%20base-brightgreen.svg)](https://github.com/yanhaijing/fis3-base) [![license](http://img.shields.io/npm/l/express.svg)](https://github.com/yanhaijing/fis3-base/blob/master/LICENSE) 2 | 基于fis3的纯前端解决方案,拿来即用的fis3脚手架。 3 | 4 | [English README](https://github.com/yanhaijing/fis3-base/blob/master/README_NG.md) 5 | 6 | ## 特色 7 | fis3 base有如下功能特色。 8 | - commonjs 9 | - ECMASCript2015 10 | - [SASS](http://sass-lang.com/) & [Compass](http://compass-style.org/) 11 | - [less](http://www.lesscss.net/) 12 | - [autoprefixer](https://github.com/postcss/autoprefixer) 13 | - [fis components](https://github.com/fis-components) or [npm](https://www.npmjs.com/package/fis3-hook-npm) 14 | - [data.js](https://github.com/yanhaijing/data.js) 15 | - [template.js](https://github.com/yanhaijing/template.js) 16 | - 集成[jsmini](https://github.com/jsmini) 17 | - html,js,css组件 18 | - 本地模拟数据 19 | - 开发,测试,发布等多种模式 20 | 21 | ## 说明文档 22 | [INTRO](INTRO.md) 23 | -------------------------------------------------------------------------------- /README_NG.md: -------------------------------------------------------------------------------- 1 | # [fis3 base](https://github.com/yanhaijing/fis3-base) [![](https://img.shields.io/badge/Powered%20by-fis3%20base-brightgreen.svg)](https://github.com/yanhaijing/fis3-base) [![license](http://img.shields.io/npm/l/express.svg)](https://github.com/yanhaijing/fis3-base/blob/master/MIT-LICENSE) 2 | A pure front end solution based on fis3 for use as a fis3 scaffolding tool. 3 | 4 | [Chinese README 中文版本](https://github.com/yanhaijing/fis3-base/blob/master/README.md) 5 | 6 | ## Features 7 | fis3 base has the following features: 8 | - commonjs 9 | - ECMASCript2015 10 | - [SASS](http://sass-lang.com/) & [Compass](http://compass-style.org/) 11 | - [less](http://www.lesscss.net/) 12 | - [autoprefixer](https://github.com/postcss/autoprefixer) 13 | - [fis components](https://github.com/fis-components) or [npm](https://www.npmjs.com/package/fis3-hook-npm) 14 | - [data.js](https://github.com/yanhaijing/data.js) 15 | - [template.js](https://github.com/yanhaijing/template.js) 16 | - Integration of [jsmini](https://github.com/jsmini) 17 | - html,js,css components 18 | - Local analog data 19 | - Developing, testing, publishing, and other modes 20 | 21 | ## Instructions 22 | [INTRO](INTRO.md) 23 | -------------------------------------------------------------------------------- /component.json: -------------------------------------------------------------------------------- 1 | { 2 | "protocol": "github", 3 | "gihub": { 4 | "author": "fis-components" 5 | }, 6 | "dependencies": [ 7 | "jquery@~1.9.1", 8 | "jquery-ui@~1.11.2", 9 | "jquery-validation@~1.13.1", 10 | "jquery-placeholder@~2.0.8", 11 | "underscore@~1.8.3", 12 | "es6-promise@~2.0.1", 13 | "fetch@~0.7.0", 14 | "bootstrap@~3.3.5", 15 | "compass-mixins@~0.12.7", 16 | "zepto@~1.1.6", 17 | "animate.css@~3.1.0", 18 | "normalize.css@~3.0.3", 19 | "react@~15.1.0", 20 | "react-dom@~15.1.0" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /fis-conf-npm.js: -------------------------------------------------------------------------------- 1 | // 设置项目属性 2 | fis.set('project.name', 'fis3-base'); 3 | fis.set('project.static', '/static'); 4 | fis.set('project.files', ['*.html', 'map.json', '/test/*']); 5 | 6 | // 引入模块化开发插件,设置规范为 commonJs 规范。 7 | 8 | fis.hook('commonjs', { 9 | baseUrl: './modules', 10 | extList: ['.js', '.es'] 11 | }); 12 | 13 | // 配置node_modules 14 | fis.unhook('components') 15 | fis.hook('node_modules') 16 | 17 | fis.match('/node_modules/**.js', { 18 | isMod: true, 19 | useSameNameRequire: true 20 | }); 21 | 22 | /*************************目录规范*****************************/ 23 | 24 | // 开启同名依赖 25 | fis.match('/modules/**', { 26 | useSameNameRequire: true 27 | }); 28 | 29 | 30 | // ------ 全局配置 31 | // 允许你在 js 中直接 require css+文件 32 | fis.match('*.{js,es}', { 33 | preprocessor: [ 34 | fis.plugin('js-require-file'), 35 | fis.plugin('js-require-css', { 36 | mode: 'dependency' 37 | }) 38 | ] 39 | }); 40 | 41 | // 配置图片压缩 42 | fis.match('**.png', { 43 | optimizer: fis.plugin('png-compressor', { 44 | type: 'pngquant' 45 | }) 46 | }); 47 | 48 | 49 | // ------ 配置lib 50 | fis.match('/lib/**.js', { 51 | release: '${project.static}/$&' 52 | }); 53 | 54 | 55 | // ------ 配置components 56 | fis.match('/components/**', { 57 | release: '${project.static}/$&' 58 | }); 59 | fis.match('/components/**.css', { 60 | isMod: true, 61 | release: '${project.static}/$&' 62 | }); 63 | fis.match('/components/**.js', { 64 | isMod: true, 65 | release: '${project.static}/$&' 66 | }); 67 | 68 | 69 | // ------ 配置modules 70 | fis.match('/modules/(**)', { 71 | release: '${project.static}/$1' 72 | }) 73 | 74 | // 配置css 75 | fis.match(/^\/modules\/(.*\.scss)$/i, { 76 | parser: fis.plugin('node-sass', { 77 | include_paths: ['modules/css', 'components'] // 加入文件查找目录 78 | }) 79 | }); 80 | fis.match(/^\/modules\/(.*\.less)$/i, { 81 | parser: fis.plugin('less', { 82 | paths: [] 83 | }) 84 | }); 85 | fis.match(/^\/modules\/(.*\.(scss|less|css))$/i, { 86 | rExt: '.css', 87 | isMod: true, 88 | release: '${project.static}/$1', 89 | postprocessor: fis.plugin('autoprefixer', { 90 | browsers: ['IE >= 8', 'Chrome >= 30', 'last 2 versions'] // pc 91 | // browsers: ['Android >= 4', 'ChromeAndroid > 1%', 'iOS >= 6'] // wap 92 | }) 93 | }); 94 | fis.match(/^\/modules\/(.*\.(?:png|jpg|gif))$/i, { 95 | release: '${project.static}/$1' 96 | }); 97 | 98 | // 配置js 99 | fis.match(/^\/modules\/(.*\.es)$/i, { 100 | parser: fis.plugin('babel-5.x'), 101 | rExt: 'js', 102 | isMod: true, 103 | release: '${project.static}/$1' 104 | }); 105 | fis.match(/^\/modules\/(.*\.js)$/i, { 106 | isMod: true, 107 | release: '${project.static}/$1' 108 | }); 109 | 110 | 111 | // ------ 配置前端模版 使用template.js 112 | fis.match('**.tmpl', { 113 | parser: fis.plugin('template', { 114 | sTag: '<#', 115 | eTag: '#>', 116 | global: 'template' 117 | }), 118 | isJsLike: true, 119 | release: false 120 | }); 121 | 122 | 123 | // ------ 配置模拟数据 124 | fis.match('/test/**', { 125 | release: '$0' 126 | }); 127 | fis.match('/test/server.conf', { 128 | release: '/config/server.conf' 129 | }); 130 | 131 | 132 | /*************************打包规范*****************************/ 133 | 134 | // 因为是纯前端项目,依赖不能自断被加载进来,所以这里需要借助一个 loader 来完成, 135 | // 注意:与后端结合的项目不需要此插件!!! 136 | fis.match('::package', { 137 | // npm install [-g] fis3-postpackager-loader 138 | // 分析 __RESOURCE_MAP__ 结构,来解决资源加载问题 139 | postpackager: fis.plugin('loader', { 140 | resourceType: 'commonJs', 141 | useInlineMap: true // 资源映射表内嵌 142 | }) 143 | }); 144 | 145 | // debug后缀 不会压缩 146 | var map = { 147 | 'rd': { 148 | host: '', 149 | path: '' 150 | }, 151 | 'rd-debug': { 152 | host: '', 153 | path: '' 154 | }, 155 | 'prod': { 156 | host: 'http://yanhaijing.com', 157 | path: '/${project.name}' 158 | }, 159 | 'prod-debug': { 160 | host: '', 161 | path: '' 162 | } 163 | }; 164 | 165 | // 通用 1.替换url前缀 2.添加mr5码 3.打包 4.合图 5.重新定义资源路径 166 | Object.keys(map).forEach(function(v) { 167 | var o = map[v]; 168 | var domain = o.host + o.path; 169 | 170 | fis.media(v) 171 | .match('**.{es,js}', { 172 | useHash: true, 173 | domain: domain 174 | }) 175 | .match('**.{scss,less,css}', { 176 | useSprite: true, 177 | useHash: true, 178 | domain: domain 179 | }) 180 | .match('::image', { 181 | useHash: true, 182 | domain: domain 183 | }) 184 | .match('**/(*_{x,y,z}.png)', { 185 | release: '/pkg/$1' 186 | }) 187 | // 启用打包插件,必须匹配 ::package 188 | .match('::package', { 189 | spriter: fis.plugin('csssprites', { 190 | layout: 'matrix', 191 | // scale: 0.5, // 移动端二倍图用 192 | margin: '10' 193 | }), 194 | postpackager: fis.plugin('loader', { 195 | allInOne: true, 196 | }) 197 | }) 198 | .match('/lib/es5-{shim,sham}.js', { 199 | packTo: '/pkg/es5-shim.js' 200 | }) 201 | .match('/components/**.css', { 202 | packTo: '/pkg/components.css' 203 | }) 204 | .match('/components/**.js', { 205 | packTo: '/pkg/components.js' 206 | }) 207 | .match('/modules/**.{scss,less,css}', { 208 | packTo: '/pkg/modules.css' 209 | }) 210 | .match('/modules/css/**.{scss,less,css}', { 211 | packTo: '' 212 | }) 213 | .match('/modules/css/common.scss', { 214 | packTo: '/pkg/common.css' 215 | }) 216 | .match('/modules/**.{es,js}', { 217 | packTo: '/pkg/modules.js' 218 | }) 219 | .match('/modules/app/**.{es,js}', { 220 | packTo: '/pkg/aio.js' 221 | }) 222 | // 为了上线方便,将静态文件发布到同一个目录 223 | // .match('**/(*.{css,less,scss,es,js,jpg,png,gif})', { 224 | // release: '/prod/$1' 225 | // }) 226 | }); 227 | 228 | 229 | // 压缩css js html 230 | Object.keys(map) 231 | .filter(function(v) { 232 | return v.indexOf('debug') < 0 233 | }) 234 | .forEach(function(v) { 235 | fis.media(v) 236 | // .match('**.html', { 237 | // optimizer: fis.plugin('html-compress') 238 | // }) 239 | .match('**.{es,js}', { 240 | optimizer: fis.plugin('uglify-js') 241 | }) 242 | .match('**.{scss,less,css}', { 243 | optimizer: fis.plugin('clean-css', { 244 | 'keepBreaks': true //保持一个规则一个换行 245 | }) 246 | }); 247 | }); 248 | 249 | // 本地产出发布 250 | fis.media('prod') 251 | .match('**', { 252 | deploy: [ 253 | fis.plugin('skip-packed', { 254 | // 默认被打包了 js 和 css 以及被 css sprite 合并了的图片都会在这过滤掉, 255 | // 但是如果这些文件满足下面的规则,则依然不过滤 256 | ignore: [] 257 | }), 258 | 259 | fis.plugin('local-deliver', { 260 | to: 'output' 261 | }) 262 | ] 263 | }); 264 | 265 | 266 | // 发布到指定的机器 267 | ['rd', 'rd-debug'].forEach(function(v) { 268 | fis.media(v) 269 | .match('*', { 270 | deploy: [ 271 | fis.plugin('skip-packed', { 272 | // 默认被打包了 js 和 css 以及被 css sprite 合并了的图片都会在这过滤掉, 273 | // 但是如果这些文件满足下面的规则,则依然不过滤 274 | ignore: [] 275 | }), 276 | fis.plugin('http-push', { 277 | receiver: 'xxx/fisreceiver.php', 278 | to: 'xxx/' + fis.get('project.name') 279 | }) 280 | ] 281 | }); 282 | }); 283 | -------------------------------------------------------------------------------- /fis-conf.js: -------------------------------------------------------------------------------- 1 | // 设置项目属性 2 | fis.set('project.name', 'fis3-base'); 3 | fis.set('project.static', '/static'); 4 | fis.set('project.files', ['*.html', 'map.json', '/test/*']); 5 | 6 | // 引入模块化开发插件,设置规范为 commonJs 规范。 7 | 8 | fis.hook('commonjs', { 9 | baseUrl: './modules', 10 | extList: ['.js', '.es'] 11 | }); 12 | 13 | /*************************目录规范*****************************/ 14 | 15 | // 开启同名依赖 16 | fis.match('/modules/**', { 17 | useSameNameRequire: true 18 | }); 19 | 20 | 21 | // ------ 全局配置 22 | // 允许你在 js 中直接 require css+文件 23 | fis.match('*.{js,es}', { 24 | preprocessor: [ 25 | fis.plugin('js-require-file'), 26 | fis.plugin('js-require-css', { 27 | mode: 'dependency' 28 | }) 29 | ] 30 | }); 31 | 32 | // 配置图片压缩 33 | fis.match('**.png', { 34 | optimizer: fis.plugin('png-compressor', { 35 | type: 'pngquant' 36 | }) 37 | }); 38 | 39 | 40 | // ------ 配置lib 41 | fis.match('/lib/**.js', { 42 | release: '${project.static}/$&' 43 | }); 44 | 45 | 46 | // ------ 配置components 47 | fis.match('/components/**', { 48 | release: '${project.static}/$&' 49 | }); 50 | fis.match('/components/**.css', { 51 | isMod: true, 52 | release: '${project.static}/$&' 53 | }); 54 | fis.match('/components/**.js', { 55 | isMod: true, 56 | release: '${project.static}/$&' 57 | }); 58 | 59 | 60 | // ------ 配置modules 61 | fis.match('/modules/(**)', { 62 | release: '${project.static}/$1' 63 | }) 64 | 65 | // 配置css 66 | fis.match(/^\/modules\/(.*\.scss)$/i, { 67 | parser: fis.plugin('node-sass', { 68 | include_paths: ['modules/css', 'components'] // 加入文件查找目录 69 | }) 70 | }); 71 | fis.match(/^\/modules\/(.*\.less)$/i, { 72 | parser: fis.plugin('less', { 73 | paths: [] 74 | }) 75 | }); 76 | fis.match(/^\/modules\/(.*\.(scss|less|css))$/i, { 77 | rExt: '.css', 78 | isMod: true, 79 | release: '${project.static}/$1', 80 | postprocessor: fis.plugin('autoprefixer', { 81 | browsers: ['IE >= 8', 'Chrome >= 30', 'last 2 versions'] // pc 82 | // browsers: ['Android >= 4', 'ChromeAndroid > 1%', 'iOS >= 6'] // wap 83 | }) 84 | }); 85 | fis.match(/^\/modules\/(.*\.(?:png|jpg|gif))$/i, { 86 | release: '${project.static}/$1' 87 | }); 88 | 89 | // 配置js 90 | fis.match(/^\/modules\/(.*\.es)$/i, { 91 | parser: fis.plugin('babel-5.x'), 92 | rExt: 'js', 93 | isMod: true, 94 | release: '${project.static}/$1' 95 | }); 96 | fis.match(/^\/modules\/(.*\.js)$/i, { 97 | isMod: true, 98 | release: '${project.static}/$1' 99 | }); 100 | 101 | 102 | // ------ 配置前端模版 使用template.js 103 | fis.match('**.tmpl', { 104 | parser: fis.plugin('template', { 105 | sTag: '<#', 106 | eTag: '#>', 107 | global: 'template' 108 | }), 109 | isJsLike: true, 110 | release: false 111 | }); 112 | 113 | 114 | // ------ 配置模拟数据 115 | fis.match('/test/**', { 116 | release: '$0' 117 | }); 118 | fis.match('/test/server.conf', { 119 | release: '/config/server.conf' 120 | }); 121 | 122 | 123 | /*************************打包规范*****************************/ 124 | 125 | // 因为是纯前端项目,依赖不能自断被加载进来,所以这里需要借助一个 loader 来完成, 126 | // 注意:与后端结合的项目不需要此插件!!! 127 | fis.match('::package', { 128 | // npm install [-g] fis3-postpackager-loader 129 | // 分析 __RESOURCE_MAP__ 结构,来解决资源加载问题 130 | postpackager: fis.plugin('loader', { 131 | resourceType: 'commonJs', 132 | useInlineMap: true // 资源映射表内嵌 133 | }) 134 | }); 135 | 136 | // debug后缀 不会压缩 137 | var map = { 138 | 'rd': { 139 | host: '', 140 | path: '' 141 | }, 142 | 'rd-debug': { 143 | host: '', 144 | path: '' 145 | }, 146 | 'prod': { 147 | host: 'http://yanhaijing.com', 148 | path: '/${project.name}' 149 | }, 150 | 'prod-debug': { 151 | host: '', 152 | path: '' 153 | } 154 | }; 155 | 156 | // 通用 1.替换url前缀 2.添加mr5码 3.打包 4.合图 5.重新定义资源路径 157 | Object.keys(map).forEach(function(v) { 158 | var o = map[v]; 159 | var domain = o.host + o.path; 160 | 161 | fis.media(v) 162 | .match('**.{es,js}', { 163 | useHash: true, 164 | domain: domain 165 | }) 166 | .match('**.{scss,less,css}', { 167 | useSprite: true, 168 | useHash: true, 169 | domain: domain 170 | }) 171 | .match('::image', { 172 | useHash: true, 173 | domain: domain 174 | }) 175 | .match('**/(*_{x,y,z}.png)', { 176 | release: '/pkg/$1' 177 | }) 178 | // 启用打包插件,必须匹配 ::package 179 | .match('::package', { 180 | spriter: fis.plugin('csssprites', { 181 | layout: 'matrix', 182 | // scale: 0.5, // 移动端二倍图用 183 | margin: '10' 184 | }), 185 | postpackager: fis.plugin('loader', { 186 | allInOne: true, 187 | }) 188 | }) 189 | .match('/lib/es5-{shim,sham}.js', { 190 | packTo: '/pkg/es5-shim.js' 191 | }) 192 | .match('/components/**.css', { 193 | packTo: '/pkg/components.css' 194 | }) 195 | .match('/components/**.js', { 196 | packTo: '/pkg/components.js' 197 | }) 198 | .match('/modules/**.{scss,less,css}', { 199 | packTo: '/pkg/modules.css' 200 | }) 201 | .match('/modules/css/**.{scss,less,css}', { 202 | packTo: '' 203 | }) 204 | .match('/modules/css/common.scss', { 205 | packTo: '/pkg/common.css' 206 | }) 207 | .match('/modules/**.{es,js}', { 208 | packTo: '/pkg/modules.js' 209 | }) 210 | .match('/modules/app/**.{es,js}', { 211 | packTo: '/pkg/aio.js' 212 | }) 213 | // 为了上线方便,将静态文件发布到同一个目录 214 | // .match('**/(*.{css,less,scss,es,js,jpg,png,gif})', { 215 | // release: '/prod/$1' 216 | // }) 217 | }); 218 | 219 | 220 | // 压缩css js html 221 | Object.keys(map) 222 | .filter(function(v) { 223 | return v.indexOf('debug') < 0 224 | }) 225 | .forEach(function(v) { 226 | fis.media(v) 227 | // .match('**.html', { 228 | // optimizer: fis.plugin('html-compress') 229 | // }) 230 | .match('**.{es,js}', { 231 | optimizer: fis.plugin('uglify-js') 232 | }) 233 | .match('**.{scss,less,css}', { 234 | optimizer: fis.plugin('clean-css', { 235 | 'keepBreaks': true //保持一个规则一个换行 236 | }) 237 | }); 238 | }); 239 | 240 | // 本地产出发布 241 | fis.media('prod') 242 | .match('**', { 243 | deploy: [ 244 | fis.plugin('skip-packed', { 245 | // 默认被打包了 js 和 css 以及被 css sprite 合并了的图片都会在这过滤掉, 246 | // 但是如果这些文件满足下面的规则,则依然不过滤 247 | ignore: [] 248 | }), 249 | 250 | fis.plugin('local-deliver', { 251 | to: 'output' 252 | }) 253 | ] 254 | }); 255 | 256 | 257 | // 发布到指定的机器 258 | ['rd', 'rd-debug'].forEach(function(v) { 259 | fis.media(v) 260 | .match('*', { 261 | deploy: [ 262 | fis.plugin('skip-packed', { 263 | // 默认被打包了 js 和 css 以及被 css sprite 合并了的图片都会在这过滤掉, 264 | // 但是如果这些文件满足下面的规则,则依然不过滤 265 | ignore: [] 266 | }), 267 | fis.plugin('http-push', { 268 | receiver: 'xxx/fisreceiver.php', 269 | to: 'xxx/' + fis.get('project.name') 270 | }) 271 | ] 272 | }); 273 | }); 274 | -------------------------------------------------------------------------------- /img/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yanhaijing/fis3-base/42290c12574872cc409cd8247e7cd3981a419fd3/img/test.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | fis3 base 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |
18 | 32 |
33 | 34 |
35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /lib/es5-sham.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * https://github.com/es-shims/es5-shim 3 | * @license es5-shim Copyright 2009-2015 by contributors, MIT License 4 | * see https://github.com/es-shims/es5-shim/blob/master/LICENSE 5 | */ 6 | 7 | // vim: ts=4 sts=4 sw=4 expandtab 8 | 9 | // Add semicolon to prevent IIFE from being passed as argument to concatenated code. 10 | ; 11 | 12 | // UMD (Universal Module Definition) 13 | // see https://github.com/umdjs/umd/blob/master/templates/returnExports.js 14 | (function (root, factory) { 15 | 'use strict'; 16 | 17 | /* global define, exports, module */ 18 | if (typeof define === 'function' && define.amd) { 19 | // AMD. Register as an anonymous module. 20 | define(factory); 21 | } else if (typeof exports === 'object') { 22 | // Node. Does not work with strict CommonJS, but 23 | // only CommonJS-like enviroments that support module.exports, 24 | // like Node. 25 | module.exports = factory(); 26 | } else { 27 | // Browser globals (root is window) 28 | root.returnExports = factory(); 29 | } 30 | }(this, function () { 31 | 32 | var call = Function.call; 33 | var prototypeOfObject = Object.prototype; 34 | var owns = call.bind(prototypeOfObject.hasOwnProperty); 35 | var isEnumerable = call.bind(prototypeOfObject.propertyIsEnumerable); 36 | var toStr = call.bind(prototypeOfObject.toString); 37 | 38 | // If JS engine supports accessors creating shortcuts. 39 | var defineGetter; 40 | var defineSetter; 41 | var lookupGetter; 42 | var lookupSetter; 43 | var supportsAccessors = owns(prototypeOfObject, '__defineGetter__'); 44 | if (supportsAccessors) { 45 | /* eslint-disable no-underscore-dangle */ 46 | defineGetter = call.bind(prototypeOfObject.__defineGetter__); 47 | defineSetter = call.bind(prototypeOfObject.__defineSetter__); 48 | lookupGetter = call.bind(prototypeOfObject.__lookupGetter__); 49 | lookupSetter = call.bind(prototypeOfObject.__lookupSetter__); 50 | /* eslint-enable no-underscore-dangle */ 51 | } 52 | 53 | // ES5 15.2.3.2 54 | // http://es5.github.com/#x15.2.3.2 55 | if (!Object.getPrototypeOf) { 56 | // https://github.com/es-shims/es5-shim/issues#issue/2 57 | // http://ejohn.org/blog/objectgetprototypeof/ 58 | // recommended by fschaefer on github 59 | // 60 | // sure, and webreflection says ^_^ 61 | // ... this will nerever possibly return null 62 | // ... Opera Mini breaks here with infinite loops 63 | Object.getPrototypeOf = function getPrototypeOf(object) { 64 | /* eslint-disable no-proto */ 65 | var proto = object.__proto__; 66 | /* eslint-enable no-proto */ 67 | if (proto || proto === null) { 68 | return proto; 69 | } else if (toStr(object.constructor) === '[object Function]') { 70 | return object.constructor.prototype; 71 | } else if (object instanceof Object) { 72 | return prototypeOfObject; 73 | } else { 74 | // Correctly return null for Objects created with `Object.create(null)` 75 | // (shammed or native) or `{ __proto__: null}`. Also returns null for 76 | // cross-realm objects on browsers that lack `__proto__` support (like 77 | // IE <11), but that's the best we can do. 78 | return null; 79 | } 80 | }; 81 | } 82 | 83 | // ES5 15.2.3.3 84 | // http://es5.github.com/#x15.2.3.3 85 | 86 | var doesGetOwnPropertyDescriptorWork = function doesGetOwnPropertyDescriptorWork(object) { 87 | try { 88 | object.sentinel = 0; 89 | return Object.getOwnPropertyDescriptor(object, 'sentinel').value === 0; 90 | } catch (exception) { 91 | return false; 92 | } 93 | }; 94 | 95 | // check whether getOwnPropertyDescriptor works if it's given. Otherwise, shim partially. 96 | if (Object.defineProperty) { 97 | var getOwnPropertyDescriptorWorksOnObject = doesGetOwnPropertyDescriptorWork({}); 98 | var getOwnPropertyDescriptorWorksOnDom = typeof document === 'undefined' || 99 | doesGetOwnPropertyDescriptorWork(document.createElement('div')); 100 | if (!getOwnPropertyDescriptorWorksOnDom || !getOwnPropertyDescriptorWorksOnObject) { 101 | var getOwnPropertyDescriptorFallback = Object.getOwnPropertyDescriptor; 102 | } 103 | } 104 | 105 | if (!Object.getOwnPropertyDescriptor || getOwnPropertyDescriptorFallback) { 106 | var ERR_NON_OBJECT = 'Object.getOwnPropertyDescriptor called on a non-object: '; 107 | 108 | /* eslint-disable no-proto */ 109 | Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) { 110 | if ((typeof object !== 'object' && typeof object !== 'function') || object === null) { 111 | throw new TypeError(ERR_NON_OBJECT + object); 112 | } 113 | 114 | // make a valiant attempt to use the real getOwnPropertyDescriptor 115 | // for I8's DOM elements. 116 | if (getOwnPropertyDescriptorFallback) { 117 | try { 118 | return getOwnPropertyDescriptorFallback.call(Object, object, property); 119 | } catch (exception) { 120 | // try the shim if the real one doesn't work 121 | } 122 | } 123 | 124 | var descriptor; 125 | 126 | // If object does not owns property return undefined immediately. 127 | if (!owns(object, property)) { 128 | return descriptor; 129 | } 130 | 131 | // If object has a property then it's for sure `configurable`, and 132 | // probably `enumerable`. Detect enumerability though. 133 | descriptor = { 134 | enumerable: isEnumerable(object, property), 135 | configurable: true 136 | }; 137 | 138 | // If JS engine supports accessor properties then property may be a 139 | // getter or setter. 140 | if (supportsAccessors) { 141 | // Unfortunately `__lookupGetter__` will return a getter even 142 | // if object has own non getter property along with a same named 143 | // inherited getter. To avoid misbehavior we temporary remove 144 | // `__proto__` so that `__lookupGetter__` will return getter only 145 | // if it's owned by an object. 146 | var prototype = object.__proto__; 147 | var notPrototypeOfObject = object !== prototypeOfObject; 148 | // avoid recursion problem, breaking in Opera Mini when 149 | // Object.getOwnPropertyDescriptor(Object.prototype, 'toString') 150 | // or any other Object.prototype accessor 151 | if (notPrototypeOfObject) { 152 | object.__proto__ = prototypeOfObject; 153 | } 154 | 155 | var getter = lookupGetter(object, property); 156 | var setter = lookupSetter(object, property); 157 | 158 | if (notPrototypeOfObject) { 159 | // Once we have getter and setter we can put values back. 160 | object.__proto__ = prototype; 161 | } 162 | 163 | if (getter || setter) { 164 | if (getter) { 165 | descriptor.get = getter; 166 | } 167 | if (setter) { 168 | descriptor.set = setter; 169 | } 170 | // If it was accessor property we're done and return here 171 | // in order to avoid adding `value` to the descriptor. 172 | return descriptor; 173 | } 174 | } 175 | 176 | // If we got this far we know that object has an own property that is 177 | // not an accessor so we set it as a value and return descriptor. 178 | descriptor.value = object[property]; 179 | descriptor.writable = true; 180 | return descriptor; 181 | }; 182 | /* eslint-enable no-proto */ 183 | } 184 | 185 | // ES5 15.2.3.4 186 | // http://es5.github.com/#x15.2.3.4 187 | if (!Object.getOwnPropertyNames) { 188 | Object.getOwnPropertyNames = function getOwnPropertyNames(object) { 189 | return Object.keys(object); 190 | }; 191 | } 192 | 193 | // ES5 15.2.3.5 194 | // http://es5.github.com/#x15.2.3.5 195 | if (!Object.create) { 196 | 197 | // Contributed by Brandon Benvie, October, 2012 198 | var createEmpty; 199 | var supportsProto = !({ __proto__: null } instanceof Object); 200 | // the following produces false positives 201 | // in Opera Mini => not a reliable check 202 | // Object.prototype.__proto__ === null 203 | 204 | // Check for document.domain and active x support 205 | // No need to use active x approach when document.domain is not set 206 | // see https://github.com/es-shims/es5-shim/issues/150 207 | // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346 208 | /* global ActiveXObject */ 209 | var shouldUseActiveX = function shouldUseActiveX() { 210 | // return early if document.domain not set 211 | if (!document.domain) { 212 | return false; 213 | } 214 | 215 | try { 216 | return !!new ActiveXObject('htmlfile'); 217 | } catch (exception) { 218 | return false; 219 | } 220 | }; 221 | 222 | // This supports IE8 when document.domain is used 223 | // see https://github.com/es-shims/es5-shim/issues/150 224 | // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346 225 | var getEmptyViaActiveX = function getEmptyViaActiveX() { 226 | var empty; 227 | var xDoc; 228 | 229 | xDoc = new ActiveXObject('htmlfile'); 230 | 231 | xDoc.write(' 16 | 17 | 18 | 21 | 22 | 23 |
24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /test-npm.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 测试页面_fis3 base 6 | 7 | 8 | 9 | 10 |
11 |

测试页面

12 |
13 | 14 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 测试页面_fis3 base 6 | 7 | 8 | 9 | 10 |
11 |

测试页面

12 |
13 | 14 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/dynamic.js: -------------------------------------------------------------------------------- 1 | module.exports = function(req, res, next) { 2 | if (req['query']['yan'] == 123) { 3 | res.sendFile(__dirname + '/test.json', function(err) { 4 | if (err) { 5 | next(err); 6 | // res.status(err.status).end(); 7 | } 8 | // res.end(); 9 | }); 10 | } else { 11 | res.write('empty'); 12 | res.end(); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /test/server.conf: -------------------------------------------------------------------------------- 1 | rewrite ^\/api\/test$ /test/test.json 2 | 3 | rewrite ^\/api\/dynamic\/time$ /test/dynamic.js 4 | 5 | -------------------------------------------------------------------------------- /test/test.json: -------------------------------------------------------------------------------- 1 | { 2 | errno: 0 3 | } 4 | -------------------------------------------------------------------------------- /wap.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | wap_fis3 base 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 |
29 | 30 | 31 | 32 | 33 | 34 | --------------------------------------------------------------------------------