├── .eslintignore ├── .eslintrc ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── nodejs.yml │ └── release.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── agent.js ├── app.js ├── app └── extend │ └── helper.js ├── config ├── config.default.js └── config.unittest.js ├── lib ├── assets_context.js ├── assets_view.js ├── dev_server.js └── util │ ├── constant.js │ └── default_template.js ├── package.json └── test ├── assets.test.js ├── dev_server.test.js ├── fixtures └── apps │ ├── assets-nonce │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── extend │ │ │ └── context.js │ │ ├── router.js │ │ └── view │ │ │ ├── account.jsx │ │ │ └── index.js │ ├── config │ │ ├── config.default.js │ │ ├── config.prod.js │ │ └── manifest.json │ └── package.json │ ├── assets-template │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ ├── index.js │ │ │ ├── template.ejs │ │ │ └── template.html │ ├── config │ │ ├── config.default.js │ │ ├── config.prod.js │ │ ├── manifest.json │ │ └── plugin.js │ └── package.json │ ├── assets │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ ├── account.jsx │ │ │ └── index.js │ ├── config │ │ ├── config.default.js │ │ ├── config.prod.js │ │ └── manifest.json │ └── package.json │ ├── autoport-offset │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ └── config.default.js │ └── package.json │ ├── autoport │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ └── config.default.js │ └── package.json │ ├── command-error │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ └── config.default.js │ └── package.json │ ├── complex-manifest │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── public │ │ │ ├── index.css │ │ │ └── index.js │ │ ├── router.js │ │ └── view │ │ │ ├── index.js │ │ │ └── layout.html │ ├── config │ │ ├── config.default.js │ │ ├── manifest.json │ │ └── plugin.js │ └── package.json │ ├── context-security │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ ├── config.default.js │ │ └── manifest.json │ └── package.json │ ├── crossorigin │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── public │ │ │ ├── index.css │ │ │ └── index.js │ │ ├── router.js │ │ └── view │ │ │ ├── index.js │ │ │ └── layout.html │ ├── config │ │ ├── config.default.js │ │ ├── manifest.json │ │ └── plugin.js │ └── package.json │ ├── custom-assets-url │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ ├── config.default.js │ │ ├── config.prod.js │ │ └── manifest.json │ └── package.json │ ├── custom-context-key │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ └── config.default.js │ └── package.json │ ├── custom-dev-server │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ ├── config.default.js │ │ └── server.js │ └── package.json │ ├── custom-public-path │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ ├── config.default.js │ │ ├── manifest.json │ │ └── server.js │ └── package.json │ ├── dev-server-no-port │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ ├── config.default.js │ │ └── server.js │ └── package.json │ ├── https-dynamic-ip │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ └── config.default.js │ ├── package.json │ ├── server.cert │ └── server.key │ ├── https │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ └── config.default.js │ ├── package.json │ ├── server.cert │ └── server.key │ ├── mocktool │ └── server.js │ ├── multiple-getscript │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ ├── config.default.js │ │ └── manifest.json │ └── package.json │ ├── no-manifest │ ├── config │ │ └── config.default.js │ └── package.json │ ├── not-listen │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ └── config.default.js │ └── package.json │ ├── other-view-engine │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.html │ ├── config │ │ ├── config.default.js │ │ ├── config.prod.js │ │ ├── manifest.json │ │ └── plugin.js │ └── package.json │ ├── tool-roadhog │ ├── app │ │ ├── controller │ │ │ └── home.js │ │ ├── router.js │ │ └── view │ │ │ └── index.js │ ├── config │ │ └── config.default.js │ └── package.json │ └── ui │ ├── app │ ├── controller │ │ └── home.js │ ├── public │ │ ├── index.css │ │ └── index.js │ ├── router.js │ └── view │ │ ├── index.js │ │ └── layout.html │ ├── config │ ├── config.default.js │ ├── manifest.json │ └── plugin.js │ └── package.json ├── roadhog.test.js └── ui.test.js /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage 2 | lib/fixtures 3 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint-config-egg" 3 | } 4 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ##### Checklist 12 | 13 | 14 | - [ ] `npm test` passes 15 | - [ ] tests and/or benchmarks are included 16 | - [ ] documentation is changed or added 17 | - [ ] commit message follows commit guidelines 18 | 19 | ##### Affected core subsystem(s) 20 | 21 | 22 | 23 | ##### Description of change 24 | 25 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | 7 | pull_request: 8 | branches: [ master ] 9 | 10 | jobs: 11 | Job: 12 | name: Node.js 13 | uses: node-modules/github-actions/.github/workflows/node-test.yml@master 14 | with: 15 | os: 'ubuntu-latest, macos-latest, windows-latest' 16 | version: '14, 16, 18, 20' 17 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | 7 | jobs: 8 | release: 9 | name: Node.js 10 | uses: eggjs/github-actions/.github/workflows/node-release.yml@master 11 | secrets: 12 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 13 | GIT_TOKEN: ${{ secrets.GIT_TOKEN }} 14 | with: 15 | checkTest: false 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs/ 2 | npm-debug.log 3 | node_modules/ 4 | coverage/ 5 | .idea/ 6 | run/ 7 | .DS_Store 8 | *.swp 9 | test/fixtures/apps/assets-template/app/view/cache.html 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [1.10.0](https://github.com/eggjs/egg-view-assets/compare/v1.9.0...v1.10.0) (2025-01-23) 4 | 5 | 6 | ### Features 7 | 8 | * css support crossorigin ([#50](https://github.com/eggjs/egg-view-assets/issues/50)) ([bbb2794](https://github.com/eggjs/egg-view-assets/commit/bbb2794d162dda65729ca828da278fa85e2b34b2)) 9 | 10 | ## [1.9.0](https://github.com/eggjs/egg-view-assets/compare/v1.8.4...v1.9.0) (2023-09-20) 11 | 12 | 13 | ### Features 14 | 15 | * change __webpack_public_path__ var value to assets.resourceBase ([#49](https://github.com/eggjs/egg-view-assets/issues/49)) ([a8f9f94](https://github.com/eggjs/egg-view-assets/commit/a8f9f949ebe43e8d80e4503a89eb0a30ba9ca93c)) 16 | 17 | ## [1.8.4](https://github.com/eggjs/egg-view-assets/compare/v1.8.3...v1.8.4) (2023-09-14) 18 | 19 | 20 | ### Bug Fixes 21 | 22 | * config.publicPath setting / to // bug ([#47](https://github.com/eggjs/egg-view-assets/issues/47)) ([b408ffd](https://github.com/eggjs/egg-view-assets/commit/b408ffd4b42cf82381c190b100815e9e7760885b)) 23 | 24 | ## [1.8.3](https://github.com/eggjs/egg-view-assets/compare/v1.8.2...v1.8.3) (2023-05-16) 25 | 26 | 27 | ### Bug Fixes 28 | 29 | * the paths should be separated by ';' ([#46](https://github.com/eggjs/egg-view-assets/issues/46)) ([d1d10a5](https://github.com/eggjs/egg-view-assets/commit/d1d10a55798bcf6ade02d276ba96eea92b39e0f2)) 30 | 31 | ## [1.8.2](https://github.com/eggjs/egg-view-assets/compare/v1.8.1...v1.8.2) (2023-05-16) 32 | 33 | 34 | ### Bug Fixes 35 | 36 | * handle path compatibility issues on Windows ([#45](https://github.com/eggjs/egg-view-assets/issues/45)) ([16d849d](https://github.com/eggjs/egg-view-assets/commit/16d849d287fea248a330516e9b3f9289bf374a4b)) 37 | 38 | ## [1.8.1](https://github.com/eggjs/egg-view-assets/compare/v1.8.0...v1.8.1) (2023-04-27) 39 | 40 | 41 | ### Bug Fixes 42 | 43 | * compatible windows env.Path environment value ([#43](https://github.com/eggjs/egg-view-assets/issues/43)) ([c66b7d1](https://github.com/eggjs/egg-view-assets/commit/c66b7d1b78761023377b6278802e62c752a50946)) 44 | 45 | --- 46 | 47 | 48 | 1.8.0 / 2021-10-16 49 | ================== 50 | 51 | **features** 52 | * [[`cdab574`](http://github.com/eggjs/egg-view-assets/commit/cdab574d0d5a95533a6b7a8af34f850b0168b532)] - feat: support config.nonce (#42) (Yiyu He <>) 53 | 54 | 1.7.0 / 2021-04-08 55 | ================== 56 | 57 | **features** 58 | * [[`6c5b719`](http://github.com/eggjs/egg-view-assets/commit/6c5b71913994a0f18bf4585df6245cbba0390e3f)] - feat: start detecting port from devServer.port (#40) (Chen Yangjian <<252317+cyjake@users.noreply.github.com>>) 59 | 60 | 1.6.2 / 2021-03-22 61 | ================== 62 | 63 | **fixes** 64 | * [[`ee0012e`](http://github.com/eggjs/egg-view-assets/commit/ee0012eca841b1ce2b3264e8154a9a4e3d5f8c15)] - fix: 修复autoPort时,port数据格式和fs模块要求数据格式不匹配问题 (#39) (拾邑 <>) 65 | 66 | 1.6.1 / 2020-06-09 67 | ================== 68 | 69 | **features** 70 | * [[`c7ec6e6`](http://github.com/eggjs/egg-view-assets/commit/c7ec6e671220a71db0ba59ef485f064ca622ccd7)] - feat: make sure `__webpack_public_path__` inserted just once (#31) (viko16 <>) 71 | 72 | **fixes** 73 | * [[`c992877`](http://github.com/eggjs/egg-view-assets/commit/c992877307e4c4178e3e337a5ca43a982e3254e4)] - fix: prefer http://127.0.0.1 even if https is on (#37) (Chen Yangjian <<252317+cyjake@users.noreply.github.com>>) 74 | 75 | 1.6.0 / 2019-09-19 76 | ================== 77 | 78 | **features** 79 | * [[`287aedb`](http://github.com/eggjs/egg-view-assets/commit/287aedb4e1ee58861e76198a364e4ff9d7122d92)] - feat: set protocol according to app.options.https (Chen Yangjian <<252317+cyjake@users.noreply.github.com>>) 80 | 81 | 1.5.0 / 2019-04-09 82 | ================== 83 | 84 | **features** 85 | * [[`226de2e`](http://github.com/eggjs/egg-view-assets/commit/226de2e5ed9d89bac203ead5a47f2a91fd9158ad)] - feat: script support crossorigin attribute (#30) (仙森 <>) 86 | 87 | 1.4.4 / 2019-01-29 88 | ================== 89 | 90 | **fixes** 91 | * [[`8f0092e`](http://github.com/eggjs/egg-view-assets/commit/8f0092ef4e4dd33b63dbf836bdad72bc7a0b88be)] - fix: use w3c valid link format (#29) (fengmk2 <>) 92 | 93 | 1.4.3 / 2019-01-08 94 | ================== 95 | 96 | **fixes** 97 | * [[`f5966ec`](http://github.com/eggjs/egg-view-assets/commit/f5966eca57fcfe5819617e264555ba00c9c6c95b)] - fix(devServer): reset port when app get port from agent (#28) (Haoliang Gao <>) 98 | * [[`a5866bc`](http://github.com/eggjs/egg-view-assets/commit/a5866bc0b47a0df4d024f44b9fc05d39494fcf47)] - fix: remove unnecessary console (#27) (Haoliang Gao <>) 99 | 100 | 1.4.2 / 2019-01-07 101 | ================== 102 | 103 | **features** 104 | * [[`f6e9fb7`](http://github.com/eggjs/egg-view-assets/commit/f6e9fb7b51435516ce9d7f20a8de2e7a62b87c61)] - feat(devServer): support autoport in env (#26) (Haoliang Gao <>) 105 | 106 | 1.4.1 / 2019-01-07 107 | ================== 108 | 109 | **fixes** 110 | * [[`9378984`](http://github.com/eggjs/egg-view-assets/commit/9378984ad71465eb9cc46beba4936e8bb95f97f6)] - fix: port should be paased from agent to app (#25) (Haoliang Gao <>) 111 | 112 | 1.4.0 / 2019-01-06 113 | ================== 114 | 115 | **features** 116 | * [[`59d20a0`](http://github.com/eggjs/egg-view-assets/commit/59d20a0e7f1451aee14cb1a5117e8cda2d999498)] - feat: auto check port with autoPort (#24) (Haoliang Gao <>) 117 | 118 | **others** 119 | * [[`bf05a99`](http://github.com/eggjs/egg-view-assets/commit/bf05a99da9661aa731c6938ec7e8443dd381d2eb)] - refactor: use inherit instead of pipe (#22) (Haoliang Gao <>) 120 | * [[`d233b74`](http://github.com/eggjs/egg-view-assets/commit/d233b74cc38648a310146802385031d001d971e9)] - test: set proc null when exit by self (#23) (Haoliang Gao <>) 121 | 122 | 1.3.0 / 2018-08-20 123 | ================== 124 | 125 | **others** 126 | * [[`0815337`](http://github.com/eggjs/egg-view-assets/commit/0815337586c10ed393786bb7c3ad8f08242a9135)] - refactor: no need to encode context with base64 (#21) (fengmk2 <>) 127 | 128 | 1.2.0 / 2018-08-15 129 | ================== 130 | 131 | **features** 132 | * [[`6d9be84`](http://github.com/eggjs/egg-view-assets/commit/6d9be84495ae1e789e20276f33f184e736cf7e86)] - feat: manifest add absolute path and complete path support (#20) (仙森 <>) 133 | 134 | 1.1.2 / 2018-04-16 135 | ================== 136 | 137 | **others** 138 | * [[`9b32a6e`](http://github.com/eggjs/egg-view-assets/commit/9b32a6ed4e2219e323946fb987e900a1477d66d9)] - refactor: atob should be minified (#16) (Haoliang Gao <>) 139 | 140 | 1.1.1 / 2018-04-15 141 | ================== 142 | 143 | **fixes** 144 | * [[`6d8793b`](http://github.com/eggjs/egg-view-assets/commit/6d8793b43e98618b2be76101011ad8732906f114)] - fix: atob browser compatible (#15) (Haoliang Gao <>) 145 | * [[`2475b7c`](http://github.com/eggjs/egg-view-assets/commit/2475b7c54fe088e2469181eb63f1a48c7c94fdbf)] - fix: command can be run on Windows (#13) (Haoliang Gao <>) 146 | * [[`ab29dee`](http://github.com/eggjs/egg-view-assets/commit/ab29deed14e0b6d266fc5a90b8f46950ce096431)] - fix: set context data more safely (#14) (Yiyu He <>) 147 | 148 | 1.1.0 / 2018-04-04 149 | ================== 150 | 151 | **features** 152 | * [[`772164a`](http://github.com/eggjs/egg-view-assets/commit/772164a3669610659cd43614caf7825a74f30c65)] - feat: unittest environment is same as local (#12) (Haoliang Gao <>) 153 | 154 | 1.0.4 / 2018-04-01 155 | ================== 156 | 157 | **fixes** 158 | * [[`9d7fdac`](http://github.com/eggjs/egg-view-assets/commit/9d7fdac51c6799db63d948b37e94ad47a280a7c4)] - fix: should transform jsx to js (#11) (Haoliang Gao <>) 159 | 160 | 1.0.3 / 2018-04-01 161 | ================== 162 | 163 | **fixes** 164 | * [[`f58d766`](http://github.com/eggjs/egg-view-assets/commit/f58d766907f6e18627a44d42b3513e41b71bcf09)] - fix: check port when devServer is enabled (#10) (Haoliang Gao <>) 165 | 166 | 1.0.2 / 2018-03-29 167 | ================== 168 | 169 | **fixes** 170 | * [[`3f02556`](http://github.com/eggjs/egg-view-assets/commit/3f0255680aa8f6460faf08957efdff184c781b3f)] - fix: publicPath should contains leading and trailing slash (#9) (Haoliang Gao <>) 171 | * [[`5db9e90`](http://github.com/eggjs/egg-view-assets/commit/5db9e906e85a414ae276e7de1033c1539aff8ea5)] - fix: more safe context when locals is from query (#8) (Haoliang Gao <>) 172 | 173 | 1.0.1 / 2018-03-15 174 | ================== 175 | 176 | **fixes** 177 | * [[`2ebef9d`](http://github.com/eggjs/egg-view-assets/commit/2ebef9d86235cc8c13dc262f1b767bdad77cea02)] - fix: publicPath should be __webpack_public_path__ (#7) (Haoliang Gao <>) 178 | 179 | 1.0.0 / 2018-03-15 180 | ================== 181 | 182 | **others** 183 | * [[`e369e2c`](http://github.com/eggjs/egg-view-assets/commit/e369e2c924bb09e949f27e5095c29d7bcddda68a)] - docs: update readme (#6) (Haoliang Gao <>),fatal: No names found, cannot describe anything. 184 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-present Alibaba Group Holding Limited and other contributors. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # egg-view-assets 2 | 3 | [![NPM version][npm-image]][npm-url] 4 | [![Node.js CI](https://github.com/eggjs/egg-view-assets/actions/workflows/nodejs.yml/badge.svg)](https://github.com/eggjs/egg-view-assets/actions/workflows/nodejs.yml) 5 | [![Test coverage][codecov-image]][codecov-url] 6 | [![npm download][download-image]][download-url] 7 | 8 | [npm-image]: https://img.shields.io/npm/v/egg-view-assets.svg?style=flat-square 9 | [npm-url]: https://npmjs.org/package/egg-view-assets 10 | [codecov-image]: https://img.shields.io/codecov/c/github/eggjs/egg-view-assets.svg?style=flat-square 11 | [codecov-url]: https://codecov.io/github/eggjs/egg-view-assets?branch=master 12 | [download-image]: https://img.shields.io/npm/dm/egg-view-assets.svg?style=flat-square 13 | [download-url]: https://npmjs.org/package/egg-view-assets 14 | 15 | Manage frontend assets in development and production. 16 | 17 | ## Install 18 | 19 | ```bash 20 | $ npm i egg-view-assets --save 21 | ``` 22 | 23 | ## Usage 24 | 25 | Add `egg-view-assets` as plugin 26 | 27 | ```js 28 | // {app_root}/config/plugin.js 29 | exports.assets = { 30 | enable: true, 31 | package: 'egg-view-assets', 32 | }; 33 | ``` 34 | 35 | Configuration, you can see full example in [egg-ant-design-pro]. 36 | 37 | ```js 38 | // {app_root}/config/config.default.js 39 | exports.view = { 40 | mapping: { 41 | '.js': 'assets', 42 | }, 43 | }; 44 | 45 | exports.assets = { 46 | devServer: { 47 | command: 'roadhog dev', 48 | port: 8000, 49 | }, 50 | }; 51 | ``` 52 | 53 | See [config/config.default.js](config/config.default.js) for more detail. 54 | 55 | ## Questions & Suggestions 56 | 57 | Please open an issue [here](https://github.com/eggjs/egg/issues). 58 | 59 | ## License 60 | 61 | [MIT](LICENSE) 62 | 63 | [egg-ant-design-pro]: https://github.com/eggjs/egg-ant-design-pro 64 | -------------------------------------------------------------------------------- /agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const DevServer = require('./lib/dev_server'); 5 | 6 | module.exports = agent => startDevServer(agent); 7 | 8 | function startDevServer(agent) { 9 | const assetsConfig = agent.config.assets; 10 | 11 | if (!assetsConfig.isLocalOrUnittest) return; 12 | if (!assetsConfig.devServer.enable) return; 13 | 14 | assert(assetsConfig.devServer.autoPort || assetsConfig.devServer.port, 'port or autoPort is required when devServer is enabled'); 15 | 16 | const server = new DevServer(agent); 17 | server.ready(err => { 18 | if (err) agent.coreLogger.error('[egg-view-assets]', err.message); 19 | }); 20 | 21 | if (assetsConfig.devServer.waitStart) { 22 | agent.beforeStart(async () => { 23 | await server.ready(); 24 | }); 25 | } 26 | 27 | agent.beforeClose(async () => { 28 | await server.close(); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const assert = require('assert'); 6 | const AssetsView = require('./lib/assets_view'); 7 | 8 | module.exports = app => { 9 | const assetsConfig = app.config.assets; 10 | 11 | if (assetsConfig.devServer.enable && assetsConfig.isLocalOrUnittest) { 12 | let port = assetsConfig.devServer.port; 13 | if (assetsConfig.devServer.autoPort === true) { 14 | try { 15 | port = fs.readFileSync(assetsConfig.devServer.portPath, 'utf8'); 16 | assetsConfig.devServer.port = Number(port); 17 | } catch (err) { 18 | // istanbul ignore next 19 | throw new Error('check autoPort fail'); 20 | } 21 | } 22 | const protocol = app.options.https && assetsConfig.dynamicLocalIP ? 'https' : 'http'; 23 | assetsConfig.url = `${protocol}://127.0.0.1:${port}`; 24 | } 25 | 26 | // it should check manifest.json on deployment 27 | if (!assetsConfig.isLocalOrUnittest) { 28 | const manifestPath = path.join(app.config.baseDir, 'config/manifest.json'); 29 | assert(fs.existsSync(manifestPath), `${manifestPath} is required`); 30 | assetsConfig.manifest = require(manifestPath); 31 | } 32 | 33 | app.view.use('assets', AssetsView); 34 | }; 35 | -------------------------------------------------------------------------------- /app/extend/helper.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const AssetsContext = require('../../lib/assets_context'); 4 | 5 | const HELPER_ASSETS = require('../../lib/util/constant').HELPER_ASSETS; 6 | const ASSETS = Symbol('Helper#assets'); 7 | 8 | module.exports = { 9 | get assets() { 10 | if (this[ASSETS]) return this[ASSETS]; 11 | if (this.ctx[HELPER_ASSETS]) { 12 | this[ASSETS] = this.ctx[HELPER_ASSETS]; 13 | } else { 14 | this[ASSETS] = new AssetsContext(this.ctx); 15 | } 16 | return this[ASSETS]; 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = appInfo => ({ 6 | /** 7 | * assets options 8 | * @member Config#assets 9 | * @property {String} url - the host of the assets, it will be `http://127.0.0.1:${devServer.port}` in development. 10 | * @property {String} publicPath - the base path of the assets 11 | * @property {Boolean} resourcePathToURL - convert the value `window.__webpack_public_path__` of the variable into url/publicPath, default is false 12 | * @property {String} templatePath - the file path of template rendering html 13 | * @property {String} templateViewEngine - the view engine for rendering template 14 | * @property {Boolean} crossorigin - if script is cross origin set this config to true 15 | * @property {Boolean} contextKey - the property name of context, default is `context` 16 | * @property {Boolean} devServer - configuration of local assets server 17 | * @property {Boolean} devServer.command - a command for starting a server, such as `webpack` 18 | * @property {Boolean} devServer.port - listening port for the server, it will be checked when starting 19 | * @property {Boolean} devServer.timeout - the timeout for checking listening port 20 | * @property {Boolean} devServer.env - custom environment 21 | * @property {Boolean} devServer.debug - show stdout/stderr for devServer 22 | * @property {Boolean} devServer.waitStart - whether wait devServer starting 23 | * @property {Function} nonce(ctx) - dynamic generate nonce for csp(https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) 24 | */ 25 | assets: { 26 | isLocalOrUnittest: appInfo.env === 'local' || appInfo.env === 'unittest', 27 | url: '', 28 | publicPath: '', 29 | resourcePathToURL: false, 30 | templatePath: '', 31 | templateViewEngine: '', 32 | crossorigin: false, 33 | contextKey: 'context', 34 | dynamicLocalIP: true, 35 | devServer: { 36 | enable: true, 37 | command: '', 38 | autoPort: false, 39 | port: null, 40 | portPath: path.join(appInfo.baseDir, 'run/assetsPort'), 41 | env: {}, 42 | debug: false, 43 | timeout: 60 * 1000, 44 | waitStart: false, 45 | }, 46 | }, 47 | }); 48 | -------------------------------------------------------------------------------- /config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.assets = { 4 | devServer: { 5 | enable: false, 6 | waitStart: true, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /lib/assets_context.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | 5 | // URL consists of host, resourceBase and entry, 6 | // E.X. http://127.0.0.1:7001/public/index.js 7 | // host is http://127.0.0.1:7001 8 | // resourceBase is /public/ 9 | // entry is index.js 10 | class Assets { 11 | 12 | constructor(ctx) { 13 | this.ctx = ctx; 14 | this.config = ctx.app.config.assets; 15 | this.isLocalOrUnittest = this.config.isLocalOrUnittest; 16 | this.manifest = this.config.manifest; 17 | this.crossorigin = this.config.crossorigin; 18 | // publicPath should contain trailing / and leading / 19 | this.publicPath = this.isLocalOrUnittest ? '/' : normalizePublicPath(this.config.publicPath); 20 | // make sure __webpack_public_path__ inserted just once 21 | this.hasWebpackGlobalVariableInserted = false; 22 | this.host = this.config.url; 23 | this.resourceBase = `${this.host}${this.publicPath}`; 24 | this.nonce = this.config.nonce && this.config.nonce(this.ctx); 25 | } 26 | 27 | getStyle(entry) { 28 | entry = entry || this.entryCss; 29 | return linkTpl({ 30 | url: this.getURL(entry), 31 | crossorigin: this.crossorigin, 32 | }); 33 | } 34 | 35 | getScript(entry) { 36 | entry = entry || this.entry; 37 | 38 | let script = ''; 39 | 40 | const webpackPublicPath = this.config.resourcePathToURL ? this.resourceBase : this.publicPath; 41 | if (webpackPublicPath && !this.hasWebpackGlobalVariableInserted) { 42 | script = inlineScriptTpl(`window.__webpack_public_path__ = '${webpackPublicPath}';`, this.nonce); 43 | this.hasWebpackGlobalVariableInserted = true; 44 | } 45 | 46 | script += scriptTpl({ 47 | url: this.getURL(entry), 48 | crossorigin: this.crossorigin, 49 | }); 50 | 51 | return script; 52 | } 53 | 54 | getContext(data) { 55 | data = safeStringify(data || this.assetsContext || {}); 56 | return inlineScriptTpl(`(function(){window.${this.config.contextKey} = JSON.parse(decodeURIComponent("${data}"));})()`, this.nonce); 57 | } 58 | 59 | getURL(entry) { 60 | let urlpath = entry; 61 | if (!this.isLocalOrUnittest) { 62 | urlpath = this.manifest[urlpath]; 63 | assert(urlpath, `Don't find ${entry} in manifest.json`); 64 | } 65 | 66 | if (urlpath.startsWith('/')) { 67 | return `${this.host}${urlpath}`; 68 | } 69 | 70 | if (urlpath.startsWith('http://') || urlpath.startsWith('https://')) { 71 | return urlpath; 72 | } 73 | 74 | return `${this.resourceBase}${urlpath}`; 75 | } 76 | 77 | setEntry(entry) { 78 | this.entry = entry.replace(/\.jsx?$/, '.js'); 79 | this.entryCss = entry.replace(/\.jsx?$/, '.css'); 80 | } 81 | 82 | setContext(context) { 83 | this.assetsContext = context; 84 | } 85 | 86 | } 87 | 88 | module.exports = Assets; 89 | 90 | function linkTpl({ url, crossorigin }) { 91 | return crossorigin ? `` : ``; 92 | } 93 | 94 | function scriptTpl({ url, crossorigin }) { 95 | return '`; 96 | } 97 | 98 | function inlineScriptTpl(content, nonce) { 99 | const startTag = nonce ? ``; 101 | } 102 | 103 | function safeStringify(data) { 104 | if (!data) return ''; 105 | return encodeURIComponent(JSON.stringify(data)); 106 | } 107 | 108 | function normalizePublicPath(publicPath) { 109 | if (!publicPath) return '/'; 110 | if (publicPath === '/') return publicPath; 111 | 112 | let firstIndex = 0; 113 | if (publicPath[firstIndex] === '/') firstIndex++; 114 | let lastIndex = publicPath.length - 1; 115 | if (publicPath[lastIndex] === '/') lastIndex--; 116 | return '/' + publicPath.slice(firstIndex, lastIndex + 1) + '/'; 117 | } 118 | -------------------------------------------------------------------------------- /lib/assets_view.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('mz/fs'); 4 | const TEMPLATE_CACHE = Symbol('AssetsView#templateCache'); 5 | const HELPER_ASSETS = require('./util/constant').HELPER_ASSETS; 6 | const renderDefault = require('./util/default_template'); 7 | 8 | 9 | class AssetsView { 10 | constructor(ctx) { 11 | this.ctx = ctx; 12 | this.config = ctx.app.config.assets; 13 | this.logger = ctx.coreLogger; 14 | 15 | if (!ctx.app[TEMPLATE_CACHE]) ctx.app[TEMPLATE_CACHE] = new Map(); 16 | this.cache = ctx.app[TEMPLATE_CACHE]; 17 | } 18 | 19 | async render(name, locals, options) { 20 | const templateViewEngine = options.templateViewEngine || this.config.templateViewEngine; 21 | const templatePath = options.templatePath || this.config.templatePath; 22 | 23 | const assets = this.ctx.helper.assets; 24 | assets.setEntry(options.name); 25 | assets.setContext(options.locals); 26 | 27 | if (templateViewEngine && templatePath) { 28 | // helper.assets will use this instance 29 | this.ctx[HELPER_ASSETS] = assets; 30 | 31 | const templateStr = await this.readFileWithCache(templatePath); 32 | this.logger.info('[egg-view-assets] use %s to render %s, entry is %s', 33 | templateViewEngine, templatePath, name); 34 | return await this.ctx.renderString(templateStr, locals, { 35 | viewEngine: templateViewEngine, 36 | }); 37 | } 38 | 39 | return renderDefault(assets); 40 | } 41 | 42 | async readFileWithCache(filepath) { 43 | let str = this.cache.get(filepath); 44 | if (str) return str; 45 | 46 | str = await fs.readFile(filepath, 'utf8'); 47 | this.cache.set(filepath, str); 48 | return str; 49 | } 50 | 51 | async renderString() { 52 | throw new Error('assets engine don\'t support renderString'); 53 | } 54 | 55 | } 56 | 57 | module.exports = AssetsView; 58 | -------------------------------------------------------------------------------- /lib/dev_server.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fs = require('mz/fs'); 5 | const spawn = require('cross-spawn'); 6 | const Base = require('sdk-base'); 7 | const sleep = require('mz-modules/sleep'); 8 | const awaitEvent = require('await-event'); 9 | const debug = require('util').debuglog('egg-view-assets:dev_server'); 10 | const detectPort = require('detect-port'); 11 | const mkdirp = require('mz-modules/mkdirp'); 12 | const is = require('is-type-of'); 13 | 14 | 15 | class DevServer extends Base { 16 | constructor(app) { 17 | super({ 18 | initMethod: 'init', 19 | }); 20 | this.app = app; 21 | this.isClosed = false; 22 | } 23 | 24 | async init() { 25 | const { devServer } = this.app.config.assets; 26 | 27 | if (devServer.autoPort) { 28 | devServer.port = await detectPort(devServer.port || 10000); 29 | await mkdirp(path.dirname(devServer.portPath)); 30 | await fs.writeFile(devServer.portPath, devServer.port.toString()); 31 | } else { 32 | // check whether the port is using 33 | if (await this.checkPortExist()) { 34 | throw new Error(`port ${this.app.config.assets.devServer.port} has been used`); 35 | } 36 | } 37 | 38 | // start dev server asynchronously 39 | this.startAsync(); 40 | await this.waitListen(); 41 | } 42 | 43 | startAsync() { 44 | const { devServer } = this.app.config.assets; 45 | devServer.command = this.replacePort(devServer.command); 46 | const [ command, ...args ] = devServer.command.split(/\s+/); 47 | 48 | const env = Object.assign({}, process.env, devServer.env); 49 | // Compatible with Windows environment 50 | const binDir = path.join(this.app.config.baseDir, 'node_modules', '.bin'); 51 | if (process.platform === 'win32') { 52 | if (env.PATH) { 53 | env.PATH = `${binDir};${env.PATH}`; 54 | } else if (env.Path) { 55 | env.Path = `${binDir};${env.Path}`; 56 | } else { 57 | throw new Error('env.PATH or env.Path not found'); 58 | } 59 | } else { 60 | env.PATH = `${binDir}:${env.PATH}`; 61 | } 62 | // replace {port} 63 | Object.keys(env).forEach(key => { 64 | env[key] = this.replacePort(env[key]); 65 | }); 66 | const opt = { 67 | // disable stdout by default 68 | stdio: [ 'inherit', 'ignore', 'inherit' ], 69 | env, 70 | }; 71 | if (devServer.cwd) opt.cwd = devServer.cwd; 72 | if (devServer.debug) opt.stdio[1] = 'inherit'; 73 | const proc = this.proc = spawn(command, args, opt); 74 | proc.once('error', err => this.exit(err)); 75 | proc.once('exit', code => this.exit(code)); 76 | } 77 | 78 | async checkPortExist() { 79 | const { devServer } = this.app.config.assets; 80 | const port = await detectPort(devServer.port); 81 | debug('check %s, get result %s', devServer.port, port); 82 | return port !== devServer.port; 83 | } 84 | 85 | async waitListen() { 86 | const logger = this.app.coreLogger; 87 | const { devServer } = this.app.config.assets; 88 | let timeout = devServer.timeout / 1000; 89 | let isSuccess = false; 90 | while (timeout > 0) { 91 | /* istanbul ignore if */ 92 | if (this.isClosed) { 93 | logger.warn('[egg-view-assets] Closing, but devServer is not listened'); 94 | return; 95 | } 96 | if (await this.checkPortExist()) { 97 | logger.warn('[egg-view-assets] Run "%s" success, listen on %s', devServer.command, devServer.port); 98 | // 成功启动 99 | isSuccess = true; 100 | break; 101 | } 102 | timeout--; 103 | await sleep(1000); 104 | debug('waiting, %s remain', timeout); 105 | } 106 | 107 | if (isSuccess) return; 108 | const err = new Error(`Run "${devServer.command}" failed after ${devServer.timeout / 1000}s`); 109 | throw err; 110 | } 111 | 112 | async close() { 113 | this.isClosed = true; 114 | /* istanbul ignore if */ 115 | if (!this.proc) return; 116 | this.app.coreLogger.warn('[egg-view-assets] dev server will be killed'); 117 | this.proc.kill(); 118 | await awaitEvent(this.proc, 'exit'); 119 | this.proc = null; 120 | } 121 | 122 | exit(codeOrError) { 123 | const logger = this.app.coreLogger; 124 | this.proc = null; 125 | 126 | if (!(codeOrError instanceof Error)) { 127 | const { devServer } = this.app.config.assets; 128 | const code = codeOrError; 129 | const message = `[egg-view-assets] Run "${devServer.command}" exit with code ${code}`; 130 | if (!code || code === 0) { 131 | logger.info(message); 132 | return; 133 | } 134 | 135 | codeOrError = new Error(message); 136 | } 137 | 138 | logger.error(codeOrError); 139 | } 140 | 141 | replacePort(str) { 142 | if (!is.string(str)) return str; 143 | return str.replace('{port}', this.app.config.assets.devServer.port); 144 | } 145 | 146 | } 147 | 148 | module.exports = DevServer; 149 | -------------------------------------------------------------------------------- /lib/util/constant.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.HELPER_ASSETS = Symbol('Helper#assets'); 4 | -------------------------------------------------------------------------------- /lib/util/default_template.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = assets => { 4 | return ` 5 | 6 | 7 | 8 | ${assets.getStyle()} 9 | 10 | 11 |
12 | ${assets.getContext()} 13 | ${assets.getScript()} 14 | 15 | 16 | `; 17 | }; 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets", 3 | "version": "1.10.0", 4 | "eggPlugin": { 5 | "name": "assets", 6 | "dependencies": [ 7 | "view" 8 | ] 9 | }, 10 | "description": "Manage frontend assets in development and production", 11 | "keywords": [ 12 | "egg", 13 | "eggPlugin", 14 | "egg-plugin", 15 | "assets" 16 | ], 17 | "dependencies": { 18 | "await-event": "^2.1.0", 19 | "cross-spawn": "^6.0.5", 20 | "detect-port": "^1.3.0", 21 | "is-type-of": "^1.2.1", 22 | "mz": "^2.7.0", 23 | "mz-modules": "^2.1.0", 24 | "sdk-base": "^3.5.1" 25 | }, 26 | "devDependencies": { 27 | "egg": "^2.14.2", 28 | "egg-bin": "^4.10.0", 29 | "egg-mock": "^3.21.0", 30 | "egg-view-ejs": "^2.0.0", 31 | "egg-view-nunjucks": "^2.1.6", 32 | "eslint": "^5.12.0", 33 | "eslint-config-egg": "^7.1.0", 34 | "puppeteer": "^1.11.0", 35 | "supertest": "^3.3.0", 36 | "uglify-js": "^3.3.21", 37 | "urllib": "^2.34.1" 38 | }, 39 | "engines": { 40 | "node": ">=8.0.0" 41 | }, 42 | "scripts": { 43 | "dev": "egg-bin dev", 44 | "test": "npm run lint -- --fix && npm run test-local", 45 | "test-local": "egg-bin test", 46 | "cov": "egg-bin cov", 47 | "lint": "eslint .", 48 | "ci": "npm run lint && npm run cov", 49 | "uglify": "uglifyjs lib/fixtures/decode.js -o lib/fixtures/decode.min.js" 50 | }, 51 | "files": [ 52 | "app", 53 | "lib", 54 | "config", 55 | "agent.js", 56 | "app.js" 57 | ], 58 | "repository": { 59 | "type": "git", 60 | "url": "git+https://github.com/eggjs/egg-view-assets.git" 61 | }, 62 | "bugs": { 63 | "url": "https://github.com/eggjs/egg/issues" 64 | }, 65 | "homepage": "https://github.com/eggjs/egg-view-assets#readme", 66 | "author": "popomore", 67 | "license": "MIT" 68 | } 69 | -------------------------------------------------------------------------------- /test/assets.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const mock = require('egg-mock'); 5 | const fs = require('mz/fs'); 6 | const assert = require('assert'); 7 | const urllib = require('urllib'); 8 | const address = require('address'); 9 | 10 | describe('test/assets.test.js', () => { 11 | 12 | afterEach(mock.restore); 13 | 14 | describe('AssetsView with default template', () => { 15 | let app; 16 | 17 | describe('local', () => { 18 | before(() => { 19 | mock.env('local'); 20 | app = mock.cluster({ 21 | baseDir: 'apps/assets', 22 | }); 23 | // app.debug(); 24 | return app.ready(); 25 | }); 26 | after(() => app.close()); 27 | 28 | it('should GET /', () => { 29 | return app.httpRequest() 30 | .get('/') 31 | .expect(/
<\/div>/) 32 | .expect(//) 33 | .expect(/ 9 | {{ helper.assets.getContext() | safe }} 10 | {{ helper.assets.getScript() | safe }} 11 | 12 | 13 | -------------------------------------------------------------------------------- /test/fixtures/apps/complex-manifest/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | exports.keys = '123456'; 6 | exports.view = { 7 | mapping: { 8 | '.js': 'assets', 9 | '.jsx': 'assets', 10 | }, 11 | }; 12 | exports.assets = { 13 | publicPath: '/public/', 14 | templateViewEngine: 'nunjucks', 15 | templatePath: path.join(__dirname, '../app/view/layout.html'), 16 | }; 17 | -------------------------------------------------------------------------------- /test/fixtures/apps/complex-manifest/config/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "index.js": "index.js", 3 | "index.css": "/index.css", 4 | "page1.js": "http://cdn.com/page1.js" 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/complex-manifest/config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | nunjucks: { 5 | enable: true, 6 | package: 'egg-view-nunjucks', 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/complex-manifest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/context-security/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.js', { 8 | query: this.ctx.query.query, 9 | }); 10 | } 11 | } 12 | 13 | module.exports = HomeController; 14 | -------------------------------------------------------------------------------- /test/fixtures/apps/context-security/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/context-security/app/view/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggjs/egg-view-assets/22debe4e59d67e56724f01df5a00906c0d39b31c/test/fixtures/apps/context-security/app/view/index.js -------------------------------------------------------------------------------- /test/fixtures/apps/context-security/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = '123456'; 4 | exports.view = { 5 | mapping: { 6 | '.js': 'assets', 7 | }, 8 | }; 9 | exports.assets = { 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/context-security/config/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "index.css": "index.css", 3 | "index.js": "index.js" 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/context-security/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/crossorigin/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.js', { 8 | data: 1, 9 | }); 10 | } 11 | } 12 | 13 | module.exports = HomeController; 14 | -------------------------------------------------------------------------------- /test/fixtures/apps/crossorigin/app/public/index.css: -------------------------------------------------------------------------------- 1 | body { color: white; } -------------------------------------------------------------------------------- /test/fixtures/apps/crossorigin/app/public/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* global window */ 4 | console.log('data:', window.context.data); 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/crossorigin/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/crossorigin/app/view/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggjs/egg-view-assets/22debe4e59d67e56724f01df5a00906c0d39b31c/test/fixtures/apps/crossorigin/app/view/index.js -------------------------------------------------------------------------------- /test/fixtures/apps/crossorigin/app/view/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ helper.assets.getStyle() | safe }} 5 | 6 | 7 |
8 | 9 | {{ helper.assets.getContext() | safe }} 10 | {{ helper.assets.getScript() | safe }} 11 | 12 | 13 | -------------------------------------------------------------------------------- /test/fixtures/apps/crossorigin/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | exports.keys = '123456'; 6 | exports.view = { 7 | mapping: { 8 | '.js': 'assets', 9 | }, 10 | }; 11 | exports.assets = { 12 | publicPath: '/public/', 13 | url: 'http://example.com', 14 | crossorigin: true, 15 | templateViewEngine: 'nunjucks', 16 | templatePath: path.join(__dirname, '../app/view/layout.html'), 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/apps/crossorigin/config/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "index.js": "/index.js", 3 | "index.css": "/index.css" 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/crossorigin/config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | nunjucks: { 5 | enable: true, 6 | package: 'egg-view-nunjucks', 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/crossorigin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "crossorigin" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-assets-url/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.js'); 8 | } 9 | 10 | async context() { 11 | await this.ctx.render('index.js', { 12 | data: 1, 13 | }); 14 | } 15 | 16 | } 17 | 18 | module.exports = HomeController; 19 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-assets-url/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | router.get('/context', controller.home.context); 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-assets-url/app/view/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggjs/egg-view-assets/22debe4e59d67e56724f01df5a00906c0d39b31c/test/fixtures/apps/custom-assets-url/app/view/index.js -------------------------------------------------------------------------------- /test/fixtures/apps/custom-assets-url/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | exports.keys = '123456'; 6 | exports.view = { 7 | mapping: { 8 | '.js': 'assets', 9 | }, 10 | }; 11 | exports.assets = { 12 | devServer: { 13 | waitStart: true, 14 | command: 'node ' + path.join(__dirname, '../../mocktool/server.js'), 15 | port: 8000, 16 | env: {}, 17 | debug: true, 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-assets-url/config/config.prod.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.assets = { 4 | url: 'http://localhost', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-assets-url/config/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "0.a94eff34.async.js": "0.a94eff34.async.js", 3 | "1.0647e11d.async.js": "1.0647e11d.async.js", 4 | "2.cbbca76b.async.js": "2.cbbca76b.async.js", 5 | "constants.js": "constants.e5eb201e.js", 6 | "index.css": "index.b8e2efea.css", 7 | "index.js": "index.c4ae6394.js", 8 | "static/yay.jpg": "static/yay.44dd3333.jpg" 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-assets-url/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-context-key/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.js'); 8 | } 9 | } 10 | 11 | module.exports = HomeController; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-context-key/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-context-key/app/view/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggjs/egg-view-assets/22debe4e59d67e56724f01df5a00906c0d39b31c/test/fixtures/apps/custom-context-key/app/view/index.js -------------------------------------------------------------------------------- /test/fixtures/apps/custom-context-key/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | exports.keys = '123456'; 6 | exports.view = { 7 | mapping: { 8 | '.js': 'assets', 9 | }, 10 | }; 11 | exports.assets = { 12 | contextKey: '__context__', 13 | devServer: { 14 | waitStart: true, 15 | command: 'node ' + path.join(__dirname, '../../mocktool/server.js'), 16 | port: 8000, 17 | env: {}, 18 | debug: true, 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-context-key/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-dev-server/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.js'); 8 | } 9 | } 10 | 11 | module.exports = HomeController; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-dev-server/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-dev-server/app/view/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggjs/egg-view-assets/22debe4e59d67e56724f01df5a00906c0d39b31c/test/fixtures/apps/custom-dev-server/app/view/index.js -------------------------------------------------------------------------------- /test/fixtures/apps/custom-dev-server/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = '123456'; 4 | exports.view = { 5 | mapping: { 6 | '.js': 'assets', 7 | }, 8 | }; 9 | exports.assets = { 10 | devServer: { 11 | waitStart: true, 12 | command: 'node ' + require.resolve('./server.js'), 13 | cwd: __dirname, 14 | port: 8000, 15 | env: { 16 | NODE_DEBUG: true, 17 | }, 18 | timeout: 5000, 19 | debug: process.env.DEV_SERVER_DEBUG === 'true', 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-dev-server/config/server.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict'; 4 | 5 | console.log('[server] cwd:', process.cwd()); 6 | console.log('[server] DEBUG:', process.env.NODE_DEBUG); 7 | 8 | if (process.env.EXIT) { 9 | process.exit(1); 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-dev-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-public-path/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.js'); 8 | } 9 | } 10 | 11 | module.exports = HomeController; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-public-path/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-public-path/app/view/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggjs/egg-view-assets/22debe4e59d67e56724f01df5a00906c0d39b31c/test/fixtures/apps/custom-public-path/app/view/index.js -------------------------------------------------------------------------------- /test/fixtures/apps/custom-public-path/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = '123456'; 4 | exports.view = { 5 | mapping: { 6 | '.js': 'assets', 7 | }, 8 | }; 9 | exports.assets = { 10 | devServer: { 11 | enable: false, 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-public-path/config/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "index.js": "index.js", 3 | "index.css": "index.css" 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-public-path/config/server.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict'; 4 | 5 | console.log('[server] cwd:', process.cwd()); 6 | console.log('[server] DEBUG:', process.env.NODE_DEBUG); 7 | 8 | if (process.env.EXIT) { 9 | process.exit(1); 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-public-path/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/dev-server-no-port/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.js'); 8 | } 9 | } 10 | 11 | module.exports = HomeController; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/dev-server-no-port/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/dev-server-no-port/app/view/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggjs/egg-view-assets/22debe4e59d67e56724f01df5a00906c0d39b31c/test/fixtures/apps/dev-server-no-port/app/view/index.js -------------------------------------------------------------------------------- /test/fixtures/apps/dev-server-no-port/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = '123456'; 4 | exports.view = { 5 | mapping: { 6 | '.js': 'assets', 7 | }, 8 | }; 9 | exports.assets = { 10 | devServer: { 11 | enable: process.env.DEV_SERVER_ENABLE !== 'false', 12 | waitStart: true, 13 | command: 'node ' + require.resolve('./server.js'), 14 | cwd: __dirname, 15 | env: { 16 | NODE_DEBUG: true, 17 | }, 18 | timeout: 5000, 19 | debug: process.env.DEV_SERVER_DEBUG === 'true', 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /test/fixtures/apps/dev-server-no-port/config/server.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict'; 4 | 5 | console.log('[server] cwd:', process.cwd()); 6 | console.log('[server] DEBUG:', process.env.NODE_DEBUG); 7 | 8 | if (process.env.EXIT) { 9 | process.exit(1); 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/dev-server-no-port/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/https-dynamic-ip/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.js'); 8 | } 9 | 10 | async context() { 11 | await this.ctx.render('index.js', { 12 | data: 1, 13 | }); 14 | } 15 | 16 | } 17 | 18 | module.exports = HomeController; 19 | -------------------------------------------------------------------------------- /test/fixtures/apps/https-dynamic-ip/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | router.get('/context', controller.home.context); 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/https-dynamic-ip/app/view/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggjs/egg-view-assets/22debe4e59d67e56724f01df5a00906c0d39b31c/test/fixtures/apps/https-dynamic-ip/app/view/index.js -------------------------------------------------------------------------------- /test/fixtures/apps/https-dynamic-ip/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | exports.keys = '123456'; 6 | exports.view = { 7 | mapping: { 8 | '.js': 'assets', 9 | }, 10 | }; 11 | exports.assets = { 12 | dynamicLocalIP: false, 13 | devServer: { 14 | waitStart: true, 15 | command: 'node ' + path.join(__dirname, '../../mocktool/server.js'), 16 | port: 8000, 17 | env: {}, 18 | debug: true, 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /test/fixtures/apps/https-dynamic-ip/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/https-dynamic-ip/server.cert: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIC9DCCAdygAwIBAgIJANhNsdON73XpMA0GCSqGSIb3DQEBCwUAMBkxFzAVBgNV 3 | BAMMDjEyNy4wLjAuMTo4NDQzMB4XDTE5MDkxODA5Mzk1MVoXDTE5MTAxODA5Mzk1 4 | MVowGTEXMBUGA1UEAwwOMTI3LjAuMC4xOjg0NDMwggEiMA0GCSqGSIb3DQEBAQUA 5 | A4IBDwAwggEKAoIBAQDRNVNmZWcD5444kPDHn/oJmrZ0MtGbAgaJeDWWi88sfAHZ 6 | skrz8akYIHnU3kP3jQ2fJYdG5h8sO9aRMscKiBSfyVT0dbzIFJJwfPxC7myzRysx 7 | 5p/J1uO7ZyUM2lo15ia//yShVjVG+YyUnwEUYE153z0KI9ni+rQIaEh9L9jgd18I 8 | oWlQYdcMpZI6udc967bMfIRYGeIap4bk32JlxYKffFs1PCtOB93G0JAFgBjCPlvf 9 | HysymSKjZkvTA8kqO3oqWBpqAW6pvVPk0XO8mtUjw5l/nHcTTehym+g3XdQ+W1vo 10 | KFChRXX7j8PmDVA2U5cJxjQFpao0N8q31u4oDq3pAgMBAAGjPzA9MBkGA1UdEQQS 11 | MBCCDjEyNy4wLjAuMTo4NDQzMAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEF 12 | BQcDATANBgkqhkiG9w0BAQsFAAOCAQEAZSg3NlR7o4OUGFd2z+EQxuaceQ0OU/2l 13 | ydZ9Hjo/DyUR6dyB700X3EpbAXKh90i6fD6DN+LHW3rPqUIdCMTsQOE7o/vQwhka 14 | rBUUOjEVs1qRSUgCq4qZzErGFH70z0z1YGSCUGvd50mRDLPhhmhqMBMRLDNJL39J 15 | 2txPMzfNKTr/NqJC+0GfWEUeyVK6blhaxVk+02HJ7Wn4IH61WWXoKz+H3HPuj23E 16 | etGKSLLnMpADjYRZU4/NAe+AOJxTVYTylUfST0Wm5XnvI/8tAjo6Ttzmfa0m1+OZ 17 | GZDt1+FF8c4eRLQpRtyF4p6BxUvrk5BrPZJL7YkcXRcmJcFEGsr9Kw== 18 | -----END CERTIFICATE----- 19 | -------------------------------------------------------------------------------- /test/fixtures/apps/https-dynamic-ip/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDRNVNmZWcD5444 3 | kPDHn/oJmrZ0MtGbAgaJeDWWi88sfAHZskrz8akYIHnU3kP3jQ2fJYdG5h8sO9aR 4 | MscKiBSfyVT0dbzIFJJwfPxC7myzRysx5p/J1uO7ZyUM2lo15ia//yShVjVG+YyU 5 | nwEUYE153z0KI9ni+rQIaEh9L9jgd18IoWlQYdcMpZI6udc967bMfIRYGeIap4bk 6 | 32JlxYKffFs1PCtOB93G0JAFgBjCPlvfHysymSKjZkvTA8kqO3oqWBpqAW6pvVPk 7 | 0XO8mtUjw5l/nHcTTehym+g3XdQ+W1voKFChRXX7j8PmDVA2U5cJxjQFpao0N8q3 8 | 1u4oDq3pAgMBAAECggEBANBAKd3S8MGlPSA3v0ani4kF9bsjXxzS3lj3TTinwTnB 9 | 00G1xgCgvTbkFQJ9oeCJC1cxT0CXD87DXeo5RoLIROdtzWBu1tXADKlm8OFbXt7y 10 | 6B+LN+H+Q8Engm0R6hyfFlGmk/r5ypz1CihjQvrahiTbwHIYj+rurkl0LTxYZaXB 11 | wQ8scpyqB2TgScseJLlyESvyCYrfQ+PoqG+3Sm6WikDvEXBAJTSOgQ9RDIlL/o6z 12 | v5RESJmXIzlIHzt8SnneyitgjkjiW6T5s0CNIRe81aW+bl5K81tMKDDejiyzYEPM 13 | fWMLbQzARTnWui3c48BEv5Um6Txm60nL7xuIbm+VfpECgYEA6yK9LRTb73HMklCo 14 | Dyg/0Yrws9A13Fx7xMVRKGIQ6TIVUl2tl0fqbtohTrJC1YMrUFdsPtOpVrsvDx5z 15 | uMxfprlzF8lXWff/7oB1BWk7ljIZnA0BJ+f00eZRmpHkSvvrLBIfGAM1uilu9w5Q 16 | SvchbV00qcJAuiuMwl8XWBpKqaUCgYEA48WhC/kLnrjRUkbcOK+Y4m88+PUy4hZa 17 | NAY25t+4mUG6tDFe5N/YBj2YphGPBOGJfZbm0R06UCA5TpvdshORyu7KU80IQimC 18 | 8OQKLJu/2mSlNL94xCzCONpUtMCkt7qJtHRlXiW32zSs8oMlJkCWScQmlvXpSOvF 19 | DtbdWNhCl/UCgYEArzReY7YUP3G7Lhb9cvXZv8hYnJN7Xqxm6PLiC0YvNaPE8W+u 20 | BnhmvZy5jssTM8ceQioyFQpgNqkZYpmdPsjCSRgMI2A6P2akhFGhYJvN85d3L6kd 21 | AGA9Mx38FkG5KwpVbKxAEQNrSEDRVzOKLqHAfZ4ivI9q7Y2/v6FdYp+MnKUCgYAe 22 | RXe/5Zt7vshjDPPbvMqu3WXXGI9oqNvYKjNFv9oC1E+B/0XDWVSWj70n5RGC7o6d 23 | WF7Yz++eEopLPj/amOs5cz8EoC1GzcmPRl9ryk9XMSUbu47LU7+EWtADLc82c941 24 | U3rdZlnnEjsiB/f5+3990knmqkwU2vDXpgrI8gT3uQKBgQCP93Bcr4MQF1ogwFeI 25 | o/cWIMYI2vbZAo7e5X1I4JVYm0R3c7bsKJo8vrYMwKMGfGqj56iF9wduN6rKORhx 26 | rA/wPES4zORRum09ppk9UOR7jIVTUqbJ9qvbmwHuXn4rn1JDvmd+Pixi7e5Ftr7G 27 | vXP18pbM3/WexDXV7UvHrqCxxA== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /test/fixtures/apps/https/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.js'); 8 | } 9 | 10 | async context() { 11 | await this.ctx.render('index.js', { 12 | data: 1, 13 | }); 14 | } 15 | 16 | } 17 | 18 | module.exports = HomeController; 19 | -------------------------------------------------------------------------------- /test/fixtures/apps/https/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | router.get('/context', controller.home.context); 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/https/app/view/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggjs/egg-view-assets/22debe4e59d67e56724f01df5a00906c0d39b31c/test/fixtures/apps/https/app/view/index.js -------------------------------------------------------------------------------- /test/fixtures/apps/https/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | exports.keys = '123456'; 6 | exports.view = { 7 | mapping: { 8 | '.js': 'assets', 9 | }, 10 | }; 11 | exports.assets = { 12 | devServer: { 13 | waitStart: true, 14 | command: 'node ' + path.join(__dirname, '../../mocktool/server.js'), 15 | port: 8000, 16 | env: {}, 17 | debug: true, 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /test/fixtures/apps/https/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/https/server.cert: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIC9DCCAdygAwIBAgIJANhNsdON73XpMA0GCSqGSIb3DQEBCwUAMBkxFzAVBgNV 3 | BAMMDjEyNy4wLjAuMTo4NDQzMB4XDTE5MDkxODA5Mzk1MVoXDTE5MTAxODA5Mzk1 4 | MVowGTEXMBUGA1UEAwwOMTI3LjAuMC4xOjg0NDMwggEiMA0GCSqGSIb3DQEBAQUA 5 | A4IBDwAwggEKAoIBAQDRNVNmZWcD5444kPDHn/oJmrZ0MtGbAgaJeDWWi88sfAHZ 6 | skrz8akYIHnU3kP3jQ2fJYdG5h8sO9aRMscKiBSfyVT0dbzIFJJwfPxC7myzRysx 7 | 5p/J1uO7ZyUM2lo15ia//yShVjVG+YyUnwEUYE153z0KI9ni+rQIaEh9L9jgd18I 8 | oWlQYdcMpZI6udc967bMfIRYGeIap4bk32JlxYKffFs1PCtOB93G0JAFgBjCPlvf 9 | HysymSKjZkvTA8kqO3oqWBpqAW6pvVPk0XO8mtUjw5l/nHcTTehym+g3XdQ+W1vo 10 | KFChRXX7j8PmDVA2U5cJxjQFpao0N8q31u4oDq3pAgMBAAGjPzA9MBkGA1UdEQQS 11 | MBCCDjEyNy4wLjAuMTo4NDQzMAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEF 12 | BQcDATANBgkqhkiG9w0BAQsFAAOCAQEAZSg3NlR7o4OUGFd2z+EQxuaceQ0OU/2l 13 | ydZ9Hjo/DyUR6dyB700X3EpbAXKh90i6fD6DN+LHW3rPqUIdCMTsQOE7o/vQwhka 14 | rBUUOjEVs1qRSUgCq4qZzErGFH70z0z1YGSCUGvd50mRDLPhhmhqMBMRLDNJL39J 15 | 2txPMzfNKTr/NqJC+0GfWEUeyVK6blhaxVk+02HJ7Wn4IH61WWXoKz+H3HPuj23E 16 | etGKSLLnMpADjYRZU4/NAe+AOJxTVYTylUfST0Wm5XnvI/8tAjo6Ttzmfa0m1+OZ 17 | GZDt1+FF8c4eRLQpRtyF4p6BxUvrk5BrPZJL7YkcXRcmJcFEGsr9Kw== 18 | -----END CERTIFICATE----- 19 | -------------------------------------------------------------------------------- /test/fixtures/apps/https/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDRNVNmZWcD5444 3 | kPDHn/oJmrZ0MtGbAgaJeDWWi88sfAHZskrz8akYIHnU3kP3jQ2fJYdG5h8sO9aR 4 | MscKiBSfyVT0dbzIFJJwfPxC7myzRysx5p/J1uO7ZyUM2lo15ia//yShVjVG+YyU 5 | nwEUYE153z0KI9ni+rQIaEh9L9jgd18IoWlQYdcMpZI6udc967bMfIRYGeIap4bk 6 | 32JlxYKffFs1PCtOB93G0JAFgBjCPlvfHysymSKjZkvTA8kqO3oqWBpqAW6pvVPk 7 | 0XO8mtUjw5l/nHcTTehym+g3XdQ+W1voKFChRXX7j8PmDVA2U5cJxjQFpao0N8q3 8 | 1u4oDq3pAgMBAAECggEBANBAKd3S8MGlPSA3v0ani4kF9bsjXxzS3lj3TTinwTnB 9 | 00G1xgCgvTbkFQJ9oeCJC1cxT0CXD87DXeo5RoLIROdtzWBu1tXADKlm8OFbXt7y 10 | 6B+LN+H+Q8Engm0R6hyfFlGmk/r5ypz1CihjQvrahiTbwHIYj+rurkl0LTxYZaXB 11 | wQ8scpyqB2TgScseJLlyESvyCYrfQ+PoqG+3Sm6WikDvEXBAJTSOgQ9RDIlL/o6z 12 | v5RESJmXIzlIHzt8SnneyitgjkjiW6T5s0CNIRe81aW+bl5K81tMKDDejiyzYEPM 13 | fWMLbQzARTnWui3c48BEv5Um6Txm60nL7xuIbm+VfpECgYEA6yK9LRTb73HMklCo 14 | Dyg/0Yrws9A13Fx7xMVRKGIQ6TIVUl2tl0fqbtohTrJC1YMrUFdsPtOpVrsvDx5z 15 | uMxfprlzF8lXWff/7oB1BWk7ljIZnA0BJ+f00eZRmpHkSvvrLBIfGAM1uilu9w5Q 16 | SvchbV00qcJAuiuMwl8XWBpKqaUCgYEA48WhC/kLnrjRUkbcOK+Y4m88+PUy4hZa 17 | NAY25t+4mUG6tDFe5N/YBj2YphGPBOGJfZbm0R06UCA5TpvdshORyu7KU80IQimC 18 | 8OQKLJu/2mSlNL94xCzCONpUtMCkt7qJtHRlXiW32zSs8oMlJkCWScQmlvXpSOvF 19 | DtbdWNhCl/UCgYEArzReY7YUP3G7Lhb9cvXZv8hYnJN7Xqxm6PLiC0YvNaPE8W+u 20 | BnhmvZy5jssTM8ceQioyFQpgNqkZYpmdPsjCSRgMI2A6P2akhFGhYJvN85d3L6kd 21 | AGA9Mx38FkG5KwpVbKxAEQNrSEDRVzOKLqHAfZ4ivI9q7Y2/v6FdYp+MnKUCgYAe 22 | RXe/5Zt7vshjDPPbvMqu3WXXGI9oqNvYKjNFv9oC1E+B/0XDWVSWj70n5RGC7o6d 23 | WF7Yz++eEopLPj/amOs5cz8EoC1GzcmPRl9ryk9XMSUbu47LU7+EWtADLc82c941 24 | U3rdZlnnEjsiB/f5+3990knmqkwU2vDXpgrI8gT3uQKBgQCP93Bcr4MQF1ogwFeI 25 | o/cWIMYI2vbZAo7e5X1I4JVYm0R3c7bsKJo8vrYMwKMGfGqj56iF9wduN6rKORhx 26 | rA/wPES4zORRum09ppk9UOR7jIVTUqbJ9qvbmwHuXn4rn1JDvmd+Pixi7e5Ftr7G 27 | vXP18pbM3/WexDXV7UvHrqCxxA== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /test/fixtures/apps/mocktool/server.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const http = require('http'); 4 | const Koa = require('koa'); 5 | 6 | const port = Number(process.argv[2]) || 8000; 7 | 8 | console.info('[server] SOCKET_SERVER: ' + process.env.SOCKET_SERVER); 9 | 10 | const app = new Koa(); 11 | app.use(async ctx => { 12 | ctx.body = 'done'; 13 | }); 14 | 15 | const server = http.createServer(app.callback()); 16 | server.once('error', err => { 17 | console.error('[server]', err.stack); 18 | process.exit(1); 19 | }); 20 | server.once('listening', () => { 21 | console.info('[server] listening ' + port); 22 | }); 23 | 24 | console.info('[server] listen ' + port); 25 | server.listen(port); 26 | 27 | process.once('SIGTERM', () => { 28 | console.log('[server] server stopped'); 29 | process.exit(); 30 | }); 31 | 32 | console.error('[server] error'); 33 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-getscript/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.js'); 8 | } 9 | } 10 | 11 | module.exports = HomeController; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-getscript/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-getscript/app/view/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggjs/egg-view-assets/22debe4e59d67e56724f01df5a00906c0d39b31c/test/fixtures/apps/multiple-getscript/app/view/index.js -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-getscript/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = '123456'; 4 | exports.view = { 5 | mapping: { 6 | '.js': 'assets', 7 | }, 8 | }; 9 | exports.assets = { 10 | devServer: { 11 | enable: false, 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-getscript/config/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "vendor.js": "vendor.js", 3 | "a.js": "a.js", 4 | "b.js": "b.js", 5 | "c.js": "c.js" 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-getscript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "multiple-getscript" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/no-manifest/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.assets = { 4 | devServer: { 5 | enable: false, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/no-manifest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/not-listen/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.js', { 8 | data: 1, 9 | }); 10 | } 11 | 12 | async renderString() { 13 | await this.ctx.renderString('', {}, { 14 | viewEngine: 'assets', 15 | }); 16 | } 17 | } 18 | 19 | module.exports = HomeController; 20 | -------------------------------------------------------------------------------- /test/fixtures/apps/not-listen/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | router.get('/renderString', controller.home.renderString); 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/not-listen/app/view/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggjs/egg-view-assets/22debe4e59d67e56724f01df5a00906c0d39b31c/test/fixtures/apps/not-listen/app/view/index.js -------------------------------------------------------------------------------- /test/fixtures/apps/not-listen/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = '123456'; 4 | exports.assets = { 5 | devServer: { 6 | command: 'echo command', 7 | port: 8000, 8 | env: {}, 9 | debug: true, 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/not-listen/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/other-view-engine/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.html', { 8 | __context__: { data: 1 }, 9 | }); 10 | } 11 | } 12 | 13 | module.exports = HomeController; 14 | -------------------------------------------------------------------------------- /test/fixtures/apps/other-view-engine/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/other-view-engine/app/view/index.html: -------------------------------------------------------------------------------- 1 | 2 | {{ helper.assets.getStyle('index.css') | safe }} 3 | {{ helper.assets.getContext(__context__) | safe }} 4 | {{ helper.assets.getScript('index.js') | safe }} 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/other-view-engine/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | exports.keys = '123456'; 6 | exports.view = { 7 | mapping: { 8 | '.html': 'nunjucks', 9 | }, 10 | }; 11 | exports.assets = { 12 | publicPath: '/app/public', 13 | devServer: { 14 | waitStart: true, 15 | command: 'node ' + path.join(__dirname, '../../mocktool/server.js'), 16 | port: 8000, 17 | env: {}, 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /test/fixtures/apps/other-view-engine/config/config.prod.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.assets = { 4 | url: 'http://cdn.com', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/other-view-engine/config/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "0.a94eff34.async.js": "0.a94eff34.async.js", 3 | "1.0647e11d.async.js": "1.0647e11d.async.js", 4 | "2.cbbca76b.async.js": "2.cbbca76b.async.js", 5 | "constants.js": "constants.e5eb201e.js", 6 | "index.css": "index.b8e2efea.css", 7 | "index.js": "index.c4ae6394.js", 8 | "static/yay.jpg": "static/yay.44dd3333.jpg" 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/other-view-engine/config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | nunjucks: { 5 | enable: true, 6 | package: 'egg-view-nunjucks', 7 | }, 8 | ejs: { 9 | enable: true, 10 | package: 'egg-view-ejs', 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /test/fixtures/apps/other-view-engine/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/tool-roadhog/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.js'); 8 | } 9 | } 10 | 11 | module.exports = HomeController; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/tool-roadhog/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/tool-roadhog/app/view/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggjs/egg-view-assets/22debe4e59d67e56724f01df5a00906c0d39b31c/test/fixtures/apps/tool-roadhog/app/view/index.js -------------------------------------------------------------------------------- /test/fixtures/apps/tool-roadhog/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = '123456'; 4 | exports.view = { 5 | mapping: { 6 | '.js': 'assets', 7 | }, 8 | }; 9 | exports.assets = { 10 | devServer: { 11 | waitStart: true, 12 | command: 'roadhog dev', 13 | port: 8000, 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/apps/tool-roadhog/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/ui/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | await this.ctx.render('index.js', { 8 | data: 1, 9 | }); 10 | } 11 | } 12 | 13 | module.exports = HomeController; 14 | -------------------------------------------------------------------------------- /test/fixtures/apps/ui/app/public/index.css: -------------------------------------------------------------------------------- 1 | body { color: white; } -------------------------------------------------------------------------------- /test/fixtures/apps/ui/app/public/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* global window */ 4 | console.log('data:', window.context.data); 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/ui/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/', controller.home.index); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/ui/app/view/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggjs/egg-view-assets/22debe4e59d67e56724f01df5a00906c0d39b31c/test/fixtures/apps/ui/app/view/index.js -------------------------------------------------------------------------------- /test/fixtures/apps/ui/app/view/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ helper.assets.getStyle() | safe }} 5 | 6 | 7 |
8 | 9 | {{ helper.assets.getContext() | safe }} 10 | {{ helper.assets.getScript() | safe }} 11 | 12 | 13 | -------------------------------------------------------------------------------- /test/fixtures/apps/ui/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | exports.keys = '123456'; 6 | exports.view = { 7 | mapping: { 8 | '.js': 'assets', 9 | '.jsx': 'assets', 10 | }, 11 | }; 12 | exports.assets = { 13 | publicPath: '/public/', 14 | templateViewEngine: 'nunjucks', 15 | templatePath: path.join(__dirname, '../app/view/layout.html'), 16 | }; 17 | -------------------------------------------------------------------------------- /test/fixtures/apps/ui/config/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "index.js": "index.js", 3 | "index.css": "index.css" 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/ui/config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | nunjucks: { 5 | enable: true, 6 | package: 'egg-view-nunjucks', 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-view-assets" 3 | } 4 | -------------------------------------------------------------------------------- /test/roadhog.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const mock = require('egg-mock'); 4 | const request = require('supertest'); 5 | const sleep = require('mz-modules/sleep'); 6 | 7 | describe.skip('roadhog', () => { 8 | let app; 9 | before(() => { 10 | mock.env('local'); 11 | app = mock.cluster({ 12 | baseDir: 'apps/tool-roadhog', 13 | }); 14 | return app.ready(); 15 | }); 16 | after(() => app.close()); 17 | 18 | it('should GET /', async () => { 19 | await app.httpRequest() 20 | .get('/') 21 | .expect(res => { 22 | res.text.includes(''); 23 | res.text.includes(''); 24 | // res.text.includes(''); 25 | }) 26 | .expect(200); 27 | 28 | await sleep(10000); 29 | 30 | await request('http://127.0.0.1:8000') 31 | .get('index.js') 32 | .expect(res => { 33 | console.log(res); 34 | }); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /test/ui.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const mock = require('egg-mock'); 4 | const puppeteer = require('puppeteer'); 5 | const sleep = require('mz-modules/sleep'); 6 | const assert = require('assert'); 7 | 8 | describe('test/ui.test.js', () => { 9 | let app; 10 | before(() => { 11 | mock.env('default'); 12 | app = mock.cluster({ 13 | baseDir: 'apps/ui', 14 | port: 7001, 15 | }); 16 | app.debug(); 17 | return app.ready(); 18 | }); 19 | after(() => app.close()); 20 | after(mock.restore); 21 | 22 | it('should request index.js', async () => { 23 | await app.httpRequest() 24 | .get('/public/index.js') 25 | .expect(/window.context.data/) 26 | .expect(200); 27 | }); 28 | 29 | it('should render html', async () => { 30 | await app.httpRequest() 31 | .get('/') 32 | .expect(res => { 33 | assert(res.text.includes('