├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── package.json ├── packages ├── 0test │ ├── 1.js │ ├── 1.png │ ├── build │ │ └── test.debug.css │ ├── clipboard-test.html │ ├── package.json │ ├── sensors_create.html │ ├── test.css │ ├── test.html │ ├── test.js │ ├── test1.html │ ├── test10.html │ ├── test11.html │ ├── test12.html │ ├── test13.html │ ├── test13.js │ ├── test13_1.js │ ├── test14.html │ ├── test15.html │ ├── test15.js │ ├── test2.html │ ├── test2.js │ ├── test3.html │ ├── test3.js │ ├── test4.html │ ├── test4.js │ ├── test5.html │ ├── test6.html │ ├── test7.html │ ├── test7.js │ ├── test71.js │ ├── test8.html │ └── test9.html ├── 10corb │ ├── 1.html │ ├── 2.html │ ├── package.json │ ├── readme.md │ └── server.js ├── 11vue-router │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── index.html │ │ └── index.js │ ├── webpack.config.js │ └── yarn.lock ├── 12vuex │ ├── app.js │ ├── dist │ │ ├── bundle.js │ │ ├── bundle.js.map │ │ └── index.html │ ├── index.html │ ├── package.json │ ├── readme.md │ ├── webpack.config.js │ └── yarn.lock ├── 13vue-ssr │ ├── config │ │ ├── webpack.base.conf.js │ │ ├── webpack.client.conf.js │ │ └── webpack.server.conf.js │ ├── dist │ │ ├── 0.bundle-client.js │ │ ├── 0.bundle-client.js.map │ │ ├── 0.bundle-server.js │ │ ├── 0.bundle-server.js.map │ │ ├── 1.bundle-client.js │ │ ├── 1.bundle-client.js.map │ │ ├── 1.bundle-server.js │ │ ├── 1.bundle-server.js.map │ │ ├── 2.bundle-client.js │ │ ├── 2.bundle-client.js.map │ │ ├── 2.bundle-server.js │ │ ├── 2.bundle-server.js.map │ │ ├── bundle-client.js │ │ ├── bundle-client.js.map │ │ ├── bundle-server.js │ │ └── bundle-server.js.map │ ├── package.json │ ├── readme.md │ ├── server │ │ └── server.js │ ├── src │ │ ├── api │ │ │ └── index.js │ │ ├── app.js │ │ ├── components │ │ │ ├── 404.vue │ │ │ ├── bar.vue │ │ │ └── foo.vue │ │ ├── entry │ │ │ ├── entry-client.js │ │ │ └── entry-server.js │ │ ├── router │ │ │ └── router.js │ │ ├── store │ │ │ └── store.js │ │ └── template.html │ └── yarn.lock ├── 14hmr │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── index.css │ │ ├── index.html │ │ └── index.js │ ├── webpack.config.js │ └── yarn.lock ├── 15prerender-spa │ ├── dist │ │ ├── bar │ │ │ └── index.html │ │ ├── bundle.js │ │ ├── bundle.js.map │ │ ├── foo │ │ │ └── index.html │ │ └── index.html │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── index.html │ │ └── index.js │ ├── webpack.config.js │ └── yarn.lock ├── 16microfe-single-spa │ ├── .travis.yml │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── app1 │ │ ├── .browserslistrc │ │ ├── .gitignore │ │ ├── README.md │ │ ├── babel.config.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── index.html │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── assets │ │ │ │ └── logo.png │ │ │ ├── components │ │ │ │ └── HelloWorld.vue │ │ │ ├── main.js │ │ │ ├── router.js │ │ │ ├── set-public-path.js │ │ │ └── views │ │ │ │ └── Home.vue │ │ └── vue.config.js │ ├── app2 │ │ ├── .browserslistrc │ │ ├── .gitignore │ │ ├── README.md │ │ ├── babel.config.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── index.html │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── assets │ │ │ │ └── logo.png │ │ │ ├── components │ │ │ │ └── HelloWorld.vue │ │ │ ├── main.js │ │ │ ├── router.js │ │ │ ├── set-public-path.js │ │ │ └── views │ │ │ │ ├── About.vue │ │ │ │ └── Home.vue │ │ └── vue.config.js │ ├── navbar │ │ ├── .browserslistrc │ │ ├── .gitignore │ │ ├── README.md │ │ ├── babel.config.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── index.html │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── assets │ │ │ │ └── logo.png │ │ │ ├── main.js │ │ │ ├── router.js │ │ │ └── set-public-path.js │ │ └── vue.config.js │ └── root-html-file │ │ ├── index.html │ │ ├── package-lock.json │ │ └── package.json ├── 17koa │ ├── koa-mini.js │ ├── package.json │ ├── server.js │ ├── static │ │ └── index.html │ └── yarn.lock ├── 18web-communication │ ├── chat │ │ ├── index.js │ │ ├── package.json │ │ ├── static │ │ │ └── index.html │ │ └── yarn.lock │ ├── http-stream │ │ ├── ie-htmlfile-stream.html │ │ ├── ie-htmlfile-stream.js │ │ ├── iframe-stream.html │ │ ├── iframe-stream.js │ │ ├── xhr-stream.html │ │ └── xhr-stream.js │ ├── long-polling │ │ ├── index.html │ │ └── lpc.js │ ├── polling │ │ ├── index.html │ │ └── polling.js │ ├── readme.md │ └── sse │ │ ├── index.html │ │ └── sse.js ├── 19canvas │ └── index.html ├── 1build │ ├── babel │ │ ├── babel.config.js │ │ ├── dist │ │ │ ├── bundle-env-use.js │ │ │ ├── bundle-env.js │ │ │ ├── bundle-rt.js │ │ │ ├── bundle-rt2.js │ │ │ ├── bundle-rt3.js │ │ │ ├── bundle.js │ │ │ └── bundle.js.map │ │ ├── index.html │ │ ├── package.json │ │ ├── src │ │ │ ├── 10.js │ │ │ ├── 11.js │ │ │ ├── 12.js │ │ │ └── 9.js │ │ └── webpack.config.js │ ├── browserify │ │ ├── README.md │ │ ├── dev │ │ │ ├── index.js │ │ │ └── page.js │ │ ├── dist │ │ │ └── bundle.js │ │ ├── gulpfile.js │ │ ├── index.html │ │ └── package.json │ ├── jest │ │ ├── __tests__ │ │ │ └── index.text.js │ │ ├── babel.config.js │ │ ├── coverage │ │ │ ├── clover.xml │ │ │ ├── coverage-final.json │ │ │ ├── lcov-report │ │ │ │ ├── base.css │ │ │ │ ├── block-navigation.js │ │ │ │ ├── index.html │ │ │ │ ├── index.ts.html │ │ │ │ ├── prettify.css │ │ │ │ ├── prettify.js │ │ │ │ ├── sort-arrow-sprite.png │ │ │ │ └── sorter.js │ │ │ └── lcov.info │ │ ├── dist │ │ │ ├── mvvm.js │ │ │ └── mvvm.js.map │ │ ├── package.json │ │ ├── src │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── webpack.config.js │ └── postcss │ │ ├── babel.config.js │ │ ├── dist │ │ ├── aa.css │ │ ├── bb.css │ │ ├── bundle.js │ │ ├── index.html │ │ └── main.css │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── src │ │ ├── index.html │ │ ├── index.js │ │ ├── index1.js │ │ ├── one.css │ │ ├── three.css │ │ └── two.css │ │ └── webpack.config.js ├── 20react-redux │ ├── .gitignore │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── components │ │ ├── Btn.js │ │ ├── CakeContainer.js │ │ ├── ChocolateContainer.js │ │ ├── HooksCakeContainer.js │ │ ├── IceCreamContainer.js │ │ ├── ItemContainer.js │ │ └── NewCakeContainer.js │ │ ├── index.css │ │ ├── index.js │ │ ├── logo.svg │ │ ├── redux │ │ ├── cake │ │ │ ├── cakeActions.js │ │ │ ├── cakeReducer.js │ │ │ └── cakeTypes.js │ │ ├── chocolate │ │ │ ├── chocolateActions.js │ │ │ ├── chocolateReducer.js │ │ │ └── chocolateTypes.js │ │ ├── iceCream │ │ │ ├── iceCreamActions.js │ │ │ ├── iceCreamReducer.js │ │ │ └── iceCreamTypes.js │ │ ├── index.js │ │ ├── rootReducer.js │ │ └── store.js │ │ ├── reportWebVitals.js │ │ └── setupTests.js ├── 21rspress-korey-site │ ├── .gitignore │ ├── docs │ │ ├── _meta.json │ │ ├── index.md │ │ └── public │ │ │ └── avatar.jpg │ ├── package.json │ ├── rspress.config.ts │ ├── theme │ │ ├── index.tsx │ │ └── search.tsx │ └── tsconfig.json ├── 22vue-project │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .prettierrc.json │ ├── README.md │ ├── cypress.config.ts │ ├── cypress │ │ ├── e2e │ │ │ ├── example.cy.ts │ │ │ └── tsconfig.json │ │ ├── fixtures │ │ │ └── example.json │ │ └── support │ │ │ ├── commands.ts │ │ │ └── e2e.ts │ ├── env.d.ts │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ ├── base.css │ │ │ ├── logo.svg │ │ │ └── main.css │ │ ├── components │ │ │ ├── HelloWorld.vue │ │ │ ├── TheWelcome.vue │ │ │ ├── WelcomeItem.vue │ │ │ ├── __tests__ │ │ │ │ └── HelloWorld.spec.ts │ │ │ └── icons │ │ │ │ ├── IconCommunity.vue │ │ │ │ ├── IconDocumentation.vue │ │ │ │ ├── IconEcosystem.vue │ │ │ │ ├── IconSupport.vue │ │ │ │ └── IconTooling.vue │ │ ├── main.ts │ │ ├── router │ │ │ └── index.ts │ │ ├── stores │ │ │ └── counter.ts │ │ └── views │ │ │ ├── AboutView.vue │ │ │ └── HomeView.vue │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ ├── tsconfig.vitest.json │ ├── vite.config.ts │ └── vitest.config.ts ├── 23rsbuild │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── rsbuild.config.ts │ ├── src │ │ ├── App.vue │ │ ├── env.d.ts │ │ ├── index.css │ │ └── index.ts │ └── tsconfig.json ├── 24rspack │ ├── .gitignore │ ├── index.html │ ├── package.json │ ├── rspack.config.js │ └── src │ │ ├── App.vue │ │ ├── assets │ │ ├── rspack.svg │ │ └── vue.svg │ │ ├── components │ │ └── HelloWorld.vue │ │ ├── main.js │ │ └── style.css ├── 25css │ ├── 1.html │ ├── 10.html │ ├── 11.html │ ├── 12.html │ ├── 2.html │ ├── 3.html │ ├── 4.html │ ├── 5.html │ ├── 6.html │ ├── 7.html │ ├── 8.html │ └── 9.html ├── 2handwrite │ ├── arguments.js │ ├── debugger.js │ ├── index.js │ ├── instanceof.js │ ├── lazy-man.js │ ├── new.js │ ├── package.json │ ├── process.js │ ├── promisify.js │ ├── pubsub.js │ └── readme.md ├── 3angular-module │ ├── README.md │ ├── test.html │ ├── test.js │ ├── test1.html │ └── test1.js ├── 4angular-todolist │ ├── README.md │ ├── css │ │ └── index.css │ ├── index.html │ └── javascripts │ │ ├── app.js │ │ └── ctrl.js ├── 5ast │ ├── index.js │ ├── package.json │ └── yarn.lock ├── 6node │ ├── 1.txt │ ├── app.js │ ├── hello.js │ ├── package.json │ ├── public │ │ ├── 1.html │ │ ├── 1.js │ │ └── 2.js │ └── test.js ├── 7typescript │ ├── .eslintrc.js │ ├── 1.js │ ├── 2.js │ ├── a.d.ts │ ├── a.js │ ├── b.js │ ├── b.ts │ ├── babel.config.js │ ├── dist │ │ ├── b.d.ts │ │ ├── hello.d.ts │ │ ├── main.js │ │ └── main.js.map │ ├── hello.d.ts │ ├── hello.js │ ├── hello.ts │ ├── package.json │ ├── tsconfig.json │ └── webpack.config.js ├── 8cilpboard │ └── index.html └── 9generator │ ├── index.js │ └── iterator.js ├── pnpm-lock.yaml └── pnpm-workspace.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | */.idea 3 | node_modules 4 | */.vscode 5 | .DS_Store 6 | .npm 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 1.0.0 (2024-01-12) 2 | 3 | 4 | ### Features 5 | 6 | * change mono ([5c8d968](https://github.com/zhaoky/demos/commit/5c8d9682c31932ca43d6662a853796d08323cb92)) 7 | * **demos:** 调整目录 ([63cd770](https://github.com/zhaoky/demos/commit/63cd77044b1cf6e5c30ac9057d5b16b92e68f356)) 8 | * **demos:** 调整web communication ([cc48206](https://github.com/zhaoky/demos/commit/cc482060261a246ede92a576903f3077d11b9f43)) 9 | * **demos:** 调整web communication ([ea28e1a](https://github.com/zhaoky/demos/commit/ea28e1ab55389fd9fa4360f364979b2f307b1be8)) 10 | * **demos:** 调整web communication ([20b41bd](https://github.com/zhaoky/demos/commit/20b41bd4366e0c6c5b8d17f3a70ca91258d462ee)) 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019-present, Keyu(Korey) Zhao 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # demos 2 | 3 | 记录一些学习的零碎的知识点的 `demo`。 4 | 5 | 每一个文件夹即为一个 `demo`,`cd` 到每个具体的文件夹即可。 6 | 7 | ## demo 列表(按入库顺序) 8 | 9 | 0. `test` 一些零碎的知识点测试 10 | 1. `build` 一些构建工具的测试 11 | 2. `handwrite` 手写一些常见实现的 demo 12 | 3. `angular-module` angular1.x 模块依赖 13 | 4. `angular-todolist` angular1.x 所开发的单页面应用 14 | 5. `ast` 15 | 6. `node` 16 | 7. `typescript` 17 | 8. `cilpboard` 粘贴板测试 18 | 9. `generator` 19 | 10. `corb` 跨域读取阻止 20 | 11. `vue-router` 21 | 12. `vuex` 22 | 13. `vue-ssr` 23 | 14. `hmr` HMR 源码解析 24 | 15. `prerender-spa` 预渲染 25 | 16. `microfe-single-spa` 微前端 26 | 17. `koa` koa 的一个跨域请求 27 | 18. `web-communication` Web 端即时通讯技术盘点 28 | 19. `canvas` canvas 进度盘 29 | 20. `react-redux` 30 | 21. `rspress-korey-site` respress demo 31 | 22. `vue-project` creat-vue 32 | 23. `rsbuild` rebuild demo 33 | 23. `rspack` rspack demo 34 | 24. `css` css相关 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demos", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", 8 | "preinstall": "npx only-allow pnpm" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "conventional-changelog-cli": "^4.1.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/0test/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/0test/1.png -------------------------------------------------------------------------------- /packages/0test/build/test.debug.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | background: #ddd; 8 | } 9 | 10 | #container { 11 | background: #eee; 12 | /* margin: 100px; */ 13 | /* width: 500px; */ 14 | height: 6.666667rem; 15 | /* display: flex; */ 16 | } 17 | 18 | .item { 19 | /* width: 100px; */ 20 | /* height: 100px; */ 21 | border: 0.013333rem solid #333; 22 | background: rgb(95, 185, 132); 23 | } 24 | 25 | #c1 { 26 | /* height: 100px; */ 27 | /* line-height: 90px; */ 28 | } 29 | 30 | #c2 { 31 | height: 120px; 32 | line-height: 0.933333rem; 33 | } 34 | 35 | #c3 { 36 | height: 2rem; 37 | line-height: 0.666667rem; 38 | } -------------------------------------------------------------------------------- /packages/0test/clipboard-test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 剪切板测试 10 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /packages/0test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "test.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /packages/0test/test.css: -------------------------------------------------------------------------------- 1 | * { 2 | 3 | margin: 0; 4 | padding: 0; 5 | } 6 | .header { 7 | width: 100%; 8 | height: 160px; 9 | } 10 | .img { 11 | display: flex; 12 | justify-content: center; 13 | } 14 | .img { 15 | width: 88px; 16 | height: 88px; 17 | } 18 | .text { 19 | font-size: 32px; 20 | color: #333333; 21 | line-height: 32px; 22 | text-align: center; 23 | margin-top: 32px; 24 | } 25 | -------------------------------------------------------------------------------- /packages/0test/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 44 | 45 | 46 | 47 |
48 |
49 | 50 |
51 |
支付成功
52 |
53 | 54 | 55 | -------------------------------------------------------------------------------- /packages/0test/test.js: -------------------------------------------------------------------------------- 1 | var name = 'zky'; 2 | (function(){ 3 | if(typeof name === 'undefined'){ 4 | var name = "liran"; 5 | console.log(1,name); 6 | }else{ 7 | console.log(2,name); 8 | } 9 | })(); -------------------------------------------------------------------------------- /packages/0test/test11.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 35 | 36 | 37 | 38 | 39 |
40 |
a
41 |
b
42 |
c
43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /packages/0test/test12.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 13 |
1
14 | 15 | 21 | 22 | -------------------------------------------------------------------------------- /packages/0test/test13.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 1 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/0test/test13.js: -------------------------------------------------------------------------------- 1 | console.log(13); 2 | import a from "./test13_1.js"; 3 | console.log(a); 4 | -------------------------------------------------------------------------------- /packages/0test/test13_1.js: -------------------------------------------------------------------------------- 1 | console.log(131); 2 | export default 1; 3 | -------------------------------------------------------------------------------- /packages/0test/test14.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 15 | 16 | 17 |
18 | aaaaaa 19 | b 20 |
21 | 22 | 69 | 70 | -------------------------------------------------------------------------------- /packages/0test/test15.js: -------------------------------------------------------------------------------- 1 | const a = function b() { 2 | b = 1; 3 | console.log(b); 4 | }; 5 | a(); //打印b为function(){b=1;console.log(b);} 6 | 7 | //为什么这里打印的 `b` 为 `b` 函数,而不是 `1`? 8 | //NFE(具名函数表达式) 声明提前:一个声明在函数体内都是可见的,函数声明优先于变量声明;`函数表达式` 如果有 `name` 的话,这个 `name` 是 `不可删除且为只读`。 -------------------------------------------------------------------------------- /packages/0test/test2.js: -------------------------------------------------------------------------------- 1 | var ff = 2, 2 | line = 1, 3 | column = 3; 4 | function removeBreakpoint({ url: ff, line, column }) { 5 | console.log(888, url, line, column); 6 | } 7 | 8 | removeBreakpoint({ 9 | ff: 1, 10 | line: 2 11 | }); 12 | -------------------------------------------------------------------------------- /packages/0test/test3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 19 | 20 | 21 | 323 22 | 23 |
1
24 | 25 | 26 | 29 | 30 | -------------------------------------------------------------------------------- /packages/0test/test3.js: -------------------------------------------------------------------------------- 1 | // 获取Array原型 2 | var arrayProto = Array.prototype; 3 | var arrayMethods = Object.create(arrayProto); 4 | var newArrProto = []; 5 | ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(method => { 6 | // 原生Array的原型方法 7 | let original = arrayMethods[method]; 8 | 9 | // 将push,pop等方法重新封装并定义在对象newArrProto的属性上 10 | // 这里需要注意的是封装好的方法是定义在newArrProto的属性上而不是其原型属性 11 | // newArrProto.__proto__ 没有改变 12 | newArrProto[method] = function mutator() { 13 | console.log('监听到数组的变化啦!'); 14 | 15 | // 调用对应的原生方法并返回结果(新数组长度) 16 | return original.apply(this, arguments); 17 | }; 18 | }); 19 | 20 | var list = [1, 2]; 21 | // 将我们要监听的数组的原型指针指向上面定义的空数组对象 22 | // newArrProto的属性上定义了我们封装好的push,pop等方法 23 | list.__proto__ = newArrProto; 24 | list.push(3); 25 | // 监听到数组的变化啦! 3 26 | 27 | // 这里的list2没有被重新定义原型指针,所以这里会正常执行原生Array上的原型方法 28 | var list2 = [1, 2]; 29 | list2.push(3); 30 | // 3 31 | -------------------------------------------------------------------------------- /packages/0test/test4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 14 | 15 | 16 |
111
17 | 18 | -------------------------------------------------------------------------------- /packages/0test/test4.js: -------------------------------------------------------------------------------- 1 | function def(obj, key, val, enumerable) { 2 | Object.defineProperty(obj, key, { 3 | value: val, 4 | enumerable: !!enumerable, 5 | configurable: true, 6 | writable: true 7 | }); 8 | } 9 | // observe array 10 | let arrayProto = Array.prototype; 11 | let arrayMethods = Object.create(arrayProto); 12 | ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(method => { 13 | // 原始数组操作方法 14 | let original = arrayMethods[method]; 15 | def(arrayMethods, method, function() { 16 | let arguments$1 = arguments; 17 | let i = arguments.length; 18 | let args = new Array(i); 19 | 20 | while (i--) { 21 | args[i] = arguments$1[i]; 22 | } 23 | // 执行数组方法 24 | let result = original.apply(this, args); 25 | // 因 arrayMethods 是为了作为 Observer 中的 value 的原型或者直接作为属性,所以此处的 this 一般就是指向 Observer 中的 value 26 | // 当然,还需要修改 Observer,使得其中的 value 有一个指向 Observer 自身的属性,__ob__,以此将两者关联起来 27 | let ob = this.__ob__; 28 | // 存放新增数组元素 29 | let inserted; 30 | // 为add 进arry中的元素进行observe 31 | switch (method) { 32 | case 'push': 33 | inserted = args; 34 | break; 35 | case 'unshift': 36 | inserted = args; 37 | break; 38 | case 'splice': 39 | // 第三个参数开始才是新增元素 40 | inserted = args.slice(2); 41 | break; 42 | } 43 | if (inserted) { 44 | ob.observeArray(inserted); 45 | } 46 | // 通知数组变化 47 | ob.dep.notify(); 48 | // 返回新数组长度 49 | return result; 50 | }); 51 | }); 52 | console.log(arrayMethods); 53 | -------------------------------------------------------------------------------- /packages/0test/test5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 14 | 15 | 16 |
17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /packages/0test/test6.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 20 | 21 | 22 |
1
23 |
2
24 |
3
25 |
4
26 |
5
27 |
6
28 |
7
29 |
8
30 | 31 | -------------------------------------------------------------------------------- /packages/0test/test7.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |
1
13 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /packages/0test/test7.js: -------------------------------------------------------------------------------- 1 | console.log('test7'); 2 | import {z} from './test71'; 3 | z(); -------------------------------------------------------------------------------- /packages/0test/test71.js: -------------------------------------------------------------------------------- 1 | var a = 1; 2 | console.log('执行test71'); 3 | 4 | function z(){ 5 | return a; 6 | } 7 | 8 | export { 9 | z 10 | } -------------------------------------------------------------------------------- /packages/0test/test9.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |
1
11 | 12 | 17 | -------------------------------------------------------------------------------- /packages/10corb/1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /packages/10corb/2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Untitled Document 5 | 6 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /packages/10corb/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "corb", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "express": "^4.17.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/10corb/readme.md: -------------------------------------------------------------------------------- 1 | # 跨域读取阻止(CORB) 2 | 3 | -[文档](https://chromium.googlesource.com/chromium/src/+/master/services/network/cross_origin_read_blocking_explainer.md) 4 | 5 | -[解析](https://juejin.im/post/5cc2e3ecf265da03904c1e06) 6 | 7 | 使用 `mkcert` 生成本地测试 `https` 证书 8 | 9 | ```sh 10 | brew install mkcert 11 | mkcert -install 12 | mkcert 192.168.50.56 #本机地址 13 | ``` 14 | 15 | 使用 `http-server` 开启本地测试服务器 16 | 17 | ```sh 18 | http-server -S -C 192.168.50.56.pem -K 192.168.50.56-key.pem 19 | ``` 20 | 21 | 这样就可以本地调试 `https` 的测试页面了 22 | -------------------------------------------------------------------------------- /packages/10corb/server.js: -------------------------------------------------------------------------------- 1 | let express = require('express'); 2 | let app = express(); 3 | 4 | let data = { 5 | name: 'wade', 6 | age: 18 7 | }; 8 | app.all('*', function(req, res, next) { 9 | // res.header('Access-Control-Allow-Origin', '*'); 10 | 11 | // res.header('Access-Control-Allow-Credentials', true); 12 | res.header('X-Content-Type-Options', 'nosniff'); 13 | 14 | // res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length, Authorization, Accept,X-Requested-With,JSON'); 15 | 16 | // res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS'); 17 | 18 | res.header('Content-Type', 'text/javascript;charset=utf-8'); 19 | 20 | next(); 21 | }); 22 | let api = '/api/user'; 23 | 24 | app.get('*', (req, res) => { 25 | console.log('服务器收到请求'); 26 | // console.log(111, req, res); 27 | // res.type('application/x-javascript'); 28 | res.send(data); 29 | 30 | // res.jsonp(data); 31 | }); 32 | 33 | //配置服务端口 34 | 35 | app.listen(8000, () => { 36 | console.log(`localhost:8000${api}`); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/11vue-router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-router", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "webpack-dev-server" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "@babel/core": "^7.9.0", 14 | "babel-loader": "^8.1.0", 15 | "html-webpack-plugin": "^4.0.4", 16 | "vue-loader": "^15.9.1", 17 | "vue-router": "^3.1.6", 18 | "vue-template-compiler": "^2.6.11", 19 | "webpack": "^4.42.1", 20 | "webpack-cli": "^3.3.11", 21 | "webpack-dev-server": "^3.10.3" 22 | }, 23 | "dependencies": { 24 | "vue": "^2.6.11" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/11vue-router/readme.md: -------------------------------------------------------------------------------- 1 | # vue-router 2 | 3 | 粗略看了下源码,行一些记录。 4 | 5 | 1. 通过 `Vue.use(VueRouter)` 安装插件 `VueRouter`,会通过 `Vue.mixin` 扩展 `beforeCreate,destroyed` 钩子,并监听 `Vue.prototype` 上的 `$router,$route`,注册全局组件 `RouterView,RouterLink`。 6 | 2. 实例化 `VueRouter` 里,根据 `mode` 不同实例化不同的 `history:HTML5History,HashHistory,AbstractHistory`,三者均继承于 `History`,其中如果是 `HashHistory`,如果路径没有 `#` 则调用 `ensureSlash` 添加上。 7 | 3. 执行 `vue` 的构建流程: 8 | 1. `beforeCreate` 里对 `VueRouter` 实例执行 `init` 初始化,执行不同的 `history.transitionTo` 后(下文分析),**执行 `history.listen` 注册路由变化回调(`init` 里),并监听 `Vue` 实例上的 `_route`(`beforeCreate` 里)**。 9 | 2. `transitionTo` 里得到需要跳转的 `route` 对象后,执行 `confirmTransition` 里通过双 `queue` 任务调度队列,先后执行了:`beforeRouteLeave->beforeEach->beforeRouteUpdate->beforeEnter,beforeRouteEnter->beforeResolve` 钩子。 10 | 3. 然后执行 `confirmTransition` 的回调里执行 `history.updateRoute` 执行**路由变化回调触发 `_route` 重新渲染视图**后,执行 `afterEach` 钩子。 11 | 4. 然后执行 `transitionTo` 的回调判断是 `HashHistory` 则设置 `scroll` 和注册事件监听:`popstate` 或 `hashchange`。(如果是 `HashHistory` 则在其实例化的时候就已经册事件监听 `popstate`了)。一旦 `hash` 变化即触发 `transitionTo` 流程,到此 `VueRouter init` 结束, 12 | 5. 继续 `vue` 的执行,在执行函数组件 `RouterView render` 函数渲染成 `vnode` 时,读取 `$route->_route` 将渲染 `watcher` 订阅,之后 `vue` 构建结束。 13 | 4. 执行 `router.push`,内部执行 `transitionTo` 后(其中会添加异步 `Vue` 的渲染 `watcher` 任务),其回调里先执行 `pushHash` 通过原生方法 `window.location.hash` 或 `window.history.pushState` 修改路由并设置 `scroll`,在下一次微循环时,执行渲染 `watcher` 更新视图时因为 `renderChildren` 存在会强制更新子组件。 14 | 5. 组件 ``在执行 `render` 函数时,创建 `a` 标签并绑定处理事件。 15 | 6. 调用 `history.pushState()` 或者 `history.replaceState()` 不会触发 `popstate` 事件和 `hashchange` 事件,`popstate` 事件只会在浏览器某些行为下触发, 比如点击后退、前进按钮(或者在 `JavaScript` 中调用 `history.back()、history.forward()、history.go()` 方法). 16 | 7. [更多分析参考](https://juejin.im/post/5b10b46df265da6e2a08a724) 17 | -------------------------------------------------------------------------------- /packages/11vue-router/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |
12 | Go to Foo 13 | Go to Bar 14 |
点击
15 | 16 | 17 | 18 |
测试popstate
19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /packages/11vue-router/webpack.config.js: -------------------------------------------------------------------------------- 1 | const VueLoaderPlugin = require('vue-loader/lib/plugin'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const path = require('path'); 4 | 5 | module.exports = { 6 | mode: 'development', 7 | devtool: 'hidden-source-map', 8 | entry: { 9 | main: path.resolve(__dirname, './src/index.js') 10 | }, 11 | output: { 12 | path: path.resolve(__dirname, './dist'), 13 | filename: 'bundle.js', 14 | publicPath: '/' 15 | }, 16 | resolve: { 17 | extensions: ['.js', '.vue'], 18 | alias: { 19 | vue$: 'vue/dist/vue.esm.js' 20 | } 21 | }, 22 | devServer: { 23 | historyApiFallback: { 24 | rewrites: [ 25 | { from: /^./, to: '/' }, 26 | { from: /^\/foo/, to: '/foo' }, 27 | { from: /^\/bar/, to: '/bar' } 28 | ] 29 | } 30 | }, 31 | module: { 32 | rules: [ 33 | { 34 | test: /\.vue$/, 35 | loader: ['vue-loader'] 36 | }, 37 | { 38 | test: /\.js$/, 39 | loader: 'babel-loader' 40 | } 41 | ] 42 | }, 43 | plugins: [ 44 | new VueLoaderPlugin(), 45 | new HtmlWebpackPlugin({ 46 | template: 'src/index.html' 47 | }) 48 | ] 49 | }; 50 | -------------------------------------------------------------------------------- /packages/12vuex/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/12vuex/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/12vuex/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuex", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "webpack", 9 | "dev": "webpack-dev-server" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "vue": "^2.6.11", 16 | "vuex": "^3.1.3" 17 | }, 18 | "devDependencies": { 19 | "@babel/core": "^7.9.0", 20 | "babel-loader": "^8.1.0", 21 | "html-webpack-plugin": "^4.2.0", 22 | "webpack": "^4.42.1", 23 | "webpack-cli": "^3.3.11", 24 | "webpack-dev-server": "^3.10.3" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/12vuex/readme.md: -------------------------------------------------------------------------------- 1 | # vuex 2 | 3 | 粗略看了下源码,行一些记录。 4 | 5 | 1. 引入 `vuex` 文件时,将执行 `Store, Module` 类等定义,并在原型上监听 `state` 及其子属性(只读)。 6 | 2. 通过 `Vue.use(Vuex)` 安装插件 `Vuex`,会通过 `Vue.mixin` 扩展 `beforeCreate` 钩子,用于执行 `vuexInit` 将 `Vue` 的传入选项 `store`(没有则取父组件的 `$store`)赋给实例属性 `$store` 上。 7 | 3. 实例化 `Vuex.Store`,内部初始化各项变量,执行插件,调试工具等。 8 | 1. `installModule` 里处理及包装各个传入的选项,如 `getters,mutations,actions,module` 等。 9 | 2. `resetStoreVM` 里监听 `Store` 实例上的 `getters` 的子属性(只读)。并实例化 `vue` 将 `store.state`(`data.$$state`属性) 和包装后的 `store.getters`(`computed` 属性) 设为响应式。 10 | 3. 严格模式下 `$watch` 了 `this._data.$$state`。一旦状态变化即会执行 `$watch` 的回调通过 `this._committing` 判断是否是通过 `commit` 改变,不是则说明为直接更改状态将报错,但不影响执行。 11 | 4. 其他 12 | - `action` 里的函数参数为 `{context,{dispatch,commit,getters,state,rootGetters,rootState},payload}`,支持异步,默认返回 `promise` 对象; 13 | - `mutations` 里的函数参数为 `{state, payload}` ,不支持异步,无返回; 14 | - `getters` 里的函数参数为:`{state, getters, rootState, rootGetters}`,返回计算值。 15 | 5. 辅助函数:`mapState,mapGetters,mapMutations,mapActions`。 16 | 6. 各 `module` 的 `action, mutation, getter` 默认注册在全局命名空间。`state` 会在 `module` 以名称为 `key` 的 `state` 对象下。 17 | 7. `flux` 相关[参考](http://www.ruanyifeng.com/blog/2016/01/flux.html) 18 | -------------------------------------------------------------------------------- /packages/12vuex/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 2 | const path = require('path'); 3 | 4 | module.exports = { 5 | mode: 'development', 6 | devtool: 'hidden-source-map', 7 | entry: { 8 | main: path.resolve(__dirname, './app.js') 9 | }, 10 | output: { 11 | path: path.resolve(__dirname, './dist'), 12 | filename: 'bundle.js', 13 | }, 14 | resolve: { 15 | extensions: ['.js'], 16 | alias: { 17 | vue$: 'vue/dist/vue.esm.js' 18 | } 19 | }, 20 | module: { 21 | rules: [ 22 | { 23 | test: /\.js$/, 24 | loader: 'babel-loader' 25 | } 26 | ] 27 | }, 28 | plugins: [ 29 | new HtmlWebpackPlugin({ 30 | template: 'index.html' 31 | }) 32 | ] 33 | }; 34 | -------------------------------------------------------------------------------- /packages/13vue-ssr/config/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const VueLoaderPlugin = require('vue-loader/lib/plugin'); 3 | 4 | module.exports = { 5 | mode: 'development', 6 | devtool: 'hidden-source-map', 7 | output: { 8 | path: path.resolve(__dirname, '../dist'), 9 | }, 10 | resolve: { 11 | extensions: ['.js', '.vue'], 12 | alias: { 13 | vue$: 'vue/dist/vue.js', 14 | }, 15 | }, 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.vue$/, 20 | loader: ['vue-loader'], 21 | }, 22 | { 23 | test: /\.js$/, 24 | loader: 'babel-loader', 25 | }, 26 | ], 27 | }, 28 | plugins: [new VueLoaderPlugin()], 29 | }; 30 | -------------------------------------------------------------------------------- /packages/13vue-ssr/config/webpack.client.conf.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge'); 2 | const base = require('./webpack.base.conf.js'); 3 | const path = require('path'); 4 | 5 | const config = merge(base, { 6 | entry: { 7 | main: path.resolve(__dirname, '../src/entry/entry-client.js'), 8 | }, 9 | output: { 10 | filename: 'bundle-client.js', 11 | }, 12 | }); 13 | 14 | module.exports = config; 15 | -------------------------------------------------------------------------------- /packages/13vue-ssr/config/webpack.server.conf.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge'); 2 | const base = require('./webpack.base.conf.js'); 3 | const path = require('path'); 4 | 5 | const config = merge(base, { 6 | entry: { 7 | main: path.resolve(__dirname, '../src/entry/entry-server.js'), 8 | }, 9 | target: 'node', 10 | output: { 11 | filename: 'bundle-server.js', 12 | libraryTarget: 'commonjs2', //服务端依赖 13 | }, 14 | }); 15 | 16 | module.exports = config; 17 | -------------------------------------------------------------------------------- /packages/13vue-ssr/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-ssr", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "server": "node server/server.js", 8 | "build-client": "webpack --config config/webpack.client.conf.js", 9 | "build-server": "webpack --config config/webpack.server.conf.js" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "axios": "^0.19.2", 16 | "koa": "^2.11.0", 17 | "vue": "^2.6.11", 18 | "vue-server-renderer": "^2.6.11", 19 | "vuex-router-sync": "^5.0.0" 20 | }, 21 | "devDependencies": { 22 | "@babel/core": "^7.9.6", 23 | "babel-loader": "^8.1.0", 24 | "koa-static": "^5.0.0", 25 | "vue-loader": "^15.9.2", 26 | "vue-router": "^3.1.6", 27 | "vue-template-compiler": "^2.6.11", 28 | "vuex": "^3.4.0", 29 | "webpack": "^4.43.0", 30 | "webpack-cli": "^3.3.11", 31 | "webpack-merge": "^4.2.2" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/13vue-ssr/server/server.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const fs = require('fs'); 3 | const static = require('koa-static'); 4 | const server = new Koa(); 5 | const createApp = require('../dist/bundle-server').default; 6 | 7 | const renderer = require('vue-server-renderer').createRenderer({ 8 | template: fs.readFileSync(__dirname + '/../src/template.html', 'utf-8'), 9 | }); 10 | server.use(static(__dirname + '/../dist')); 11 | server.use((ctx) => { 12 | const context = { 13 | title: '1111', 14 | meta: ` 15 | 16 | 17 | `, 18 | url: ctx.url, 19 | }; 20 | 21 | return createApp(context) 22 | .then((app) => { 23 | renderer.renderToString(app, context, (err, html) => { 24 | ctx.body = html; 25 | }); 26 | }) 27 | .catch(() => {}); 28 | }); 29 | 30 | server.listen(3000, () => { 31 | console.log(`渲染地址:http://localhost:3000`); 32 | }); 33 | -------------------------------------------------------------------------------- /packages/13vue-ssr/src/api/index.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | export const data = { 4 | list: () => 5 | axios 6 | .get('http://rap2.taobao.org:38080/app/mock/254238/get//api/ele?type=1') 7 | .then((res) => { 8 | return res.data; 9 | }) 10 | .catch((err) => { 11 | console.log('axios error:', err); 12 | }), 13 | }; 14 | -------------------------------------------------------------------------------- /packages/13vue-ssr/src/app.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import { createRouter } from './router/router'; 3 | import { createStore } from './store/store'; 4 | import { sync } from 'vuex-router-sync'; 5 | 6 | export function createApp() { 7 | const router = createRouter(); 8 | const store = createStore(); 9 | 10 | sync(store, router); 11 | 12 | const app = new Vue({ 13 | router, 14 | store, 15 | template: ` 16 |
17 |
18 | I am the navigation bar 19 | Go to foo 20 | Go to bar 21 |
22 | 23 |
24 | `, 25 | }); 26 | return { app, router, store }; 27 | } 28 | -------------------------------------------------------------------------------- /packages/13vue-ssr/src/components/404.vue: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /packages/13vue-ssr/src/components/bar.vue: -------------------------------------------------------------------------------- 1 | 9 | 21 | -------------------------------------------------------------------------------- /packages/13vue-ssr/src/components/foo.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /packages/13vue-ssr/src/entry/entry-client.js: -------------------------------------------------------------------------------- 1 | import { createApp } from '../app'; 2 | 3 | const { app, router, store } = createApp(); 4 | if (window.__INITIAL_STATE__) { 5 | store.replaceState(window.__INITIAL_STATE__); 6 | } 7 | 8 | router.onReady(() => { 9 | app.$mount('#app'); 10 | 11 | // 客户端数据预取(非首屏渲染的情况),也可以将此逻辑放到对应视图组件的 beforeMount 里执行。 12 | router.beforeResolve((to, from, next) => { 13 | const matched = router.getMatchedComponents(to); 14 | const prevMatched = router.getMatchedComponents(from); 15 | const activated = matched.filter((item) => prevMatched.every((i) => i !== item)); 16 | 17 | if (!activated.length) { 18 | return next(); 19 | } 20 | 21 | Promise.all( 22 | activated.map((item) => { 23 | if (item.asyncData) { 24 | return item.asyncData({ store }); 25 | } 26 | }) 27 | ) 28 | .then(() => { 29 | next(); 30 | }) 31 | .catch(() => { 32 | next(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /packages/13vue-ssr/src/entry/entry-server.js: -------------------------------------------------------------------------------- 1 | import { createApp } from '../app'; 2 | 3 | export default (context) => { 4 | return new Promise((resolve, reject) => { 5 | const { app, router, store } = createApp(); 6 | 7 | router.push(context.url); 8 | 9 | router.onReady(() => { 10 | // 首屏渲染拉取对应组件数据 11 | const matchedComponents = router.getMatchedComponents(); 12 | 13 | if (!matchedComponents.length) { 14 | return reject({ code: 404 }); 15 | } 16 | 17 | Promise.all( 18 | matchedComponents.map((comp) => { 19 | if (comp.asyncData) { 20 | return comp.asyncData({ store }); 21 | } else { 22 | return Promise.resolve(); 23 | } 24 | }) 25 | ).then(() => { 26 | context.state = store.state; //renderToString 里会将state 注入到 window.__INITIAL_STATE__ 27 | resolve(app); 28 | }); 29 | }, reject); 30 | }); 31 | }; 32 | -------------------------------------------------------------------------------- /packages/13vue-ssr/src/router/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Router from 'vue-router'; 3 | 4 | const Foo = () => import('../components/foo.vue'); 5 | const Bar = () => import('../components/bar.vue'); 6 | const NoFound = () => import('../components/404.vue'); 7 | 8 | Vue.use(Router); 9 | 10 | export function createRouter() { 11 | return new Router({ 12 | mode: 'history', 13 | routes: [ 14 | { 15 | path: '/foo', 16 | component: Foo, 17 | }, 18 | { 19 | path: '/bar', 20 | component: Bar, 21 | }, 22 | { 23 | path: '*', 24 | component: NoFound, 25 | }, 26 | ], 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /packages/13vue-ssr/src/store/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuex from 'vuex'; 3 | import { data } from '../api/index'; 4 | 5 | Vue.use(Vuex); 6 | 7 | export function createStore() { 8 | return new Vuex.Store({ 9 | state: { 10 | list: [], 11 | }, 12 | actions: { 13 | async fetchList({ commit }) { 14 | let list = await data.list(); 15 | commit('setList', list.list); 16 | }, 17 | }, 18 | mutations: { 19 | setList(state, list) { 20 | state.list = list; 21 | }, 22 | }, 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /packages/13vue-ssr/src/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ title }} 5 | {{{ meta }}} 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/14hmr/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hmr", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "devDependencies": { 7 | "css-loader": "^4.3.0", 8 | "html-webpack-plugin": "^4.5.0", 9 | "style-loader": "^2.0.0", 10 | "webpack-dev-server": "^3.11.0" 11 | }, 12 | "scripts": { 13 | "dev": "webpack-dev-server" 14 | }, 15 | "dependencies": { 16 | "webpack": "4", 17 | "webpack-cli": "3" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/14hmr/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #ddd; 3 | } 4 | -------------------------------------------------------------------------------- /packages/14hmr/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |

12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/14hmr/src/index.js: -------------------------------------------------------------------------------- 1 | import './index.css'; 2 | document.getElementById('app').innerHTML = '13'; 3 | if (module.hot) { 4 | module.hot.accept(); 5 | } 6 | -------------------------------------------------------------------------------- /packages/14hmr/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebPackPlugin = require('html-webpack-plugin'); 2 | module.exports = { 3 | entry: './src/index.js', 4 | devServer: { 5 | port: 9001, 6 | hot: true, 7 | }, 8 | devtool: 'source-map', 9 | module: { 10 | rules: [{ test: /\.css$/, use: [{ loader: 'style-loader' }, { loader: 'css-loader' }] }], 11 | }, 12 | plugins: [ 13 | new HtmlWebPackPlugin({ 14 | template: 'src/index.html', 15 | filename: 'index.html', 16 | }), 17 | ], 18 | }; 19 | -------------------------------------------------------------------------------- /packages/15prerender-spa/dist/bar/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 纯浏览器渲染 6 | 11 | 12 | 13 |
1
Go to Foo Go to Bar
123
14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/15prerender-spa/dist/foo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 纯浏览器渲染 6 | 11 | 12 | 13 |
1
Go to Foo Go to Bar
foo
14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/15prerender-spa/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 纯浏览器渲染 8 | 13 | 14 | 15 |
16 |
1
17 | Go to Foo 18 | Go to Bar 19 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /packages/15prerender-spa/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "prerender-spa", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "webpack" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "@babel/core": "^7.9.6", 14 | "babel-loader": "^8.1.0", 15 | "html-webpack-plugin": "^4.3.0", 16 | "prerender-spa-plugin": "^3.4.0", 17 | "vue-router": "^3.1.6", 18 | "webpack": "^4.43.0", 19 | "webpack-cli": "^3.3.11" 20 | }, 21 | "dependencies": { 22 | "vue": "^2.6.11" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/15prerender-spa/readme.md: -------------------------------------------------------------------------------- 1 | # 预渲染 demo 2 | 3 | 采用[官方推荐](https://ssr.vuejs.org/zh/#%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AB%AF%E6%B8%B2%E6%9F%93-vs-%E9%A2%84%E6%B8%B2%E6%9F%93-ssr-vs-prerendering)的插件:`prerender-spa-plugin` 4 | 5 | 构建阶段生成匹配预渲染路径的 `html` 文件(注意:每个需要预渲染的路由都有一个对应的 `html`)。构建出来的 `html` 文件已有部分内容。 6 | 7 | ## 安装方法 8 | 9 | ```bash 10 | yarn add prerender-spa-plugin -D 11 | ``` 12 | 13 | 网络不好则执行: 14 | 15 | ```bash 16 | yarn add prerender-spa-plugin -D --ignore-scripts 17 | ``` 18 | 19 | 然后去下载对应要求的 `chromium` 版本,放在 `node_modules/puppeteer/.local-chromium/mac-686378/chrome-mac` 文件夹下,其中 `mac-686378` 数字为对应版本号。 20 | 21 | ## 预渲染好处 22 | 23 | - 再 webpack 构建的最后,使用无界面浏览器如 puppeteer 访问对应的路径,使用默认的 defaultState 生成 HTML,并保存到对应的目录。访问的时候优先访问有静态 HTML 的页面。 24 | - 预渲染不适合数据频繁变化的页面 25 | - 只是减少白屏时间,并不会减少首屏时间 26 | - 因为不需要等数据回来,所以白屏性能可能比服务端渲染好 27 | 28 | ## 原理 29 | 30 | `prerender-spa-plugin` 利用了 `Puppeteer` 的爬取页面的功能。 31 | 32 | `Puppeteer` 是一个 `Chrome` 官方出品的 `headlessChromenode` 库。它提供了一系列的 `API`, 可以在无 `UI` 的情况下调用 `Chrome` 的功能, 适用于爬虫、自动化处理等各种场景。 33 | 34 | 它很强大,所以很简单就能将运行时的 `HTML` 打包到文件中。 35 | 36 | 原理是在 `Webpack` 构建阶段的最后,在本地启动一个 `Puppeteer` 的服务,访问配置了预渲染的路由,然后将 `Puppeteer` 中渲染的页面输出到 `HTML` 文件中,并建立路由对应的目录。 37 | 38 | ## 如何使用 39 | 40 | 根据原理,他会得到渲染后的 `html` 代码输出到 `html` 文件的对应位置,适合静态无交互,无事件的页面。 41 | 42 | 如果需要他被客户端 `js` 接管,即执行 `js`,则需要配合 `vue-router` 且 `mode` 设为 `history`,并相应的调整服务器配置。 43 | -------------------------------------------------------------------------------- /packages/15prerender-spa/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 纯浏览器渲染 8 | 13 | 14 | 15 |
16 |
1
17 | Go to Foo 18 | Go to Bar 19 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /packages/15prerender-spa/src/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueRouter from 'vue-router'; 3 | 4 | Vue.use(VueRouter); 5 | 6 | const routes = [ 7 | { 8 | path: '/foo', 9 | component: { 10 | template: '
foo
', 11 | }, 12 | }, 13 | { 14 | path: '/bar', 15 | component: { 16 | template: '
{{b}}
', 17 | data() { 18 | return { 19 | a: 123, 20 | b: '', 21 | }; 22 | }, 23 | methods: { 24 | plus() { 25 | console.log(1111111); 26 | }, 27 | }, 28 | mounted() { 29 | setTimeout(() => { 30 | this.b = '456'; 31 | }, 3000); 32 | }, 33 | }, 34 | }, 35 | ]; 36 | 37 | const router = new VueRouter({ 38 | routes, 39 | mode: 'history', 40 | }); 41 | 42 | var root = new Vue({ 43 | router, 44 | mounted() { 45 | document.dispatchEvent(new Event('render-event')); 46 | }, 47 | }); 48 | document.addEventListener('DOMContentLoaded', function () { 49 | root.$mount('#main'); 50 | }); 51 | -------------------------------------------------------------------------------- /packages/15prerender-spa/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 2 | const PrerenderSPAPlugin = require('prerender-spa-plugin'); 3 | const Renderer = PrerenderSPAPlugin.PuppeteerRenderer; 4 | const path = require('path'); 5 | 6 | module.exports = { 7 | mode: 'development', 8 | devtool: 'hidden-source-map', 9 | entry: { 10 | main: path.resolve(__dirname, './src/index.js'), 11 | }, 12 | output: { 13 | path: path.resolve(__dirname, './dist'), 14 | filename: 'bundle.js', 15 | publicPath: '../', 16 | }, 17 | resolve: { 18 | extensions: ['.js', '.vue'], 19 | alias: { 20 | vue$: 'vue/dist/vue.esm.js', 21 | }, 22 | }, 23 | module: { 24 | rules: [ 25 | { 26 | test: /\.js$/, 27 | loader: 'babel-loader', 28 | }, 29 | ], 30 | }, 31 | plugins: [ 32 | new HtmlWebpackPlugin({ 33 | template: 'src/index.html', 34 | }), 35 | new PrerenderSPAPlugin({ 36 | staticDir: path.join(__dirname, 'dist'), 37 | routes: ['/foo', '/bar'], 38 | renderer: new Renderer({ 39 | inject: { 40 | foo: 'bar', 41 | }, 42 | headless: false, 43 | renderAfterDocumentEvent: 'render-event', 44 | }), 45 | }), 46 | ], 47 | }; 48 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/.travis.yml: -------------------------------------------------------------------------------- 1 | 2 | # THIS IS NOT HOW YOU SHOULD DO DEPLOYMENTS FOR YOUR ORGANIZATION 3 | # 4 | # First off, the sed stuff for modifying import maps is quite hacky and shouldn't 5 | # be what you rely on. 6 | # 7 | # Secondly, each vue app should be in a separate repo and deployed separately, as 8 | # explained in the README.md. 9 | language: node_js 10 | node_js: 11 | - "node" 12 | script: 13 | - cd navbar && npm ci && npm run build && rm dist/index.html 14 | - cd ../app1 && npm ci && npm run build && rm dist/index.html 15 | - cd ../app2 && npm ci && npm run build && rm dist/index.html 16 | - cd .. 17 | - mkdir -p static/navbar static/app1 static/app2 && cp -a navbar/dist/* static/navbar && cp -a app1/dist/* static/app1 && cp -a app2/dist/* static/app2 18 | - cp root-html-file/index.html static 19 | - echo "Files that will be deployed" 20 | - find static 21 | - sed -i 's/http:\/\/localhost:8080/\/navbar/g' static/index.html 22 | - sed -i 's/http:\/\/localhost:8081/\/app1/g' static/index.html 23 | - sed -i 's/http:\/\/localhost:8082/\/app2/g' static/index.html 24 | - cp static/index.html static/200.html 25 | - echo "Files to deploy" 26 | - find static 27 | deploy: 28 | provider: surge 29 | project: ./static/ 30 | domain: coexisting-vue-microfrontends.surge.sh 31 | skip_cleanup: true -------------------------------------------------------------------------------- /packages/16microfe-single-spa/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Joel Denning 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 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/Makefile: -------------------------------------------------------------------------------- 1 | DEFAULT_GOAL := help 2 | 3 | port := 5000 4 | 5 | .PHONY: help 6 | help: 7 | @echo 8 | @echo Manage micro-frontends with single-spa 9 | @echo 10 | @fgrep "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/:.*## / - /' 11 | @echo 12 | 13 | .PHONY: install 14 | install: ## Install all dependencies 15 | @pushd ./root-html-file >/dev/null && (npm install &) && popd >/dev/null 16 | @pushd ./app1 >/dev/null && (npm install &) && popd >/dev/null 17 | @pushd ./app2 >/dev/null && (npm install &) && popd >/dev/null 18 | @pushd ./navbar >/dev/null && (npm install &) && popd >/dev/null 19 | 20 | .PHONY: clean 21 | clean: ## Clean all endpoints 22 | @rm */node_modules -rf 23 | 24 | .PHONY: start 25 | start: ## Start all endpoints 26 | @pushd ./root-html-file >/dev/null && (npx serve -s -l $(port) &) && popd >/dev/null 27 | @pushd ./app1 >/dev/null && (npx vue-cli-service serve --port 8081 &) && popd >/dev/null 28 | @pushd ./app2 >/dev/null && (npx vue-cli-service serve --port 8082 &) && popd >/dev/null 29 | @pushd ./navbar >/dev/null && (npx vue-cli-service serve --port 8080 &) && popd >/dev/null 30 | 31 | .PHONY: stop 32 | stop: ## Stop all endpoints 33 | @pkill -2 node 34 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/README.md: -------------------------------------------------------------------------------- 1 | # app1 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app1", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve --port 8081", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "core-js": "^3.4.3", 11 | "single-spa-vue": "^1.5.4", 12 | "systemjs-webpack-interop": "^1.1.2", 13 | "vue": "^2.6.10", 14 | "vue-router": "^3.1.3" 15 | }, 16 | "devDependencies": { 17 | "@vue/cli-plugin-babel": "^4.1.0", 18 | "@vue/cli-plugin-router": "^4.1.0", 19 | "@vue/cli-service": "^4.1.0", 20 | "vue-cli-plugin-single-spa": "^1.0.1", 21 | "vue-template-compiler": "^2.6.10" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/16microfe-single-spa/app1/public/favicon.ico -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | app1 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/16microfe-single-spa/app1/src/assets/logo.png -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/src/main.js: -------------------------------------------------------------------------------- 1 | import './set-public-path' 2 | import Vue from 'vue'; 3 | import App from './App.vue'; 4 | import router from './router'; 5 | import singleSpaVue from 'single-spa-vue'; 6 | 7 | Vue.config.productionTip = false; 8 | 9 | const vueLifecycles = singleSpaVue({ 10 | Vue, 11 | appOptions: { 12 | render: (h) => h(App), 13 | router, 14 | }, 15 | }); 16 | 17 | export const bootstrap = vueLifecycles.bootstrap; 18 | export const mount = vueLifecycles.mount; 19 | export const unmount = vueLifecycles.unmount; 20 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/src/router.js: -------------------------------------------------------------------------------- 1 | import Router from 'vue-router' 2 | import Home from './views/Home.vue' 3 | 4 | export default new Router({ 5 | mode: 'history', 6 | base: process.env.BASE_URL, 7 | routes: [ 8 | { 9 | path: '/app1', 10 | name: 'home', 11 | component: Home 12 | }, 13 | ] 14 | }) 15 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/src/set-public-path.js: -------------------------------------------------------------------------------- 1 | import { setPublicPath } from 'systemjs-webpack-interop' 2 | 3 | setPublicPath('app1', 2) -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 21 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app1/vue.config.js: -------------------------------------------------------------------------------- 1 | // Temporary until we can use https://github.com/webpack/webpack-dev-server/pull/2143 2 | module.exports = { 3 | chainWebpack: config => { 4 | config.devServer.set('inline', false) 5 | config.devServer.set('hot', true) 6 | // Vue CLI 4 output filename is js/[chunkName].js, different from Vue CLI 3 7 | // More Detail: https://github.com/vuejs/vue-cli/blob/master/packages/%40vue/cli-service/lib/config/app.js#L29 8 | if (process.env.NODE_ENV !== 'production') { 9 | config.output.filename(`js/[name].js`) 10 | } 11 | config.externals(['vue', 'vue-router']) 12 | }, 13 | filenameHashing: false 14 | } 15 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/README.md: -------------------------------------------------------------------------------- 1 | # app2 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app2", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve --port 8082", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "core-js": "^3.4.3", 11 | "single-spa-vue": "^1.5.4", 12 | "systemjs-webpack-interop": "^1.1.2", 13 | "vue": "^2.6.10", 14 | "vue-router": "^3.1.3" 15 | }, 16 | "devDependencies": { 17 | "@vue/cli-plugin-babel": "^4.1.0", 18 | "@vue/cli-plugin-router": "^4.1.0", 19 | "@vue/cli-service": "^4.1.0", 20 | "vue-cli-plugin-single-spa": "^1.0.1", 21 | "vue-template-compiler": "^2.6.10" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/16microfe-single-spa/app2/public/favicon.ico -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | app2 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/16microfe-single-spa/app2/src/assets/logo.png -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 17 | 33 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/src/main.js: -------------------------------------------------------------------------------- 1 | import './set-public-path' 2 | import Vue from 'vue'; 3 | import App from './App.vue'; 4 | import router from './router'; 5 | import singleSpaVue from 'single-spa-vue'; 6 | 7 | Vue.config.productionTip = false; 8 | 9 | const vueLifecycles = singleSpaVue({ 10 | Vue, 11 | appOptions: { 12 | render: (h) => h(App), 13 | router, 14 | }, 15 | }); 16 | 17 | export const bootstrap = vueLifecycles.bootstrap; 18 | export const mount = vueLifecycles.mount; 19 | export const unmount = vueLifecycles.unmount; 20 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/src/router.js: -------------------------------------------------------------------------------- 1 | import Router from 'vue-router' 2 | import Home from './views/Home.vue' 3 | 4 | export default new Router({ 5 | mode: 'history', 6 | base: process.env.BASE_URL, 7 | routes: [ 8 | { 9 | path: '/app2', 10 | name: 'home', 11 | component: Home 12 | }, 13 | { 14 | path: '/app2/about', 15 | name: 'about', 16 | // route level code-splitting 17 | // this generates a separate chunk (about.[hash].js) for this route 18 | // which is lazy-loaded when the route is visited. 19 | component: () => import(/* webpackChunkName: "about" */ './views/About.vue') 20 | } 21 | ] 22 | }) 23 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/src/set-public-path.js: -------------------------------------------------------------------------------- 1 | import { setPublicPath } from 'systemjs-webpack-interop' 2 | 3 | setPublicPath('app2', 2) -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/src/views/About.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 19 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/app2/vue.config.js: -------------------------------------------------------------------------------- 1 | // Temporary until we can use https://github.com/webpack/webpack-dev-server/pull/2143 2 | module.exports = { 3 | chainWebpack: config => { 4 | config.devServer.set('inline', false) 5 | config.devServer.set('hot', true) 6 | // Vue CLI 4 output filename is js/[chunkName].js, different from Vue CLI 3 7 | // More Detail: https://github.com/vuejs/vue-cli/blob/master/packages/%40vue/cli-service/lib/config/app.js#L29 8 | if (process.env.NODE_ENV !== 'production') { 9 | config.output.filename(`js/[name].js`) 10 | } 11 | config.externals(['vue', 'vue-router']) 12 | }, 13 | filenameHashing: false, 14 | } 15 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/README.md: -------------------------------------------------------------------------------- 1 | # navbar 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "navbar", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve --port 8080", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "core-js": "^3.4.3", 11 | "single-spa-vue": "^1.5.4", 12 | "systemjs-webpack-interop": "^1.1.2", 13 | "vue": "^2.6.10", 14 | "vue-router": "^3.1.3" 15 | }, 16 | "devDependencies": { 17 | "@vue/cli-plugin-babel": "^4.1.0", 18 | "@vue/cli-plugin-router": "^4.1.0", 19 | "@vue/cli-service": "^4.1.0", 20 | "vue-cli-plugin-single-spa": "^1.0.1", 21 | "vue-template-compiler": "^2.6.10" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/16microfe-single-spa/navbar/public/favicon.ico -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | navbar 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/src/App.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 32 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/16microfe-single-spa/navbar/src/assets/logo.png -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/src/main.js: -------------------------------------------------------------------------------- 1 | import './set-public-path' 2 | import Vue from 'vue'; 3 | import App from './App.vue'; 4 | import router from './router'; 5 | import singleSpaVue from 'single-spa-vue'; 6 | 7 | Vue.config.productionTip = false; 8 | 9 | const vueLifecycles = singleSpaVue({ 10 | Vue, 11 | appOptions: { 12 | render: (h) => h(App), 13 | router, 14 | }, 15 | }); 16 | 17 | export const bootstrap = vueLifecycles.bootstrap; 18 | export const mount = vueLifecycles.mount; 19 | export const unmount = vueLifecycles.unmount; 20 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/src/router.js: -------------------------------------------------------------------------------- 1 | import Router from 'vue-router' 2 | 3 | export default new Router({ 4 | mode: 'history', 5 | base: process.env.BASE_URL, 6 | routes: [ 7 | // { 8 | // path: '/', 9 | // name: 'home', 10 | // component: Home 11 | // }, 12 | // { 13 | // path: '/about', 14 | // name: 'about', 15 | // // route level code-splitting 16 | // // this generates a separate chunk (about.[hash].js) for this route 17 | // // which is lazy-loaded when the route is visited. 18 | // component: () => import(/* webpackChunkName: "about" */ './views/About.vue') 19 | // } 20 | ] 21 | }) 22 | -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/src/set-public-path.js: -------------------------------------------------------------------------------- 1 | import { setPublicPath } from 'systemjs-webpack-interop' 2 | 3 | setPublicPath('navbar', 2) -------------------------------------------------------------------------------- /packages/16microfe-single-spa/navbar/vue.config.js: -------------------------------------------------------------------------------- 1 | // Temporary until we can use https://github.com/webpack/webpack-dev-server/pull/2143 2 | module.exports = { 3 | chainWebpack: config => { 4 | config.devServer.set('inline', false) 5 | config.devServer.set('hot', false) 6 | // Vue CLI 4 output filename is js/[chunkName].js, different from Vue CLI 3 7 | // More Detail: https://github.com/vuejs/vue-cli/blob/master/packages/%40vue/cli-service/lib/config/app.js#L29 8 | if (process.env.NODE_ENV !== 'production') { 9 | config.output.filename(`js/[name].js`) 10 | } 11 | config.externals(['vue', 'vue-router']) 12 | }, 13 | filenameHashing: false, 14 | } -------------------------------------------------------------------------------- /packages/16microfe-single-spa/root-html-file/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "root-html-file", 3 | "scripts": { 4 | "serve": "serve -s -l 5000" 5 | }, 6 | "devDependencies": { 7 | "serve": "^11.1.0" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/17koa/koa-mini.js: -------------------------------------------------------------------------------- 1 | const http = require('http'); 2 | 3 | function compose(middlewares) { 4 | return (ctx) => { 5 | const dispatch = (i) => { 6 | const middleware = middlewares[i]; 7 | if (i === middlewares.length) { 8 | return; 9 | } 10 | return middleware(ctx, () => dispatch(i + 1)); 11 | }; 12 | return dispatch(0); 13 | }; 14 | } 15 | 16 | class Context { 17 | constructor(req, res) { 18 | this.req = req; 19 | this.res = res; 20 | } 21 | } 22 | 23 | class KoaMini { 24 | constructor() { 25 | this.middlewares = []; 26 | } 27 | 28 | listen(...args) { 29 | const server = http.createServer(this.callback()); 30 | server.listen(...args); 31 | } 32 | 33 | callback() { 34 | return async (req, res) => { 35 | const ctx = new Context(req, res); 36 | const fn = compose(this.middlewares); 37 | try { 38 | await fn(ctx); 39 | } catch (e) { 40 | console.error(e); 41 | ctx.res.statusCode = 500; 42 | ctx.res.end('Internel Server Error'); 43 | } 44 | ctx.res.end(ctx.body); 45 | }; 46 | } 47 | 48 | use(middleware) { 49 | this.middlewares.push(middleware); 50 | } 51 | } 52 | 53 | module.exports = KoaMini; 54 | -------------------------------------------------------------------------------- /packages/17koa/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "koa", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "koa": "^2.12.0", 14 | "koa-static": "^5.0.0" 15 | }, 16 | "dependencies": {} 17 | } 18 | -------------------------------------------------------------------------------- /packages/17koa/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |
10 | 11 | 12 | 33 | 34 | -------------------------------------------------------------------------------- /packages/18web-communication/chat/index.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const fs = require('fs'); 3 | const app = new Koa(); 4 | const static = require('koa-static'); 5 | const router = require('koa-router')(); 6 | const server = require('http').Server(app.callback()); 7 | const io = require('socket.io')(server); 8 | 9 | // 静态资源服务器 10 | app.use(static(__dirname + '/static')); 11 | 12 | router.get('/', async (ctx) => { 13 | ctx.response.type = 'html'; 14 | ctx.body = fs.readFileSync('./index.html'); 15 | }); 16 | 17 | app.use(router.routes()); 18 | app.use(router.allowedMethods()); 19 | // 保存登录的在线用户 20 | const onlineUsers = {}; 21 | // 在线人数 22 | let number = 0; 23 | 24 | io.on('connection', (socket) => { 25 | // 监听用户登录 26 | socket.on('login', (userName) => { 27 | socket.uid = `rd_${new Date().getTime().toString()}${Math.floor(Math.random() * 100000)}`; 28 | onlineUsers[socket.uid] = userName; 29 | number++; 30 | io.emit('login', { 31 | onlineUsers, 32 | number, 33 | curUser: { 34 | userName, 35 | uid: socket.uid, 36 | }, 37 | }); 38 | }); 39 | // 监听用户退出 40 | socket.on('disconnect', () => { 41 | if (!socket.uid) { 42 | return; 43 | } 44 | number--; 45 | const userName = onlineUsers[socket.uid]; 46 | delete onlineUsers[socket.uid]; 47 | console.log(Object.values(onlineUsers)); 48 | io.emit('logout', { 49 | onlineUsers, 50 | number, 51 | curUser: { 52 | uid: socket.uid, 53 | userName, 54 | }, 55 | }); 56 | }); 57 | // 监听普通数据 58 | socket.on('message', (res) => { 59 | // 只会向除了自己的其他用户发送消息 60 | socket.broadcast.emit('message', res); 61 | }); 62 | }); 63 | 64 | server.listen(3000, () => { 65 | console.log(`聊天室地址:http://localhost:3000`); 66 | }); 67 | -------------------------------------------------------------------------------- /packages/18web-communication/chat/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chat", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "koa": "^2.12.1", 14 | "koa-router": "^9.0.1", 15 | "koa-static": "^5.0.0", 16 | "socket.io": "^2.3.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/18web-communication/http-stream/ie-htmlfile-stream.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 基于htmlfile的数据流通信 8 | 9 | 10 | 11 | 28 | 29 | -------------------------------------------------------------------------------- /packages/18web-communication/http-stream/ie-htmlfile-stream.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var fs = require('fs'); 3 | var count = 0; 4 | var server = http 5 | .createServer(function (req, res) { 6 | if (req.url == '/htmlfile') { 7 | res.setHeader('content-type', 'text/html'); 8 | var timer = setInterval(function () { 9 | sendRandomData(timer, res); 10 | }, 2000); 11 | } 12 | if (req.url == '/') { 13 | fs.readFile('./ie-htmlfile-stream.html', 'binary', function (err, file) { 14 | if (!err) { 15 | res.writeHead(200, { 'Content-Type': 'text/html' }); 16 | res.write(file, 'binary'); 17 | res.end(); 18 | } 19 | }); 20 | } 21 | }) 22 | .listen(3000, 'localhost'); 23 | function sendRandomData(timer, res) { 24 | var randomNum = Math.floor(10000 * Math.random()); 25 | console.log(randomNum.toString()); 26 | if (count++ == 100) { 27 | clearInterval(timer); 28 | res.end(' "); 29 | } 30 | res.write(' "); 31 | } 32 | console.log('请打开地址体验IE中基于htmlfile的stream:http://localhost:3000'); 33 | -------------------------------------------------------------------------------- /packages/18web-communication/http-stream/iframe-stream.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 基于 iframe 的数据流 8 | 9 | 10 | 11 | 23 | 24 | -------------------------------------------------------------------------------- /packages/18web-communication/http-stream/iframe-stream.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var fs = require('fs'); 3 | var count = 0; 4 | var server = http 5 | .createServer(function (req, res) { 6 | if (req.url == '/iframe') { 7 | res.setHeader('content-type', 'text/html'); 8 | var timer = setInterval(function () { 9 | sendRandomData(timer, res); 10 | }, 2000); 11 | } 12 | if (req.url == '/') { 13 | fs.readFile('./iframe-stream.html', 'binary', function (err, file) { 14 | if (!err) { 15 | res.writeHead(200, { 'Content-Type': 'text/html' }); 16 | res.write(file, 'binary'); 17 | res.end(); 18 | } 19 | }); 20 | } 21 | }) 22 | .listen(3000, 'localhost'); 23 | function sendRandomData(timer, res) { 24 | var randomNum = Math.floor(10000 * Math.random()); 25 | console.log(randomNum.toString()); 26 | if (count++ == 100) { 27 | clearInterval(timer); 28 | res.end(' "); 29 | } 30 | res.write(' "); 31 | } 32 | console.log('请打开地址体验基于iframe的stream:http://localhost:3000'); 33 | -------------------------------------------------------------------------------- /packages/18web-communication/http-stream/xhr-stream.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 基于 XHR 对象的 streaming 方式 8 | 9 | 10 | 11 | 41 | 42 | -------------------------------------------------------------------------------- /packages/18web-communication/http-stream/xhr-stream.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var fs = require('fs'); 3 | var count = 0; 4 | function sendRandomData(timer, res) { 5 | var randomNum = Math.floor(10000 * Math.random()); 6 | console.log(randomNum); 7 | if (count++ == 100) { 8 | clearInterval(timer); 9 | res.end(randomNum.toString()); 10 | } 11 | res.write(randomNum.toString()); 12 | } 13 | http 14 | .createServer(function (req, res) { 15 | if (req.url == '/stream') { 16 | res.setHeader('content-type', 'multipart/octet-stream'); 17 | var timer = setInterval(function () { 18 | sendRandomData(timer, res); 19 | }, 2000); 20 | } 21 | if (req.url == '/') { 22 | fs.readFile('./xhr-stream.html', 'binary', function (err, file) { 23 | if (!err) { 24 | res.writeHead(200, { 'Content-Type': 'text/html' }); 25 | res.write(file, 'binary'); 26 | res.end(); 27 | } 28 | }); 29 | } 30 | }) 31 | .listen(3000, 'localhost'); 32 | console.log('请打开地址体验xhr-stream:http://localhost:3000'); 33 | -------------------------------------------------------------------------------- /packages/18web-communication/long-polling/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 长轮询(long-polling) 8 | 9 | 10 | 11 | 53 | 54 | -------------------------------------------------------------------------------- /packages/18web-communication/long-polling/lpc.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var fs = require('fs'); 3 | //用随机数模拟数据是否变化 4 | function sendData(res) { 5 | var randomNum = Math.floor(10 * Math.random()); 6 | console.log(randomNum); 7 | if (randomNum >= 0 && randomNum <= 5) { 8 | res.write(new Date().toLocaleString()); 9 | res.end(); 10 | } 11 | } 12 | http 13 | .createServer(function (req, res) { 14 | if (req.url == '/time') { 15 | setInterval(function () { 16 | sendData(res); 17 | }, 10000); 18 | } 19 | if (req.url == '/') { 20 | fs.readFile('./index.html', 'binary', function (err, file) { 21 | if (!err) { 22 | res.writeHead(200, { 'Content-Type': 'text/html' }); 23 | res.write(file, 'binary'); 24 | res.end(); 25 | } 26 | }); 27 | } 28 | }) 29 | .listen(3000, 'localhost'); 30 | 31 | console.log('请打开地址体验长轮询long-polling:http://localhost:3000'); 32 | -------------------------------------------------------------------------------- /packages/18web-communication/polling/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 普通ajax轮询 8 | 9 | 10 | 11 | 53 | 54 | -------------------------------------------------------------------------------- /packages/18web-communication/polling/polling.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var fs = require('fs'); 3 | var server = http 4 | .createServer(function (req, res) { 5 | if (req.url == '/time') { 6 | //res.writeHead(200, {'Content-Type': 'text/plain','Access-Control-Allow-Origin':'http://localhost'}); 7 | res.end(new Date().toLocaleString()); 8 | } 9 | if (req.url == '/') { 10 | fs.readFile('./index.html', 'binary', function (err, file) { 11 | if (!err) { 12 | res.writeHead(200, { 'Content-Type': 'text/html' }); 13 | res.write(file, 'binary'); 14 | res.end(); 15 | } 16 | }); 17 | } 18 | }) 19 | .listen(8088, 'localhost'); 20 | server.on('connection', function (socket) { 21 | console.log('客户端连接已经建立 '); 22 | }); 23 | server.on('close', function () { 24 | console.log('服务器被关闭'); 25 | }); 26 | console.log('请打开地址体验普通ajax轮询:http://localhost:8088'); 27 | -------------------------------------------------------------------------------- /packages/18web-communication/sse/sse.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var fs = require('fs'); 3 | 4 | http 5 | .createServer(function (req, res) { 6 | if (req.url === '/msg') { 7 | // 1. 设定头信息 8 | res.writeHead(200, { 9 | 'Content-Type': 'text/event-stream', 10 | 'Cache-Control': 'no-cache', 11 | Connection: 'keep-alive', 12 | }); 13 | 14 | // 2. 输出内容,必须 "data:" 开头 "\n\n" 结尾(代表结束) 15 | setInterval(function () { 16 | res.write('data: ' + Date.now() + '\n\n'); 17 | }, 1000); 18 | } else { 19 | // 其他请求显示index.html 20 | fs.readFile('./index.html', function (err, content) { 21 | res.writeHead(200, { 'Content-Type': 'text/html' }); 22 | res.end(content, 'utf-8'); 23 | }); 24 | } 25 | }) 26 | .listen(3000); 27 | 28 | console.log('请打开地址体验服务器推送事件SSE:http://localhost:3000'); 29 | -------------------------------------------------------------------------------- /packages/1build/babel/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/env', 5 | { 6 | useBuiltIns: false, // usage-按需引入 entry-入口引入(整体引入) false-不引入polyfill 7 | corejs: 3 // 2-corejs@2 3-corejs@3 8 | } 9 | ] 10 | ], 11 | plugins: [ 12 | [ 13 | '@babel/plugin-transform-runtime', 14 | { 15 | corejs: 3 16 | } 17 | ] 18 | ] 19 | }; 20 | -------------------------------------------------------------------------------- /packages/1build/babel/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 1 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/1build/babel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "debug": "webpack" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@babel/core": "^7.4.4", 15 | "@babel/plugin-transform-runtime": "^7.4.4", 16 | "@babel/preset-env": "^7.4.5", 17 | "@babel/runtime": "^7.4.5", 18 | "@babel/runtime-corejs2": "^7.4.5", 19 | "@babel/runtime-corejs3": "^7.4.5", 20 | "babel-loader": "^8.0.6", 21 | "core-js": "^3.1.4", 22 | "regenerator-runtime": "^0.13.2", 23 | "webpack": "^4.17.1", 24 | "webpack-cli": "^3.1.0" 25 | }, 26 | "browserslist": [ 27 | "Chrome > 20", 28 | "ie > 6" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /packages/1build/babel/src/10.js: -------------------------------------------------------------------------------- 1 | async function i() { 2 | return 2222222; 3 | } 4 | i().then(res => { 5 | console.log(res); 6 | }); 7 | 8 | var a = [4, 5, 6]; 9 | a.find(4); 10 | -------------------------------------------------------------------------------- /packages/1build/babel/src/11.js: -------------------------------------------------------------------------------- 1 | var a = [1, 2, 3].includes(2); 2 | console.log(a); 3 | -------------------------------------------------------------------------------- /packages/1build/babel/src/12.js: -------------------------------------------------------------------------------- 1 | import './11.js'; 2 | [4, 5, 6].includes(4); 3 | -------------------------------------------------------------------------------- /packages/1build/babel/src/9.js: -------------------------------------------------------------------------------- 1 | import './10.js'; 2 | 3 | async function f() { 4 | return 1111111; 5 | } 6 | f().then(res => { 7 | console.log(res); 8 | }); 9 | 10 | // var a = new Promise((r, t) => { 11 | // r(666666666); 12 | // }); 13 | // a.then(res => { 14 | // console.log(res); 15 | // }); 16 | -------------------------------------------------------------------------------- /packages/1build/babel/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devtool: 'source-map', 3 | entry: ['./src/9.js'], 4 | output: { 5 | filename: 'bundle.js', 6 | path: __dirname + '/dist' 7 | }, 8 | // mode: 'production', 9 | mode: 'development', 10 | module: { 11 | rules: [ 12 | { 13 | test: /\.js$/, 14 | exclude: /(node_modules|bower_components)/, 15 | use: ['babel-loader'] 16 | } 17 | ] 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /packages/1build/browserify/README.md: -------------------------------------------------------------------------------- 1 | # browserify 2 | 3 | browserify demo 4 | 5 | gulp-browserify 停止维护 6 | 7 | 参考资料 8 | 9 | - [当 React 遇见 Gulp 和 Browserify](http://www.jianshu.com/p/tY6UPN) 10 | -------------------------------------------------------------------------------- /packages/1build/browserify/dev/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by zhaoky on 2017/1/11. 3 | */ 4 | import page from './page'; 5 | 6 | let cat = "li"; 7 | let dog = "wang"; 8 | let p = page; 9 | 10 | let zoo = {cat,dog,p}; 11 | 12 | console.log(zoo); 13 | -------------------------------------------------------------------------------- /packages/1build/browserify/dev/page.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by zhaoky on 2017/1/11. 3 | */ 4 | export default "hello"; -------------------------------------------------------------------------------- /packages/1build/browserify/dist/bundle.js: -------------------------------------------------------------------------------- 1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o { 9 | return browserify("dev/index.js") 10 | .transform(babelify,{presets:["es2015"]}) 11 | .bundle() 12 | .pipe(source('bundle.js')) 13 | .pipe(gulp.dest("dist")); 14 | }); -------------------------------------------------------------------------------- /packages/1build/browserify/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/1build/browserify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "es6-demo", 3 | "version": "1.0.0", 4 | "description": "es6 demo", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "babel-preset-es2015": "^6.18.0", 13 | "babelify": "^7.3.0", 14 | "browserify": "^13.3.0", 15 | "gulp": "^3.9.1", 16 | "vinyl-source-stream": "^1.1.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/1build/jest/__tests__/index.text.js: -------------------------------------------------------------------------------- 1 | import sum from './../src/index'; 2 | 3 | test('sum', () => { 4 | expect(sum(2, 3)).toBe(5); 5 | }); 6 | -------------------------------------------------------------------------------- /packages/1build/jest/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/env', 5 | { 6 | targets: '> 1%, not dead' 7 | } 8 | ], 9 | '@babel/preset-typescript' 10 | ], 11 | plugins: [ 12 | [ 13 | '@babel/plugin-transform-runtime', 14 | { 15 | corejs: 3 16 | } 17 | ], 18 | '@babel/plugin-proposal-class-properties' 19 | ] 20 | }; 21 | -------------------------------------------------------------------------------- /packages/1build/jest/coverage/clover.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/1build/jest/coverage/coverage-final.json: -------------------------------------------------------------------------------- 1 | {"/nice/jest-demo/src/index.ts": {"path":"/nice/jest-demo/src/index.ts","statementMap":{"0":{"start":{"line":2,"column":2},"end":{"line":2,"column":15}}},"fnMap":{"0":{"name":"a","decl":{"start":{"line":1,"column":24},"end":{"line":1,"column":25}},"loc":{"start":{"line":1,"column":47},"end":{"line":3,"column":1}},"line":1}},"branchMap":{},"s":{"0":1},"f":{"0":1},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"68a732583aded7bddb7b2c4bc798a90da06ccb05"} 2 | } 3 | -------------------------------------------------------------------------------- /packages/1build/jest/coverage/lcov-report/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} 2 | -------------------------------------------------------------------------------- /packages/1build/jest/coverage/lcov-report/sort-arrow-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/1build/jest/coverage/lcov-report/sort-arrow-sprite.png -------------------------------------------------------------------------------- /packages/1build/jest/coverage/lcov.info: -------------------------------------------------------------------------------- 1 | TN: 2 | SF:/nice/jest-demo/src/index.ts 3 | FN:1,a 4 | FNF:1 5 | FNH:1 6 | FNDA:1,a 7 | DA:2,1 8 | LF:1 9 | LH:1 10 | BRF:0 11 | BRH:0 12 | end_of_record 13 | -------------------------------------------------------------------------------- /packages/1build/jest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jest", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node --inspect-brk=5858 ./node_modules/.bin/jest --coverage", 8 | "lint": "jest", 9 | "build": "webpack" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "jest": "^24.9.0" 16 | }, 17 | "devDependencies": { 18 | "@babel/core": "^7.5.5", 19 | "@babel/plugin-proposal-class-properties": "^7.5.5", 20 | "@babel/plugin-transform-runtime": "^7.5.5", 21 | "@babel/preset-env": "^7.5.5", 22 | "@babel/preset-typescript": "^7.3.3", 23 | "@babel/runtime-corejs3": "^7.5.5", 24 | "@types/node": "^12.7.2", 25 | "babel-loader": "^8.0.6", 26 | "fork-ts-checker-webpack-plugin": "^1.5.0", 27 | "typescript": "^3.5.3", 28 | "webpack": "^4.39.2", 29 | "webpack-cli": "^3.3.7" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/1build/jest/src/index.ts: -------------------------------------------------------------------------------- 1 | export default function a(a: any, b: any): any { 2 | return a + b; 3 | } 4 | -------------------------------------------------------------------------------- /packages/1build/jest/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "experimentalDecorators": true, 5 | "emitDecoratorMetadata": true, 6 | "module": "commonjs", 7 | "noUnusedParameters": true, 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "outDir": "lib/", 11 | "lib": ["dom", "es2016.array.include", "es2015", "es2016"], 12 | "sourceMap": true, 13 | "allowJs": true, 14 | "noEmit": true 15 | }, 16 | "include": ["src/**/*"] 17 | } 18 | -------------------------------------------------------------------------------- /packages/1build/jest/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | // const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); 4 | 5 | const config = { 6 | mode: 'development', 7 | entry: path.resolve(__dirname, './src/core/mvvm.ts'), 8 | output: { 9 | path: path.resolve(__dirname, './dist'), 10 | filename: 'mvvm.js' 11 | }, 12 | resolve: { 13 | extensions: ['.js', '.ts'] 14 | }, 15 | module: { 16 | rules: [ 17 | { 18 | test: /\.(ts|js)$/, 19 | exclude: /(node_modules|bower_components)/, 20 | use: ['babel-loader'] 21 | } 22 | ] 23 | }, 24 | plugins: [new ForkTsCheckerWebpackPlugin()] 25 | }; 26 | config.devtool = 'source-map'; 27 | config.devServer = { 28 | stats: 'errors-only', 29 | contentBase: path.join(__dirname, 'dist'), 30 | overlay: true 31 | // config.plugins.push( 32 | // new HtmlWebpackPlugin({ 33 | // template: path.resolve(__dirname, './src/index.html') 34 | // }) 35 | // ); 36 | }; 37 | 38 | module.exports = config; 39 | -------------------------------------------------------------------------------- /packages/1build/postcss/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/env', 5 | { 6 | targets: '> 1%, not dead' 7 | } 8 | ] 9 | ] 10 | }; 11 | -------------------------------------------------------------------------------- /packages/1build/postcss/dist/aa.css: -------------------------------------------------------------------------------- 1 | 2 | .a{ 3 | -webkit-transform: scale(2); 4 | -moz-transform: scale(2); 5 | -o-transform: scale(2); 6 | transform: scale(2); 7 | display: -webkit-box; 8 | display: -webkit-flex; 9 | display: -moz-box; 10 | display: flex; 11 | } 12 | .a{ 13 | -webkit-transition: all 2s; 14 | -o-transition: all 2s; 15 | -moz-transition: all 2s; 16 | transition: all 2s; 17 | } 18 | -------------------------------------------------------------------------------- /packages/1build/postcss/dist/bb.css: -------------------------------------------------------------------------------- 1 | .a{ 2 | color:red; 3 | } 4 | -------------------------------------------------------------------------------- /packages/1build/postcss/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 13 | 14 | 15 |
111
16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/1build/postcss/dist/main.css: -------------------------------------------------------------------------------- 1 | 2 | .a{ 3 | -webkit-transform: scale(2); 4 | -moz-transform: scale(2); 5 | -o-transform: scale(2); 6 | transform: scale(2); 7 | display: -webkit-box; 8 | display: -webkit-flex; 9 | display: -moz-box; 10 | display: flex; 11 | } 12 | .a{ 13 | -webkit-transition: all 2s; 14 | -o-transition: all 2s; 15 | -moz-transition: all 2s; 16 | transition: all 2s; 17 | } 18 | -------------------------------------------------------------------------------- /packages/1build/postcss/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postcss", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "@babel/core": "^7.4.5", 14 | "@babel/preset-env": "^7.4.5", 15 | "autoprefixer": "^9.5.1", 16 | "babel-loader": "^8.0.6", 17 | "css-loader": "^2.1.1", 18 | "html-webpack-plugin": "^3.2.0", 19 | "mini-css-extract-plugin": "^0.6.0", 20 | "optimize-css-assets-webpack-plugin": "^5.0.1", 21 | "postcss-loader": "^3.0.0", 22 | "style-loader": "^0.23.1", 23 | "webpack": "^4.32.2", 24 | "webpack-cli": "^3.3.2" 25 | }, 26 | "browserslist": [ 27 | "> 1%", 28 | "last 100 versions", 29 | "not dead" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /packages/1build/postcss/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // parser: 'sugarss', 3 | plugins: { 4 | autoprefixer: {} 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /packages/1build/postcss/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 13 | 14 | 15 |
111
16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/1build/postcss/src/index.js: -------------------------------------------------------------------------------- 1 | import a from './one.css'; 2 | import './two.css'; 3 | console.log(666, a); 4 | -------------------------------------------------------------------------------- /packages/1build/postcss/src/index1.js: -------------------------------------------------------------------------------- 1 | import './three.css'; 2 | -------------------------------------------------------------------------------- /packages/1build/postcss/src/one.css: -------------------------------------------------------------------------------- 1 | 2 | .a{ 3 | transform: scale(2); 4 | display: flex; 5 | } -------------------------------------------------------------------------------- /packages/1build/postcss/src/three.css: -------------------------------------------------------------------------------- 1 | .a{ 2 | color:red; 3 | } -------------------------------------------------------------------------------- /packages/1build/postcss/src/two.css: -------------------------------------------------------------------------------- 1 | .a{ 2 | transition: all 2s; 3 | } -------------------------------------------------------------------------------- /packages/1build/postcss/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 5 | const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); 6 | 7 | const config = { 8 | mode: 'development', 9 | entry: { 10 | aa: './src/index.js', 11 | bb: './src/index1.js' 12 | }, 13 | output: { 14 | path: path.resolve(__dirname, './dist'), 15 | filename: 'bundle.js' 16 | }, 17 | devtool: 'eval-source-map', 18 | resolve: { 19 | extensions: ['.js'] 20 | }, 21 | optimization: { 22 | minimizer: [new OptimizeCSSAssetsPlugin({})] 23 | }, 24 | module: { 25 | rules: [ 26 | { 27 | test: /.js$/, 28 | exclude: /(node_modules|bower_components)/, 29 | use: ['babel-loader'] 30 | }, 31 | { 32 | test: /.css$/, 33 | exclude: /(node_modules|bower_components)/, 34 | use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'] 35 | } 36 | ] 37 | }, 38 | plugins: [ 39 | new HtmlWebpackPlugin({ 40 | template: path.resolve(__dirname, './src/index.html') 41 | }), 42 | new MiniCssExtractPlugin({ 43 | filename: '[name].css' 44 | }) 45 | // new OptimizeCSSAssetsPlugin({}) 46 | ] 47 | }; 48 | 49 | module.exports = config; 50 | -------------------------------------------------------------------------------- /packages/20react-redux/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | /.vscode -------------------------------------------------------------------------------- /packages/20react-redux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-redux", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.5", 7 | "@testing-library/react": "^11.1.0", 8 | "@testing-library/user-event": "^12.1.10", 9 | "react": "^17.0.1", 10 | "react-dom": "^17.0.1", 11 | "react-redux": "^7.2.1", 12 | "react-scripts": "4.0.0", 13 | "redux": "^4.0.5", 14 | "redux-devtools-extension": "^2.13.8", 15 | "redux-logger": "^3.0.6", 16 | "web-vitals": "^0.2.4" 17 | }, 18 | "scripts": { 19 | "start": "react-scripts start", 20 | "build": "react-scripts build", 21 | "test": "react-scripts test", 22 | "eject": "react-scripts eject" 23 | }, 24 | "eslintConfig": { 25 | "extends": [ 26 | "react-app", 27 | "react-app/jest" 28 | ] 29 | }, 30 | "browserslist": { 31 | "production": [ 32 | ">0.2%", 33 | "not dead", 34 | "not op_mini all" 35 | ], 36 | "development": [ 37 | "last 1 chrome version", 38 | "last 1 firefox version", 39 | "last 1 safari version" 40 | ] 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/20react-redux/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/20react-redux/public/favicon.ico -------------------------------------------------------------------------------- /packages/20react-redux/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/20react-redux/public/logo192.png -------------------------------------------------------------------------------- /packages/20react-redux/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/20react-redux/public/logo512.png -------------------------------------------------------------------------------- /packages/20react-redux/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /packages/20react-redux/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /packages/20react-redux/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } -------------------------------------------------------------------------------- /packages/20react-redux/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import { Provider } from 'react-redux'; 3 | import store from './redux/store'; 4 | import CakeContainer from './components/CakeContainer'; 5 | import HooksCakeContainer from './components/HooksCakeContainer'; 6 | import IceCreamContainer from './components/IceCreamContainer'; 7 | import ChocolateContainer from './components/ChocolateContainer'; 8 | import NewCakeContainer from './components/NewCakeContainer'; 9 | import ItemContainer from './components/ItemContainer'; 10 | 11 | function App() { 12 | return ( 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 |
24 | ); 25 | } 26 | 27 | export default App; 28 | -------------------------------------------------------------------------------- /packages/20react-redux/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/20react-redux/src/components/Btn.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { setBtn } from '../redux'; 3 | import { useSelector, useDispatch } from 'react-redux'; 4 | 5 | function Btn() { 6 | console.log('Btn'); 7 | const status = useSelector((state) => state.chocolate.status); 8 | const dispatch = useDispatch(); 9 | return ( 10 |
11 |

Number of Chocolate-btn - {`${status}`}

12 | 19 |
20 | ); 21 | } 22 | 23 | // const mapStateToProps = (state) => { 24 | // return { 25 | // status: state.chocolate.status, 26 | // }; 27 | // }; 28 | 29 | // const mapDispatchToProps = (dispatch) => { 30 | // return { 31 | // setBtn: (p) => dispatch(setBtn(p)), 32 | // }; 33 | // }; 34 | 35 | // export default connect(mapStateToProps, mapDispatchToProps)(Btn); 36 | export default React.memo(Btn); 37 | -------------------------------------------------------------------------------- /packages/20react-redux/src/components/CakeContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { buyCake } from '../redux'; 3 | import { connect } from 'react-redux'; 4 | 5 | function CakeContainer(props) { 6 | console.log('CakeContainer'); 7 | return ( 8 |
9 |

Number of Cakes - {props.numOfCakes}

10 | 11 |
12 | ); 13 | } 14 | 15 | const mapStateToProps = (state) => { 16 | return { 17 | numOfCakes: state.cake.numOfCakes, 18 | }; 19 | }; 20 | 21 | const mapDispatchToProps = (dispatch) => { 22 | return { 23 | buyCake: () => dispatch(buyCake()), 24 | }; 25 | }; 26 | 27 | export default connect(mapStateToProps, mapDispatchToProps)(CakeContainer); 28 | -------------------------------------------------------------------------------- /packages/20react-redux/src/components/ChocolateContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { buyChocolate } from '../redux'; 3 | import { useSelector, useDispatch } from 'react-redux'; 4 | import Btn from './Btn'; 5 | 6 | function ChocolateContainer(props) { 7 | console.log('ChocolateContainer'); 8 | const numOfCakes = useSelector((state) => state.chocolate.numOfChocolate); 9 | const dispatch = useDispatch(); 10 | return ( 11 |
12 |

Number of Chocolate - {numOfCakes}

13 | 20 | 21 |
22 | ); 23 | } 24 | 25 | // const mapStateToProps = (state) => { 26 | // return { 27 | // numOfChocolate: state.chocolate.numOfChocolate, 28 | // }; 29 | // }; 30 | 31 | // const mapDispatchToProps = (dispatch) => { 32 | // return { 33 | // buyChocolate: () => dispatch(buyChocolate()), 34 | // }; 35 | // }; 36 | 37 | export default ChocolateContainer; 38 | -------------------------------------------------------------------------------- /packages/20react-redux/src/components/HooksCakeContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useSelector, useDispatch } from 'react-redux'; 3 | import { buyCake } from '../redux'; 4 | 5 | function HooksCakeContainer() { 6 | console.log('HooksCakeContainer'); 7 | const numOfCakes = useSelector((state) => state.cake.numOfCakes); 8 | const dispatch = useDispatch(); 9 | return ( 10 |
11 |

Number of Cake - {numOfCakes}

12 | 13 |
14 | ); 15 | } 16 | 17 | export default HooksCakeContainer; 18 | -------------------------------------------------------------------------------- /packages/20react-redux/src/components/IceCreamContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { buyIceCream } from '../redux'; 3 | import { connect } from 'react-redux'; 4 | 5 | function IceCreamContainer(props) { 6 | console.log('IceCreamContainer'); 7 | return ( 8 |
9 |

Number of IceCream - {props.numOfIceCreams}

10 | 11 |
12 | ); 13 | } 14 | 15 | const mapStateToProps = (state) => { 16 | return { 17 | numOfIceCreams: state.iceCream.numOfIceCreams, 18 | }; 19 | }; 20 | 21 | const mapDispatchToProps = (dispatch) => { 22 | return { 23 | buyIceCream: () => dispatch(buyIceCream()), 24 | }; 25 | }; 26 | 27 | export default connect(mapStateToProps, mapDispatchToProps)(IceCreamContainer); 28 | -------------------------------------------------------------------------------- /packages/20react-redux/src/components/ItemContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import { buyCake, buyIceCream } from '../redux/'; 4 | 5 | function ItemContainer(props) { 6 | console.log('ItemContainer', props); 7 | return ( 8 |
9 |

10 | {props.cake ? 'cake' : 'iceCream'} Item - {props.item}{' '} 11 |

12 | 13 |
14 | ); 15 | } 16 | 17 | const mapStateToProps = (state, ownProps) => { 18 | const itemState = ownProps.cake ? state.cake.numOfCakes : state.iceCream.numOfIceCreams; 19 | 20 | return { 21 | item: itemState, 22 | }; 23 | }; 24 | 25 | const mapDispatchToProps = (dispatch, ownProps) => { 26 | const dispatchFunction = ownProps.cake ? () => dispatch(buyCake()) : () => dispatch(buyIceCream()); 27 | 28 | return { 29 | buyItem: dispatchFunction, 30 | }; 31 | }; 32 | 33 | export default connect(mapStateToProps, mapDispatchToProps)(ItemContainer); 34 | -------------------------------------------------------------------------------- /packages/20react-redux/src/components/NewCakeContainer.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { buyCake } from '../redux'; 3 | import { connect } from 'react-redux'; 4 | 5 | function NewCakeContainer(props) { 6 | console.log('NewCakeContainer'); 7 | const [number, setNumber] = useState(1); 8 | return ( 9 |
10 |

Number of Cakes - {props.numOfCakes}

11 | setNumber(e.target.value)} /> 12 | 13 |
14 | ); 15 | } 16 | 17 | const mapStateToProps = (state) => { 18 | return { 19 | numOfCakes: state.cake.numOfCakes, 20 | }; 21 | }; 22 | 23 | const mapDispatchToProps = (dispatch) => { 24 | return { 25 | buyCake: (number) => dispatch(buyCake(number)), 26 | }; 27 | }; 28 | 29 | export default connect(mapStateToProps, mapDispatchToProps)(NewCakeContainer); 30 | -------------------------------------------------------------------------------- /packages/20react-redux/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /packages/20react-redux/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /packages/20react-redux/src/redux/cake/cakeActions.js: -------------------------------------------------------------------------------- 1 | import { BUY_CAKE } from "./cakeTypes"; 2 | 3 | export const buyCake = (number = 1) => { 4 | return { 5 | type: BUY_CAKE, 6 | payload: number, 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /packages/20react-redux/src/redux/cake/cakeReducer.js: -------------------------------------------------------------------------------- 1 | import { BUY_CAKE } from './cakeTypes'; 2 | 3 | const initialState = { 4 | numOfCakes: 10, 5 | }; 6 | 7 | const cakeReducer = (state = initialState, action) => { 8 | switch (action.type) { 9 | case BUY_CAKE: 10 | return { 11 | ...state, 12 | numOfCakes: state.numOfCakes - action.payload, 13 | }; 14 | default: 15 | return state; 16 | } 17 | }; 18 | 19 | export default cakeReducer; 20 | -------------------------------------------------------------------------------- /packages/20react-redux/src/redux/cake/cakeTypes.js: -------------------------------------------------------------------------------- 1 | export const BUY_CAKE = 'BUY_CAKE'; 2 | -------------------------------------------------------------------------------- /packages/20react-redux/src/redux/chocolate/chocolateActions.js: -------------------------------------------------------------------------------- 1 | import { BUY_CHOCOLATE, SS } from './chocolateTypes'; 2 | 3 | export const buyChocolate = () => { 4 | return { 5 | type: BUY_CHOCOLATE, 6 | }; 7 | }; 8 | export const setBtn = (p) => { 9 | return { 10 | type: SS, 11 | payload: p, 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /packages/20react-redux/src/redux/chocolate/chocolateReducer.js: -------------------------------------------------------------------------------- 1 | import { BUY_CHOCOLATE, SS } from './chocolateTypes'; 2 | 3 | const initialState = { 4 | numOfChocolate: 15, 5 | status: false, 6 | }; 7 | 8 | const chocolateReducer = (state = initialState, action) => { 9 | switch (action.type) { 10 | case BUY_CHOCOLATE: 11 | return { 12 | ...state, 13 | numOfChocolate: state.numOfChocolate - 1, 14 | }; 15 | case SS: 16 | return { 17 | ...state, 18 | status: action.payload, 19 | }; 20 | default: 21 | return state; 22 | } 23 | }; 24 | 25 | export default chocolateReducer; 26 | -------------------------------------------------------------------------------- /packages/20react-redux/src/redux/chocolate/chocolateTypes.js: -------------------------------------------------------------------------------- 1 | export const BUY_CHOCOLATE = 'BUY_CHOCOLATE'; 2 | export const SS = 'SS'; 3 | -------------------------------------------------------------------------------- /packages/20react-redux/src/redux/iceCream/iceCreamActions.js: -------------------------------------------------------------------------------- 1 | import { BUY_ICECREAM } from "./iceCreamTypes"; 2 | 3 | export const buyIceCream = () => { 4 | return { 5 | type: BUY_ICECREAM, 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /packages/20react-redux/src/redux/iceCream/iceCreamReducer.js: -------------------------------------------------------------------------------- 1 | import { BUY_ICECREAM } from "./iceCreamTypes"; 2 | 3 | const initialState = { 4 | numOfIceCreams: 20, 5 | }; 6 | 7 | const iceCreamReducer = (state = initialState, action) => { 8 | switch (action.type) { 9 | case BUY_ICECREAM: 10 | return { 11 | ...state, 12 | numOfIceCreams: state.numOfIceCreams - 1, 13 | }; 14 | 15 | default: 16 | return state; 17 | } 18 | }; 19 | 20 | export default iceCreamReducer; 21 | -------------------------------------------------------------------------------- /packages/20react-redux/src/redux/iceCream/iceCreamTypes.js: -------------------------------------------------------------------------------- 1 | export const BUY_ICECREAM = 'BUY_ICECREAM'; -------------------------------------------------------------------------------- /packages/20react-redux/src/redux/index.js: -------------------------------------------------------------------------------- 1 | export { buyCake } from './cake/cakeActions'; 2 | export { buyIceCream } from './iceCream/iceCreamActions'; 3 | export { buyChocolate, setBtn } from './chocolate/chocolateActions'; 4 | -------------------------------------------------------------------------------- /packages/20react-redux/src/redux/rootReducer.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import cakeReducer from './cake/cakeReducer'; 3 | import iceCreamReducer from './iceCream/iceCreamReducer'; 4 | import chocolateReducer from './chocolate/chocolateReducer'; 5 | 6 | const rootReducer = combineReducers({ 7 | cake: cakeReducer, 8 | iceCream: iceCreamReducer, 9 | chocolate: chocolateReducer, 10 | }); 11 | export default rootReducer; 12 | -------------------------------------------------------------------------------- /packages/20react-redux/src/redux/store.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware } from "redux"; 2 | import rootReducer from "./rootReducer"; 3 | import logger from 'redux-logger'; 4 | import { composeWithDevTools } from 'redux-devtools-extension'; 5 | 6 | const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(logger))); 7 | 8 | export default store; 9 | -------------------------------------------------------------------------------- /packages/20react-redux/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /packages/20react-redux/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /packages/21rspress-korey-site/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | doc_build 26 | -------------------------------------------------------------------------------- /packages/21rspress-korey-site/docs/_meta.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "text": "Micro Frontends", 4 | "link": "/micro/", 5 | "activeMatch": "/micro/" 6 | }, 7 | { 8 | "text": "Source Code", 9 | "items": [ 10 | { 11 | "text": "webpack 4", 12 | "link": "/code/webpack4/372", 13 | "activeMatch": "/code/webpack4/" 14 | }, 15 | { 16 | "text": "vue 2", 17 | "link": "/code/vue2/392", 18 | "activeMatch": "/code/vue2/" 19 | } 20 | ] 21 | }, 22 | { 23 | "text": "JavaScript", 24 | "link": "/js/402", 25 | "activeMatch": "/js/" 26 | }, 27 | { 28 | "text": "CSS", 29 | "link": "/css/415", 30 | "activeMatch": "/css/" 31 | }, 32 | { 33 | "text": "MISC", 34 | "link": "/misc/414", 35 | "activeMatch": "/misc/" 36 | }, 37 | { 38 | "text": "Hexo", 39 | "link": "/hexo/408", 40 | "activeMatch": "/hexo/" 41 | } 42 | ] 43 | -------------------------------------------------------------------------------- /packages/21rspress-korey-site/docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | pageType: home 3 | 4 | hero: 5 | name: 前端轻语 6 | text: 7 | tagline: 8 | actions: 9 | - theme: brand 10 | text: 个人博客 11 | link: /code/webpack4/372.html 12 | - theme: alt 13 | text: 个人简历(未开放) 14 | link: 15 | image: 16 | src: /avatar.jpg 17 | alt: korey的前端笔记 Logo 18 | features: 19 | - title: 前端技术栈 20 | details: react、vue2/3、angularJs等等 21 | icon: 🏃🏻‍♀️ 22 | - title: 微前端领域爱好者 23 | details: wujie、qiankun、guru、hel 24 | icon: 📦 25 | - title: 开源爱好者 26 | details: tdesgin、wujie 27 | icon: 🎨 28 | - title: 应用类型 29 | details: H5/PC、小程序、快应用、electron、web APP等 30 | icon: 🌍 31 | - title: 团队管理 32 | details: 111 33 | icon: 🌈 34 | - title: 成功案例 35 | details: 222 36 | icon: 🔥 37 | --- 38 | -------------------------------------------------------------------------------- /packages/21rspress-korey-site/docs/public/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/21rspress-korey-site/docs/public/avatar.jpg -------------------------------------------------------------------------------- /packages/21rspress-korey-site/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "korey-site", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "rspress dev", 7 | "build": "rspress build", 8 | "preview": "rspress preview" 9 | }, 10 | "dependencies": { 11 | "react": "^18.2.0", 12 | "react-dom": "^18.2.0", 13 | "rspress": "^1.9.0" 14 | }, 15 | "devDependencies": { 16 | "@types/node": "^20" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/21rspress-korey-site/rspress.config.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import { defineConfig } from 'rspress/config'; 3 | 4 | export default defineConfig({ 5 | root: path.join(__dirname, 'docs'), 6 | title: 'korey的前端笔记', 7 | description: '前端工程师简历,FE简历,web前端学习,前端开发', 8 | icon: '/avatar.jpg', 9 | logo: { 10 | light: '/avatar.jpg', 11 | dark: '/avatar.jpg', 12 | }, 13 | themeConfig: { 14 | socialLinks: [ 15 | { icon: 'github', mode: 'link', content: 'https://github.com/zhaoky' }, 16 | { icon: 'juejin', mode: 'link', content: 'https://juejin.cn/user/1345457961309672' }, 17 | { icon: 'zhihu', mode: 'link', content: 'https://www.zhihu.com/people/fe_korey' }, 18 | ], 19 | footer:{ 20 | message:'蜀ICP备15021330号 © 2014-2024 Korey Zhao All Rights Reserved.' 21 | }, 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /packages/21rspress-korey-site/theme/index.tsx: -------------------------------------------------------------------------------- 1 | import Theme from 'rspress/theme'; 2 | import { usePageData } from 'rspress/runtime'; 3 | import { MySearch } from './search'; 4 | 5 | const Layout = () => { 6 | console.log(444, usePageData(),Theme); 7 | return {MySearch()}} />; 8 | }; 9 | export default { 10 | ...Theme, 11 | Layout, 12 | }; 13 | 14 | export * from 'rspress/theme'; 15 | -------------------------------------------------------------------------------- /packages/21rspress-korey-site/theme/search.tsx: -------------------------------------------------------------------------------- 1 | import { useFullTextSearch } from 'rspress/theme'; 2 | import { useEffect } from 'react'; 3 | 4 | function MySearch() { 5 | const { initialized, search } = useFullTextSearch(); 6 | 7 | const s = async()=>{ 8 | console.log(5,initialized) 9 | const results = await search('remote'); 10 | console.log(results); 11 | } 12 | 13 | useEffect(() => { 14 | console.log(6); 15 | async function searchSomeKeywords(keywords: string) { 16 | if (initialized) { 17 | // 搜索关键字 18 | const results = await search(keywords); 19 | console.log(666,results); 20 | } 21 | } 22 | searchSomeKeywords('remote'); 23 | }, [initialized]); 24 | 25 | return
Search
; 26 | } 27 | 28 | export { MySearch }; 29 | -------------------------------------------------------------------------------- /packages/21rspress-korey-site/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react-jsx", 4 | "esModuleInterop": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/22vue-project/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | require('@rushstack/eslint-patch/modern-module-resolution') 3 | 4 | module.exports = { 5 | root: true, 6 | 'extends': [ 7 | 'plugin:vue/vue3-essential', 8 | 'eslint:recommended', 9 | '@vue/eslint-config-typescript', 10 | '@vue/eslint-config-prettier/skip-formatting' 11 | ], 12 | overrides: [ 13 | { 14 | files: [ 15 | 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}', 16 | 'cypress/support/**/*.{js,ts,jsx,tsx}' 17 | ], 18 | 'extends': [ 19 | 'plugin:cypress/recommended' 20 | ] 21 | } 22 | ], 23 | parserOptions: { 24 | ecmaVersion: 'latest' 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/22vue-project/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | 30 | *.tsbuildinfo 31 | -------------------------------------------------------------------------------- /packages/22vue-project/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "printWidth": 100, 7 | "trailingComma": "none" 8 | } -------------------------------------------------------------------------------- /packages/22vue-project/cypress.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'cypress' 2 | 3 | export default defineConfig({ 4 | e2e: { 5 | specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}', 6 | baseUrl: 'http://localhost:4173' 7 | } 8 | }) 9 | -------------------------------------------------------------------------------- /packages/22vue-project/cypress/e2e/example.cy.ts: -------------------------------------------------------------------------------- 1 | // https://on.cypress.io/api 2 | 3 | describe('My First Test', () => { 4 | it('visits the app root url', () => { 5 | cy.visit('/') 6 | cy.contains('h1', 'You did it!') 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /packages/22vue-project/cypress/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": ["./**/*", "../support/**/*"], 4 | "compilerOptions": { 5 | "isolatedModules": false, 6 | "target": "es5", 7 | "lib": ["es5", "dom"], 8 | "types": ["cypress"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/22vue-project/cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } 6 | -------------------------------------------------------------------------------- /packages/22vue-project/cypress/support/commands.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // *********************************************** 3 | // This example commands.ts shows you how to 4 | // create various custom commands and overwrite 5 | // existing commands. 6 | // 7 | // For more comprehensive examples of custom 8 | // commands please read more here: 9 | // https://on.cypress.io/custom-commands 10 | // *********************************************** 11 | // 12 | // 13 | // -- This is a parent command -- 14 | // Cypress.Commands.add('login', (email, password) => { ... }) 15 | // 16 | // 17 | // -- This is a child command -- 18 | // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) 19 | // 20 | // 21 | // -- This is a dual command -- 22 | // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) 23 | // 24 | // 25 | // -- This will overwrite an existing command -- 26 | // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) 27 | // 28 | // declare global { 29 | // namespace Cypress { 30 | // interface Chainable { 31 | // login(email: string, password: string): Chainable 32 | // drag(subject: string, options?: Partial): Chainable 33 | // dismiss(subject: string, options?: Partial): Chainable 34 | // visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable 35 | // } 36 | // } 37 | // } 38 | 39 | export {} 40 | -------------------------------------------------------------------------------- /packages/22vue-project/cypress/support/e2e.ts: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands' 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') 21 | -------------------------------------------------------------------------------- /packages/22vue-project/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/22vue-project/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/22vue-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-project", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "run-p type-check \"build-only {@}\" --", 9 | "preview": "vite preview", 10 | "test:unit": "vitest", 11 | "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'", 12 | "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'", 13 | "build-only": "vite build", 14 | "type-check": "vue-tsc --build --force", 15 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", 16 | "format": "prettier --write src/" 17 | }, 18 | "dependencies": { 19 | "pinia": "^2.1.7", 20 | "vue": "^3.3.11", 21 | "vue-router": "^4.2.5" 22 | }, 23 | "devDependencies": { 24 | "@rushstack/eslint-patch": "^1.3.3", 25 | "@tsconfig/node18": "^18.2.2", 26 | "@types/jsdom": "^21.1.6", 27 | "@types/node": "^18.19.3", 28 | "@vitejs/plugin-vue": "^4.5.2", 29 | "@vitejs/plugin-vue-jsx": "^3.1.0", 30 | "@vue/eslint-config-prettier": "^8.0.0", 31 | "@vue/eslint-config-typescript": "^12.0.0", 32 | "@vue/test-utils": "^2.4.3", 33 | "@vue/tsconfig": "^0.5.0", 34 | "cypress": "^13.6.1", 35 | "eslint": "^8.49.0", 36 | "eslint-plugin-cypress": "^2.15.1", 37 | "eslint-plugin-vue": "^9.17.0", 38 | "jsdom": "^23.0.1", 39 | "npm-run-all2": "^6.1.1", 40 | "prettier": "^3.0.3", 41 | "start-server-and-test": "^2.0.3", 42 | "typescript": "~5.3.0", 43 | "vite": "^5.0.10", 44 | "vitest": "^1.0.4", 45 | "vue-tsc": "^1.8.25" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/22vue-project/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/22vue-project/public/favicon.ico -------------------------------------------------------------------------------- /packages/22vue-project/src/App.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 22 | 23 | 86 | -------------------------------------------------------------------------------- /packages/22vue-project/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /packages/22vue-project/src/assets/main.css: -------------------------------------------------------------------------------- 1 | @import './base.css'; 2 | 3 | #app { 4 | max-width: 1280px; 5 | margin: 0 auto; 6 | padding: 2rem; 7 | font-weight: normal; 8 | } 9 | 10 | a, 11 | .green { 12 | text-decoration: none; 13 | color: hsla(160, 100%, 37%, 1); 14 | transition: 0.4s; 15 | padding: 3px; 16 | } 17 | 18 | @media (hover: hover) { 19 | a:hover { 20 | background-color: hsla(160, 100%, 37%, 0.2); 21 | } 22 | } 23 | 24 | @media (min-width: 1024px) { 25 | body { 26 | display: flex; 27 | place-items: center; 28 | } 29 | 30 | #app { 31 | display: grid; 32 | grid-template-columns: 1fr 1fr; 33 | padding: 0 2rem; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/22vue-project/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 42 | -------------------------------------------------------------------------------- /packages/22vue-project/src/components/WelcomeItem.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 88 | -------------------------------------------------------------------------------- /packages/22vue-project/src/components/__tests__/HelloWorld.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | 3 | import { mount } from '@vue/test-utils' 4 | import HelloWorld from '../HelloWorld.vue' 5 | 6 | describe('HelloWorld', () => { 7 | it('renders properly', () => { 8 | const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } }) 9 | expect(wrapper.text()).toContain('Hello Vitest') 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/22vue-project/src/components/icons/IconCommunity.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /packages/22vue-project/src/components/icons/IconDocumentation.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /packages/22vue-project/src/components/icons/IconSupport.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /packages/22vue-project/src/components/icons/IconTooling.vue: -------------------------------------------------------------------------------- 1 | 2 | 20 | -------------------------------------------------------------------------------- /packages/22vue-project/src/main.ts: -------------------------------------------------------------------------------- 1 | import './assets/main.css' 2 | 3 | import { createApp } from 'vue' 4 | import { createPinia } from 'pinia' 5 | 6 | // import App from './App.vue' 7 | import App from './views/HomeView.vue'; 8 | import router from './router' 9 | 10 | const app = createApp(App) 11 | 12 | app.use(createPinia()) 13 | app.use(router) 14 | 15 | app.mount('#app') 16 | -------------------------------------------------------------------------------- /packages/22vue-project/src/router/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory } from 'vue-router' 2 | import HomeView from '../views/HomeView.vue' 3 | 4 | const router = createRouter({ 5 | history: createWebHistory(import.meta.env.BASE_URL), 6 | routes: [ 7 | { 8 | path: '/', 9 | name: 'home', 10 | component: HomeView 11 | }, 12 | { 13 | path: '/about', 14 | name: 'about', 15 | // route level code-splitting 16 | // this generates a separate chunk (About.[hash].js) for this route 17 | // which is lazy-loaded when the route is visited. 18 | component: () => import('../views/AboutView.vue') 19 | } 20 | ] 21 | }) 22 | 23 | export default router 24 | -------------------------------------------------------------------------------- /packages/22vue-project/src/stores/counter.ts: -------------------------------------------------------------------------------- 1 | import { ref, computed } from 'vue' 2 | import { defineStore } from 'pinia' 3 | 4 | export const useCounterStore = defineStore('counter', () => { 5 | const count = ref(0) 6 | const doubleCount = computed(() => count.value * 2) 7 | function increment() { 8 | count.value++ 9 | } 10 | 11 | return { count, doubleCount, increment } 12 | }) 13 | -------------------------------------------------------------------------------- /packages/22vue-project/src/views/AboutView.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /packages/22vue-project/src/views/HomeView.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | -------------------------------------------------------------------------------- /packages/22vue-project/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], 4 | "exclude": ["src/**/__tests__/*"], 5 | "compilerOptions": { 6 | "composite": true, 7 | "noEmit": true, 8 | "baseUrl": ".", 9 | "paths": { 10 | "@/*": ["./src/*"] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/22vue-project/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.node.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | }, 10 | { 11 | "path": "./tsconfig.vitest.json" 12 | } 13 | ], 14 | "compilerOptions": { 15 | "module": "NodeNext" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/22vue-project/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node18/tsconfig.json", 3 | "include": [ 4 | "vite.config.*", 5 | "vitest.config.*", 6 | "cypress.config.*", 7 | "nightwatch.conf.*", 8 | "playwright.config.*" 9 | ], 10 | "compilerOptions": { 11 | "composite": true, 12 | "noEmit": true, 13 | "module": "ESNext", 14 | "moduleResolution": "Bundler", 15 | "types": ["node"] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/22vue-project/tsconfig.vitest.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.app.json", 3 | "exclude": [], 4 | "compilerOptions": { 5 | "composite": true, 6 | "lib": [], 7 | "types": ["node", "jsdom"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/22vue-project/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import { defineConfig } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | import vueJsx from '@vitejs/plugin-vue-jsx' 6 | 7 | // https://vitejs.dev/config/ 8 | export default defineConfig({ 9 | plugins: [ 10 | vue(), 11 | vueJsx(), 12 | ], 13 | resolve: { 14 | alias: { 15 | '@': fileURLToPath(new URL('./src', import.meta.url)) 16 | } 17 | } 18 | }) 19 | -------------------------------------------------------------------------------- /packages/22vue-project/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import { mergeConfig, defineConfig, configDefaults } from 'vitest/config' 3 | import viteConfig from './vite.config' 4 | 5 | export default mergeConfig( 6 | viteConfig, 7 | defineConfig({ 8 | test: { 9 | environment: 'jsdom', 10 | exclude: [...configDefaults.exclude, 'e2e/*'], 11 | root: fileURLToPath(new URL('./', import.meta.url)) 12 | } 13 | }) 14 | ) 15 | -------------------------------------------------------------------------------- /packages/23rsbuild/.gitignore: -------------------------------------------------------------------------------- 1 | # Local 2 | .DS_Store 3 | *.local 4 | *.log* 5 | 6 | # Dist 7 | node_modules 8 | dist/ 9 | 10 | # IDE 11 | .vscode/* 12 | !.vscode/extensions.json 13 | .idea 14 | -------------------------------------------------------------------------------- /packages/23rsbuild/README.md: -------------------------------------------------------------------------------- 1 | # Rsbuild Project 2 | 3 | ## Setup 4 | 5 | Install the dependencies: 6 | 7 | ```bash 8 | pnpm install 9 | ``` 10 | 11 | ## Get Started 12 | 13 | Start the dev server: 14 | 15 | ```bash 16 | pnpm dev 17 | ``` 18 | 19 | Build the app for production: 20 | 21 | ```bash 22 | pnpm build 23 | ``` 24 | 25 | Preview the production build locally: 26 | 27 | ```bash 28 | pnpm preview 29 | ``` 30 | -------------------------------------------------------------------------------- /packages/23rsbuild/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rsbuild-vue3-ts", 3 | "private": true, 4 | "version": "1.0.0", 5 | "scripts": { 6 | "dev": "rsbuild dev --open", 7 | "build": "rsbuild build", 8 | "preview": "rsbuild preview" 9 | }, 10 | "dependencies": { 11 | "vue": "^3.3.4" 12 | }, 13 | "devDependencies": { 14 | "@rsbuild/core": "^1.0.0", 15 | "@rsbuild/plugin-vue": "^1.0.0", 16 | "typescript": "^5.3.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/23rsbuild/rsbuild.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@rsbuild/core'; 2 | import { pluginVue } from '@rsbuild/plugin-vue'; 3 | 4 | export default defineConfig({ 5 | plugins: [pluginVue()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/23rsbuild/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 29 | -------------------------------------------------------------------------------- /packages/23rsbuild/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue'; 5 | 6 | const component: DefineComponent<{}, {}, any>; 7 | export default component; 8 | } 9 | -------------------------------------------------------------------------------- /packages/23rsbuild/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | color: #fff; 4 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 5 | background-image: linear-gradient(to bottom, #020917, #101725); 6 | } 7 | -------------------------------------------------------------------------------- /packages/23rsbuild/src/index.ts: -------------------------------------------------------------------------------- 1 | import './index.css'; 2 | import { createApp } from 'vue'; 3 | import App from './App.vue'; 4 | 5 | createApp(App).mount('#root'); 6 | -------------------------------------------------------------------------------- /packages/23rsbuild/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["DOM", "ES2020"], 5 | "module": "ESNext", 6 | "strict": true, 7 | "skipLibCheck": true, 8 | "isolatedModules": true, 9 | "resolveJsonModule": true, 10 | "moduleResolution": "bundler" 11 | }, 12 | "include": ["src"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/24rspack/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /packages/24rspack/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /packages/24rspack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rspack-vue-starter", 3 | "version": "1.0.0", 4 | "description": "", 5 | "private": true, 6 | "main": "index.js", 7 | "scripts": { 8 | "dev": "rspack serve", 9 | "build": "rspack build" 10 | }, 11 | "dependencies": { 12 | "vue": "3.2.45" 13 | }, 14 | "devDependencies": { 15 | "@rspack/cli": "0.5.0", 16 | "@rspack/core": "0.5.0", 17 | "vue-loader": "^17.2.2" 18 | }, 19 | "keywords": [], 20 | "author": "", 21 | "license": "ISC" 22 | } -------------------------------------------------------------------------------- /packages/24rspack/rspack.config.js: -------------------------------------------------------------------------------- 1 | const rspack = require("@rspack/core"); 2 | const { VueLoaderPlugin } = require("vue-loader"); 3 | const isDev = process.env.NODE_ENV == "development"; 4 | /** @type {import('@rspack/cli').Configuration} */ 5 | const config = { 6 | context: __dirname, 7 | entry: { 8 | main: "./src/main.js" 9 | }, 10 | resolve: { 11 | extensions: ["...", ".ts"] 12 | }, 13 | plugins: [ 14 | new VueLoaderPlugin(), 15 | new rspack.HtmlRspackPlugin({ 16 | template: "./index.html" 17 | }) 18 | ], 19 | module: { 20 | rules: [ 21 | { 22 | test: /\.vue$/, 23 | loader: "vue-loader", 24 | options: { 25 | experimentalInlineMatchResource: true 26 | } 27 | }, 28 | { 29 | test: /\.(js|ts)$/, 30 | use: [ 31 | { 32 | loader: "builtin:swc-loader", 33 | options: { 34 | sourceMap: true, 35 | jsc: { 36 | parser: { 37 | syntax: "typescript", 38 | tsx: false 39 | } 40 | }, 41 | env: { 42 | targets: [ 43 | "chrome >= 87", 44 | "edge >= 88", 45 | "firefox >= 78", 46 | "safari >= 14" 47 | ] 48 | } 49 | } 50 | } 51 | ] 52 | }, 53 | { 54 | test: /\.svg/, 55 | type: "asset/resource" 56 | } 57 | ] 58 | } 59 | }; 60 | module.exports = config; 61 | -------------------------------------------------------------------------------- /packages/24rspack/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 19 | 20 | 36 | -------------------------------------------------------------------------------- /packages/24rspack/src/assets/vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/24rspack/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 31 | 32 | 37 | -------------------------------------------------------------------------------- /packages/24rspack/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue"; 2 | import "./style.css"; 3 | import App from "./App.vue"; 4 | 5 | createApp(App).mount("#app"); 6 | -------------------------------------------------------------------------------- /packages/24rspack/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 3 | font-size: 16px; 4 | line-height: 24px; 5 | font-weight: 400; 6 | 7 | color-scheme: light dark; 8 | color: rgba(255, 255, 255, 0.87); 9 | background-color: #242424; 10 | 11 | font-synthesis: none; 12 | text-rendering: optimizeLegibility; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | -webkit-text-size-adjust: 100%; 16 | } 17 | 18 | a { 19 | font-weight: 500; 20 | color: #646cff; 21 | text-decoration: inherit; 22 | } 23 | a:hover { 24 | color: #535bf2; 25 | } 26 | 27 | a { 28 | font-weight: 500; 29 | color: #646cff; 30 | text-decoration: inherit; 31 | } 32 | a:hover { 33 | color: #535bf2; 34 | } 35 | 36 | body { 37 | margin: 0; 38 | display: flex; 39 | place-items: center; 40 | min-width: 320px; 41 | min-height: 100vh; 42 | } 43 | 44 | h1 { 45 | font-size: 3.2em; 46 | line-height: 1.1; 47 | } 48 | 49 | button { 50 | border-radius: 8px; 51 | border: 1px solid transparent; 52 | padding: 0.6em 1.2em; 53 | font-size: 1em; 54 | font-weight: 500; 55 | font-family: inherit; 56 | background-color: #1a1a1a; 57 | cursor: pointer; 58 | transition: border-color 0.25s; 59 | } 60 | button:hover { 61 | border-color: #646cff; 62 | } 63 | button:focus, 64 | button:focus-visible { 65 | outline: 4px auto -webkit-focus-ring-color; 66 | } 67 | 68 | .card { 69 | padding: 2em; 70 | } 71 | 72 | #app { 73 | max-width: 1280px; 74 | margin: 0 auto; 75 | padding: 2rem; 76 | text-align: center; 77 | } 78 | 79 | @media (prefers-color-scheme: light) { 80 | :root { 81 | color: #213547; 82 | background-color: #ffffff; 83 | } 84 | a:hover { 85 | color: #747bff; 86 | } 87 | button { 88 | background-color: #f9f9f9; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /packages/25css/10.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 外边距合并 7 | 30 | 31 | 32 |
33 |
34 |
35 |
36 |
37 | 38 | -------------------------------------------------------------------------------- /packages/25css/11.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Margin Box Example 6 | 24 | 25 | 26 |
27 |
28 |
Block Element
29 |
30 | 31 | -------------------------------------------------------------------------------- /packages/25css/12.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 1 6 | 30 | 31 | 32 |
33 | 1 34 |
35 | 36 |
37 |
38 | 39 | 40 | -------------------------------------------------------------------------------- /packages/25css/2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Clear Float Example 6 | 23 | 24 | 25 |
26 |
27 | 28 | -------------------------------------------------------------------------------- /packages/25css/3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | 27 |
28 |
float
29 |
block
30 |
block
31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /packages/25css/4.html: -------------------------------------------------------------------------------- 1 | 17 |
18 |
float
19 |
inline inline
20 |
21 | -------------------------------------------------------------------------------- /packages/25css/5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BFC Example 6 | 26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | -------------------------------------------------------------------------------- /packages/25css/6.html: -------------------------------------------------------------------------------- 1 | 24 | 25 |
26 |
27 | 28 |
29 | 30 |
-------------------------------------------------------------------------------- /packages/25css/7.html: -------------------------------------------------------------------------------- 1 | 14 |
15 |
16 |
-------------------------------------------------------------------------------- /packages/25css/8.html: -------------------------------------------------------------------------------- 1 | 13 |
14 | asdjasijdiasdjasdjasi,jdiasdjasdjasijdiasdjasdjasijdiasd,jasdjasijdiasdjasdjasijdiasdjasdjasijdi asdjasdjasijdiasdjasdjasijdiasdjasdjasijdiasdjasdj asijdiasdjasdjasijdiasdjasdjasijdiasdjasdj,asijdiasdjasdjasijdiasdjasdjasijdiasdjasdjasijdiasdj asdjasijdiasdjasdjasijdiasdjasdjas.ijdiasdjasdjasijdiasdjasdjasijdiasdjasdjasijdias djasdjasijdiasdjasdjasijdiasdj.asasd,as,das,dasd 15 |
-------------------------------------------------------------------------------- /packages/25css/9.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /packages/2handwrite/arguments.js: -------------------------------------------------------------------------------- 1 | function containsAll(haystack) { 2 | console.log(33, haystack); 3 | 4 | for (var i = 1; i < arguments.length; i++) { 5 | var needle = arguments[i]; 6 | if (haystack.indexOf(needle) === -1) { 7 | return false; 8 | } 9 | } 10 | return true; 11 | } 12 | containsAll('banana', 'b', 'nan'); 13 | 14 | //善用 arguments 与参数个数 15 | -------------------------------------------------------------------------------- /packages/2handwrite/debugger.js: -------------------------------------------------------------------------------- 1 | !(function t() { 2 | try { 3 | !(function t(e) { 4 | (1 !== ('' + e / e).length || 0 === e) && function() {}.constructor('debugger')(), t(++e); 5 | })(0); 6 | } catch (e) { 7 | setTimeout(t, 500); 8 | } 9 | })(); 10 | -------------------------------------------------------------------------------- /packages/2handwrite/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | 斐波那契数列 3 | */ 4 | // 普通算法 5 | function fibonacci(n) { 6 | if (n < 1) { 7 | throw Error('error'); 8 | } 9 | if (n === 1 || n === 2) { 10 | return 1; 11 | } 12 | return fibonacci(n - 1) + fibonacci(n - 2); 13 | } 14 | 15 | //空间换时间 16 | let obj = {}; 17 | memory = (fn) => (n) => { 18 | if (obj[n] === undefined) { 19 | obj[n] = fn(n); 20 | } 21 | return obj[n]; 22 | }; 23 | fibonacci = memory(fibonacci); 24 | 25 | //动态规划(推荐) 26 | function fibonacci(n) { 27 | let res = 1; 28 | if (n === 1 && n === 2) return res; 29 | n = n - 2; 30 | let cur = 1, 31 | pre = 1; 32 | while (n) { 33 | res = cur + pre; 34 | pre = cur; 35 | cur = res; 36 | n--; 37 | } 38 | return res; 39 | } 40 | 41 | /* 42 | 洗牌算法 43 | */ 44 | 45 | // 原地 46 | function shuffle(arr) { 47 | for (let i = 0; i < arr.length; i++) { 48 | let index = i + Math.floor(Math.random() * (arr.length - i)); 49 | [arr[i], arr[index]] = [arr[index], arr[i]]; 50 | } 51 | } 52 | 53 | // 非原地 54 | function shuffle1(arr) { 55 | let _arr = []; 56 | while (arr.length) { 57 | let index = Math.floor(Math.random() * arr.length); 58 | _arr.push(arr.splice(index, 1)[0]); 59 | } 60 | return _arr; 61 | } 62 | 63 | /* 64 | promisify 65 | */ 66 | 67 | function promisify(fn) { 68 | return function (...args) { 69 | return new Promise((resolve, reject) => { 70 | args.push((err, ...values) => { 71 | if (err) { 72 | return reject(err); 73 | } 74 | return resolve(...values); 75 | }); 76 | fn.call(this, ...args); 77 | }); 78 | }; 79 | } 80 | 81 | const fsp = new Proxy(fs, { 82 | get(target, key) { 83 | return promisify(target[key]); 84 | }, 85 | }); 86 | 87 | //使用方法,适合 error-first 风格(nodejs) 88 | 89 | await fsp.writeFile('./index.js', data); 90 | -------------------------------------------------------------------------------- /packages/2handwrite/instanceof.js: -------------------------------------------------------------------------------- 1 | var H = (function () { 2 | function Dialog() { 3 | if (Dialog.prototype.init) { 4 | Dialog.prototype = { 5 | init: function () { 6 | console.log('ok'); 7 | }, 8 | }; 9 | } 10 | } 11 | 12 | new Dialog(); 13 | 14 | return Dialog; 15 | })(); 16 | 17 | var a = new H(); 18 | 19 | console.log(a instanceof H); 20 | 21 | //https://www.cnblogs.com/yanhaijing/p/3291292.html 22 | -------------------------------------------------------------------------------- /packages/2handwrite/new.js: -------------------------------------------------------------------------------- 1 | function Foo() { 2 | getName = function() { 3 | console.log(1); 4 | }; 5 | return this; 6 | } 7 | Foo.getName = function() { 8 | console.log(2); 9 | }; 10 | Foo.prototype.getName = function() { 11 | console.log(3); 12 | }; 13 | var getName = function() { 14 | console.log(4); 15 | }; 16 | function getName() { 17 | console.log(5); 18 | } 19 | 20 | //请写出以下输出结果: 21 | Foo.getName(); 22 | getName(); 23 | Foo().getName(); 24 | getName(); 25 | new Foo.getName(); 26 | new Foo().getName(); 27 | new new Foo().getName(); 28 | 29 | //在 JavaScript 中,如果构造函数不带参数的话,new 的时候可以省略括号。 30 | 31 | //第一种是普通的用法,就和上面代码 new Foo 一样。这种时候它的优先级是仅次于括号(点和括号是同级别的)。 32 | 33 | //但是 new 还有另一个种用法,那就是输入构造参数的情况。比如上面代码第二个代码 new Foo(),即使构造函数的参数为空,这种情况下 new 就有括号的性质,前括号的 new 关键字,后括号是用来输入构造参数的小括号。 34 | 35 | //https://segmentfault.com/q/1010000011576064/ 36 | -------------------------------------------------------------------------------- /packages/2handwrite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "handwrite", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "preinstall": "npx only-allow pnpm" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /packages/2handwrite/process.js: -------------------------------------------------------------------------------- 1 | let users = { 2 | admin: '123', 3 | user1: '321', 4 | user2: '213', 5 | }; 6 | let username = ''; 7 | 8 | process.stdout.write('请输入用户名:'); 9 | process.stdin.on('data', (input) => { 10 | input = input.toString().trim(); 11 | if (!username) { 12 | if (Object.keys(users).indexOf(input) === -1) { 13 | process.stdout.write('用户名不存在' + '\n'); 14 | process.stdout.write('请输入用户名:'); 15 | username = ''; 16 | } else { 17 | process.stdout.write('请输入密码:'); 18 | username = input; 19 | } 20 | } 21 | //输入密码 22 | else { 23 | if (input === users[username]) { 24 | console.log('登陆成功'); 25 | process.stdin.emit('end'); 26 | } else { 27 | process.stdout.write('请输入密码' + '\n'); 28 | } 29 | } 30 | }); 31 | process.stdin.on('end', () => { 32 | process.stdout.write('end'); 33 | }); 34 | -------------------------------------------------------------------------------- /packages/2handwrite/promisify.js: -------------------------------------------------------------------------------- 1 | //异步接口:返回当天在线用户数 2 | function getonlinePerson(callback) { 3 | //模拟实现 4 | var onlinePerson = Math.ceil(Math.random() * 1000); 5 | setTimeout(function() { 6 | callback(onlinePerson); 7 | }, Math.random * 1000); 8 | } 9 | //异步接口:返回当天总注册用户数 10 | function getRegPerson(callback) { 11 | //模拟实现 12 | var regPerson = Math.ceil(Math.random() * 1000) + 1000; 13 | setTimeout(function() { 14 | callback(regPerson); 15 | }, Math.random() * 1000); 16 | } 17 | //异步接口:返回当天在线人数百分比,需要【当天在线用户数】以及【当天总注册用户数】做参数 18 | function calOnlinePercent(onlinePerson, regPerson, callback) { 19 | //模拟实现 20 | var percent = Math.ceil((onlinePerson / regPerson) * 100); 21 | setTimeout(function() { 22 | callback(percent); 23 | }, Math.random * 1000); 24 | } 25 | //异步函数promise化 26 | function promisify(fn) { 27 | return (...args) => 28 | new Promise((resolve, reject) => { 29 | args.push((result, err) => { 30 | if (err) { 31 | reject(err); 32 | } else { 33 | resolve(result); 34 | } 35 | }); 36 | fn.apply(null, args); 37 | }); 38 | } 39 | 40 | //结合以上几个函数,编写getOnlinePercent函数,在回调中返回当天在线人数百分比 41 | function getOnlinePercent(callback) { 42 | //此处编写你的逻辑代码 43 | var getonlinePerson2 = promisify(getonlinePerson); 44 | var getRegPerson2 = promisify(getRegPerson); 45 | var calOnlinePercent2 = promisify(calOnlinePercent); 46 | Promise.all([getonlinePerson2(), getRegPerson2()]) 47 | .then(arr => { 48 | return calOnlinePercent2(...arr); 49 | }) 50 | .then(result => callback(result)); 51 | } 52 | getOnlinePercent(result => console.log(result + '%')); 53 | -------------------------------------------------------------------------------- /packages/2handwrite/pubsub.js: -------------------------------------------------------------------------------- 1 | function EventTarget() { 2 | this.handlers = {}; 3 | } 4 | 5 | EventTarget.prototype = { 6 | constructor: EventTarget, 7 | //定义一个方法,增加 8 | addHandler: function (type, handler) { 9 | if (typeof this.handlers[type] == 'undefined') { 10 | this.handlers[type] = []; 11 | } 12 | 13 | this.handlers[type].push(handler); 14 | }, 15 | //定义一个方法:执行 16 | fire: function (event) { 17 | if (!event.target) { 18 | event.target = this; 19 | } 20 | if (this.handlers[event.type] instanceof Array) { 21 | var handlers = this.handlers[event.type]; 22 | for (var i = 0, len = handlers.length; i < len; i++) { 23 | handlers[i](event); 24 | } 25 | } 26 | }, 27 | //定义一个方法:删除 28 | removeHandler: function (type, handler) { 29 | if (this.handlers[type] instanceof Array) { 30 | var handlers = this.handlers[type]; 31 | for (var i = 0, len = handlers.length; i < len; i++) { 32 | if (handlers[i] === handler) { 33 | break; 34 | } 35 | } 36 | 37 | handlers.splice(i, 1); 38 | } 39 | }, 40 | }; 41 | function handleMessage(event) { 42 | alert('Message received: ' + event.message); 43 | } 44 | //创建一个新对象 45 | var target = new EventTarget(); 46 | 47 | //添加一个事件处理程序 48 | target.addHandler('message', handleMessage); 49 | 50 | //触发事件 51 | target.fire({ type: 'message', message: 'Hello world!' }); 52 | 53 | //删除事件处理程序 54 | target.removeHandler('message', handleMessage); 55 | 56 | //再次,应没有处理程序 57 | target.fire({ type: 'message', message: 'Hello world!' }); 58 | -------------------------------------------------------------------------------- /packages/2handwrite/readme.md: -------------------------------------------------------------------------------- 1 | ## 手写一些常见的方法 2 | -------------------------------------------------------------------------------- /packages/3angular-module/README.md: -------------------------------------------------------------------------------- 1 | # angular-module-demo 2 | 3 | angular1.x 模块依赖 demo 4 | -------------------------------------------------------------------------------- /packages/3angular-module/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Title 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/3angular-module/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by zhaoky on 2017/1/17. 3 | */ 4 | angular 5 | .module("demoModule", [ 6 | "module1", 7 | "module2", 8 | "module3", 9 | "module4" 10 | ]); 11 | 12 | angular 13 | .module("module1", []) 14 | .controller("controller1", function () { 15 | console.log("controller1"); 16 | }); 17 | 18 | angular 19 | .module("module2", []) 20 | .service("service2", function () { 21 | this.name = "zky"; 22 | }) 23 | .controller("controller2", function () { 24 | console.log("controller2"); 25 | }); 26 | 27 | angular 28 | .module("module3", []) 29 | .controller("controller3", [ 30 | "service2", 31 | function (service2) { 32 | console.log("controller3", service2.name); 33 | }]); 34 | 35 | 36 | angular 37 | .module("module4", []) 38 | .controller("controller4", function () { 39 | console.log("controller4"); 40 | }); 41 | window.onload=function(){ 42 | angular.bootstrap(document, ["demoModule"]); 43 | }; 44 | -------------------------------------------------------------------------------- /packages/3angular-module/test1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Title 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 17 | 18 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /packages/3angular-module/test1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by zhaoky on 2017/1/17. 3 | */ 4 | angular 5 | .module("module1", []) 6 | .controller("controller1", function () { 7 | console.log("controller1"); 8 | }); 9 | 10 | angular 11 | .module("module2", []) 12 | .service("service2", function () { 13 | this.name = "zky"; 14 | }) 15 | .controller("controller2", function () { 16 | console.log("controller2"); 17 | }); 18 | 19 | angular 20 | .module("module3", []) 21 | .controller("controller3", [ 22 | "service2", 23 | function (service2) { 24 | console.log("controller3", service2.name); 25 | }]); 26 | 27 | angular 28 | .module("module4", []) 29 | .controller("controller4", function () { 30 | console.log("controller4"); 31 | }); 32 | 33 | -------------------------------------------------------------------------------- /packages/4angular-todolist/README.md: -------------------------------------------------------------------------------- 1 | # angular-todolist 2 | 3 | 我的一个用 angular 框架写的一个单页面应用 4 | 5 | 具有缓存,双击编辑,切换,计数等简单功能 6 | -------------------------------------------------------------------------------- /packages/4angular-todolist/javascripts/app.js: -------------------------------------------------------------------------------- 1 | //应用程序文件 2 | var app = angular.module("app",[]); -------------------------------------------------------------------------------- /packages/5ast/index.js: -------------------------------------------------------------------------------- 1 | const esprima = require('esprima'); 2 | const estraverse = require('estraverse'); 3 | const escodegen = require('escodegen'); 4 | 5 | let code = `var a = b=>{console.log(123);}`; 6 | let tree = esprima.parseScript(code); 7 | estraverse.traverse(tree, { 8 | leave(node) { 9 | if (node.type === 'ArrowFunctionExpression') { 10 | node.type = 'FunctionDeclaration'; 11 | } 12 | }, 13 | }); 14 | let r = escodegen.generate(tree); 15 | console.log(r); 16 | -------------------------------------------------------------------------------- /packages/5ast/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ast", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "node index.js" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "escodegen": "^1.12.0", 14 | "esprima": "^4.0.1", 15 | "estraverse": "^4.3.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/6node/1.txt: -------------------------------------------------------------------------------- 1 | 第一行:1111 2 | 第二行2222 3 | aaa -------------------------------------------------------------------------------- /packages/6node/app.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const express = require("express"); 3 | const proxy = require("express-http-proxy"); 4 | const app = express(); 5 | app.use(express.static(`${__dirname}/public`)); 6 | app.get("/1", function(req, res) { 7 | res.sendFile(`${__dirname}/public/1.html`); 8 | }); 9 | app.use("/a", proxy("www.flqin.com")); 10 | app.listen(3000, () => { 11 | console.log("服务已启动:localhost:3000"); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/6node/hello.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | console.log("hello,zky"); 3 | console.log(process); 4 | -------------------------------------------------------------------------------- /packages/6node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "testzky", 3 | "bin": { 4 | "nbb": "hello.js", 5 | "a": "app.js" 6 | }, 7 | "version": "1.0.2", 8 | "devDependencies": { 9 | "express": "^4.16.4", 10 | "express-http-proxy": "^1.5.0" 11 | }, 12 | "dependencies": { 13 | "axios": "^0.18.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/6node/public/1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 1 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /packages/6node/public/1.js: -------------------------------------------------------------------------------- 1 | import a from "./2.js"; 2 | // import axios from "axios"; 3 | axios.get("/a?ID=1234").then(res => { 4 | console.log(1, a); 5 | }); 6 | -------------------------------------------------------------------------------- /packages/6node/public/2.js: -------------------------------------------------------------------------------- 1 | var a = 1; 2 | export default a; 3 | -------------------------------------------------------------------------------- /packages/7typescript/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: '@typescript-eslint/parser', 4 | plugins: ['@typescript-eslint'], 5 | extends: ['plugin:@typescript-eslint/recommended', 'google', 'prettier', 'prettier/@typescript-eslint'], 6 | env: { 7 | browser: true, 8 | es6: true 9 | }, 10 | globals: { 11 | Atomics: 'readonly', 12 | SharedArrayBuffer: 'readonly' 13 | }, 14 | parserOptions: { 15 | ecmaVersion: 2018, 16 | sourceType: 'module' 17 | }, 18 | rules: {} 19 | }; 20 | -------------------------------------------------------------------------------- /packages/7typescript/1.js: -------------------------------------------------------------------------------- 1 | const a = 1; 2 | console.log(a); 3 | -------------------------------------------------------------------------------- /packages/7typescript/2.js: -------------------------------------------------------------------------------- 1 | import {a,getJumeiInfo} from './a'; 2 | 3 | console.log(a); 4 | getJumeiInfo -------------------------------------------------------------------------------- /packages/7typescript/a.d.ts: -------------------------------------------------------------------------------- 1 | declare let qxq: number; 2 | /** 3 | * xxx 4 | * @param {number} id [聚美用户的id] 5 | * @param {string} name [聚美用户的名字] 6 | * @return {number} 7 | */ 8 | declare function getJumeiInfo(id: number, name: string):number; 9 | 10 | declare let a: number; 11 | // a = 1; 12 | // a = 3; 13 | 14 | export { a,getJumeiInfo }; 15 | -------------------------------------------------------------------------------- /packages/7typescript/a.js: -------------------------------------------------------------------------------- 1 | /** 2 | * asd 3 | * 4 | * @export 5 | * @param {*} id 6 | * @param {*} name 7 | * @return {number} 8 | */ 9 | export function getJumeiInfo(id,name){ 10 | console.log(id,name); 11 | return 1; 12 | } 13 | 14 | let qxq = 2; 15 | qxq = 3; 16 | console.log(qxq); 17 | 18 | getJumeiInfo() -------------------------------------------------------------------------------- /packages/7typescript/b.js: -------------------------------------------------------------------------------- 1 | // /** 2 | // * xxx 3 | // * 4 | // * @param {number} id 5 | // * @param {string} y 6 | // * @return {number} 7 | // */ 8 | // function getJumeiInfo(id:number,y:string):number{ 9 | // console.log(id,y); 10 | // return id; 11 | // } 12 | -------------------------------------------------------------------------------- /packages/7typescript/b.ts: -------------------------------------------------------------------------------- 1 | // /** 2 | // * xxx 3 | // * 4 | // * @param {number} id 5 | // * @param {string} y 6 | // * @return {number} 7 | // */ 8 | // function getJumeiInfo(id:number,y:string):number{ 9 | // console.log(id,y); 10 | // return id; 11 | // } 12 | -------------------------------------------------------------------------------- /packages/7typescript/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/env', 5 | { 6 | targets: '> 1%, not dead' 7 | } 8 | ], 9 | '@babel/preset-typescript' 10 | ] 11 | }; 12 | -------------------------------------------------------------------------------- /packages/7typescript/dist/b.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoky/demos/a347b8e05eed3e12444c5be91d2dd636dd189cc1/packages/7typescript/dist/b.d.ts -------------------------------------------------------------------------------- /packages/7typescript/dist/hello.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /packages/7typescript/hello.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /packages/7typescript/hello.js: -------------------------------------------------------------------------------- 1 | import { a } from "./a"; 2 | /** 3 | * 1 4 | * 5 | * @param {number} person 6 | * @return {string} 7 | */ 8 | function sayHello(person) { 9 | return "Hello, " + person; 10 | } 11 | console.log(a); 12 | const user = "zky"; 13 | var Days; 14 | (function (Days) { 15 | Days[Days["Sun"] = 0] = "Sun"; 16 | Days[Days["Mon"] = 1] = "Mon"; 17 | Days[Days["Tue"] = 2] = "Tue"; 18 | Days[Days["Wed"] = 3] = "Wed"; 19 | Days[Days["Thu"] = 4] = "Thu"; 20 | Days[Days["Fri"] = 5] = "Fri"; 21 | Days[Days["Sat"] = 6] = "Sat"; 22 | })(Days || (Days = {})); 23 | const b = 1; 24 | console.log(Days["Sun"] === 0); 25 | console.log(sayHello(user), b); 26 | -------------------------------------------------------------------------------- /packages/7typescript/hello.ts: -------------------------------------------------------------------------------- 1 | import { a } from "./a"; 2 | /** 3 | * 1 4 | * 5 | * @param {number} person 6 | * @return {string} 7 | */ 8 | function sayHello(person: string):string { 9 | return "Hello, " + person; 10 | } 11 | console.log(a); 12 | const user = "zky"; 13 | enum Days { 14 | Sun, 15 | Mon, 16 | Tue, 17 | Wed, 18 | Thu, 19 | Fri, 20 | Sat 21 | } 22 | const b = 1; 23 | console.log(Days["Sun"] === 0); 24 | console.log(sayHello(user), b); 25 | -------------------------------------------------------------------------------- /packages/7typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ts", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "1.js", 6 | "scripts": {}, 7 | "keywords": [], 8 | "author": "", 9 | "license": "ISC", 10 | "types": "./a.d.ts", 11 | "devDependencies": { 12 | "@babel/core": "^7.5.5", 13 | "@babel/preset-env": "^7.5.5", 14 | "@babel/preset-typescript": "^7.3.3", 15 | "@types/node": "^12.6.8", 16 | "@typescript-eslint/eslint-plugin": "^1.13.0", 17 | "@typescript-eslint/parser": "^1.13.0", 18 | "babel-loader": "^8.0.6", 19 | "eslint": "^6.1.0", 20 | "eslint-config-google": "^0.13.0", 21 | "eslint-config-prettier": "^6.0.0", 22 | "eslint-plugin-prettier": "^3.1.0", 23 | "fork-ts-checker-webpack-plugin": "^1.4.3", 24 | "prettier": "^1.18.2", 25 | "typescript": "^3.5.3", 26 | "webpack": "^4.37.0", 27 | "webpack-cli": "^3.3.6", 28 | "webpack-dev-server": "^3.7.2" 29 | }, 30 | "dependencies": {} 31 | } 32 | -------------------------------------------------------------------------------- /packages/7typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "declaration": true, 5 | "declarationDir": "./dist" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/7typescript/webpack.config.js: -------------------------------------------------------------------------------- 1 | const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); 2 | const path = require('path'); 3 | module.exports = { 4 | mode: 'development', 5 | entry: ['./hello.ts'], 6 | output: { 7 | path: path.resolve(__dirname, './dist'), 8 | filename: '[name].js' 9 | }, 10 | devtool: 'source-map', 11 | devServer: { 12 | stats: 'errors-only', 13 | contentBase: path.join(__dirname, 'dist'), 14 | overlay: true 15 | }, 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.(ts|js)$/, 20 | exclude: /node_modules/, 21 | use: ['babel-loader'] 22 | } 23 | ] 24 | }, 25 | plugins: [new ForkTsCheckerWebpackPlugin()], 26 | resolve: { 27 | extensions: ['.js', '.jsx', '.ts', '.tsx'] 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /packages/9generator/index.js: -------------------------------------------------------------------------------- 1 | function f() { 2 | console.log('执行f'); 3 | return 9; 4 | } 5 | function f1() { 6 | console.log('执行f1'); 7 | return 'F1'; 8 | } 9 | function b() { 10 | console.log('执行b'); 11 | return 'b'; 12 | } 13 | function c() { 14 | setTimeout(() => { 15 | return 'c'; 16 | }, 5000); 17 | return 'cc'; 18 | } 19 | function* main() { 20 | console.log('start'); 21 | var a = yield f(); 22 | console.log('a:', a); 23 | var b = yield f1(); 24 | console.log('a:', c); 25 | return 'finish'; 26 | } 27 | 28 | var vv = main(); //调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象即遍历器对象(Iterator Object)。 29 | var one = vv.next(); //每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止,但要执行yield后面的表达式。得到 { value: 'hello'(yield表达式的值), done: false(标志遍历是否结束) } 30 | var two = vv.next(b()); //yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作**上一个** yield 表达式的返回值。 31 | var three = vv.next(); 32 | console.log(one, two); 33 | 34 | // 遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。 35 | // 下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。 36 | // 如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。 37 | // 如果该函数没有return语句,则返回的对象的value属性值为undefined。 38 | -------------------------------------------------------------------------------- /packages/9generator/iterator.js: -------------------------------------------------------------------------------- 1 | // for...of循环、扩展运算符(...)、解构赋值 和 Array.from 方法可以自动遍历 Generator 函数运行时生成的Iterator对象,且此时不再需要调用next方法。 2 | function* foo() { 3 | yield 1; 4 | yield 2; 5 | yield 3; 6 | yield 4; 7 | yield 5; 8 | return 6; 9 | } 10 | 11 | for (let v of foo()) { 12 | console.log(v); 13 | } 14 | // 1 2 3 4 5 15 | 16 | function* fibs() { 17 | var a = 0; 18 | var b = 1; 19 | while (true) { 20 | yield a; 21 | [a, b] = [b, a + b]; 22 | } 23 | } 24 | 25 | var [a, b, c, d, e, f] = fibs(); 26 | console.log(f); 27 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' --------------------------------------------------------------------------------