├── .eslintrc ├── .gitignore ├── .sass-lint.yml ├── .travis.yml ├── CHANGELOG.md ├── README.md ├── config ├── clean.config.js ├── copy.config.js ├── html.config.js ├── server.config.js ├── sprite.config.js ├── style.config.js ├── style.config.production.js ├── test.conf.js ├── webpack.config.js ├── webpack.config.production.js └── webpack.core.js ├── frp.config.js ├── index.js ├── lib ├── cmds │ ├── build.js │ ├── create.js │ ├── exe.js │ ├── serve.js │ ├── task.js │ └── test.js ├── frp.js ├── interaction.js ├── tasks │ ├── clean.js │ ├── copy.js │ ├── html.js │ ├── index.js │ ├── script.js │ ├── server.js │ ├── sprite.js │ ├── style.js │ └── test.js └── util │ ├── download.js │ ├── install.js │ ├── timer.js │ └── util.js ├── package.json ├── template └── sprite │ └── sprite.ejs ├── test ├── index.js ├── install.js ├── task │ ├── clean.js │ ├── copy.js │ ├── html.js │ ├── index.js │ ├── script.js │ ├── server.js │ ├── sprite.js │ ├── style.js │ └── test.js ├── timer.js └── util.js └── yarn.lock /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "mocha": true, 5 | "es6": true 6 | }, 7 | "parserOptions": { 8 | "sourceType": "module" 9 | }, 10 | "rules": { 11 | "comma-dangle": [1, "never"], 12 | "no-console": 1, 13 | "eol-last": 0, 14 | "block-scoped-var": 0, 15 | "complexity": 1, 16 | "consistent-return": 1, 17 | "default-case": 1, 18 | "eqeqeq": 1, 19 | "no-alert": 1, 20 | "no-caller": 1, 21 | "no-eval": 2, 22 | "no-new": 0, 23 | "no-new-func": 1, 24 | "no-proto": 2, 25 | "no-script-url": 1, 26 | "no-self-compare": 1, 27 | "no-void": 2, 28 | "no-var": 2, 29 | "camelcase": [2, {"properties": "always"}], 30 | "no-array-constructor": 1, 31 | "quotes": [0, "single"], 32 | "no-unused-vars": 1, 33 | "space-after-keywords": 0, 34 | "space-infix-ops": 0, 35 | "space-return-throw-case": 0, 36 | "comma-spacing": 0, 37 | "prefer-const": 0, 38 | "no-undef": 0, 39 | "curly": 0 40 | }, 41 | "ecmaFeatures": { 42 | "arrowFunctions": true, 43 | "binaryLiterals": true, 44 | "blockBindings": true, 45 | "classes": true, 46 | "defaultParams": true, 47 | "destructuring": true, 48 | "forOf": true, 49 | "generators": true, 50 | "modules": true, 51 | "objectLiteralComputedProperties": true, 52 | "objectLiteralDuplicateProperties": true, 53 | "objectLiteralShorthandMethods": true, 54 | "objectLiteralShorthandProperties": true, 55 | "octalLiterals": true, 56 | "regexUFlag": true, 57 | "regexYFlag": true, 58 | "restParams": true, 59 | "spread": true, 60 | "superInFunctions": true, 61 | "templateStrings": true, 62 | "unicodeCodePointEscapes": true, 63 | "globalReturn": true, 64 | "jsx": true 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | guide -------------------------------------------------------------------------------- /.sass-lint.yml: -------------------------------------------------------------------------------- 1 | # sass-lint config generated by make-sass-lint-config v0.0.3 2 | # 3 | # The following scss-lint Linters are not yet supported by sass-lint: 4 | # BemDepth, DisableLinterReason, ElsePlacement, PropertyCount 5 | # PropertyUnits, SelectorDepth, SelectorFormat, SpaceAroundOperator 6 | # TrailingWhitespace, UnnecessaryMantissa, UnnecessaryParentReference, Compass::* 7 | # 8 | # The following settings/values are unsupported by sass-lint: 9 | # Linter Indentation, option "allow_non_nested_indentation" 10 | # Linter Indentation, option "character" 11 | # Linter NestingDepth, option "ignore_parent_selectors" 12 | # Linter PropertySortOrder, option "ignore_unspecified" 13 | # Linter PropertySortOrder, option "min_properties" 14 | # Linter PropertySortOrder, option "separate_groups" 15 | # Linter SpaceBeforeBrace, option "allow_single_line_padding" 16 | # Linter VendorPrefix, option "identifier_list" 17 | 18 | files: 19 | include: 'src/sass/**/*.scss' 20 | ignore: 21 | - 'src/sass/base/_mixin.scss' 22 | - 'src/sass/base/_sanitize.scss' 23 | options: 24 | formatter: stylish 25 | merge-default-rules: false 26 | rules: 27 | border-zero: 28 | - 0 29 | - convention: zero 30 | brace-style: 31 | - 1 32 | - allow-single-line: true 33 | clean-import-paths: 34 | - 1 35 | - filename-extension: false 36 | leading-underscore: false 37 | empty-line-between-blocks: 38 | - 0 39 | - ignore-single-line-rulesets: true 40 | extends-before-declarations: 1 41 | extends-before-mixins: 1 42 | final-newline: 43 | - 0 44 | - include: true 45 | force-attribute-nesting: 1 46 | force-element-nesting: 1 47 | force-pseudo-nesting: 1 48 | function-name-format: 49 | - 0 50 | - allow-leading-underscore: true 51 | convention: hyphenatedbem 52 | hex-length: 53 | - 0 54 | - style: short 55 | hex-notation: 56 | - 0 57 | - style: lowercase 58 | indentation: 59 | - 0 60 | - size: 2 61 | leading-zero: 62 | - 0 63 | - include: false 64 | mixin-name-format: 65 | - 1 66 | - allow-leading-underscore: true 67 | convention: hyphenatedlowercase 68 | mixins-before-declarations: 0 69 | nesting-depth: 70 | - 1 71 | - max-depth: 3 72 | no-color-literals: 0 73 | no-css-comments: 0 74 | no-debug: 1 75 | no-duplicate-properties: 1 76 | no-empty-rulesets: 1 77 | no-extends: 0 78 | no-ids: 1 79 | no-important: 0 80 | no-invalid-hex: 1 81 | no-mergeable-selectors: 0 82 | no-misspelled-properties: 83 | - 1 84 | - extra-properties: ['*zoom'] 85 | no-qualifying-elements: 86 | - 1 87 | - allow-element-with-attribute: false 88 | allow-element-with-class: false 89 | allow-element-with-id: false 90 | no-trailing-zero: 0 91 | no-transition-all: 0 92 | no-url-protocols: 1 93 | no-vendor-prefixes: 94 | - 0 95 | - additional-identifiers: [] 96 | excluded-identifiers: [] 97 | placeholder-in-extend: 1 98 | placeholder-name-format: 99 | - 1 100 | - allow-leading-underscore: true 101 | convention: hyphenatedlowercase 102 | property-sort-order: 0 103 | quotes: 104 | - 0 105 | - style: double 106 | shorthand-values: 107 | - 1 108 | - allowed-shorthands: 109 | - 1 110 | - 2 111 | - 3 112 | single-line-per-selector: 0 113 | space-after-bang: 114 | - 0 115 | - include: false 116 | space-after-colon: 117 | - 0 118 | - include: true 119 | space-after-comma: 120 | - 0 121 | - include: true 122 | space-before-bang: 123 | - 0 124 | - include: true 125 | space-before-brace: 126 | - 0 127 | - include: true 128 | space-before-colon: 1 129 | space-between-parens: 130 | - 0 131 | - include: false 132 | trailing-semicolon: 1 133 | url-quotes: 0 134 | variable-for-property: 135 | - 0 136 | - properties: [] 137 | variable-name-format: 138 | - 0 139 | - allow-leading-underscore: true 140 | convention: hyphenatedlowercase 141 | zero-unit: 0 142 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - '7' 5 | - '6' 6 | - '5' 7 | script: 8 | - npm test 9 | notifications: 10 | slack: 11 | secure: U1Ta+5fq1Np5Vig6D2qte0jvrnzHJc2DpKpgJSZOd8LGP3FWZ/t1vTT7sepY6WzMETuen0BGtO56wlCE2qFBAQUPIC5rkH71wy2hFE3WGjOuNSB6Sqpf9mfK6XvEQJRi9UDVlSDFuBHAftrnit855IyUEL7aZZWsvhdYUS+j4DQ= 12 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ## [4.2.2](https://github.com/frontainer/frontplate-cli/compare/v4.2.1...v4.2.2) (2017-09-07) 3 | 4 | 5 | ### fix 6 | 7 | * cleanタスクで削除オプションを設定できるように ([c9b6c2733c298c237606e0825a476f3553b68d28](https://github.com/frontainer/frontplate-cli/commit/c9b6c2733c298c237606e0825a476f3553b68d28)) 8 | * node-sassのメモリリークによりビルドに失敗する #23 ([fc08e568cd97c43fd99612dc81fd289069a9a655](https://github.com/frontainer/frontplate-cli/commit/fc08e568cd97c43fd99612dc81fd289069a9a655)) 9 | 10 | 11 | 12 | 13 | ## [4.2.1](https://github.com/frontainer/frontplate-cli/compare/v4.2.0...v4.2.1) (2017-03-21) 14 | 15 | 16 | ### fix 17 | 18 | * スプライトイメージ生成のオプションが反映されない #21 ([56a282477a60502171a81cda1eac573f2fa558ab](https://github.com/frontainer/frontplate-cli/commit/56a282477a60502171a81cda1eac573f2fa558ab)) 19 | 20 | ### new 21 | 22 | * yarn.lockを追加 ([e486f2e08f865e5215b0e88cea3f5569e94ae67a](https://github.com/frontainer/frontplate-cli/commit/e486f2e08f865e5215b0e88cea3f5569e94ae67a)) 23 | 24 | 25 | 26 | 27 | # [4.2.0](https://github.com/frontainer/frontplate-cli/compare/v4.1.0...v4.2.0) (2017-01-10) 28 | 29 | 30 | ### fix 31 | 32 | * AutoPrefixerの対象ブラウザを`> 3% in JP`に ([620f262e625f1f8fc7e0f7beff8d6c11ce9916e5](https://github.com/frontainer/frontplate-cli/commit/620f262e625f1f8fc7e0f7beff8d6c11ce9916e5)) 33 | * e.formattedがないエラーがでることがある ([f91a243875303e5e05ce92d8ad5a29f83a2f9ea8](https://github.com/frontainer/frontplate-cli/commit/f91a243875303e5e05ce92d8ad5a29f83a2f9ea8)) 34 | 35 | ### new 36 | 37 | * jsビルドの結果を通知するように ([4f14a8cf41c781876134d4daf4ca32d65ccf2775](https://github.com/frontainer/frontplate-cli/commit/4f14a8cf41c781876134d4daf4ca32d65ccf2775)) 38 | 39 | ### test 40 | 41 | * CIでのテスト対象にversion7追加 ([29deecf8668f0f9083e951a319ed9b8d2d0b29df](https://github.com/frontainer/frontplate-cli/commit/29deecf8668f0f9083e951a319ed9b8d2d0b29df)) 42 | 43 | 44 | 45 | 46 | # [4.1.0](https://github.com/frontainer/frontplate-cli/compare/v4.0.0...v4.1.0) (2016-12-27) 47 | 48 | 49 | ### fix 50 | 51 | * HTMLの属性でvalなしを許容 ([2b073dd674d3fdac9f30cea7c3882810f4f22b3c](https://github.com/frontainer/frontplate-cli/commit/2b073dd674d3fdac9f30cea7c3882810f4f22b3c)) 52 | * sassのエラーメッセージが1行しか表示されない ([592ef1b4d615dfbdfbea060a83ddba43e12395ae](https://github.com/frontainer/frontplate-cli/commit/592ef1b4d615dfbdfbea060a83ddba43e12395ae)) 53 | * typo https://github.com/frontainer/frontplate-cli/pull/18 ([f4d64cf6cbb3d8effcf5b268b96caf81f37fbd29](https://github.com/frontainer/frontplate-cli/commit/f4d64cf6cbb3d8effcf5b268b96caf81f37fbd29)) 54 | * エラーが1行しか表示されない ([2cdb00a773c051774dea8b917387eb29a929e3aa](https://github.com/frontainer/frontplate-cli/commit/2cdb00a773c051774dea8b917387eb29a929e3aa)) 55 | * ファイルサイズが250KBを超えたときのwebpackのwarningを非表示 ([5b1be1ee392d1597266ce03b692cf07d776e60c7](https://github.com/frontainer/frontplate-cli/commit/5b1be1ee392d1597266ce03b692cf07d776e60c7)) 56 | * 未使用で呼び出しているパッケージを削除 ([d061b5fe07df9a741c2284c7b3bc6bfa10029ace](https://github.com/frontainer/frontplate-cli/commit/d061b5fe07df9a741c2284c7b3bc6bfa10029ace)) 57 | 58 | ### new 59 | 60 | * ejs出力時の拡張子を変更できるように ([07fe02db2953221a0f1958b654c5cc6068f37aae](https://github.com/frontainer/frontplate-cli/commit/07fe02db2953221a0f1958b654c5cc6068f37aae)) 61 | 62 | ### refactor 63 | 64 | * インデントをスペース2に統一 ([f6aa3561fbceb9da54e466bd0e749ce88e7abf9a](https://github.com/frontainer/frontplate-cli/commit/f6aa3561fbceb9da54e466bd0e749ce88e7abf9a)) 65 | 66 | 67 | 68 | 69 | # [4.0.0](https://github.com/frontainer/frontplate-cli/compare/v3.1.1...v4.0.0) (2016-12-10) 70 | 71 | 72 | ### add 73 | 74 | * `frp test` でユニットテストのみ実行できるコマンドを追加 ([0c259a9b6920b3a5342c2bc60ec435396bdd713f](https://github.com/frontainer/frontplate-cli/commit/0c259a9b6920b3a5342c2bc60ec435396bdd713f)) 75 | * 対話式コマンドにもtestを追加 ([4cbf4c69fa5e8448803096810ad209e0a094533c](https://github.com/frontainer/frontplate-cli/commit/4cbf4c69fa5e8448803096810ad209e0a094533c)) 76 | 77 | ### breaking 78 | 79 | * `frp build` の実行タスクからテストを削除 => `frp test` コマンドに分離 ([d1c086ce74ffea7f97ad7cee0060e8c470d6d073](https://github.com/frontainer/frontplate-cli/commit/d1c086ce74ffea7f97ad7cee0060e8c470d6d073)) 80 | 81 | 82 | 83 | 84 | ## [3.1.1](https://github.com/frontainer/frontplate-cli/compare/v3.1.0...v3.1.1) (2016-12-09) 85 | 86 | 87 | ### fix 88 | 89 | * ユニットテストのコンパイルエラー時のメッセージがわかりにくい #16 ([f545ea236854eeb586534c1910e0f263af3ce14b](https://github.com/frontainer/frontplate-cli/commit/f545ea236854eeb586534c1910e0f263af3ce14b)) 90 | 91 | 92 | 93 | 94 | # [3.1.0](https://github.com/frontainer/frontplate-cli/compare/v3.0.0...v3.1.0) (2016-12-07) 95 | 96 | 97 | ### new 98 | 99 | * frp exe でローカルにあるスクリプトをfrpプラグインとして実行できる機能 ([10427a03e9e60822d9280e11557cea5b76b899c7](https://github.com/frontainer/frontplate-cli/commit/10427a03e9e60822d9280e11557cea5b76b899c7)) 100 | 101 | 102 | 103 | 104 | # [3.0.0](https://github.com/frontainer/frontplate-cli/compare/v2.1.2...v3.0.0) (2016-12-06) 105 | 106 | 107 | ### breaking 108 | 109 | * 複数指定のglobで削除できるようにrimrafからdelに乗り換え ([e787d55e5bf6262d5fe7ef24a0415c663b9605d8](https://github.com/frontainer/frontplate-cli/commit/e787d55e5bf6262d5fe7ef24a0415c663b9605d8)) 110 | 111 | ### fix 112 | 113 | * babelコンパイルをすべてwebpackに集約 ([ca3c63d9c48de0b0f5b9673ba78db20050c4369b](https://github.com/frontainer/frontplate-cli/commit/ca3c63d9c48de0b0f5b9673ba78db20050c4369b)) 114 | * SASS3.3のmap_getなどがWarningになってしまう ([1459b8439279e9f105fae60ad4ca9e47f7ade6f1](https://github.com/frontainer/frontplate-cli/commit/1459b8439279e9f105fae60ad4ca9e47f7ade6f1)) 115 | * watch時の監視対象が多くメモリ使用量が多い #15 ([e5078a3fd806d1a34e484bc4fdea15bc36755b03](https://github.com/frontainer/frontplate-cli/commit/e5078a3fd806d1a34e484bc4fdea15bc36755b03)) 116 | * エラーメッセージを赤字表示に ([00f036c35d52991869d790873bf911a840ecddad](https://github.com/frontainer/frontplate-cli/commit/00f036c35d52991869d790873bf911a840ecddad)) 117 | 118 | ### new 119 | 120 | * Retina対応したSpriteを生成できるように #13 ([e89c3a8d975a74421c879753669f4d7322ced11e](https://github.com/frontainer/frontplate-cli/commit/e89c3a8d975a74421c879753669f4d7322ced11e)) 121 | 122 | 123 | 124 | 125 | ## [2.1.2](https://github.com/frontainer/frontplate-cli/compare/v2.1.1...v2.1.2) (2016-11-25) 126 | 127 | 128 | ### fix 129 | 130 | * processの終了検知がserveタスク以外でも実行されてしまう ([00751fefdc1106a1101216caf20b09618237ac47](https://github.com/frontainer/frontplate-cli/commit/00751fefdc1106a1101216caf20b09618237ac47)) 131 | 132 | 133 | 134 | 135 | ## [2.1.1](https://github.com/frontainer/frontplate-cli/compare/v2.1.0...v2.1.1) (2016-11-25) 136 | 137 | 138 | ### fix 139 | 140 | * karmaのconfigを最新版の設定ファイルに更新 ([7be8ef83f1bd3b9e95af3af8e5207d76ba1226fa](https://github.com/frontainer/frontplate-cli/commit/7be8ef83f1bd3b9e95af3af8e5207d76ba1226fa)) 141 | * プロセスが正しく終了しないことがある ([1fe135e71dbaedc6ea30334c1cabbf05d3cee0b9](https://github.com/frontainer/frontplate-cli/commit/1fe135e71dbaedc6ea30334c1cabbf05d3cee0b9)) 142 | 143 | 144 | 145 | 146 | # [2.1.0](https://github.com/frontainer/frontplate-cli/compare/v2.0.9...v2.1.0) (2016-11-23) 147 | 148 | 149 | ### fix 150 | 151 | * copyタスク監視実行時にブラウザが更新されないことがある ([31bf8246e7eec936a80c1e3468071177fad92bad](https://github.com/frontainer/frontplate-cli/commit/31bf8246e7eec936a80c1e3468071177fad92bad)) 152 | * webpackのpublicPathのデフォルト間違い ([28e92c0422c98e5dc9addaa13acdcea48029c2df](https://github.com/frontainer/frontplate-cli/commit/28e92c0422c98e5dc9addaa13acdcea48029c2df)) 153 | * デフォルトのejs監視対象をsvg,htmlも含めるように ([58aaac218367a9780cbb93cc5af32f33e3eb3b51](https://github.com/frontainer/frontplate-cli/commit/58aaac218367a9780cbb93cc5af32f33e3eb3b51)) 154 | 155 | 156 | 157 | 158 | ## [2.0.9](https://github.com/frontainer/frontplate-cli/compare/v2.0.8...v2.0.9) (2016-11-21) 159 | 160 | 161 | ### new 162 | 163 | * cleanタスクのsrcがnull/falseの場合は処理をスキップできるように ([ccf2a49547ad772d074366e880e70735e6c7f859](https://github.com/frontainer/frontplate-cli/commit/ccf2a49547ad772d074366e880e70735e6c7f859)) 164 | 165 | 166 | 167 | 168 | ## [2.0.8](https://github.com/frontainer/frontplate-cli/compare/v2.0.7...v2.0.8) (2016-11-20) 169 | 170 | 171 | ### fix 172 | 173 | * ejsのデフォルト参照をFRP_SRC直下から参照するように ([51f68e92e5397c7c7230bc1cc033e29a5effddc1](https://github.com/frontainer/frontplate-cli/commit/51f68e92e5397c7c7230bc1cc033e29a5effddc1)) 174 | 175 | ### new 176 | 177 | * スタイルガイドを生成しないオプション ([1699cd85eb227b8e78226abc35bb2f6646edca4a](https://github.com/frontainer/frontplate-cli/commit/1699cd85eb227b8e78226abc35bb2f6646edca4a)) 178 | 179 | 180 | 181 | 182 | ## [2.0.7](https://github.com/frontainer/frontplate-cli/compare/v2.0.6...v2.0.7) (2016-11-14) 183 | 184 | 185 | ### fix 186 | 187 | * src/jsディレクトリにパスが通っていなかったのを修正 ([f78783a2a385d35a8ac7a2ed8487a504ee5615d6](https://github.com/frontainer/frontplate-cli/commit/f78783a2a385d35a8ac7a2ed8487a504ee5615d6)) 188 | * webpack2.1.0-beta.26でloader指定で-loaderを省略するとbabelコンパイルできない ([58bd92d9506caadd3179a7c27b1934852259115c](https://github.com/frontainer/frontplate-cli/commit/58bd92d9506caadd3179a7c27b1934852259115c)) 189 | 190 | 191 | 192 | 193 | ## [2.0.6](https://github.com/frontainer/frontplate-cli/compare/v2.0.5...v2.0.6) (2016-11-11) 194 | 195 | 196 | ### fix 197 | 198 | * frp create コマンドでpresetが効かない ([c8f3fc6084b8ac5b00c97b2d372829be1f71b36b](https://github.com/frontainer/frontplate-cli/commit/c8f3fc6084b8ac5b00c97b2d372829be1f71b36b)) 199 | 200 | 201 | 202 | 203 | ## [2.0.5](https://github.com/frontainer/frontplate-cli/compare/v2.0.4...v2.0.5) (2016-11-11) 204 | 205 | 206 | ### add 207 | 208 | * sassのimportでの'~'記法をサポート ([4be0f708631a609cedb4b9bd3bdcda924adbcac7](https://github.com/frontainer/frontplate-cli/commit/4be0f708631a609cedb4b9bd3bdcda924adbcac7)) 209 | 210 | 211 | 212 | 213 | ## [2.0.4](https://github.com/frontainer/frontplate-cli/compare/v2.0.3...v2.0.4) (2016-11-09) 214 | 215 | 216 | ### fix 217 | 218 | * scssがエラーになった際にエラーの内容が表示されない ([1924494b0fc059e7505cbebe4ba3c39077181d72](https://github.com/frontainer/frontplate-cli/commit/1924494b0fc059e7505cbebe4ba3c39077181d72)) 219 | * webpack-configでresolve,resolveLoaderを変更している場合にjsエラーが発生する可能性がある ([cd8d4fa0c1df1c4d9da8139bf561b33ef78ee5d4](https://github.com/frontainer/frontplate-cli/commit/cd8d4fa0c1df1c4d9da8139bf561b33ef78ee5d4)) 220 | 221 | 222 | 223 | 224 | ## [2.0.3](https://github.com/frontainer/frontplate-cli/compare/v2.0.2...v2.0.3) (2016-11-08) 225 | 226 | 227 | ### fix 228 | 229 | * CLIで動的に生成していたscriptのモジュール読み込み先を設定ファイルに記述することで統一 ([402ce1f1142a1aff88914bc7b67617835e53d2aa](https://github.com/frontainer/frontplate-cli/commit/402ce1f1142a1aff88914bc7b67617835e53d2aa)) 230 | * GAなどのスクリプトを頻繁に入れることがあるため、"head-script-disabled"をチェックしないように ([f4b41c09469148c664c194bb3b77cefc280177a0](https://github.com/frontainer/frontplate-cli/commit/f4b41c09469148c664c194bb3b77cefc280177a0)) 231 | * ユニットテストでwebpackの設定が反映されずカスタマイズするとビルドできなくなる ([5c3f94001866427f7231146f1401972f1cebb7e7](https://github.com/frontainer/frontplate-cli/commit/5c3f94001866427f7231146f1401972f1cebb7e7)) 232 | 233 | 234 | 235 | 236 | ## [2.0.2](https://github.com/frontainer/frontplate-cli/compare/v2.0.1...v2.0.2) (2016-11-07) 237 | 238 | 239 | ### fix 240 | 241 | * eslintの設定をES6モジュールをサポートするように ([4c632727f030af0f6dedc7f9252e9834a5828979](https://github.com/frontainer/frontplate-cli/commit/4c632727f030af0f6dedc7f9252e9834a5828979)) 242 | 243 | 244 | 245 | 246 | ## [2.0.1](https://github.com/frontainer/frontplate-cli/compare/v2.0.0...v2.0.1) (2016-11-04) 247 | 248 | 249 | ### fix 250 | 251 | * babel-eslintは不要になっているので削除 ([01332fc0819a04dde87193f36f8562a10975835e](https://github.com/frontainer/frontplate-cli/commit/01332fc0819a04dde87193f36f8562a10975835e)) 252 | * frpコマンドの対話でcreateできない ([002c702bf93ee7fe2bc4d8e2890c2186246a68ed](https://github.com/frontainer/frontplate-cli/commit/002c702bf93ee7fe2bc4d8e2890c2186246a68ed)) 253 | 254 | 255 | 256 | 257 | # [2.0.0](https://github.com/frontainer/frontplate-cli/compare/v1.7.1...v2.0.0) (2016-11-03) 258 | 259 | 260 | ### breaking 261 | 262 | * frp initコマンドは影響が大きくアップデートを阻害するので削除 ([3f4fe2f6bd70beebe5ac65744ce27181f29d1049](https://github.com/frontainer/frontplate-cli/commit/3f4fe2f6bd70beebe5ac65744ce27181f29d1049)) 263 | 264 | ### fix 265 | 266 | * `frp build` cannot automatically load local .eslintrc #8 ([5d91a6fd5d01cbdb91228cf42709f2973c5d5a2d](https://github.com/frontainer/frontplate-cli/commit/5d91a6fd5d01cbdb91228cf42709f2973c5d5a2d)) 267 | 268 | ### new 269 | 270 | * configからビルドソースのディレクトリを指定できるように ([d63c567955fbdf3734041268b91ea0afa8971434](https://github.com/frontainer/frontplate-cli/commit/d63c567955fbdf3734041268b91ea0afa8971434)) 271 | * frp単体で対話式にコマンド実行できる機能 ([d39c9012648a3bf1bda6d6b5fc0611ffe66a966d](https://github.com/frontainer/frontplate-cli/commit/d39c9012648a3bf1bda6d6b5fc0611ffe66a966d)) 272 | 273 | ### refactor 274 | 275 | * フォルダを整理してCLIヘルパーをcommanderからyargsに乗せ換え ([62fa05dac809c3968a0b766ddebc1561263bc995](https://github.com/frontainer/frontplate-cli/commit/62fa05dac809c3968a0b766ddebc1561263bc995)) 276 | 277 | 278 | 279 | 280 | ## [1.7.1](https://github.com/frontainer/frontplate-cli/compare/v1.7.0...v1.7.1) (2016-11-01) 281 | 282 | 283 | ### fix 284 | 285 | * ローカルに導入したeslintプラグインが参照できない ([9a9c1bc92584ff265f25537160658ca7976ab359](https://github.com/frontainer/frontplate-cli/commit/9a9c1bc92584ff265f25537160658ca7976ab359)) 286 | 287 | 288 | 289 | 290 | # [1.7.0](https://github.com/frontainer/frontplate-cli/compare/v1.6.0...v1.7.0) (2016-10-30) 291 | 292 | 293 | ### breaking 294 | 295 | * closure-cmpiler-jsはAngular他ライブラリとの互換性が今のところ不安定なのでUglifyに差し戻し ([3b06bf1aa584fd9f549c14d0bfd7d67375505d0f](https://github.com/frontainer/frontplate-cli/commit/3b06bf1aa584fd9f549c14d0bfd7d67375505d0f)) 296 | 297 | ### fix 298 | 299 | * webpack2に合わせてmodule.loadersからmodule.rulesに修正 ([2ed03906b6ecf1d76dff377ed0e020dce7afdf63](https://github.com/frontainer/frontplate-cli/commit/2ed03906b6ecf1d76dff377ed0e020dce7afdf63)) 300 | * スタイルガイド生成によってsass変更時もブラウザフル更新されるのを修正 ([3e8eb48dae25059bb6e8efd4b1845cf1e360cd3e](https://github.com/frontainer/frontplate-cli/commit/3e8eb48dae25059bb6e8efd4b1845cf1e360cd3e)) 301 | 302 | ### update 303 | 304 | * eslint package ([81c02b01cc73d5dbbf472a4da02d1339c8071d54](https://github.com/frontainer/frontplate-cli/commit/81c02b01cc73d5dbbf472a4da02d1339c8071d54)) 305 | 306 | 307 | 308 | 309 | # [1.6.0](https://github.com/frontainer/frontplate-cli/compare/v1.5.0...v1.6.0) (2016-10-27) 310 | 311 | 312 | ### breaking 313 | 314 | * configの継承は行わず、第2階層以降は置き換えるよう変更 ([219f9f3e08859af1e8fb6dec69bdfe6d90622213](https://github.com/frontainer/frontplate-cli/commit/219f9f3e08859af1e8fb6dec69bdfe6d90622213)) 315 | 316 | ### fix 317 | 318 | * sprite config ([20f2a5d509a0e0ae50f49de6e863b11ffeee57b1](https://github.com/frontainer/frontplate-cli/commit/20f2a5d509a0e0ae50f49de6e863b11ffeee57b1)) 319 | * オプションがきちんと継承できていない ([05ce7be04aee852631f2ec1e658d8c58d284f6ed](https://github.com/frontainer/frontplate-cli/commit/05ce7be04aee852631f2ec1e658d8c58d284f6ed)) 320 | 321 | 322 | 323 | 324 | # [1.5.0](https://github.com/frontainer/frontplate-cli/compare/v1.4.0...v1.5.0) (2016-10-27) 325 | 326 | 327 | ### breaking 328 | 329 | * cleanタスクの設定もconfig外部ファイル化 ([035bbe3abc587033160ef15f166e1d556ca2bd76](https://github.com/frontainer/frontplate-cli/commit/035bbe3abc587033160ef15f166e1d556ca2bd76)) 330 | * frp initの仕様変更 - config全部展開ではなくfrp.config.jsのテンプレとlint設定ファイルだけを出力するように ([35589edfebded64d7709b5b0cbcb2c56662684a1](https://github.com/frontainer/frontplate-cli/commit/35589edfebded64d7709b5b0cbcb2c56662684a1)) 331 | 332 | 333 | 334 | 335 | # [1.4.0](https://github.com/frontainer/frontplate-cli/compare/v1.3.1...v1.4.0) (2016-10-27) 336 | 337 | 338 | ### breaking 339 | 340 | * chrom-launcherからphantomjs-launcherに変更 ([5eb027b5c6ca8639965f48176d794a7a36a0da9e](https://github.com/frontainer/frontplate-cli/commit/5eb027b5c6ca8639965f48176d794a7a36a0da9e)) 341 | * test関連の設定ファイルを通常のオブジェクトに変更 ([c94a559bc000b7d2b4f7fc94ec2a27899c0f6315](https://github.com/frontainer/frontplate-cli/commit/c94a559bc000b7d2b4f7fc94ec2a27899c0f6315)) 342 | 343 | ### fix 344 | 345 | * indentと0 unitは軽微なためsass lintしない ([c5d2806c9cb5f25a282e23174f37494dea67855b](https://github.com/frontainer/frontplate-cli/commit/c5d2806c9cb5f25a282e23174f37494dea67855b)) 346 | * svgを多用するとwarningが出るのでデフォルトのattr-lowercaseをオフに ([7d1fcb317f462cb5e600c9e4c8cf7d5cf31392ef](https://github.com/frontainer/frontplate-cli/commit/7d1fcb317f462cb5e600c9e4c8cf7d5cf31392ef)) 347 | 348 | 349 | 350 | 351 | ## [1.3.1](https://github.com/frontainer/frontplate-cli/compare/v1.3.0...v1.3.1) (2016-10-27) 352 | 353 | 354 | ### fix 355 | 356 | * serveコマンドが動作しない ([7b0c1ea308d63644b45d3b34def7534175ed78c5](https://github.com/frontainer/frontplate-cli/commit/7b0c1ea308d63644b45d3b34def7534175ed78c5)) 357 | 358 | 359 | 360 | 361 | # [1.3.0](https://github.com/frontainer/frontplate-cli/compare/v1.2.3...v1.3.0) (2016-10-26) 362 | 363 | 364 | ### breaking 365 | 366 | * 画像圧縮タスクが環境依存が激しいため削除 ([a87885a86579e8e49e45ec9e354323aef1823beb](https://github.com/frontainer/frontplate-cli/commit/a87885a86579e8e49e45ec9e354323aef1823beb)) 367 | 368 | 369 | 370 | 371 | ## [1.2.3](https://github.com/frontainer/frontplate-cli/compare/v1.2.2...v1.2.3) (2016-10-26) 372 | 373 | 374 | ### add 375 | 376 | * frp initしたタイミングでconfigで使われているパッケージをローカルインストールするように ([348391067a045d06ac82dec0949c94fdc33449a5](https://github.com/frontainer/frontplate-cli/commit/348391067a045d06ac82dec0949c94fdc33449a5)) 377 | * packageを指定したnpm installが実行できるように ([772077f5778b6b0c56623f58549090b18b00ef7b](https://github.com/frontainer/frontplate-cli/commit/772077f5778b6b0c56623f58549090b18b00ef7b)) 378 | 379 | 380 | 381 | 382 | ## [1.2.2](https://github.com/frontainer/frontplate-cli/compare/v1.2.1...v1.2.2) (2016-10-25) 383 | 384 | 385 | ### fix 386 | 387 | * htmlhintの設定が反映されていない #6 ([e7dfdf74fdc36541dce204c54067bcbd3be93278](https://github.com/frontainer/frontplate-cli/commit/e7dfdf74fdc36541dce204c54067bcbd3be93278)) 388 | 389 | 390 | 391 | 392 | ## [1.2.1](https://github.com/frontainer/frontplate-cli/compare/v1.2.0...v1.2.1) (2016-10-25) 393 | 394 | 395 | ### fix 396 | 397 | * imagemin-imozjpegをimagemin-jpegoptimに変更 ([86e69d72103926c90f43286d6eef21045c791c9c](https://github.com/frontainer/frontplate-cli/commit/86e69d72103926c90f43286d6eef21045c791c9c)) 398 | 399 | 400 | 401 | 402 | # [1.2.0](https://github.com/frontainer/frontplate-cli/compare/v1.1.5...v1.2.0) (2016-10-19) 403 | 404 | 405 | ### add 406 | 407 | * frp createコマンドに -y,--yarn オプションを追加。 npm installの代わりにyarn installを実行する ([b1463c244a7e9cfbbf96b33d2802cfadd5554561](https://github.com/frontainer/frontplate-cli/commit/b1463c244a7e9cfbbf96b33d2802cfadd5554561)) 408 | 409 | ### break 410 | 411 | * core.configが指定として複雑になっていたのでグローバル変数FRP_DESTで定義 ([0aa50d697dc9328e318239378a558b505daa9ef5](https://github.com/frontainer/frontplate-cli/commit/0aa50d697dc9328e318239378a558b505daa9ef5)) 412 | 413 | 414 | 415 | 416 | ## [1.1.5](https://github.com/frontainer/frontplate-cli/compare/v1.1.4...v1.1.5) (2016-10-12) 417 | 418 | 419 | ### fix 420 | 421 | * frpをグローバルにインストールした後、npm -g listするとエラーが出ている #3 ([2e2d5863cc1d49c98349e93d55ac53a34aa13488](https://github.com/frontainer/frontplate-cli/commit/2e2d5863cc1d49c98349e93d55ac53a34aa13488)) 422 | * imageminで画像が圧縮できていない ([c24aa60baf55d07f9f9a4bcf19414761ed556dd0](https://github.com/frontainer/frontplate-cli/commit/c24aa60baf55d07f9f9a4bcf19414761ed556dd0)) 423 | 424 | 425 | 426 | 427 | ## [1.1.4](https://github.com/frontainer/frontplate-cli/compare/v1.1.3...v1.1.4) (2016-10-11) 428 | 429 | 430 | ### fix 431 | 432 | * imageタスクで階層構造が維持されない ([a3e389bf2f436acc6f99bf33d1cdfd1d84b8e25c](https://github.com/frontainer/frontplate-cli/commit/a3e389bf2f436acc6f99bf33d1cdfd1d84b8e25c)) 433 | * 配列0件に対するレスポンスをシンプルなRx.Observable.of([])に変更 ([de09e1e90ac8cf148b29f100d63302251f443ef1](https://github.com/frontainer/frontplate-cli/commit/de09e1e90ac8cf148b29f100d63302251f443ef1)) 434 | 435 | 436 | 437 | 438 | ## [1.1.3](https://github.com/frontainer/frontplate-cli/compare/v1.1.2...v1.1.3) (2016-10-10) 439 | 440 | 441 | ### fix 442 | 443 | * ユニットテスト用のファイル名を*-spec.jsではなく*spec.jsに ([eaf58d650582f74837b25ee9bc67a3ba0ac11a40](https://github.com/frontainer/frontplate-cli/commit/eaf58d650582f74837b25ee9bc67a3ba0ac11a40)) 444 | 445 | 446 | 447 | 448 | ## [1.1.2](https://github.com/frontainer/frontplate-cli/compare/v1.1.1...v1.1.2) (2016-10-10) 449 | 450 | 451 | ### fix 452 | 453 | * babelrcの設定が反映されていない ([8a14f66317bfc89a99c5013a312841bac199637c](https://github.com/frontainer/frontplate-cli/commit/8a14f66317bfc89a99c5013a312841bac199637c)) 454 | * BrowserSyncのproxyプロパティが指定できない ([a04188b416d92b64df2c7b3ef440680a051ac95f](https://github.com/frontainer/frontplate-cli/commit/a04188b416d92b64df2c7b3ef440680a051ac95f)) 455 | * merge後のユニットテスト結果が一致していない ([ac24a305d0ba824b7a3952fe6f9296dc816339d0](https://github.com/frontainer/frontplate-cli/commit/ac24a305d0ba824b7a3952fe6f9296dc816339d0)) 456 | 457 | 458 | 459 | 460 | # [1.1.0](https://github.com/frontainer/frontplate-cli/compare/v1.0.2...v1.1.0) (2016-10-10) 461 | 462 | 463 | ### feat 464 | 465 | * 差分で設定を変更できるように ([b44380658885d7871d5c6f752bc6dd79fb2ecdb6](https://github.com/frontainer/frontplate-cli/commit/b44380658885d7871d5c6f752bc6dd79fb2ecdb6)) 466 | 467 | 468 | 469 | 470 | ## [1.0.2](https://github.com/frontainer/frontplate-cli/compare/v1.0.1...v1.0.2) (2016-10-09) 471 | 472 | 473 | ### fix 474 | 475 | * frp create --branchオプションを使うとエラーになる ([7d4e80cf96979d898188db3d949f07a6af7cbcea](https://github.com/frontainer/frontplate-cli/commit/7d4e80cf96979d898188db3d949f07a6af7cbcea)) 476 | 477 | 478 | 479 | 480 | ## [1.0.1](https://github.com/frontainer/frontplate-cli/compare/v1.0.0...v1.0.1) (2016-10-09) 481 | 482 | 483 | 484 | 485 | 486 | # [1.0.0](https://github.com/frontainer/frontplate-cli/compare/v0.3.2...v1.0.0) (2016-10-09) 487 | 488 | 489 | ### feat 490 | 491 | * versionが表記されたテキストを出力 ([12f8c460ac818025e109ce1ac65fcf6dd877edce](https://github.com/frontainer/frontplate-cli/commit/12f8c460ac818025e109ce1ac65fcf6dd877edce)) 492 | * 指定ブランチからプロジェクトを生成できるようにfrp createに-b --branchオプションを追加 ([a0c5c993840a6ecf4105b76c5ef344d0a4141693](https://github.com/frontainer/frontplate-cli/commit/a0c5c993840a6ecf4105b76c5ef344d0a4141693)) 493 | 494 | 495 | 496 | 497 | ## [0.3.2](https://github.com/frontainer/frontplate-cli/compare/v0.3.1...v0.3.2) (2016-10-08) 498 | 499 | 500 | ### feat 501 | 502 | * production時にcssもsourcemapなしの最適化した形で出力 ([a0c97ab52dc3e052dd8914908679d72de3a8f421](https://github.com/frontainer/frontplate-cli/commit/a0c97ab52dc3e052dd8914908679d72de3a8f421)) 503 | 504 | 505 | 506 | 507 | ## [0.3.1](https://github.com/frontainer/frontplate-cli/compare/v0.3.0...v0.3.1) (2016-10-08) 508 | 509 | 510 | ### temp 511 | 512 | * テンプレートダウンロード先をdevelopブランチに ([a533fc3d7f4b3b2dd599b35a6d2c9a8149b7e0cb](https://github.com/frontainer/frontplate-cli/commit/a533fc3d7f4b3b2dd599b35a6d2c9a8149b7e0cb)) 513 | 514 | 515 | 516 | 517 | # [0.3.0](https://github.com/frontainer/frontplate-cli/compare/v0.2.4...v0.3.0) (2016-10-08) 518 | 519 | 520 | ### feat 521 | 522 | * 1つのビューテンプレートから複数HTMLを出力 ([8cea58c58b26d04e6e3531e99937e25f8d35650f](https://github.com/frontainer/frontplate-cli/commit/8cea58c58b26d04e6e3531e99937e25f8d35650f)) 523 | * スタイルガイド生成にfrontnote追加 ([ce2919960fa13bbc2a85159cd0fade0f4170e752](https://github.com/frontainer/frontplate-cli/commit/ce2919960fa13bbc2a85159cd0fade0f4170e752)) 524 | 525 | 526 | 527 | 528 | ## [0.2.4](https://github.com/frontainer/frontplate-cli/compare/v0.2.3...v0.2.4) (2016-10-06) 529 | 530 | 531 | ### feat 532 | 533 | * basePathを一括で変更できるようにcore.config.jsを追加 ([07010ab0d6a9e665c401b6e4e7d10396cb9a98ac](https://github.com/frontainer/frontplate-cli/commit/07010ab0d6a9e665c401b6e4e7d10396cb9a98ac)) 534 | 535 | 536 | 537 | 538 | ## [0.2.3](https://github.com/frontainer/frontplate-cli/compare/v0.2.2...v0.2.3) (2016-10-06) 539 | 540 | 541 | ### fix 542 | 543 | * -spec.js内でimportできない ([ff8fd29f3d786d1815156de541b89126f258d031](https://github.com/frontainer/frontplate-cli/commit/ff8fd29f3d786d1815156de541b89126f258d031)) 544 | 545 | 546 | 547 | 548 | ## [0.2.2](https://github.com/frontainer/frontplate-cli/compare/v0.2.1...v0.2.2) (2016-10-06) 549 | 550 | 551 | ### fix 552 | 553 | * styleとimageのwatchタスクがエラーになる ([09d9ba3c3f7c6975ba6dda3e339d8a9b033d638c](https://github.com/frontainer/frontplate-cli/commit/09d9ba3c3f7c6975ba6dda3e339d8a9b033d638c)) 554 | 555 | 556 | 557 | 558 | ## [0.2.1](https://github.com/frontainer/frontplate-cli/compare/v0.2.0...v0.2.1) (2016-10-06) 559 | 560 | 561 | ### fix 562 | 563 | * テストに失敗してもSucceededが表示されている ([18bb924b9e379e791cba5676847db6d7895b8b3d](https://github.com/frontainer/frontplate-cli/commit/18bb924b9e379e791cba5676847db6d7895b8b3d)) 564 | 565 | 566 | 567 | 568 | # [0.2.0](https://github.com/frontainer/frontplate-cli/compare/v0.1.8...v0.2.0) (2016-10-06) 569 | 570 | 571 | ### breaking 572 | 573 | * babel関連の設定をwebpack.configから.babelrcへ ([a599fb14b0d90a2432a887362dd2b2ca6f93d5a5](https://github.com/frontainer/frontplate-cli/commit/a599fb14b0d90a2432a887362dd2b2ca6f93d5a5)) 574 | * mocha + power-assertからjasmineに ([f77e11987d9f6f4c780f8f8977688063d812c665](https://github.com/frontainer/frontplate-cli/commit/f77e11987d9f6f4c780f8f8977688063d812c665)) 575 | * webpack2用に設定をマイグレーション ([bd03e0d62844023d2dd33f4cab0727048411c8b8](https://github.com/frontainer/frontplate-cli/commit/bd03e0d62844023d2dd33f4cab0727048411c8b8)) 576 | 577 | ### feat 578 | 579 | * production build時にwebpack.optimize.AggressiveSplittingPluginを実行 ([29308a8269595e0a627b6cdd20ad8bc609f855b6](https://github.com/frontainer/frontplate-cli/commit/29308a8269595e0a627b6cdd20ad8bc609f855b6)) 580 | 581 | ### fix 582 | 583 | * entryが空だとエラーになる ([bb13f1efb3328de74e4d89eb9c99156a47ce7bb1](https://github.com/frontainer/frontplate-cli/commit/bb13f1efb3328de74e4d89eb9c99156a47ce7bb1)) 584 | 585 | 586 | 587 | 588 | ## [0.1.8](https://github.com/frontainer/frontplate-cli/compare/v0.1.7...v0.1.8) (2016-10-03) 589 | 590 | 591 | ### doc 592 | 593 | * add comments ([15ab64eb8e5a9653a37ca1e29b9350a162d30d4d](https://github.com/frontainer/frontplate-cli/commit/15ab64eb8e5a9653a37ca1e29b9350a162d30d4d)) 594 | 595 | 596 | 597 | 598 | ## [0.1.7](https://github.com/frontainer/frontplate-cli/compare/v0.1.6...v0.1.7) (2016-10-02) 599 | 600 | 601 | ### fix 602 | 603 | * scriptパス間違い ([52f241874eabb3468da70e08e8d77237a81c625c](https://github.com/frontainer/frontplate-cli/commit/52f241874eabb3468da70e08e8d77237a81c625c)) 604 | 605 | 606 | 607 | 608 | ## [0.1.6](https://github.com/frontainer/frontplate-cli/compare/v0.1.5...v0.1.6) (2016-10-02) 609 | 610 | 611 | ### fix 612 | 613 | * ローカルにインストールされたスクリプトを呼ぶと処理位置がわからなくなるので廃止 ([910f89d684ac35edd0904a5cf5a159c9f9f8e1b5](https://github.com/frontainer/frontplate-cli/commit/910f89d684ac35edd0904a5cf5a159c9f9f8e1b5)) 614 | 615 | 616 | 617 | 618 | ## [0.1.5](https://github.com/frontainer/frontplate-cli/compare/v0.1.4...v0.1.5) (2016-10-02) 619 | 620 | 621 | ### feat 622 | 623 | * ダウンロードしたファイルのpackage.jsonにfrpプロパティがある場合に続けて依存ファイルをダウンロードする機能 ([d6464be1ecbb7c5a087a12d5f91e82b60b7c9496](https://github.com/frontainer/frontplate-cli/commit/d6464be1ecbb7c5a087a12d5f91e82b60b7c9496)) 624 | 625 | ### fix 626 | 627 | * configの引数がオプションになってしまっている ([64713370f01252d8c756c61a5755ce6259d1e716](https://github.com/frontainer/frontplate-cli/commit/64713370f01252d8c756c61a5755ce6259d1e716)) 628 | 629 | 630 | 631 | 632 | ## [0.1.4](https://github.com/frontainer/frontplate-cli/compare/v0.1.3...v0.1.4) (2016-10-01) 633 | 634 | 635 | ### feat 636 | 637 | * update packages ([81470504c94455ada8d481e3cf2335860181173f](https://github.com/frontainer/frontplate-cli/commit/81470504c94455ada8d481e3cf2335860181173f)) 638 | 639 | 640 | 641 | 642 | ## [0.1.3](https://github.com/frontainer/frontplate-cli/compare/v0.1.2...v0.1.3) (2016-10-01) 643 | 644 | 645 | ### fix 646 | 647 | * scss更新後に正しくビルドされない ([a811d05d292a7b47602978d1ad2956385567bd0e](https://github.com/frontainer/frontplate-cli/commit/a811d05d292a7b47602978d1ad2956385567bd0e)) 648 | 649 | 650 | 651 | 652 | ## [0.1.2](https://github.com/frontainer/frontplate-cli/compare/v0.1.1...v0.1.2) (2016-10-01) 653 | 654 | 655 | ### fix 656 | 657 | * globですべてmain.jsになってしまったので差し戻し ([de8c73f749b478a63beeb257fd5e1964cc97b555](https://github.com/frontainer/frontplate-cli/commit/de8c73f749b478a63beeb257fd5e1964cc97b555)) 658 | 659 | 660 | 661 | 662 | ## [0.1.1](https://github.com/frontainer/frontplate-cli/compare/v0.1.0...v0.1.1) (2016-09-30) 663 | 664 | 665 | ### feat 666 | 667 | * ./src/jsをrootパスに ([5482c9ba8951583ce2c4680e49b02fba543cab1d](https://github.com/frontainer/frontplate-cli/commit/5482c9ba8951583ce2c4680e49b02fba543cab1d)) 668 | 669 | ### fix 670 | 671 | * ビルドするjsを./src/js/xxxx.js(-spec.jsは除く)に修正 ([824855c9bd633eddde3231588b6fb4730d12a3fe](https://github.com/frontainer/frontplate-cli/commit/824855c9bd633eddde3231588b6fb4730d12a3fe)) 672 | 673 | 674 | 675 | 676 | # [0.1.0](https://github.com/frontainer/frontplate-cli/compare/v0.0.12...v0.1.0) (2016-09-29) 677 | 678 | 679 | ### fix 680 | 681 | * frp createに失敗する ([162b6e532431d9863067173a5c4e5ef77b026221](https://github.com/frontainer/frontplate-cli/commit/162b6e532431d9863067173a5c4e5ef77b026221)) 682 | 683 | 684 | 685 | 686 | ## [0.0.12](https://github.com/frontainer/frontplate-cli/compare/v0.0.11...v0.0.12) (2016-09-29) 687 | 688 | 689 | ### doc 690 | 691 | * task command追加 & 不要になった記述を削除 ([282d29bb1c5c3a57e329833f199a66ee29b880fa](https://github.com/frontainer/frontplate-cli/commit/282d29bb1c5c3a57e329833f199a66ee29b880fa)) 692 | 693 | ### feat 694 | 695 | * add changelog ([93f362966e0702d3cde353ea6b2cbd3d96f46c8d](https://github.com/frontainer/frontplate-cli/commit/93f362966e0702d3cde353ea6b2cbd3d96f46c8d)) 696 | * add unit testing ([abbf8c36068f6e4ea33b88349a210da464fd4975](https://github.com/frontainer/frontplate-cli/commit/abbf8c36068f6e4ea33b88349a210da464fd4975)) 697 | 698 | ### fix 699 | 700 | * configに引数統一できていない ([7796b3a763132c6283315465cabb42f1c39caa40](https://github.com/frontainer/frontplate-cli/commit/7796b3a763132c6283315465cabb42f1c39caa40)) 701 | 702 | 703 | 704 | 705 | ## [0.0.11](https://github.com/frontainer/frontplate-cli/compare/v0.0.10...v0.0.11) (2016-09-28) 706 | 707 | 708 | ### feat 709 | 710 | * 個別にタスクを実行できるtask コマンドを追加 ([be5e59e1340b64799ac1a5d61cf0bdecab33f7af](https://github.com/frontainer/frontplate-cli/commit/be5e59e1340b64799ac1a5d61cf0bdecab33f7af)) 711 | 712 | ### fix 713 | 714 | * 各タスクの引数をすべてconfigのみに統一 ([d071600613e380e0bead2dc2fd7da323f0c35a8b](https://github.com/frontainer/frontplate-cli/commit/d071600613e380e0bead2dc2fd7da323f0c35a8b)) 715 | 716 | 717 | 718 | 719 | ## [0.0.10](https://github.com/frontainer/frontplate-cli/compare/v0.0.9...v0.0.10) (2016-09-28) 720 | 721 | 722 | ### fix 723 | 724 | * 2重でdevelop version warningが表示される ([bc4a6037b2d650fbb594080f3ea2108c274cc4e6](https://github.com/frontainer/frontplate-cli/commit/bc4a6037b2d650fbb594080f3ea2108c274cc4e6)) 725 | * ejsのエラーが表示されない ([d8dcc81b1e49a2f040bee647831bc42031cfc9bf](https://github.com/frontainer/frontplate-cli/commit/d8dcc81b1e49a2f040bee647831bc42031cfc9bf)) 726 | * ローカルのfrp.config.jsが反映されない ([2cac177e0b070c8168bb1696c2494ed5598760fa](https://github.com/frontainer/frontplate-cli/commit/2cac177e0b070c8168bb1696c2494ed5598760fa)) 727 | 728 | 729 | 730 | 731 | ## [0.0.9](https://github.com/frontainer/frontplate-cli/compare/v0.0.8...v0.0.9) (2016-09-28) 732 | 733 | 734 | ### fix 735 | 736 | * compilerのログレベルをQUIETに ([4f589cf2d0fc7cb7f09ad4089914b139b8e39170](https://github.com/frontainer/frontplate-cli/commit/4f589cf2d0fc7cb7f09ad4089914b139b8e39170)) 737 | * loaderの順番間違い ([e604894b638093037f8680e796846db06aeaf106](https://github.com/frontainer/frontplate-cli/commit/e604894b638093037f8680e796846db06aeaf106)) 738 | 739 | 740 | 741 | 742 | ## [0.0.8](https://github.com/frontainer/frontplate-cli/compare/v0.0.7...v0.0.8) (2016-09-28) 743 | 744 | 745 | ### feat 746 | 747 | * devビルド時にはwebpackをdebugモードで実行する ([feb99ab50413b99ff75da8a4988dbdc0491c432d](https://github.com/frontainer/frontplate-cli/commit/feb99ab50413b99ff75da8a4988dbdc0491c432d)) 748 | 749 | ### fix 750 | 751 | * production実行時にないパッケージを参照してエラーになっている ([938fd3077052e9fbd11ba8c135422295f50fcfe1](https://github.com/frontainer/frontplate-cli/commit/938fd3077052e9fbd11ba8c135422295f50fcfe1)) 752 | 753 | 754 | 755 | 756 | ## [0.0.7](https://github.com/frontainer/frontplate-cli/compare/v0.0.6...v0.0.7) (2016-09-27) 757 | 758 | 759 | ### feat 760 | 761 | * ビルド環境に応じて環境変数を定義しつつ、devビルドであることをconsoleで表示するように変更 ([b41b416a59feb40422e0aaabddf52faa3ee4c5d2](https://github.com/frontainer/frontplate-cli/commit/b41b416a59feb40422e0aaabddf52faa3ee4c5d2)) 762 | 763 | ### fix 764 | 765 | * console.logではなくconsole.warnでdevビルドであることを強調表示 ([678120e1a0ec2c492a7172626ac6d4dc03d4d9fe](https://github.com/frontainer/frontplate-cli/commit/678120e1a0ec2c492a7172626ac6d4dc03d4d9fe)) 766 | 767 | 768 | 769 | 770 | ## [0.0.6](https://github.com/frontainer/frontplate-cli/compare/v0.0.5...v0.0.6) (2016-09-26) 771 | 772 | 773 | 774 | 775 | 776 | ## [0.0.5](https://github.com/frontainer/frontplate-cli/compare/v0.0.4...v0.0.5) (2016-09-26) 777 | 778 | 779 | 780 | 781 | 782 | ## [0.0.4](https://github.com/frontainer/frontplate-cli/compare/v0.0.3...v0.0.4) (2016-09-26) 783 | 784 | 785 | 786 | 787 | 788 | ## [0.0.3](https://github.com/frontainer/frontplate-cli/compare/v0.0.2...v0.0.3) (2016-09-26) 789 | 790 | 791 | ### fix 792 | 793 | * github オプションを参照するように修正 ([0f1c19e766041668a1b20fa9027a68c459c8619c](https://github.com/frontainer/frontplate-cli/commit/0f1c19e766041668a1b20fa9027a68c459c8619c)) 794 | 795 | 796 | 797 | 798 | ## [0.0.2](https://github.com/frontainer/frontplate-cli/compare/dbe182440b17aa371241c373564418feeafb7fa7...v0.0.2) (2016-09-25) 799 | 800 | 801 | ### fix 802 | 803 | * bin path ([dbe182440b17aa371241c373564418feeafb7fa7](https://github.com/frontainer/frontplate-cli/commit/dbe182440b17aa371241c373564418feeafb7fa7)) 804 | 805 | 806 | 807 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # frontplate-cli 2 | 3 | CLI for Front-end developers. (Inspired by angular-cli) 4 | 5 | ## Feature 6 | 7 | - HTMLモジュール([ejs](https://www.npmjs.com/package/ejs)) 8 | - SASS([node-sass](https://www.npmjs.com/package/node-sass)) 9 | - SASSLint([sass-lint](https://www.npmjs.com/package/sass-lint)) 10 | - スタイルガイド生成([frontnote](https://www.npmjs.com/package/frontnote)) 11 | - JSモジュールバンドラー([webpack](https://www.npmjs.com/package/webpack)) 12 | - ES2015([babel](https://www.npmjs.com/package/babel)) 13 | - スプライト画像の作成とSassファイルの出力([spritesmith](https://www.npmjs.com/package/spritesmith)) 14 | - CSS/JSの圧縮と最適化([postcss-csso](https://www.npmjs.com/package/postcss-csso) [google-closure-compiler](https://www.npmjs.com/package/google-closure-compiler)) 15 | - CSSのベンダープレフィックス付与自動化([autoprefixer](https://www.npmjs.com/package/autoprefixer)) 16 | - ユニットテスト([karma](https://www.npmjs.com/package/karma) [jasmine](https://www.npmjs.com/package/jasmine)) 17 | - LiveReload([browser-sync](https://www.npmjs.com/package/browser-sync)) 18 | - ESLint([eslint](https://www.npmjs.com/package/eslint)) 19 | - HTMLHint([htmlhint](https://www.npmjs.com/package/htmlhint)) 20 | 21 | ## Usage 22 | 23 | 詳しくは[wiki](https://github.com/frontainer/frontplate-cli/wiki)を参照ください 24 | 25 | https://github.com/frontainer/frontplate-cli/wiki -------------------------------------------------------------------------------- /config/clean.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | src: FRP_DEST 4 | }; 5 | -------------------------------------------------------------------------------- /config/copy.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | // 'path/from': '/path/to' 4 | [`${FRP_SRC}/lib/**/*`]: `${FRP_DEST}/assets/lib`, 5 | [`${FRP_SRC}/images/**/*`]: `${FRP_DEST}/assets/images` 6 | }; -------------------------------------------------------------------------------- /config/html.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | src: `${FRP_SRC}/**/*.{ejs,svg,html}`, // 読み込むビューファイル 4 | dest: FRP_DEST, // 出力先 5 | params: { // ビューで使うグローバル変数 6 | title: 'title' 7 | }, 8 | ext: '.html', // 出力する際の拡張子 9 | // 1つのテンプレートで複数作成するときに使用する 10 | pages: [ 11 | // { 12 | // name: 'filename', // 出力するファイル名 13 | // src: `${FRP_SRC}/view/tmpl/_template.ejs`, // テンプレート 14 | // params: { // ページに渡す変数 15 | // title: 'page title' 16 | // } 17 | // } 18 | ], 19 | // htmlhintルール(https://github.com/yaniswang/HTMLHint/wiki/Rules) 20 | rules: { 21 | "tagname-lowercase": true, 22 | "attr-lowercase": false, 23 | "attr-value-double-quotes": true, 24 | "attr-value-not-empty": false, 25 | "attr-no-duplication": true, 26 | "doctype-first": false, 27 | "tag-pair": true, 28 | "tag-self-close": false, 29 | "spec-char-escape": true, 30 | "id-unique": true, 31 | "src-not-empty": true, 32 | "head-script-disabled": false, 33 | "img-alt-require": true, 34 | "doctype-html5": true, 35 | "id-class-value": false, 36 | "style-disabled": false, 37 | "space-tab-mixed-disabled": true, 38 | "id-class-ad-disabled": true, 39 | "href-abs-or-rel": false, 40 | "attr-unsafe-chars": true 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /config/server.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | "server": FRP_DEST, // ドキュメントルート 4 | "port": 3000, // ポート 5 | "middleware": [], 6 | "ghostMode": { 7 | "clicks": true, 8 | "scroll": true, 9 | "forms": { 10 | "submit": true, 11 | "inputs": true, 12 | "toggles": true 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /config/sprite.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = [ 3 | { 4 | src: `${FRP_SRC}/sprites/icon/*.{png,gif,jpg}`, // 読み込む画像 5 | destImage: `${FRP_SRC}/images/icon.png`, // 画像出力先 6 | destCSS: `${FRP_SRC}/sass/sprites/_icon.scss`, // CSS出力先 7 | imgPath: '../images/icon.png', // CSS内での画像パス 8 | padding: 2, // 画像の間隔 9 | scale: 1.0, // 画像表示サイズ(Retina対応なら0.5にする) 10 | mixin: true, // @mixin spriteを出力するかどうか 11 | selector: true // .icon {&.icon-name {}}のクラス定義を出力するかどうか 12 | } 13 | ]; -------------------------------------------------------------------------------- /config/style.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | src: `${FRP_SRC}/sass/**/*.scss`, // 読み込むscss 4 | dest: `${FRP_DEST}/assets/css`, // 出力先 5 | outputStyle: 'compact', 6 | sourceMap: true, 7 | plugins: [ // postcssプラグイン 8 | require('autoprefixer')({ // autoprefixer(https://github.com/postcss/autoprefixer) 9 | browsers: [ 10 | '> 3% in JP' 11 | ] 12 | }) 13 | ], 14 | noGuide: false, 15 | styleguide: { 16 | title: 'StyleGuide', 17 | verbose: false, 18 | clean: true, 19 | params: {}, 20 | css: `../${FRP_DEST}/assets/css/style.css`, 21 | // script: '../public/assets/js/app.js', 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /config/style.config.production.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const conf = require('./style.config'); 3 | const merge = require('webpack-merge'); 4 | module.exports = merge(conf, { 5 | sourceMap: false, 6 | plugins: [ // postcssプラグイン 7 | require('postcss-csso')() 8 | ] 9 | }); -------------------------------------------------------------------------------- /config/test.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * karma conf 4 | * url: https://karma-runner.github.io/1.0/config/configuration-file.html 5 | */ 6 | 7 | const webpackConfig = require('./webpack.config'); 8 | module.exports = { 9 | // base path that will be used to resolve all patterns (eg. files, exclude) 10 | basePath: '', 11 | // frameworks to use 12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 13 | frameworks: ['jasmine'], 14 | 15 | // list of files / patterns to load in the browser 16 | files: [ 17 | `${FRP_SRC}/js/**/*spec.js` 18 | ], 19 | preprocessors: { 20 | '**/*spec.js': ['webpack'] 21 | }, 22 | webpack: webpackConfig, 23 | webpackMiddleware: { 24 | stats: 'errors-only' 25 | }, 26 | exclude: [], 27 | // test results reporter to use 28 | // possible values: 'dots', 'progress' 29 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 30 | reporters: ['progress'], 31 | client: { 32 | captureConsole: true 33 | }, 34 | // web server port 35 | port: 9001, 36 | 37 | // enable / disable colors in the output (reporters and logs) 38 | colors: true, 39 | 40 | // level of logging 41 | //'OFF' | 'ERROR' | 'INFO' | 'DEBUG' 42 | logLevel: 'INFO', 43 | 44 | // enable / disable watching file and executing tests whenever any file changes 45 | autoWatch: false, 46 | 47 | // start these browsers 48 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 49 | browsers: ['PhantomJS'], 50 | 51 | // Continuous Integration mode 52 | // if true, Karma captures browsers, runs the tests and exits 53 | singleRun: true, 54 | 55 | // Concurrency level 56 | // how many browser should be started simultaneous 57 | concurrency: Infinity 58 | 59 | }; 60 | -------------------------------------------------------------------------------- /config/webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const webpack = require("webpack"); 3 | const merge = require("webpack-merge"); 4 | const core = require("./webpack.core"); 5 | /** 6 | * webpack config 7 | * url: https://webpack.github.io/docs/configuration.html 8 | */ 9 | module.exports = merge(core, { 10 | devtool: '#source-map', 11 | module: { 12 | rules: [ 13 | {test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader'} 14 | ] 15 | }, 16 | plugins: [ 17 | new webpack.DefinePlugin({ 18 | 'process.env': { 19 | 'NODE_ENV': JSON.stringify('development') 20 | } 21 | }), 22 | new webpack.BannerPlugin({ 23 | banner: 'console.warn("This script is development version.");', 24 | raw: true 25 | }) 26 | ] 27 | }); -------------------------------------------------------------------------------- /config/webpack.config.production.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const webpack = require("webpack"); 3 | const merge = require("webpack-merge"); 4 | const core = require("./webpack.core"); 5 | /** 6 | * webpack config for production 7 | * url: https://webpack.github.io/docs/configuration.html 8 | */ 9 | module.exports = merge(core, { 10 | module: { 11 | rules: [ 12 | {test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader'} 13 | ] 14 | }, 15 | plugins: [ 16 | new webpack.optimize.UglifyJsPlugin({ 17 | beautify: false, 18 | mangle: { 19 | screw_ie8: true, 20 | keep_fnames: true 21 | }, 22 | compress: { 23 | warnings: false, 24 | screw_ie8: true 25 | }, 26 | comments: false 27 | }), 28 | new webpack.optimize.AggressiveMergingPlugin(), 29 | new webpack.optimize.OccurrenceOrderPlugin(), 30 | new webpack.DefinePlugin({ 31 | 'process.env': { 32 | 'NODE_ENV': JSON.stringify('production') 33 | } 34 | }) 35 | ], 36 | }); -------------------------------------------------------------------------------- /config/webpack.core.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const webpack = require("webpack"); 3 | const entries = require("webpack-entries"); 4 | const path = require("path"); 5 | const util = require("../lib/util/util"); 6 | const localConfig = path.join(process.cwd(), '.eslintrc'); 7 | const globalConfig = path.join(__dirname, '/../.eslintrc'); 8 | const WebpackBuildNotifierPlugin = require('webpack-build-notifier'); 9 | /** 10 | * webpack config 11 | * url: https://webpack.github.io/docs/configuration.html 12 | */ 13 | module.exports = { 14 | entry: entries(`./${FRP_SRC}/js/!(_*|*spec).js`, true), 15 | output: { 16 | path: FRP_DEST + '/assets/js', 17 | publicPath: '/assets/js/', 18 | filename: "[name].js", 19 | sourceMapFilename: 'maps/[name].map', 20 | jsonpFunction: 'fr' 21 | }, 22 | resolve: { 23 | modules: [ 24 | `${FRP_SRC}/js`, 25 | path.join(process.cwd(), 'node_modules'), 26 | path.join(__dirname, '../node_modules'), 27 | "node_modules" 28 | ], 29 | }, 30 | resolveLoader: { 31 | modules: [ 32 | path.join(process.cwd(), 'node_modules'), 33 | path.join(__dirname, '../node_modules'), 34 | "node_modules" 35 | ] 36 | }, 37 | module: { 38 | rules: [ 39 | {test: /\.js$/, exclude: /node_modules/, loader: 'eslint-loader', enforce: 'pre'}, 40 | {test: /\.html$/, loader: 'html-loader'}, 41 | {test: /\.json$/, loader: 'json-loader'}, 42 | ] 43 | }, 44 | plugins: [ 45 | new WebpackBuildNotifierPlugin({ 46 | title: "frp task script", 47 | suppressSuccess: true 48 | }), 49 | new webpack.LoaderOptionsPlugin({ 50 | options: { 51 | eslint: { 52 | configFile: util.exists(localConfig) ? localConfig : globalConfig, 53 | failOnError: true 54 | }, 55 | babel: { 56 | presets: ["es2015"] 57 | } 58 | } 59 | }) 60 | ], 61 | watchOptions: { 62 | ignored: /node_modules/ 63 | }, 64 | performance: { 65 | hints: false 66 | } 67 | }; -------------------------------------------------------------------------------- /frp.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(production) { 3 | global.FRP_SRC = global.FRP_SRC || 'src'; 4 | global.FRP_DEST = global.FRP_DEST || 'public'; 5 | return { 6 | clean: require('./config/clean.config'), 7 | html: require('./config/html.config'), 8 | style: production ? require('./config/style.config.production') : require('./config/style.config'), 9 | script: production ? require('./config/webpack.config.production') : require('./config/webpack.config'), 10 | server: require('./config/server.config'), 11 | copy: require('./config/copy.config'), 12 | sprite: require('./config/sprite.config'), 13 | test: require('./config/test.conf') 14 | } 15 | }; -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | const path = require('path'); 4 | const spawn = require('cross-spawn'); 5 | const updateNotifier = require('update-notifier'); 6 | const pkg = require('./package.json'); 7 | updateNotifier({ 8 | pkg: pkg, 9 | defer: false 10 | }).notify(); 11 | 12 | const localScript = path.join(__dirname, 'lib/frp.js'); 13 | let argv = process.argv; 14 | let env = process.env; 15 | let modulePath = [ 16 | path.join(__dirname,'node_modules'), 17 | path.join(process.cwd(),'node_modules') 18 | ]; 19 | argv[1] = localScript; 20 | env.NODE_PATH = modulePath.join(path.delimiter); 21 | spawn(argv.shift(), argv, { 22 | cwd: process.cwd(), 23 | env: env, 24 | stdio: 'inherit' 25 | }).on('exit', (code) => { 26 | process.exit(code); 27 | }); -------------------------------------------------------------------------------- /lib/cmds/build.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Rx = require('rxjs'); 4 | const chalk = require('chalk'); 5 | const timer = require('../util/timer'); 6 | const t = require('../tasks'); 7 | const util = require('../util/util'); 8 | const coreUtil = require('util'); 9 | 10 | exports.command = 'build'; 11 | exports.desc = 'Execute build tasks'; 12 | exports.builder = { 13 | production: { 14 | alias: 'p', 15 | default: false, 16 | describe: 'production mode', 17 | type: 'boolean', 18 | global: true 19 | }, 20 | }; 21 | exports.aliases = []; 22 | exports.handler = function (argv) { 23 | const config = util.getConfig(argv); 24 | try { 25 | t.clean(config.clean) 26 | .flatMap(() => { 27 | return Rx.Observable.combineLatest( 28 | t.copy(config.copy), 29 | t.sprite(config.sprite), 30 | t.html(config.html) 31 | ); 32 | }).flatMap(() => { 33 | return Rx.Observable.combineLatest( 34 | t.script(config.script), 35 | t.style(config.style) 36 | ); 37 | }).subscribe(() => { 38 | timer.output(); 39 | console.log(chalk.green('Succeeded')); 40 | process.exit(0); 41 | }, (e) => { 42 | if (e) { 43 | if (e.formatted) { 44 | console.log('\n', chalk.red(e.formatted)); 45 | } else { 46 | console.error('\n', chalk.red(coreUtil.inspect(e))); 47 | } 48 | } 49 | process.exit(1); 50 | }); 51 | } catch (e) { 52 | if (e) { 53 | if (e.formatted) { 54 | console.log('\n', chalk.red(e.formatted)); 55 | } else { 56 | console.error('\n', chalk.red(coreUtil.inspect(e))); 57 | } 58 | } 59 | process.exit(1); 60 | } 61 | }; -------------------------------------------------------------------------------- /lib/cmds/create.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Rx = require('rxjs'); 4 | const path = require('path'); 5 | const mkdirp = require('mkdirp'); 6 | const chalk = require('chalk'); 7 | const ora = require('ora'); 8 | const download = require('../util/download'); 9 | const install = require('../util/install'); 10 | const util = require('../util/util'); 11 | 12 | exports.command = 'create '; 13 | exports.desc = 'Create project'; 14 | exports.builder = { 15 | branch: { 16 | default: null, 17 | alias: 'b', 18 | describe: 'branch name', 19 | type: 'string' 20 | }, 21 | preset: { 22 | default: 'default', 23 | alias: 'p', 24 | describe: 'preset template name', 25 | type: 'string' 26 | }, 27 | github: { 28 | default: null, 29 | alias: 'g', 30 | describe: 'Template github repository', 31 | type: 'string' 32 | }, 33 | yarn: { 34 | default: false, 35 | alias: 'y', 36 | describe: 'Use "yarn install" instead of "npm install"', 37 | type: 'string' 38 | } 39 | }; 40 | exports.aliases = []; 41 | exports.handler = function (argv) { 42 | const destPath = path.join(process.cwd(), argv.name); 43 | mkdirp.sync(destPath); 44 | let template = 'frontainer/frontplate'; 45 | switch (argv.preset) { 46 | case 'wp': 47 | template = 'frontainer/wp-frontplate'; 48 | break; 49 | default: 50 | break; 51 | } 52 | if (argv.github) { 53 | template = argv.github; 54 | } 55 | if (argv.branch) { 56 | template += '#' + argv.branch; 57 | } 58 | download(template, destPath) 59 | .flatMap(() => { 60 | return install(destPath, argv.yarn || false); 61 | }) 62 | .subscribe(() => { 63 | let pkg = require(path.join(destPath, 'package.json')); 64 | if (pkg.frp) { 65 | Rx.Observable.pairs(pkg.frp).flatMap((v) => { 66 | return download(v[0], path.join(destPath, v[1])); 67 | }).subscribe(() => { 68 | console.log(chalk.green(`Succeeded creating project!`)); 69 | process.exit(0); 70 | }); 71 | } else { 72 | console.log(chalk.green(`Succeeded creating project!`)); 73 | process.exit(0); 74 | } 75 | }, (e) => { 76 | console.log(chalk.red(`Error creating project...`), e); 77 | process.exit(1); 78 | }); 79 | }; -------------------------------------------------------------------------------- /lib/cmds/exe.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const chalk = require('chalk'); 5 | const timer = require('../util/timer'); 6 | const util = require('../util/util'); 7 | const coreUtil = require('util'); 8 | 9 | exports.command = 'exe'; 10 | exports.desc = 'Execute task from script file'; 11 | exports.builder = { 12 | production: { 13 | alias: 'p', 14 | default: false, 15 | describe: 'production mode', 16 | type: 'boolean', 17 | global: true 18 | }, 19 | }; 20 | exports.aliases = []; 21 | exports.handler = function (argv) { 22 | const config = util.getConfig(argv); 23 | if (argv._.length < 1) { 24 | throw new Error('frp exe [OPTIONS]'); 25 | } 26 | let script = require(path.join(process.cwd(), argv._[1])); 27 | script(argv, config).subscribe(() => { 28 | 29 | }, (e) => { 30 | console.error('\n',chalk.red(coreUtil.inspect(e))); 31 | throw new Error('FRP EXE ERROR'); 32 | }); 33 | }; -------------------------------------------------------------------------------- /lib/cmds/serve.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const gaze = require('gaze'); 5 | const chalk = require('chalk'); 6 | const t = require('../tasks'); 7 | const util = require('../util/util'); 8 | 9 | let browser; 10 | let config; 11 | let watches = []; 12 | 13 | exports.command = 'serve'; 14 | exports.desc = 'Start server & watch tasks'; 15 | exports.builder = { 16 | production: { 17 | alias: 'p', 18 | default: false, 19 | describe: 'production mode', 20 | type: 'boolean', 21 | global: true 22 | }, 23 | test: { 24 | alias: 't', 25 | default: false, 26 | describe: 'Unit test watching', 27 | type: 'boolean' 28 | } 29 | }; 30 | exports.aliases = []; 31 | exports.handler = function (argv) { 32 | 33 | process.on('exit', (code) => { 34 | // 監視停止処理 35 | watches.forEach((watcher) => { 36 | watcher.close(); 37 | }); 38 | watches = []; 39 | // ブラウザ停止 40 | if (browser) browser.exit(); 41 | }); 42 | 43 | config = util.getConfig(argv); 44 | if (config.server.proxy) { 45 | delete config.server.server; 46 | } 47 | browser = t.server(config.server); 48 | 49 | gaze(config.style.src, (err, watcher) => { 50 | watcher.on('all', (event, filepath) => { 51 | t.style(config.style).subscribe((css) => { 52 | css = util.flatten(css).filter((filepath) => { 53 | return (path.extname(filepath) !== '.map') 54 | }); 55 | browser.reload(css); 56 | }, () => { 57 | // on error 58 | }); 59 | }); 60 | watches.push(watcher); 61 | }); 62 | gaze(config.html.src, (err, watcher) => { 63 | watcher.on('all', (event, filepath) => { 64 | t.html(config.html).subscribe((files) => { 65 | browser.reload(files); 66 | }, () => { 67 | // on error 68 | }); 69 | }); 70 | watches.push(watcher); 71 | }); 72 | 73 | config.sprite.forEach((sp) => { 74 | gaze(sp.src, (err, watcher) => { 75 | watcher.on('all', (event, filepath) => { 76 | t.sprite([sp]).subscribe(() => { 77 | }, () => { 78 | // on error 79 | }); 80 | }); 81 | watches.push(watcher); 82 | }); 83 | }); 84 | 85 | t.copy(config.copy, {watch: true, initialCopy: false}).subscribe((res) => { 86 | browser.reload(res); 87 | }, () => { 88 | // on error 89 | }); 90 | 91 | config.script.watch = true; 92 | t.script(config.script).subscribe((res) => { 93 | browser.reload(); 94 | }, () => { 95 | // on error 96 | }); 97 | 98 | if (argv.test) { 99 | t.test(config.test, true).subscribe((res) => { 100 | // 101 | }, () => { 102 | // on error 103 | }); 104 | } 105 | }; -------------------------------------------------------------------------------- /lib/cmds/task.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Rx = require('rxjs'); 4 | const path = require('path'); 5 | const chalk = require('chalk'); 6 | const timer = require('../util/timer'); 7 | const t = require('../tasks'); 8 | const util = require('../util/util'); 9 | const coreUtil = require('util'); 10 | 11 | exports.command = 'task '; 12 | exports.desc = 'Execute single build task'; 13 | exports.builder = { 14 | production: { 15 | alias: 'p', 16 | default: false, 17 | describe: 'production mode', 18 | type: 'boolean', 19 | global: true 20 | }, 21 | }; 22 | exports.aliases = []; 23 | exports.handler = function (argv) { 24 | try { 25 | const config = util.getConfig(argv); 26 | let name = argv.name; 27 | if (!t[name]) { 28 | throw new Error(`Not found task name.(${name})`); 29 | } 30 | t[name](config[name]).subscribe(() => { 31 | timer.output(); 32 | console.log(chalk.green('Succeeded')); 33 | process.exit(0); 34 | }, (e) => { 35 | if (e) { 36 | if (e.formatted) { 37 | console.log('\n', chalk.red(e.formatted)); 38 | } else { 39 | console.error('\n', chalk.red(coreUtil.inspect(e))); 40 | } 41 | } 42 | process.exit(1); 43 | }); 44 | } catch (e) { 45 | console.error('\n',chalk.red(coreUtil.inspect(e))); 46 | process.exit(1); 47 | } 48 | }; -------------------------------------------------------------------------------- /lib/cmds/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Rx = require('rxjs'); 4 | const chalk = require('chalk'); 5 | const timer = require('../util/timer'); 6 | const t = require('../tasks'); 7 | const util = require('../util/util'); 8 | const coreUtil = require('util'); 9 | 10 | exports.command = 'test'; 11 | exports.desc = 'Execute unit testing'; 12 | exports.builder = { 13 | production: { 14 | alias: 'p', 15 | default: false, 16 | describe: 'production mode', 17 | type: 'boolean', 18 | global: true 19 | } 20 | }; 21 | exports.aliases = []; 22 | exports.handler = function (argv) { 23 | const config = util.getConfig(argv); 24 | t.test(config.test).subscribe(() => { 25 | timer.output(); 26 | console.log(chalk.green('Succeeded')); 27 | process.exit(0); 28 | }, (e) => { 29 | process.exit(1); 30 | console.error('\n',chalk.red(coreUtil.inspect(e))); 31 | throw new Error('BUILD ERROR'); 32 | }); 33 | }; -------------------------------------------------------------------------------- /lib/frp.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | const path = require('path'); 4 | const yargs = require("yargs"); 5 | 6 | const argv = yargs.usage('frp [options]') 7 | .commandDir('cmds') 8 | // .demand(1) 9 | .options({ 10 | config: { 11 | alias: 'c', 12 | default: null, 13 | describe: 'config file path', 14 | type: 'string', 15 | global: true 16 | } 17 | }) 18 | .version() 19 | .help('help') 20 | .alias('help', 'h') 21 | .alias('version', 'v') 22 | .argv; 23 | 24 | if (argv._.length === 0) { 25 | require('./interaction')(argv); 26 | } -------------------------------------------------------------------------------- /lib/interaction.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | const inquirer = require('inquirer'); 4 | const glob = require('glob'); 5 | const path = require('path'); 6 | const chalk = require('chalk'); 7 | const spawn = require('cross-spawn'); 8 | const COMMANDS = [ 9 | 'serve', 10 | 'build', 11 | 'create', 12 | 'task', 13 | 'test' 14 | ]; 15 | const TASKS = [ 16 | 'script', 17 | 'style', 18 | 'html', 19 | 'test', 20 | 'copy', 21 | 'sprite', 22 | 'clean', 23 | 'server' 24 | ]; 25 | const PRESET = [ 26 | 'default', 27 | 'wp' 28 | ]; 29 | module.exports = function (argv) { 30 | const CONFIGS = glob.sync('frp*.js'); 31 | inquirer.prompt([{ 32 | name: 'command', 33 | message: 'choose execute command', 34 | type: 'list', 35 | choices: COMMANDS 36 | }, { 37 | name: 'config', 38 | message: 'choose config file', 39 | type: 'list', 40 | choices: CONFIGS, 41 | when(args) { 42 | if (CONFIGS.length === 0) return false; 43 | if (CONFIGS.length === 1) { 44 | args.config = CONFIGS[0]; 45 | return false; 46 | } 47 | return true; 48 | } 49 | }, { 50 | name: 'task', 51 | message: 'choose execute task?', 52 | type: 'list', 53 | choices: TASKS, 54 | when(args) { 55 | return (args.command === 'task'); 56 | } 57 | }, { 58 | name: 'appname', 59 | message: 'input project name', 60 | type: 'input', 61 | when(args) { 62 | return (args.command === 'create'); 63 | }, 64 | validate(val) { 65 | if (val) { 66 | return true; 67 | } 68 | return false; 69 | } 70 | }, { 71 | name: 'preset', 72 | message: 'choose preset template.', 73 | type: 'list', 74 | choices: PRESET, 75 | when(args) { 76 | return (args.command === 'create'); 77 | } 78 | }, { 79 | name: 'test', 80 | message: 'watch unit testing?', 81 | type: 'confirm', 82 | default: false, 83 | when(args) { 84 | return (args.command === 'serve'); 85 | } 86 | }, { 87 | name: 'production', 88 | message: 'use production build?', 89 | type: 'confirm', 90 | default: false, 91 | when(args) { 92 | return (args.command !== 'create'); 93 | } 94 | }]).then((answers) => { 95 | let params = [ 96 | path.join(__dirname, '../index.js'), 97 | answers.command 98 | ]; 99 | if (answers.task) { 100 | params.push(answers.task); 101 | } 102 | if (answers.appname) { 103 | params.push(answers.appname); 104 | } 105 | if (answers.config) { 106 | params.push('-c', answers.config); 107 | } 108 | if (answers.preset) { 109 | params.push('--preset', answers.preset); 110 | } 111 | if (answers.test) { 112 | params.push('-t') 113 | } 114 | if (answers.production) { 115 | params.push('-p'); 116 | } 117 | console.log(chalk.blue(`frp ${params.slice(1).join(' ')}`)); 118 | spawn('node', params, { 119 | cwd: process.cwd(), 120 | env: process.env, 121 | stdio: 'inherit' 122 | }).on('exit', (code) => { 123 | process.exit(code); 124 | }); 125 | }); 126 | }; -------------------------------------------------------------------------------- /lib/tasks/clean.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const del = require('del'); 3 | const ora = require('ora'); 4 | const Rx = require('rxjs'); 5 | const timer = require('../util/timer'); 6 | 7 | /** 8 | * clean task 9 | * @param pattern{string} glob pattern string 10 | * @param options{object} rimraf options (https://www.npmjs.com/package/rimraf) 11 | * @returns {Rx.Observable} 12 | */ 13 | module.exports = function (config) { 14 | config = config || {}; 15 | config.options = config.options || {}; 16 | return Rx.Observable.create((observer) => { 17 | timer.start('clean'); 18 | const spinner = ora('[build] clean').start(); 19 | if (!config.src) { 20 | spinner.succeed(); 21 | timer.end('clean'); 22 | return observer.next(config.src); 23 | } 24 | del(config.src, config.options).then((paths) => { 25 | spinner.succeed(); 26 | timer.end('clean'); 27 | observer.next(config.src); 28 | }, (e) => { 29 | spinner.fail(); 30 | timer.end('clean'); 31 | return observer.error(e); 32 | }); 33 | }); 34 | }; -------------------------------------------------------------------------------- /lib/tasks/copy.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const Rx = require('rxjs'); 3 | const cpx = require('cpx'); 4 | const ora = require('ora'); 5 | const timer = require('../util/timer'); 6 | 7 | /** 8 | * copy 9 | * @param from{string} 10 | * @param to{string} 11 | * @param options{object} 12 | * @returns {Rx.Observable} 13 | */ 14 | function copy(from, to, options) { 15 | options = options || {}; 16 | return Rx.Observable.create((observer) => { 17 | if (options.watch) { 18 | cpx.watch(from, to, options).on('copy', (e) => { 19 | observer.next(e.dstPath); 20 | }).on('remove', (e) => { 21 | observer.next(e.dstPath); 22 | }); 23 | } else { 24 | cpx.copy(from, to, options, (e) => { 25 | if (e) return observer.error(e); 26 | observer.next({from: from, to: to}); 27 | }); 28 | } 29 | }); 30 | } 31 | 32 | /** 33 | * copy task 34 | * @param data{object[]} 'from' and 'to' object 35 | * @param options{object} cpx options(https://www.npmjs.com/package/cpx) 36 | * @returns {Rx.Observable} 37 | */ 38 | module.exports = function (data, options) { 39 | timer.start('copy'); 40 | options = options || {}; 41 | const spinner = ora('[build] copy'); 42 | if (!options.watch || options.initialCopy !== false) { 43 | spinner.start(); 44 | } 45 | let observables = Object.keys(data).map((key, index) => { 46 | return copy(key, data[key], options); 47 | }); 48 | let obs; 49 | if (options.watch) { 50 | obs = Rx.Observable.from(observables).mergeAll().share(); 51 | } else { 52 | obs = Rx.Observable.combineLatest(observables).share(); 53 | } 54 | obs.subscribe((e) => { 55 | if (!options.watch || options.initialCopy !== false) { 56 | spinner.succeed(); 57 | } 58 | timer.end('copy'); 59 | }, () => { 60 | spinner.fail(); 61 | }); 62 | return obs; 63 | }; -------------------------------------------------------------------------------- /lib/tasks/html.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const Rx = require('rxjs'); 3 | const path = require('path'); 4 | const fs = require('fs-extra'); 5 | const ejs = require('ejs'); 6 | const ora = require('ora'); 7 | const chalk = require('chalk'); 8 | const lint = require('htmlhint').HTMLHint; 9 | const timer = require('../util/timer'); 10 | const util = require('../util/util'); 11 | const coreUtil = require('util'); 12 | 13 | /** 14 | * ejs render 15 | * @param filepath{string} input file path 16 | * @param outputPath{string} output path 17 | * @param data{object} ejs param object 18 | * @param options{object} ejs options 19 | * @returns {Rx.Observable} 20 | */ 21 | function render(filepath, outputPath, data, options) { 22 | options = options || {}; 23 | return Rx.Observable.create((observer) => { 24 | ejs.renderFile(filepath, data, options, (err, str) => { 25 | if (err) return observer.error(err); 26 | let messages = lint.format(lint.verify(str, options.rules), {colors: true}); 27 | if (messages.length > 0) { 28 | console.log(chalk.yellow.bold('\nHTML WARNING')); 29 | } 30 | messages.forEach((message) => { 31 | console.log(message); 32 | }); 33 | fs.outputFile(outputPath, str, options, (err) => { 34 | if (err) return observer.error(err); 35 | observer.next(outputPath); 36 | }); 37 | }); 38 | }); 39 | } 40 | 41 | /** 42 | * HTML Parse task 43 | * @param config{object} html task config 44 | * @returns {Rx.Observable} 45 | */ 46 | module.exports = function (config) { 47 | timer.start('html'); 48 | const spinner = ora('[build] html').start(); 49 | let files = util.getPath(config.src); 50 | files = files.filter((filepath) => { 51 | return (path.basename(filepath).charAt(0) !== '_'); 52 | }); 53 | let observables = files.map((filepath) => { 54 | let outputPath = util.destPath(config.src, config.dest, filepath, config.ext); 55 | return render(filepath, outputPath, config.params, config); 56 | }); 57 | if (config.pages) { 58 | observables = observables.concat(config.pages.map((page) => { 59 | let outputPath = util.destPath(page.src, config.dest, page.name, config.ext); 60 | return render(page.src, outputPath, page.params, config); 61 | })); 62 | } 63 | if (observables.length === 0) { 64 | return Rx.Observable.of([]); 65 | } 66 | let obs = Rx.Observable.combineLatest(observables).share(); 67 | obs.subscribe(() => { 68 | spinner.succeed(); 69 | timer.end('html'); 70 | }, (e) => { 71 | spinner.fail(); 72 | }); 73 | return obs; 74 | }; 75 | -------------------------------------------------------------------------------- /lib/tasks/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.clean = require('./clean'); 4 | module.exports.copy = require('./copy'); 5 | module.exports.html = require('./html'); 6 | module.exports.script = require('./script'); 7 | module.exports.server = require('./server'); 8 | module.exports.sprite = require('./sprite'); 9 | module.exports.style = require('./style'); 10 | module.exports.test = require('./test'); -------------------------------------------------------------------------------- /lib/tasks/script.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Rx = require('rxjs'); 4 | const path = require('path'); 5 | const webpack = require('webpack'); 6 | const ora = require('ora'); 7 | const timer = require('../util/timer'); 8 | 9 | /** 10 | * script task 11 | * @param config{object} webpack config object 12 | * @returns {Rx.Observable} 13 | */ 14 | module.exports = function (config) { 15 | timer.start('script'); 16 | const spinner = ora('[build] script').start(); 17 | 18 | if (process.env.NODE_PATH) { 19 | let paths = process.env.NODE_PATH.split(path.delimiter); 20 | config.resolve.modules = config.resolve.modules ? config.resolve.modules.concat(paths) : paths; 21 | config.resolveLoader.modules = config.resolveLoader.modules ? config.resolveLoader.modules.concat(paths) : paths; 22 | } 23 | config.entry = config.entry || {}; 24 | return Rx.Observable.create((observer) => { 25 | webpack(config, (err, stats) => { 26 | console.log(stats.toString({ 27 | chunks: false, 28 | colors: true 29 | })); 30 | if (err || stats.hasErrors()) { 31 | spinner.fail(); 32 | return observer.error(err); 33 | } 34 | let sj = stats.toJson(true); 35 | let files = []; 36 | sj.chunks.forEach((c) => { 37 | files = files.concat(c.files); 38 | }); 39 | spinner.succeed(); 40 | timer.end('script'); 41 | observer.next(files); 42 | }); 43 | }); 44 | }; -------------------------------------------------------------------------------- /lib/tasks/server.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const BrowserSync = require('browser-sync'); 3 | 4 | /** 5 | * server tasks 6 | * @param config{object} BrowserSync options(https://www.npmjs.com/package/browser-sync) 7 | * @returns {BrowserSync.Browser} 8 | */ 9 | module.exports = function (config) { 10 | const browser = BrowserSync.create(); 11 | browser.init(config); 12 | return browser; 13 | }; -------------------------------------------------------------------------------- /lib/tasks/sprite.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const fs = require('fs-extra'); 3 | const path = require('path'); 4 | const Spritesmith = require('spritesmith'); 5 | const json2css = require('json2css'); 6 | const ora = require('ora'); 7 | const Rx = require('rxjs'); 8 | const util = require('../util/util'); 9 | const timer = require('../util/timer'); 10 | const ejs = require('ejs'); 11 | 12 | /** 13 | * sprite task 14 | * @param sprites{object[]} sprite config object 15 | * @returns {Rx.Observable} 16 | */ 17 | module.exports = function (sprites) { 18 | timer.start('sprite'); 19 | const spinner = ora('[build] sprite').start(); 20 | 21 | let observables = sprites.map((sprite) => { 22 | let src = util.getPath(sprite.src); 23 | return generate(src, sprite); 24 | }); 25 | if (observables.length === 0) { 26 | return Rx.Observable.of([]); 27 | } 28 | let obs = Rx.Observable.combineLatest(observables).share(); 29 | obs.subscribe(() => { 30 | spinner.succeed(); 31 | timer.end('sprite'); 32 | }, () => { 33 | spinner.fail(); 34 | }); 35 | return obs; 36 | }; 37 | 38 | /** 39 | * generate sprite image & css 40 | * @param src{string} directory of sprites 41 | * @param config{object} spritesmith options(https://www.npmjs.com/package/spritesmith) 42 | * @returns {Rx.Observable} 43 | */ 44 | function generate(src, config) { 45 | return Rx.Observable.create((observer) => { 46 | let op = Object.assign({}, config, { src }); 47 | Spritesmith.run(op, (err, result) => { 48 | if (err) return observer.error(err); 49 | let coordinates = Object.keys(result.coordinates); 50 | if (coordinates.length === 0) { 51 | return observer.next([]); 52 | } 53 | let spriteParams = coordinates.map((key) => { 54 | let data = result.coordinates[key]; 55 | let ext = path.extname(key); 56 | let filename = path.basename(key, ext); 57 | return { 58 | name: filename, 59 | x: data.x, 60 | y: data.y, 61 | width: data.width, 62 | height: data.height, 63 | total_width: result.properties.width, 64 | total_height: result.properties.height, 65 | image: config.imgPath || 'images/sprite.png' 66 | }; 67 | }); 68 | output(result, spriteParams, config).subscribe((res) => { 69 | observer.next(res); 70 | }, (e) => { 71 | observer.error(e); 72 | }); 73 | }); 74 | }); 75 | } 76 | 77 | function output(result, spriteParams, config) { 78 | let destImgPath = config.destImage || 'images/sprite.png'; 79 | let destCSSPath = config.destCSS || 'src/scss/sprites/_sprite.scss'; 80 | 81 | let filename = path.basename(destCSSPath, path.extname(destCSSPath)).replace(/^_/, ''); 82 | json2css.addTemplate('scss-beauty', (args) => { 83 | let templatePath = config.template || path.join(__dirname, '../../template/sprite/sprite.ejs'); 84 | const template = fs.readFileSync(templatePath); 85 | return ejs.render(template.toString(), { 86 | items: args.items, 87 | options: args.options, 88 | filename: filename, 89 | config: config 90 | }); 91 | }); 92 | 93 | let css = json2css(spriteParams, { 94 | format: 'scss-beauty',//config.format || 'scss', 95 | cssSelector: function (item) { 96 | return `${filename}-${item}`; 97 | } 98 | }); 99 | 100 | 101 | let imgObs = Rx.Observable.create((observer) => { 102 | fs.outputFile(destImgPath, result.image, (err) => { 103 | if (err) return observer.error(err); 104 | observer.next(destImgPath); 105 | }); 106 | }); 107 | let cssObs = Rx.Observable.create((observer) => { 108 | fs.outputFile(destCSSPath, css, (err) => { 109 | if (err) return observer.error(err); 110 | observer.next(destCSSPath); 111 | }); 112 | }); 113 | return Rx.Observable.combineLatest(imgObs, cssObs); 114 | } -------------------------------------------------------------------------------- /lib/tasks/style.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Rx = require('rxjs'); 4 | const fs = require('fs-extra'); 5 | const path = require('path'); 6 | const chalk = require('chalk'); 7 | const sass = require('node-sass'); 8 | const postcss = require('postcss'); 9 | const sasslint = require('sass-lint'); 10 | const ora = require('ora'); 11 | const frontnote = require('frontnote'); 12 | const util = require('../util/util'); 13 | const timer = require('../util/timer'); 14 | 15 | /** 16 | * style tasks (sass/css) 17 | * @param config{object} style tasks config 18 | * @returns {Rx.Observable} 19 | */ 20 | module.exports = function (config) { 21 | timer.start('style'); 22 | const spinner = ora('[build] style').start(); 23 | lint(); 24 | 25 | let processor = postcss(config.plugins || []); 26 | let files = util.getPath(config.src); 27 | files = files.filter((filepath) => { 28 | return (path.basename(filepath).charAt(0) !== '_'); 29 | }); 30 | 31 | let observables = files.map((filepath) => { 32 | let outputPath = util.destPath(config.src, config.dest, filepath, '.css'); 33 | return parse(processor, filepath, outputPath, config); 34 | }); 35 | 36 | if (config.noGuide !== true) { 37 | let fn = new frontnote(config.styleguide || {}); 38 | observables.push(Rx.Observable.create((obs) => { 39 | fn.render(config.src).subscribe(() => { 40 | obs.next([]); 41 | }, () => { 42 | obs.complete() 43 | }, (e) => { 44 | obs.error(e) 45 | }); 46 | })); 47 | } 48 | 49 | let obs = Rx.Observable.combineLatest(observables).share(); 50 | obs.subscribe(() => { 51 | spinner.succeed(); 52 | timer.end('style'); 53 | }, (e) => { 54 | spinner.fail(); 55 | }); 56 | return obs; 57 | }; 58 | 59 | /** 60 | * SASS Lint 61 | */ 62 | function lint() { 63 | let configPath = path.join(process.cwd(), '.sass-lint.yml'); 64 | if (!util.exists(configPath)) { 65 | configPath = path.join(__dirname, '../../.sass-lint.yml'); 66 | } 67 | let result = sasslint.lintFiles(null, {}, configPath); 68 | sasslint.outputResults(result); 69 | } 70 | 71 | /** 72 | * scss to css 73 | * @param processor{PostCSSProcessor} postcss processor object 74 | * @param filepath{string} scss file path 75 | * @param outputPath{string} dest path 76 | * @returns {Rx.Observable} 77 | */ 78 | function parse(processor, filepath, outputPath, config) { 79 | return Rx.Observable.create((observer) => { 80 | let sourcemap = config.hasOwnProperty('sourceMap') ? config.sourceMap : true; 81 | sass.render({ 82 | file: filepath, 83 | outputStyle: config.outputStyle || 'compact', 84 | sourceMap: sourcemap ? true : false, 85 | outFile: sourcemap ? outputPath : null, 86 | importer(url, prev, done) { 87 | if (url[0] === '~') { 88 | url = path.resolve('node_modules', url.substr(1)); 89 | } 90 | return {file: url}; 91 | } 92 | }, (e, result) => { 93 | if (e) return observer.error(e); 94 | let basename = path.basename(outputPath); 95 | processor.process(result.css.toString(), { 96 | to: basename, 97 | map: result.map ? { 98 | annotation: `maps/${basename}.map`, 99 | prev: result.map.toString() 100 | } : null 101 | }).then((result) => { 102 | output(outputPath, result).subscribe((res) => { 103 | observer.next(res); 104 | }, (e) => { 105 | observer.error(e); 106 | }); 107 | }); 108 | }); 109 | }); 110 | } 111 | 112 | /** 113 | * output css & map 114 | * @param outputPath{string} dest path 115 | * @param result{PostCSSResultObject} 116 | * @returns {Rx.Observable} 117 | */ 118 | function output(outputPath, result) { 119 | let cssObs = Rx.Observable.create((observer) => { 120 | fs.outputFile(outputPath, result.css, (err) => { 121 | if (err) return observer.error(err); 122 | observer.next(outputPath); 123 | }); 124 | }); 125 | if (result.map) { 126 | let basename = path.basename(outputPath); 127 | let map = path.join(path.dirname(outputPath), 'maps', `${basename}.map`); 128 | let mapObs = Rx.Observable.create((observer) => { 129 | fs.outputFile(map, result.map, (err) => { 130 | if (err) return observer.error(err); 131 | observer.next(map); 132 | }); 133 | }); 134 | cssObs = cssObs.combineLatest(mapObs); 135 | } 136 | return cssObs; 137 | } -------------------------------------------------------------------------------- /lib/tasks/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Rx = require('rxjs'); 4 | const Server = require('karma').Server; 5 | const timer = require('../util/timer'); 6 | 7 | /** 8 | * test task 9 | * @param config{Function} karma config function 10 | * @returns {Rx.Observable} 11 | */ 12 | module.exports = function (config, watch) { 13 | timer.start('test'); 14 | return Rx.Observable.create((observer) => { 15 | if (watch) { 16 | config.autoWatch = true; 17 | config.singleRun = false; 18 | } 19 | new Server(config) 20 | .on('run_complete', (browser, result) => { 21 | timer.end('test'); 22 | if (result.error) { 23 | observer.error(result.failed); 24 | } else { 25 | setTimeout(() => { 26 | observer.next(browser) 27 | }); 28 | } 29 | }).on('browser_error', (browser, err) => { 30 | timer.end('test'); 31 | observer.error(err); 32 | }).start(); 33 | }); 34 | }; 35 | -------------------------------------------------------------------------------- /lib/util/download.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const Rx = require('rxjs'); 3 | const downloader = require('download-github-repo'); 4 | const ora = require('ora'); 5 | 6 | function download(template, destPath) { 7 | return Rx.Observable.create((observer) => { 8 | const spinner = ora(`[download] ${template}`).start(); 9 | downloader(template, destPath, (e) => { 10 | if (e) { 11 | console.error(e); 12 | spinner.fail(); 13 | observer.error(e); 14 | process.exit(1); 15 | } 16 | spinner.succeed(); 17 | observer.next(destPath); 18 | }); 19 | }); 20 | } 21 | 22 | module.exports = download; -------------------------------------------------------------------------------- /lib/util/install.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const Rx = require('rxjs'); 3 | const spawn = require('cross-spawn'); 4 | 5 | /** 6 | * npm startコマンドを実行 7 | */ 8 | function npmInstall(dir, useYarn, packageNames) { 9 | return Rx.Observable.create((observer) => { 10 | let command = 'npm'; 11 | if (useYarn) { 12 | command = 'yarn'; 13 | } 14 | let params = ['install']; 15 | if (packageNames) { 16 | params = params.concat(packageNames); 17 | } 18 | spawn(command, params, { 19 | cwd: dir, 20 | stdio: 'inherit' 21 | }).on('exit', (code, signal) => { 22 | if (code === 0) { 23 | observer.next(code); 24 | } else { 25 | observer.error(code); 26 | } 27 | }); 28 | }); 29 | } 30 | module.exports = npmInstall; -------------------------------------------------------------------------------- /lib/util/timer.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const Table = require('cli-table'); 3 | const chalk = require('chalk'); 4 | 5 | /** 6 | * Build time logger 7 | */ 8 | class TimeLogger { 9 | constructor() { 10 | this.logs = {}; 11 | this.record = {}; 12 | } 13 | 14 | /** 15 | * start timer 16 | * @param name{string} timer name 17 | */ 18 | start(name) { 19 | this.logs[name] = Date.now(); 20 | } 21 | 22 | /** 23 | * stop timer 24 | * @param name{string} timer name 25 | * @returns {number} lap time(ms) 26 | */ 27 | end(name) { 28 | let lap = Date.now() - this.logs[name]; 29 | this.record[name] = lap; 30 | return lap; 31 | } 32 | 33 | /** 34 | * Get lap time 35 | * @param name{string} timer name 36 | * @returns {*|Number} lap time(ms) or NaN 37 | */ 38 | get(name) { 39 | return this.record[name] || NaN; 40 | } 41 | 42 | /** 43 | * Reset all timer 44 | */ 45 | reset() { 46 | this.logs = {}; 47 | this.record = {}; 48 | } 49 | 50 | /** 51 | * Output time logs 52 | */ 53 | output() { 54 | const table = new Table({ 55 | head: ['Task name', 'Time(ms)'], 56 | style: { 57 | head: ['cyan'], 58 | compact: true 59 | } 60 | }); 61 | let totalTime = 0; 62 | Object.keys(this.record).forEach((key) => { 63 | totalTime += this.record[key]; 64 | }); 65 | Object.keys(this.record).forEach((key) => { 66 | let time = this.record[key]; 67 | let bar = createBar(time, totalTime); 68 | table.push([key, bar]); 69 | }); 70 | table.push(['total', `${totalTime}ms`]); 71 | //table.push(['total', createBar(totalTime,totalTime)]); 72 | let str = table.toString(); 73 | console.log(str); 74 | return str; 75 | } 76 | } 77 | 78 | /** 79 | * Create string bar 80 | * @param time{Number} build time 81 | * @param totalTime{Number} total build time 82 | * @returns {string} bar string 83 | */ 84 | function createBar(time, totalTime) { 85 | let percentage = time / totalTime; 86 | let rounded = Math.round(percentage * 100); 87 | if (rounded === 0) { 88 | return `${time}ms`; 89 | } 90 | let barLength = Math.ceil(50 * percentage) + 1; 91 | let bar = new Array(barLength).join('■'); 92 | if (time > 5000) { 93 | return `${bar} ${chalk.red(time)}ms`; 94 | } else if (time > 2000) { 95 | return `${bar} ${chalk.yellow(time)}ms`; 96 | } 97 | return `${bar} ${time}ms`; 98 | } 99 | 100 | module.exports = new TimeLogger(); -------------------------------------------------------------------------------- /lib/util/util.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const path = require('path'); 3 | const fs = require('fs'); 4 | const glob = require('glob'); 5 | const globBase = require('glob-base'); 6 | const merge = require('webpack-merge'); 7 | 8 | /** 9 | * Utilities 10 | * @type {object} 11 | */ 12 | const Util = { 13 | /** 14 | * Get filepath by glob pattern string 15 | * @param pattern{string} glob pattern string 16 | * @returns {stringp[]} 17 | */ 18 | getPath(pattern) { 19 | return glob.sync(pattern); 20 | }, 21 | /** 22 | * Get config file path (local or global) 23 | * @returns {string} 24 | */ 25 | getLocalConfig() { 26 | let script = path.join(process.cwd(), 'frp.config.js'); 27 | try { 28 | if (fs.statSync(script).isFile()) { 29 | return script; 30 | } 31 | } catch (e) { 32 | } 33 | return path.join(__dirname, '../frp.config.js'); 34 | }, 35 | /** 36 | * Create dest file path 37 | * @param pattern{string} glob pattern string 38 | * @param dest{string} dest path 39 | * @param filepath{string} filepath 40 | * @param ext{string} file extension 41 | * @returns {string} 42 | */ 43 | destPath(pattern, dest, filepath, ext) { 44 | let globStats = globBase(pattern), 45 | baseExt = path.extname(filepath), 46 | filename = path.basename(filepath, baseExt), 47 | dirname = path.dirname(filepath).replace(globStats.base, ''); 48 | ext = ext || baseExt; 49 | return path.join(dest, dirname, filename + ext); 50 | }, 51 | /** 52 | * Check file exists 53 | * @param filepath{string} 54 | * @returns {boolean} 55 | */ 56 | exists(filepath) { 57 | try { 58 | let stats = fs.statSync(filepath); 59 | return stats.isFile() || stats.isDirectory(); 60 | } catch (e) { 61 | } 62 | return false; 63 | }, 64 | existsConfig() { 65 | let confpath = path.join(process.cwd(), 'frp.config.js'); 66 | return this.exists(confpath); 67 | }, 68 | flatten(arr) { 69 | if (!arr) return []; 70 | return Array.prototype.concat.apply([], arr); 71 | }, 72 | getConfig(program) { 73 | let config = {}; 74 | let localConfig = path.join(process.cwd(), 'frp.config.js'); 75 | if (program.config) { 76 | config = require(path.join(process.cwd(), program.config))(program.production || false); 77 | } else if (this.exists(localConfig)) { 78 | config = require(localConfig)(program.production || false); 79 | } 80 | let defaultConfig = require('../../frp.config')(program.production || false); 81 | for (let key in config) { 82 | if (config[key] instanceof Object) { 83 | if (!defaultConfig[key]) defaultConfig[key] = {}; 84 | for (let inkey in config[key]) { 85 | defaultConfig[key][inkey] = config[key][inkey]; 86 | } 87 | } else { 88 | defaultConfig[key] = config[key]; 89 | } 90 | } 91 | return defaultConfig; 92 | } 93 | }; 94 | module.exports = Util; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontplate-cli", 3 | "version": "4.2.2", 4 | "description": "", 5 | "main": "index.js", 6 | "engines": { 7 | "node": ">=5.0.0" 8 | }, 9 | "scripts": { 10 | "test": "mocha --require intelli-espower-loader -R spec ./test/index.js", 11 | "changelog": "conventional-changelog -p eslint -i CHANGELOG.md -w -s -r 0" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://frontainer@github.com/frontainer/frontplate-cli.git" 16 | }, 17 | "keywords": [ 18 | "frontplate", 19 | "cli", 20 | "front-end", 21 | "development", 22 | "template" 23 | ], 24 | "author": "frontainer", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/frontainer/frontplate-cli/issues" 28 | }, 29 | "bin": { 30 | "frp": "./index.js" 31 | }, 32 | "homepage": "https://github.com/frontainer/frontplate-cli#readme", 33 | "dependencies": { 34 | "autoprefixer": "6.6.1", 35 | "babel-cli": "6.18.0", 36 | "babel-loader": "6.2.10", 37 | "babel-preset-es2015": "6.18.0", 38 | "browser-sync": "2.18.5", 39 | "chalk": "1.1.3", 40 | "cli-table": "0.3.1", 41 | "cpx": "1.5.0", 42 | "cross-spawn": "5.0.1", 43 | "del": "2.2.2", 44 | "download-github-repo": "0.1.3", 45 | "ejs": "2.5.5", 46 | "eslint": "3.12.2", 47 | "eslint-loader": "1.6.1", 48 | "frontnote": "2.0.4", 49 | "fs-extra": "1.0.0", 50 | "gaze": "1.1.2", 51 | "glob": "7.1.1", 52 | "glob-base": "0.3.0", 53 | "html-loader": "0.4.4", 54 | "htmlhint": "0.9.13", 55 | "inquirer": "2.0.0", 56 | "jasmine": "2.5.2", 57 | "json-loader": "0.5.4", 58 | "json2css": "6.1.0", 59 | "karma": "1.3.0", 60 | "karma-jasmine": "1.1.0", 61 | "karma-phantomjs-launcher": "1.0.2", 62 | "karma-webpack": "1.8.1", 63 | "mkdirp": "0.5.1", 64 | "node-sass": "4.5", 65 | "ora": "0.4.0", 66 | "phantomjs-prebuilt": "2.1.14", 67 | "postcss": "5.2.8", 68 | "postcss-csso": "1.1.2", 69 | "rxjs": "5.0.2", 70 | "sass-lint": "1.10.2", 71 | "spritesmith": "3.1.0", 72 | "update-notifier": "1.0.3", 73 | "webpack": "2.2.0-rc.3", 74 | "webpack-build-notifier": "0.1.13", 75 | "webpack-entries": "1.0.0", 76 | "webpack-merge": "2.0.0", 77 | "yargs": "6.6.0" 78 | }, 79 | "devDependencies": { 80 | "conventional-changelog-cli": "1.2.0", 81 | "espower-loader": "1.2.0", 82 | "intelli-espower-loader": "1.0.1", 83 | "mocha": "3.2.0", 84 | "power-assert": "1.4.2", 85 | "rimraf": "2.5.4" 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /template/sprite/sprite.ejs: -------------------------------------------------------------------------------- 1 | <% items.forEach(function(item) {%>$<%= filename %>-<%= item.name %>: ( 2 | x: <%= item.x %>, 3 | y: <%= item.y %>, 4 | width: <%= item.width %>, 5 | height: <%= item.height %>, 6 | total_width: <%= item.total_width %>, 7 | total_height: <%= item.total_height %>, 8 | image: "<%= item.image %>", 9 | offset_x: <%= item.offset_x %>, 10 | offset_y: <%= item.offset_y %> 11 | );<% }); %> 12 | <% if (config.mixin !== false) {%> 13 | @mixin sprite($variable,$scale:1) { 14 | $image: map_get($variable,image); 15 | $offset_x: map_get($variable,offset_x) * $scale; 16 | $offset_y: map_get($variable,offset_y) * $scale; 17 | $width: map_get($variable,width) * $scale; 18 | $height: map_get($variable,height) * $scale; 19 | $total_width: map_get($variable,total_width) * $scale; 20 | $total_height: map_get($variable,total_height) * $scale; 21 | background-image: url($image); 22 | background-position: #{$offset_x}px #{$offset_y}px; 23 | background-size: #{$total_width}px #{$total_height}px; 24 | width: #{$width}px; 25 | height: #{$height}px; 26 | } 27 | <% } %> 28 | <% if (config.selector !== false) { var scale = config.scale || 1; %> 29 | .<%= filename %> { 30 | display: inline-block; 31 | background-repeat: no-repeat; 32 | <% items.forEach(function(item) {%> 33 | &.<%= filename %>-<%= item.name %>{ 34 | @include sprite($<%= filename %>-<%= item.name %>, <%= scale%>); 35 | }<% }); %> 36 | }<% } %> -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | // require('./install'); 3 | require('./timer'); 4 | require('./util'); 5 | require('./task'); -------------------------------------------------------------------------------- /test/install.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const assert = require('power-assert'); 3 | const install = require('../lib/util/install'); 4 | describe('install', function() { 5 | this.timeout(1000000); 6 | it('install',(done) => { 7 | install(process.cwd()).subscribe((code) => { 8 | assert(code === 0); 9 | done(); 10 | }); 11 | }); 12 | }); -------------------------------------------------------------------------------- /test/task/clean.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const assert = require('power-assert'); 3 | const clean = require('../../lib/tasks/clean'); 4 | describe('clean', function() { 5 | it('init',(done) => { 6 | clean({src: 'tmp'}).subscribe(() => { 7 | done(); 8 | }); 9 | }); 10 | }); -------------------------------------------------------------------------------- /test/task/copy.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const assert = require('power-assert'); 3 | const copy = require('../../lib/tasks/copy'); 4 | describe('copy', function() { 5 | it('init',() => { 6 | copy({}).subscribe(() => { 7 | done(); 8 | }); 9 | }); 10 | }); -------------------------------------------------------------------------------- /test/task/html.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const assert = require('power-assert'); 3 | const html = require('../../lib/tasks/html'); 4 | describe('html', function() { 5 | it('init',(done) => { 6 | html({src: 'src/**/*.ejs',dest:'public'}).subscribe(() => { 7 | done(); 8 | }); 9 | }); 10 | }); -------------------------------------------------------------------------------- /test/task/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.clean = require('./clean'); 4 | module.exports.copy = require('./copy'); 5 | module.exports.html = require('./html'); 6 | module.exports.script = require('./script'); 7 | module.exports.server = require('./server'); 8 | module.exports.sprite = require('./sprite'); 9 | module.exports.style = require('./style'); 10 | module.exports.test = require('./test'); -------------------------------------------------------------------------------- /test/task/script.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const assert = require('power-assert'); 3 | const script = require('../../lib/tasks/script'); 4 | describe('script', function() { 5 | it('init',(done) => { 6 | script({}).subscribe(() => { 7 | done(); 8 | }); 9 | }); 10 | }); -------------------------------------------------------------------------------- /test/task/server.js: -------------------------------------------------------------------------------- 1 | // 'use strict'; 2 | // const assert = require('power-assert'); 3 | // const fs = require('fs'); 4 | // const rimraf = require('rimraf'); 5 | // const server = require('../../lib/tasks/server'); 6 | // describe('server', function() { 7 | // beforeEach(() => { 8 | // // rimraf.sync(DEST); 9 | // }); 10 | // afterEach(() => { 11 | // // rimraf.sync(DEST); 12 | // }); 13 | // it('',() => { 14 | // 15 | // }); 16 | // }); -------------------------------------------------------------------------------- /test/task/sprite.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const assert = require('power-assert'); 3 | const sprite = require('../../lib/tasks/sprite'); 4 | describe('sprite', function() { 5 | it('init',(done) => { 6 | sprite([]).subscribe(() => { 7 | done(); 8 | }); 9 | }); 10 | }); -------------------------------------------------------------------------------- /test/task/style.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const assert = require('power-assert'); 3 | const style = require('../../lib/tasks/style'); 4 | describe('style', function() { 5 | it('init',(done) => { 6 | style({src:'src/**/.scss',dest:'public'}).subscribe(() => { 7 | done(); 8 | }); 9 | }); 10 | }); -------------------------------------------------------------------------------- /test/task/test.js: -------------------------------------------------------------------------------- 1 | // 'use strict'; 2 | // const assert = require('power-assert'); 3 | // const test = require('../../lib/tasks/test'); 4 | // describe('test', function() { 5 | // this.timeout(100000); 6 | // it('init',(done) => { 7 | // test(function() { 8 | // return {}; 9 | // },false).subscribe(() => { 10 | // done(); 11 | // }); 12 | // }); 13 | // }); -------------------------------------------------------------------------------- /test/timer.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const assert = require('power-assert'); 3 | const fs = require('fs'); 4 | const rimraf = require('rimraf'); 5 | const timer = require('../lib/util/timer'); 6 | describe('timer', function() { 7 | beforeEach(() => { 8 | timer.reset(); 9 | }); 10 | afterEach(() => { 11 | 12 | }); 13 | it('default',() => { 14 | assert(isNaN(timer.get('test'))); 15 | }); 16 | it('record',(done) => { 17 | timer.start('test'); 18 | timer.start('test2'); 19 | setTimeout(() => { 20 | timer.end('test'); 21 | timer.end('test2'); 22 | assert(!isNaN(timer.get('test'))); 23 | assert(!isNaN(timer.get('test2'))); 24 | done(); 25 | },100); 26 | }); 27 | it('reset',(done) => { 28 | timer.start('test'); 29 | setTimeout(() => { 30 | timer.end('test'); 31 | timer.reset(); 32 | assert(isNaN(timer.get('test'))); 33 | done(); 34 | },100); 35 | }); 36 | it('output',(done) => { 37 | timer.start('test'); 38 | timer.start('test2'); 39 | setTimeout(() => { 40 | timer.end('test'); 41 | timer.end('test2'); 42 | let str = timer.output(); 43 | assert(str); 44 | done(); 45 | },100); 46 | }); 47 | }); -------------------------------------------------------------------------------- /test/util.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const assert = require('power-assert'); 3 | const fs = require('fs'); 4 | const rimraf = require('rimraf'); 5 | const util = require('../lib/util/util'); 6 | const merge = require('webpack-merge'); 7 | describe('install', function () { 8 | beforeEach(() => { 9 | // rimraf.sync(DEST); 10 | }); 11 | afterEach(() => { 12 | // rimraf.sync(DEST); 13 | }); 14 | it('getPath', () => { 15 | let p = util.getPath('*.js'); 16 | assert(p.length === 2); 17 | assert.deepEqual(p, [ 18 | 'frp.config.js', 19 | 'index.js' 20 | ]); 21 | 22 | p = util.getPath('test/*.js'); 23 | assert(p.length === 4); 24 | assert.deepEqual(p, [ 25 | 'test/index.js', 26 | 'test/install.js', 27 | 'test/timer.js', 28 | 'test/util.js' 29 | ]); 30 | }); 31 | it('getLocalConfig', () => { 32 | assert(util.getLocalConfig() === process.cwd() + '/frp.config.js'); 33 | }); 34 | it('destPath', () => { 35 | assert(util.destPath('*.js', 'public', 'test.js') === 'public/test.js'); 36 | assert(util.destPath('js/*.js', 'public', 'test.js') === 'public/test.js'); 37 | assert(util.destPath('js/*.ts', 'public', 'test.ts', '.js') === 'public/test.js'); 38 | assert(util.destPath('js/**/*.ts', 'public/js', 'test.ts', '.js') === 'public/js/test.js'); 39 | }); 40 | it('exists', () => { 41 | assert(util.exists('./frp.config.js')); 42 | assert(!util.exists('./hoge.config.js')); 43 | }); 44 | it('existsConfig', () => { 45 | assert(util.existsConfig()); 46 | }); 47 | it('flatten', () => { 48 | assert.deepEqual(util.flatten(null), []); 49 | assert.deepEqual(util.flatten(['a', 'b', 'c']), ['a', 'b', 'c']); 50 | assert.deepEqual(util.flatten(['a', 'b', ['c']]), ['a', 'b', 'c']); 51 | assert.deepEqual(util.flatten([['a'], 'b', ['c']]), ['a', 'b', 'c']); 52 | assert.deepEqual(util.flatten([['a', 'b'], ['c']]), ['a', 'b', 'c']); 53 | assert.deepEqual(util.flatten([['a', ['b']], ['c']]), ['a', ['b'], 'c']); 54 | assert.deepEqual(util.flatten(util.flatten([['a', ['b']], ['c']])), ['a', 'b', 'c']); 55 | }); 56 | it('getConfig', () => { 57 | assert.deepEqual(util.getConfig({}),{ 58 | clean: { 59 | src: 'public' 60 | }, 61 | html: require('../config/html.config'), 62 | style: require('../config/style.config'), 63 | script: require('../config/webpack.config'), 64 | server: require('../config/server.config'), 65 | copy: require('../config/copy.config'), 66 | sprite: require('../config/sprite.config'), 67 | test: require('../config/test.conf') 68 | }); 69 | assert.deepEqual(util.getConfig({production:true}),{ 70 | clean: { 71 | src: 'public' 72 | }, 73 | html: require('../config/html.config'), 74 | style: require('../config/style.config.production'), 75 | script: require('../config/webpack.config.production'), 76 | server: require('../config/server.config'), 77 | copy: require('../config/copy.config'), 78 | sprite: require('../config/sprite.config'), 79 | test: require('../config/test.conf') 80 | }); 81 | }); 82 | }); --------------------------------------------------------------------------------