├── .gitignore ├── 2021重新整理前的老版本 ├── .gitignore ├── chapter1 │ └── 第一章:课程介绍.pdf ├── chapter2 │ ├── async │ │ ├── a. nonblocking │ │ │ ├── example.js │ │ │ ├── package-lock.json │ │ │ └── package.json │ │ ├── b. callback │ │ │ ├── callback-hell.js │ │ │ └── error-first.js │ │ ├── c. promise │ │ │ ├── 1.js │ │ │ ├── 2. PromiseLink.js │ │ │ ├── 3. PromiseLinkPromise.js │ │ │ ├── 4. Promise.all.js │ │ │ └── 5. PromiseLastExample.js │ │ └── d. async-await │ │ │ └── index.js │ ├── commonjs │ │ ├── commonjs初探 │ │ │ ├── dist │ │ │ │ └── main.js │ │ │ ├── index.js │ │ │ └── lib.js │ │ ├── eventemitter │ │ │ ├── geektime.js │ │ │ └── index.js │ │ └── 用commonjs优化石头剪刀布游戏 │ │ │ ├── game.js │ │ │ └── index.js │ ├── http │ │ ├── express │ │ │ ├── http │ │ │ │ ├── game.js │ │ │ │ ├── index.html │ │ │ │ └── index.js │ │ │ └── package.json │ │ ├── koa │ │ │ ├── http │ │ │ │ ├── game.js │ │ │ │ ├── index.html │ │ │ │ └── index.js │ │ │ └── package.json │ │ └── 石头剪刀布 │ │ │ ├── game.js │ │ │ ├── index.html │ │ │ └── index.js │ ├── rpc │ │ ├── buffer │ │ │ ├── index.js │ │ │ └── test.proto │ │ ├── duplex │ │ │ ├── client.js │ │ │ ├── package.json │ │ │ └── server.js │ │ └── half-duplex │ │ │ ├── client.js │ │ │ ├── package.json │ │ │ └── server.js │ ├── 初试&石头剪刀布游戏 │ │ ├── index.js │ │ └── spr.js │ └── 第二章:技术预研篇.pdf ├── chapter3 │ ├── 1.download │ │ ├── index.js │ │ └── source │ │ │ ├── index.htm │ │ │ └── static │ │ │ ├── 9.88a55aada0b5e3e79968.js │ │ │ ├── aliplayer-min.css │ │ │ ├── aliplayer-min.js │ │ │ ├── analytics.js │ │ │ ├── app.39632140dd6cf68f1a0cea8e6e4f460e.css │ │ │ ├── app.98bcbd1f507597608a42.js │ │ │ ├── code.f041ed7.png │ │ │ ├── code2.484bdd7.png │ │ │ ├── font_372689_nw1guejwd2q.js │ │ │ ├── hm.js │ │ │ ├── jweixin-1.3.2.js │ │ │ ├── logo.522f12a.png │ │ │ ├── manifest.b3eebba6782b27b5890e.js │ │ │ ├── meiqia.js │ │ │ ├── page1-img1.a023db4.png │ │ │ ├── page1-img2.b42f242.png │ │ │ ├── page1-img3.41e010c.png │ │ │ ├── page2-bg.af9a743.png │ │ │ ├── page2-word5.1645448.png │ │ │ ├── page3-img1.65fa93c.png │ │ │ ├── page3-img2.cbced1f.png │ │ │ ├── page3-img3.59afeb0.png │ │ │ ├── page4-big.3e14a6f.png │ │ │ ├── page4-small.5da02ba.png │ │ │ ├── page5-img1.bbbbe4a.png │ │ │ ├── page5-img2.73774ee.png │ │ │ ├── saved_resource(1).html │ │ │ ├── saved_resource(2).html │ │ │ ├── saved_resource(3).html │ │ │ ├── saved_resource(4).html │ │ │ ├── saved_resource(5).html │ │ │ ├── saved_resource(6).html │ │ │ ├── saved_resource.html │ │ │ ├── shadow.4c5d43f.png │ │ │ ├── sync-cookie.html │ │ │ ├── vendor.aa0daa078f9134c361c2.js │ │ │ └── widget.js │ ├── 2.detail │ │ ├── client.js │ │ ├── detail.proto │ │ ├── index.js │ │ ├── source │ │ │ ├── index.html │ │ │ └── static │ │ │ │ ├── 0.7c3b3351c3cdfe36ae03.js │ │ │ │ ├── 2aa01da86c8fb550b32c79f8ca4f67b0.jpg │ │ │ │ ├── 42db8ef7b28bcdc26410141dd97b8178.jpg │ │ │ │ ├── 995176c4b4cb6c197414430998ad8c9b.jpg │ │ │ │ ├── aliplayer-min.css │ │ │ │ ├── aliplayer-min.js │ │ │ │ ├── analytics.js │ │ │ │ ├── app.39632140dd6cf68f1a0cea8e6e4f460e.css │ │ │ │ ├── app.98bcbd1f507597608a42.js │ │ │ │ ├── c674eb1df43af0f1bd2f73f629b532fd.jpg │ │ │ │ ├── cb0daf759635bacb07aed0e1cec43561.jpg │ │ │ │ ├── eb6bf600f044f7d21f241eb8d6ed0439.jpg │ │ │ │ ├── font_372689_nw1guejwd2q.js │ │ │ │ ├── hm.js │ │ │ │ ├── jweixin-1.3.2.js │ │ │ │ ├── manifest.17eb82567d34333afd6d.js │ │ │ │ ├── meiqia.js │ │ │ │ ├── saved_resource(1).html │ │ │ │ ├── saved_resource(2).html │ │ │ │ ├── saved_resource(3).html │ │ │ │ ├── saved_resource(4).html │ │ │ │ ├── saved_resource(5).html │ │ │ │ ├── saved_resource(6).html │ │ │ │ ├── saved_resource.html │ │ │ │ ├── sync-cookie.html │ │ │ │ ├── vendor.aa0daa078f9134c361c2.js │ │ │ │ └── widget.js │ │ └── template │ │ │ ├── index.html │ │ │ └── index.js │ ├── 3.play │ │ ├── .gitignore │ │ ├── __server │ │ │ └── index.js │ │ ├── index.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── rpc-client │ │ │ ├── comment-client.js │ │ │ └── praise-client.js │ │ ├── schema.js │ │ ├── schema │ │ │ ├── comment.gql │ │ │ └── comment.proto │ │ └── source │ │ │ ├── index.htm │ │ │ └── static │ │ │ ├── 132 │ │ │ ├── 0c54aa0c.jpg │ │ │ ├── 23479d05.jpg │ │ │ ├── 29841bda.jpg │ │ │ ├── 2a4170c2.jpg │ │ │ ├── 3edaec82.jpg │ │ │ ├── 4.3e6db69f7e47c828bca4.js │ │ │ ├── 46a7ef4e.jpg │ │ │ ├── 61dfc022.jpg │ │ │ ├── 74cf4934.jpg │ │ │ ├── 765c1325.jpg │ │ │ ├── 7913cdb0.jpg │ │ │ ├── 7c12fcc3.jpg │ │ │ ├── 83a02223.jpg │ │ │ ├── 8b51021d.jpg │ │ │ ├── 951a1a46.jpg │ │ │ ├── a576bfce.jpg │ │ │ ├── a8bb42c0.jpg │ │ │ ├── aliplayer-hls-min.js │ │ │ ├── aliplayer-min.css │ │ │ ├── aliplayer-min.js │ │ │ ├── aliplayer-vod-min.js │ │ │ ├── analytics.js │ │ │ ├── app.39632140dd6cf68f1a0cea8e6e4f460e.css │ │ │ ├── app.98bcbd1f507597608a42.js │ │ │ ├── f6695148.jpg │ │ │ ├── font_372689_nw1guejwd2q.js │ │ │ ├── hm.js │ │ │ ├── jweixin-1.3.2.js │ │ │ ├── manifest.17eb82567d34333afd6d.js │ │ │ ├── meiqia.js │ │ │ ├── saved_resource(1).html │ │ │ ├── saved_resource(2).html │ │ │ ├── saved_resource(3).html │ │ │ ├── saved_resource(4).html │ │ │ ├── saved_resource(5).html │ │ │ ├── saved_resource(6).html │ │ │ ├── saved_resource.html │ │ │ ├── sync-cookie.html │ │ │ ├── vendor.aa0daa078f9134c361c2.js │ │ │ └── widget.js │ ├── 4.list │ │ ├── browser │ │ │ ├── index.jsx │ │ │ └── webpack.config.js │ │ ├── component │ │ │ ├── column_item.jsx │ │ │ └── container.jsx │ │ └── node │ │ │ ├── app.jsx │ │ │ ├── get-data.js │ │ │ ├── index.htm │ │ │ ├── index.js │ │ │ ├── list-client.js │ │ │ ├── list.proto │ │ │ ├── source │ │ │ ├── 12.781e08a04adc7000f826.js │ │ │ ├── 2703e65de1b7699fffa1754c80985eb5.jpg │ │ │ ├── 2d5e1c53fd7aa2a8f7663db0dae0ee12.jpg │ │ │ ├── 42db8ef7b28bcdc26410141dd97b8178.jpg │ │ │ ├── 4d544deddd94e30924f840eb8b28f48b.jpg │ │ │ ├── 5ad916cc2f38a4e85e261930c38492fd.jpg │ │ │ ├── 5ececab2885832a6ef22d1c3b3e61e35.png │ │ │ ├── 7503b89359b2920c5ad4312a23652cab.jpg │ │ │ ├── 937c6584122951abcc85f4781028f5b9.jpg │ │ │ ├── ab5a43490b577940c9e937461b54b563.jpg │ │ │ ├── aliplayer-min.css │ │ │ ├── aliplayer-min.js │ │ │ ├── analytics.js │ │ │ ├── app.39632140dd6cf68f1a0cea8e6e4f460e.css │ │ │ ├── app.98bcbd1f507597608a42.js │ │ │ ├── b683240befccbdcaa86da8f382d3a11a.jpg │ │ │ ├── c674eb1df43af0f1bd2f73f629b532fd.jpg │ │ │ ├── ca39e9384b7793c4713dcc762da5f5c0.jpg │ │ │ ├── dfe48389682b96854d36e161b6e8e487.jpg │ │ │ ├── dfe9e621882fc283612f4f4deb77d1db.jpg │ │ │ ├── ed2d0aa1e881ee055ba14f58c9603fe0.jpg │ │ │ ├── font_372689_nw1guejwd2q.js │ │ │ ├── hm.js │ │ │ ├── jweixin-1.3.2.js │ │ │ ├── mactalk.8a01bbc.png │ │ │ ├── main.js │ │ │ ├── manifest.17eb82567d34333afd6d.js │ │ │ ├── meiqia.js │ │ │ ├── newcomer-benefits.d8ec0db.png │ │ │ ├── qrcode.bc44c82.png │ │ │ ├── saved_resource(1).html │ │ │ ├── saved_resource(2).html │ │ │ ├── saved_resource(3).html │ │ │ ├── saved_resource(4).html │ │ │ ├── saved_resource(5).html │ │ │ ├── saved_resource(6).html │ │ │ ├── saved_resource.html │ │ │ ├── student-certificate.2a355a2.png │ │ │ ├── sync-cookie.html │ │ │ ├── vendor.aa0daa078f9134c361c2.js │ │ │ └── widget.js │ │ │ └── template.js │ ├── backend │ │ ├── comment-list.js │ │ ├── comment-praise.js │ │ ├── detail.js │ │ ├── lib │ │ │ ├── geeknode-rpc-server.js │ │ │ └── rpc-server.js │ │ ├── list.js │ │ └── mockdata │ │ │ ├── column.js │ │ │ └── comment.js │ ├── entry.js │ ├── package-lock.json │ ├── package.json │ ├── readme.md │ ├── server.js │ └── 第三章:项目开发篇.pdf ├── chapter4 │ ├── caddon │ │ ├── binding.gyp │ │ ├── build │ │ │ ├── Makefile │ │ │ ├── Release │ │ │ │ ├── .deps │ │ │ │ │ └── Release │ │ │ │ │ │ ├── obj.target │ │ │ │ │ │ └── test │ │ │ │ │ │ │ └── index.o.d │ │ │ │ │ │ └── test.node.d │ │ │ │ ├── obj.target │ │ │ │ │ └── test │ │ │ │ │ │ └── index.o │ │ │ │ └── test.node │ │ │ ├── binding.Makefile │ │ │ ├── config.gypi │ │ │ ├── gyp-mac-tool │ │ │ └── test.target.mk │ │ ├── index.cc │ │ ├── index.js │ │ ├── package-lock.json │ │ └── package.json │ ├── node-serial-benchmark │ │ ├── .gitignore │ │ ├── .jshintignore │ │ ├── .jshintrc │ │ ├── README.md │ │ ├── codecs │ │ │ ├── node-protobuf.js │ │ │ ├── protobufjs.js │ │ │ └── protocol-buffers.js │ │ ├── gen-nodejs │ │ │ └── user_types.js │ │ ├── index.js │ │ ├── input.json │ │ ├── modules │ │ │ └── node-protobuf │ │ │ │ ├── .clang-format │ │ │ │ ├── .gitattributes │ │ │ │ ├── .npmignore │ │ │ │ ├── .travis.yml │ │ │ │ ├── CHANGES.md │ │ │ │ ├── Gruntfile.js │ │ │ │ ├── README.md │ │ │ │ ├── binding.gyp │ │ │ │ ├── generate-descriptors.sh │ │ │ │ ├── lp.sh │ │ │ │ ├── lpb_release │ │ │ │ ├── LICENSE │ │ │ │ ├── include │ │ │ │ │ └── google │ │ │ │ │ │ └── protobuf │ │ │ │ │ │ ├── any.h │ │ │ │ │ │ ├── any.pb.h │ │ │ │ │ │ ├── any.proto │ │ │ │ │ │ ├── api.pb.h │ │ │ │ │ │ ├── api.proto │ │ │ │ │ │ ├── arena.h │ │ │ │ │ │ ├── arenastring.h │ │ │ │ │ │ ├── compiler │ │ │ │ │ │ ├── code_generator.h │ │ │ │ │ │ ├── command_line_interface.h │ │ │ │ │ │ ├── cpp │ │ │ │ │ │ │ └── cpp_generator.h │ │ │ │ │ │ ├── csharp │ │ │ │ │ │ │ ├── csharp_generator.h │ │ │ │ │ │ │ └── csharp_names.h │ │ │ │ │ │ ├── importer.h │ │ │ │ │ │ ├── java │ │ │ │ │ │ │ ├── java_generator.h │ │ │ │ │ │ │ └── java_names.h │ │ │ │ │ │ ├── javanano │ │ │ │ │ │ │ └── javanano_generator.h │ │ │ │ │ │ ├── js │ │ │ │ │ │ │ └── js_generator.h │ │ │ │ │ │ ├── objectivec │ │ │ │ │ │ │ ├── objectivec_generator.h │ │ │ │ │ │ │ └── objectivec_helpers.h │ │ │ │ │ │ ├── parser.h │ │ │ │ │ │ ├── php │ │ │ │ │ │ │ └── php_generator.h │ │ │ │ │ │ ├── plugin.h │ │ │ │ │ │ ├── plugin.pb.h │ │ │ │ │ │ ├── plugin.proto │ │ │ │ │ │ ├── python │ │ │ │ │ │ │ └── python_generator.h │ │ │ │ │ │ └── ruby │ │ │ │ │ │ │ └── ruby_generator.h │ │ │ │ │ │ ├── descriptor.h │ │ │ │ │ │ ├── descriptor.pb.h │ │ │ │ │ │ ├── descriptor.proto │ │ │ │ │ │ ├── descriptor_database.h │ │ │ │ │ │ ├── duration.pb.h │ │ │ │ │ │ ├── duration.proto │ │ │ │ │ │ ├── dynamic_message.h │ │ │ │ │ │ ├── empty.pb.h │ │ │ │ │ │ ├── empty.proto │ │ │ │ │ │ ├── extension_set.h │ │ │ │ │ │ ├── field_mask.pb.h │ │ │ │ │ │ ├── field_mask.proto │ │ │ │ │ │ ├── generated_enum_reflection.h │ │ │ │ │ │ ├── generated_enum_util.h │ │ │ │ │ │ ├── generated_message_reflection.h │ │ │ │ │ │ ├── generated_message_util.h │ │ │ │ │ │ ├── has_bits.h │ │ │ │ │ │ ├── io │ │ │ │ │ │ ├── coded_stream.h │ │ │ │ │ │ ├── gzip_stream.h │ │ │ │ │ │ ├── printer.h │ │ │ │ │ │ ├── strtod.h │ │ │ │ │ │ ├── tokenizer.h │ │ │ │ │ │ ├── zero_copy_stream.h │ │ │ │ │ │ ├── zero_copy_stream_impl.h │ │ │ │ │ │ └── zero_copy_stream_impl_lite.h │ │ │ │ │ │ ├── map.h │ │ │ │ │ │ ├── map_entry.h │ │ │ │ │ │ ├── map_entry_lite.h │ │ │ │ │ │ ├── map_field.h │ │ │ │ │ │ ├── map_field_inl.h │ │ │ │ │ │ ├── map_field_lite.h │ │ │ │ │ │ ├── map_type_handler.h │ │ │ │ │ │ ├── message.h │ │ │ │ │ │ ├── message_lite.h │ │ │ │ │ │ ├── metadata.h │ │ │ │ │ │ ├── reflection.h │ │ │ │ │ │ ├── reflection_ops.h │ │ │ │ │ │ ├── repeated_field.h │ │ │ │ │ │ ├── service.h │ │ │ │ │ │ ├── source_context.pb.h │ │ │ │ │ │ ├── source_context.proto │ │ │ │ │ │ ├── struct.pb.h │ │ │ │ │ │ ├── struct.proto │ │ │ │ │ │ ├── stubs │ │ │ │ │ │ ├── atomic_sequence_num.h │ │ │ │ │ │ ├── atomicops.h │ │ │ │ │ │ ├── atomicops_internals_arm64_gcc.h │ │ │ │ │ │ ├── atomicops_internals_arm_gcc.h │ │ │ │ │ │ ├── atomicops_internals_arm_qnx.h │ │ │ │ │ │ ├── atomicops_internals_atomicword_compat.h │ │ │ │ │ │ ├── atomicops_internals_generic_gcc.h │ │ │ │ │ │ ├── atomicops_internals_macosx.h │ │ │ │ │ │ ├── atomicops_internals_mips_gcc.h │ │ │ │ │ │ ├── atomicops_internals_pnacl.h │ │ │ │ │ │ ├── atomicops_internals_power.h │ │ │ │ │ │ ├── atomicops_internals_ppc_gcc.h │ │ │ │ │ │ ├── atomicops_internals_solaris.h │ │ │ │ │ │ ├── atomicops_internals_tsan.h │ │ │ │ │ │ ├── atomicops_internals_x86_gcc.h │ │ │ │ │ │ ├── atomicops_internals_x86_msvc.h │ │ │ │ │ │ ├── bytestream.h │ │ │ │ │ │ ├── callback.h │ │ │ │ │ │ ├── casts.h │ │ │ │ │ │ ├── common.h │ │ │ │ │ │ ├── fastmem.h │ │ │ │ │ │ ├── hash.h │ │ │ │ │ │ ├── logging.h │ │ │ │ │ │ ├── macros.h │ │ │ │ │ │ ├── mutex.h │ │ │ │ │ │ ├── once.h │ │ │ │ │ │ ├── platform_macros.h │ │ │ │ │ │ ├── port.h │ │ │ │ │ │ ├── scoped_ptr.h │ │ │ │ │ │ ├── shared_ptr.h │ │ │ │ │ │ ├── singleton.h │ │ │ │ │ │ ├── status.h │ │ │ │ │ │ ├── stl_util.h │ │ │ │ │ │ ├── stringpiece.h │ │ │ │ │ │ ├── template_util.h │ │ │ │ │ │ └── type_traits.h │ │ │ │ │ │ ├── text_format.h │ │ │ │ │ │ ├── timestamp.pb.h │ │ │ │ │ │ ├── timestamp.proto │ │ │ │ │ │ ├── type.pb.h │ │ │ │ │ │ ├── type.proto │ │ │ │ │ │ ├── unknown_field_set.h │ │ │ │ │ │ ├── util │ │ │ │ │ │ ├── field_comparator.h │ │ │ │ │ │ ├── field_mask_util.h │ │ │ │ │ │ ├── json_util.h │ │ │ │ │ │ ├── message_differencer.h │ │ │ │ │ │ ├── time_util.h │ │ │ │ │ │ ├── type_resolver.h │ │ │ │ │ │ └── type_resolver_util.h │ │ │ │ │ │ ├── wire_format.h │ │ │ │ │ │ ├── wire_format_lite.h │ │ │ │ │ │ ├── wire_format_lite_inl.h │ │ │ │ │ │ ├── wrappers.pb.h │ │ │ │ │ │ └── wrappers.proto │ │ │ │ └── lib │ │ │ │ │ └── libprotobuf.lib │ │ │ │ ├── package.json │ │ │ │ ├── protobuf.js │ │ │ │ ├── run_leak.sh │ │ │ │ ├── src │ │ │ │ ├── common.h │ │ │ │ ├── init.cpp │ │ │ │ ├── leak.js │ │ │ │ ├── native.cpp │ │ │ │ ├── native.h │ │ │ │ ├── parse.cpp │ │ │ │ ├── parse.h │ │ │ │ ├── serialize.cpp │ │ │ │ └── serialize.h │ │ │ │ └── test │ │ │ │ ├── perf │ │ │ │ ├── perfTest.desc │ │ │ │ ├── perfTest.js │ │ │ │ ├── perfTest.proto │ │ │ │ ├── points.desc │ │ │ │ ├── points.js │ │ │ │ └── points.proto │ │ │ │ ├── test.desc │ │ │ │ ├── test.js │ │ │ │ ├── test.proto │ │ │ │ ├── testUnknown.desc │ │ │ │ └── testUnknown.proto │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── user.desc │ │ ├── user.proto │ │ └── user.thrift │ ├── process │ │ ├── app.js │ │ └── boot.js │ └── 第四章:性能调优篇.pdf ├── chapter5 │ ├── backend │ │ ├── article.js │ │ ├── comment-list.js │ │ ├── comment-praise.js │ │ ├── detail.js │ │ ├── lib │ │ │ ├── geeknode-rpc-server.js │ │ │ └── rpc-server.js │ │ ├── mockdata │ │ │ ├── column.js │ │ │ └── comment.js │ │ ├── proto │ │ │ └── detail.proto │ │ └── run.js │ ├── business │ │ └── play │ │ │ ├── data.js │ │ │ └── template.tpl │ ├── package.json │ ├── readme.md │ ├── server │ │ ├── create-template.js │ │ ├── request-factory.js │ │ ├── requestors │ │ │ ├── geek-rpc.js │ │ │ └── http.js │ │ ├── run.js │ │ └── test.js │ ├── workspace │ │ ├── build.js │ │ ├── src │ │ │ ├── page.data.js │ │ │ ├── play.template.html │ │ │ └── proto │ │ │ │ └── detail.proto │ │ └── uploader.js │ └── 第五章:框架和工程化篇.pdf ├── lottery │ └── index.js └── readme.md ├── section10 ├── game.js └── index.js ├── section12 ├── geektime.js └── index.js ├── section13 ├── glob.js └── package.json ├── section14 ├── callback-hell.js └── error-first.js ├── section16 ├── 1.js ├── 2.js ├── 3.PromiseLink.js ├── 4.PromiseAll.js └── 5.PromiseLastExample.js ├── section17 └── index.js ├── section19 ├── index.html └── index.js ├── section20 ├── game.js ├── index.html └── index.js ├── section21 ├── game.js ├── index.html ├── index.js ├── package-lock.json └── package.json ├── section22 ├── game.js ├── index.html ├── index.js ├── package-lock.json └── package.json ├── section24 ├── buffer.js ├── package-lock.json ├── package.json ├── protobuf.js └── test.proto ├── section25 ├── dubplex │ ├── client.js │ └── server.js ├── half-duplex │ ├── client.js │ └── server.js ├── simplex │ ├── client.js │ └── server.js └── 本节的例子需要启动node client.js和node server.js两个node ├── section27 ├── index.js ├── package-lock.json ├── package.json └── source │ ├── index.htm │ └── static │ ├── 9.88a55aada0b5e3e79968.js │ ├── aliplayer-min.css │ ├── aliplayer-min.js │ ├── analytics.js │ ├── app.39632140dd6cf68f1a0cea8e6e4f460e.css │ ├── app.98bcbd1f507597608a42.js │ ├── code.f041ed7.png │ ├── code2.484bdd7.png │ ├── font_372689_nw1guejwd2q.js │ ├── hm.js │ ├── jweixin-1.3.2.js │ ├── logo.522f12a.png │ ├── manifest.b3eebba6782b27b5890e.js │ ├── meiqia.js │ ├── page1-img1.a023db4.png │ ├── page1-img2.b42f242.png │ ├── page1-img3.41e010c.png │ ├── page2-bg.af9a743.png │ ├── page2-word5.1645448.png │ ├── page3-img1.65fa93c.png │ ├── page3-img2.cbced1f.png │ ├── page3-img3.59afeb0.png │ ├── page4-big.3e14a6f.png │ ├── page4-small.5da02ba.png │ ├── page5-img1.bbbbe4a.png │ ├── page5-img2.73774ee.png │ ├── saved_resource(1).html │ ├── saved_resource(2).html │ ├── saved_resource(3).html │ ├── saved_resource(4).html │ ├── saved_resource(5).html │ ├── saved_resource(6).html │ ├── saved_resource.html │ ├── shadow.4c5d43f.png │ ├── sync-cookie.html │ ├── vendor.aa0daa078f9134c361c2.js │ └── widget.js ├── section29 ├── index.js └── 封装完成版 │ └── index.js ├── section30 ├── detail-server │ ├── 本目录下的代码属于后台服务,在BFF架构里可以不是Node.js实现的部分。用node start.js启动即可 │ ├── detail.proto │ ├── lib │ │ ├── geeknode-rpc-server.js │ │ └── rpc-server.js │ ├── mockdata │ │ ├── column.js │ │ └── comment.js │ ├── package-lock.json │ ├── package.json │ └── start.js ├── node-client │ ├── client.js │ ├── detail.proto │ ├── index.js │ ├── package-lock.json │ ├── package.json │ ├── source │ │ ├── index.html │ │ └── static │ │ │ ├── 0.7c3b3351c3cdfe36ae03.js │ │ │ ├── 2aa01da86c8fb550b32c79f8ca4f67b0.jpg │ │ │ ├── 42db8ef7b28bcdc26410141dd97b8178.jpg │ │ │ ├── 995176c4b4cb6c197414430998ad8c9b.jpg │ │ │ ├── aliplayer-min.css │ │ │ ├── aliplayer-min.js │ │ │ ├── analytics.js │ │ │ ├── app.39632140dd6cf68f1a0cea8e6e4f460e.css │ │ │ ├── app.98bcbd1f507597608a42.js │ │ │ ├── c674eb1df43af0f1bd2f73f629b532fd.jpg │ │ │ ├── cb0daf759635bacb07aed0e1cec43561.jpg │ │ │ ├── eb6bf600f044f7d21f241eb8d6ed0439.jpg │ │ │ ├── font_372689_nw1guejwd2q.js │ │ │ ├── hm.js │ │ │ ├── jweixin-1.3.2.js │ │ │ ├── manifest.17eb82567d34333afd6d.js │ │ │ ├── meiqia.js │ │ │ ├── saved_resource(1).html │ │ │ ├── saved_resource(2).html │ │ │ ├── saved_resource(3).html │ │ │ ├── saved_resource(4).html │ │ │ ├── saved_resource(5).html │ │ │ ├── saved_resource(6).html │ │ │ ├── saved_resource.html │ │ │ ├── sync-cookie.html │ │ │ ├── vendor.aa0daa078f9134c361c2.js │ │ │ └── widget.js │ ├── template │ │ ├── index.html │ │ └── index.js │ └── 本目录属于Node页面服务,也就是BFF架构下Node.js主要发挥的部分 └── 启动方式: 进入client目录和server目录分别启动node进程,然后浏览器访问 localhost:3000?column=3 ├── section32 ├── 1 │ ├── index.js │ └── query.js ├── 2 │ ├── schema.js │ └── server.js ├── package-lock.json └── package.json ├── section33 ├── mock-database.js ├── package-lock.json ├── package.json ├── schema.js ├── server.js └── source │ ├── index.htm │ └── static │ ├── 132 │ ├── 0c54aa0c.jpg │ ├── 23479d05.jpg │ ├── 29841bda.jpg │ ├── 2a4170c2.jpg │ ├── 3edaec82.jpg │ ├── 4.3e6db69f7e47c828bca4.js │ ├── 46a7ef4e.jpg │ ├── 61dfc022.jpg │ ├── 74cf4934.jpg │ ├── 765c1325.jpg │ ├── 7913cdb0.jpg │ ├── 7c12fcc3.jpg │ ├── 83a02223.jpg │ ├── 8b51021d.jpg │ ├── 951a1a46.jpg │ ├── a576bfce.jpg │ ├── a8bb42c0.jpg │ ├── aliplayer-hls-min.js │ ├── aliplayer-min.css │ ├── aliplayer-min.js │ ├── aliplayer-vod-min.js │ ├── analytics.js │ ├── app.39632140dd6cf68f1a0cea8e6e4f460e.css │ ├── app.98bcbd1f507597608a42.js │ ├── f6695148.jpg │ ├── font_372689_nw1guejwd2q.js │ ├── hm.js │ ├── jweixin-1.3.2.js │ ├── manifest.17eb82567d34333afd6d.js │ ├── meiqia.js │ ├── saved_resource(1).html │ ├── saved_resource(2).html │ ├── saved_resource(3).html │ ├── saved_resource(4).html │ ├── saved_resource(5).html │ ├── saved_resource(6).html │ ├── saved_resource.html │ ├── sync-cookie.html │ ├── vendor.aa0daa078f9134c361c2.js │ └── widget.js ├── section35 ├── index.js ├── index.jsx ├── package-lock.json └── package.json ├── section36 ├── backend.js ├── backend │ ├── lib │ │ ├── geeknode-rpc-server.js │ │ └── rpc-server.js │ ├── list.proto │ ├── mockdata │ │ └── column.js │ └── server.js ├── browser │ ├── index.jsx │ └── webpack.config.js ├── component │ ├── column_item.jsx │ └── container.jsx ├── node │ ├── app.jsx │ ├── get-data.js │ ├── index.htm │ ├── index.js │ ├── list-client.js │ ├── list.proto │ ├── source │ │ ├── 12.781e08a04adc7000f826.js │ │ ├── 2703e65de1b7699fffa1754c80985eb5.jpg │ │ ├── 2d5e1c53fd7aa2a8f7663db0dae0ee12.jpg │ │ ├── 42db8ef7b28bcdc26410141dd97b8178.jpg │ │ ├── 4d544deddd94e30924f840eb8b28f48b.jpg │ │ ├── 5ad916cc2f38a4e85e261930c38492fd.jpg │ │ ├── 5ececab2885832a6ef22d1c3b3e61e35.png │ │ ├── 7503b89359b2920c5ad4312a23652cab.jpg │ │ ├── 937c6584122951abcc85f4781028f5b9.jpg │ │ ├── ab5a43490b577940c9e937461b54b563.jpg │ │ ├── aliplayer-min.css │ │ ├── aliplayer-min.js │ │ ├── analytics.js │ │ ├── app.39632140dd6cf68f1a0cea8e6e4f460e.css │ │ ├── app.98bcbd1f507597608a42.js │ │ ├── b683240befccbdcaa86da8f382d3a11a.jpg │ │ ├── c674eb1df43af0f1bd2f73f629b532fd.jpg │ │ ├── ca39e9384b7793c4713dcc762da5f5c0.jpg │ │ ├── dfe48389682b96854d36e161b6e8e487.jpg │ │ ├── dfe9e621882fc283612f4f4deb77d1db.jpg │ │ ├── ed2d0aa1e881ee055ba14f58c9603fe0.jpg │ │ ├── font_372689_nw1guejwd2q.js │ │ ├── hm.js │ │ ├── jweixin-1.3.2.js │ │ ├── mactalk.8a01bbc.png │ │ ├── main.js │ │ ├── manifest.17eb82567d34333afd6d.js │ │ ├── meiqia.js │ │ ├── newcomer-benefits.d8ec0db.png │ │ ├── qrcode.bc44c82.png │ │ ├── saved_resource(1).html │ │ ├── saved_resource(2).html │ │ ├── saved_resource(3).html │ │ ├── saved_resource(4).html │ │ ├── saved_resource(5).html │ │ ├── saved_resource(6).html │ │ ├── saved_resource.html │ │ ├── student-certificate.2a355a2.png │ │ ├── sync-cookie.html │ │ ├── vendor.aa0daa078f9134c361c2.js │ │ └── widget.js │ └── template.js ├── package-lock.json ├── package.json ├── server.js └── 启动方式:分别启动server.js和backend.js,然后浏览器访问 localhost:3000?column=3 ├── section41 ├── binding.gyp ├── build │ ├── Makefile │ ├── Release │ │ ├── .deps │ │ │ └── Release │ │ │ │ ├── obj.target │ │ │ │ └── test │ │ │ │ │ └── index.o.d │ │ │ │ └── test.node.d │ │ ├── obj.target │ │ │ └── test │ │ │ │ └── index.o │ │ └── test.node │ ├── binding.Makefile │ ├── config.gypi │ ├── gyp-mac-tool │ └── test.target.mk ├── index.cc ├── index.js ├── node-serial-benchmark │ ├── .gitignore │ ├── .jshintignore │ ├── .jshintrc │ ├── README.md │ ├── codecs │ │ ├── node-protobuf.js │ │ ├── protobufjs.js │ │ └── protocol-buffers.js │ ├── gen-nodejs │ │ └── user_types.js │ ├── index.js │ ├── input.json │ ├── modules │ │ └── node-protobuf │ │ │ ├── .clang-format │ │ │ ├── .gitattributes │ │ │ ├── .npmignore │ │ │ ├── .travis.yml │ │ │ ├── CHANGES.md │ │ │ ├── Gruntfile.js │ │ │ ├── README.md │ │ │ ├── binding.gyp │ │ │ ├── generate-descriptors.sh │ │ │ ├── lp.sh │ │ │ ├── lpb_release │ │ │ ├── LICENSE │ │ │ ├── include │ │ │ │ └── google │ │ │ │ │ └── protobuf │ │ │ │ │ ├── any.h │ │ │ │ │ ├── any.pb.h │ │ │ │ │ ├── any.proto │ │ │ │ │ ├── api.pb.h │ │ │ │ │ ├── api.proto │ │ │ │ │ ├── arena.h │ │ │ │ │ ├── arenastring.h │ │ │ │ │ ├── compiler │ │ │ │ │ ├── code_generator.h │ │ │ │ │ ├── command_line_interface.h │ │ │ │ │ ├── cpp │ │ │ │ │ │ └── cpp_generator.h │ │ │ │ │ ├── csharp │ │ │ │ │ │ ├── csharp_generator.h │ │ │ │ │ │ └── csharp_names.h │ │ │ │ │ ├── importer.h │ │ │ │ │ ├── java │ │ │ │ │ │ ├── java_generator.h │ │ │ │ │ │ └── java_names.h │ │ │ │ │ ├── javanano │ │ │ │ │ │ └── javanano_generator.h │ │ │ │ │ ├── js │ │ │ │ │ │ └── js_generator.h │ │ │ │ │ ├── objectivec │ │ │ │ │ │ ├── objectivec_generator.h │ │ │ │ │ │ └── objectivec_helpers.h │ │ │ │ │ ├── parser.h │ │ │ │ │ ├── php │ │ │ │ │ │ └── php_generator.h │ │ │ │ │ ├── plugin.h │ │ │ │ │ ├── plugin.pb.h │ │ │ │ │ ├── plugin.proto │ │ │ │ │ ├── python │ │ │ │ │ │ └── python_generator.h │ │ │ │ │ └── ruby │ │ │ │ │ │ └── ruby_generator.h │ │ │ │ │ ├── descriptor.h │ │ │ │ │ ├── descriptor.pb.h │ │ │ │ │ ├── descriptor.proto │ │ │ │ │ ├── descriptor_database.h │ │ │ │ │ ├── duration.pb.h │ │ │ │ │ ├── duration.proto │ │ │ │ │ ├── dynamic_message.h │ │ │ │ │ ├── empty.pb.h │ │ │ │ │ ├── empty.proto │ │ │ │ │ ├── extension_set.h │ │ │ │ │ ├── field_mask.pb.h │ │ │ │ │ ├── field_mask.proto │ │ │ │ │ ├── generated_enum_reflection.h │ │ │ │ │ ├── generated_enum_util.h │ │ │ │ │ ├── generated_message_reflection.h │ │ │ │ │ ├── generated_message_util.h │ │ │ │ │ ├── has_bits.h │ │ │ │ │ ├── io │ │ │ │ │ ├── coded_stream.h │ │ │ │ │ ├── gzip_stream.h │ │ │ │ │ ├── printer.h │ │ │ │ │ ├── strtod.h │ │ │ │ │ ├── tokenizer.h │ │ │ │ │ ├── zero_copy_stream.h │ │ │ │ │ ├── zero_copy_stream_impl.h │ │ │ │ │ └── zero_copy_stream_impl_lite.h │ │ │ │ │ ├── map.h │ │ │ │ │ ├── map_entry.h │ │ │ │ │ ├── map_entry_lite.h │ │ │ │ │ ├── map_field.h │ │ │ │ │ ├── map_field_inl.h │ │ │ │ │ ├── map_field_lite.h │ │ │ │ │ ├── map_type_handler.h │ │ │ │ │ ├── message.h │ │ │ │ │ ├── message_lite.h │ │ │ │ │ ├── metadata.h │ │ │ │ │ ├── reflection.h │ │ │ │ │ ├── reflection_ops.h │ │ │ │ │ ├── repeated_field.h │ │ │ │ │ ├── service.h │ │ │ │ │ ├── source_context.pb.h │ │ │ │ │ ├── source_context.proto │ │ │ │ │ ├── struct.pb.h │ │ │ │ │ ├── struct.proto │ │ │ │ │ ├── stubs │ │ │ │ │ ├── atomic_sequence_num.h │ │ │ │ │ ├── atomicops.h │ │ │ │ │ ├── atomicops_internals_arm64_gcc.h │ │ │ │ │ ├── atomicops_internals_arm_gcc.h │ │ │ │ │ ├── atomicops_internals_arm_qnx.h │ │ │ │ │ ├── atomicops_internals_atomicword_compat.h │ │ │ │ │ ├── atomicops_internals_generic_gcc.h │ │ │ │ │ ├── atomicops_internals_macosx.h │ │ │ │ │ ├── atomicops_internals_mips_gcc.h │ │ │ │ │ ├── atomicops_internals_pnacl.h │ │ │ │ │ ├── atomicops_internals_power.h │ │ │ │ │ ├── atomicops_internals_ppc_gcc.h │ │ │ │ │ ├── atomicops_internals_solaris.h │ │ │ │ │ ├── atomicops_internals_tsan.h │ │ │ │ │ ├── atomicops_internals_x86_gcc.h │ │ │ │ │ ├── atomicops_internals_x86_msvc.h │ │ │ │ │ ├── bytestream.h │ │ │ │ │ ├── callback.h │ │ │ │ │ ├── casts.h │ │ │ │ │ ├── common.h │ │ │ │ │ ├── fastmem.h │ │ │ │ │ ├── hash.h │ │ │ │ │ ├── logging.h │ │ │ │ │ ├── macros.h │ │ │ │ │ ├── mutex.h │ │ │ │ │ ├── once.h │ │ │ │ │ ├── platform_macros.h │ │ │ │ │ ├── port.h │ │ │ │ │ ├── scoped_ptr.h │ │ │ │ │ ├── shared_ptr.h │ │ │ │ │ ├── singleton.h │ │ │ │ │ ├── status.h │ │ │ │ │ ├── stl_util.h │ │ │ │ │ ├── stringpiece.h │ │ │ │ │ ├── template_util.h │ │ │ │ │ └── type_traits.h │ │ │ │ │ ├── text_format.h │ │ │ │ │ ├── timestamp.pb.h │ │ │ │ │ ├── timestamp.proto │ │ │ │ │ ├── type.pb.h │ │ │ │ │ ├── type.proto │ │ │ │ │ ├── unknown_field_set.h │ │ │ │ │ ├── util │ │ │ │ │ ├── field_comparator.h │ │ │ │ │ ├── field_mask_util.h │ │ │ │ │ ├── json_util.h │ │ │ │ │ ├── message_differencer.h │ │ │ │ │ ├── time_util.h │ │ │ │ │ ├── type_resolver.h │ │ │ │ │ └── type_resolver_util.h │ │ │ │ │ ├── wire_format.h │ │ │ │ │ ├── wire_format_lite.h │ │ │ │ │ ├── wire_format_lite_inl.h │ │ │ │ │ ├── wrappers.pb.h │ │ │ │ │ └── wrappers.proto │ │ │ └── lib │ │ │ │ └── libprotobuf.lib │ │ │ ├── package.json │ │ │ ├── protobuf.js │ │ │ ├── run_leak.sh │ │ │ ├── src │ │ │ ├── common.h │ │ │ ├── init.cpp │ │ │ ├── leak.js │ │ │ ├── native.cpp │ │ │ ├── native.h │ │ │ ├── parse.cpp │ │ │ ├── parse.h │ │ │ ├── serialize.cpp │ │ │ └── serialize.h │ │ │ └── test │ │ │ ├── perf │ │ │ ├── perfTest.desc │ │ │ ├── perfTest.js │ │ │ ├── perfTest.proto │ │ │ ├── points.desc │ │ │ ├── points.js │ │ │ └── points.proto │ │ │ ├── test.desc │ │ │ ├── test.js │ │ │ ├── test.proto │ │ │ ├── testUnknown.desc │ │ │ └── testUnknown.proto │ ├── package-lock.json │ ├── package.json │ ├── user.desc │ ├── user.proto │ └── user.thrift ├── package-lock.json └── package.json ├── section42 ├── app.js └── boot.js ├── section50-54 ├── backend │ ├── article.js │ ├── comment-list.js │ ├── comment-praise.js │ ├── detail.js │ ├── lib │ │ ├── geeknode-rpc-server.js │ │ └── rpc-server.js │ ├── mockdata │ │ ├── column.js │ │ └── comment.js │ ├── proto │ │ └── detail.proto │ └── run.js ├── business │ └── play │ │ ├── data.js │ │ └── template.tpl ├── package.json ├── readme.md ├── server │ ├── create-template.js │ ├── request-factory.js │ ├── requestors │ │ ├── geek-rpc.js │ │ └── http.js │ ├── run.js │ └── test.js └── workspace │ ├── build.js │ ├── src │ ├── page.data.js │ ├── play.template.html │ └── proto │ │ └── detail.proto │ └── uploader.js ├── section8 ├── index.js └── spr.js ├── section9 ├── dist │ └── main.js ├── index.js └── lib.js ├── 第一章:课程介绍.pdf ├── 第三章:项目开发篇.pdf ├── 第二章:技术预研篇.pdf ├── 第五章:框架和工程化篇.pdf └── 第四章:性能调优篇.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | afterclass -------------------------------------------------------------------------------- /2021重新整理前的老版本/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | chapter5-bak -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter1/第一章:课程介绍.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter1/第一章:课程介绍.pdf -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/async/a. nonblocking/example.js: -------------------------------------------------------------------------------- 1 | const glob = require('glob'); 2 | 3 | console.time('sync') 4 | const result = glob.sync(__dirname + '/**/*') 5 | console.timeEnd('sync') 6 | console.log(result.length) 7 | 8 | 9 | 10 | console.time('async') 11 | const result2 = glob(__dirname + '/**/*', function (err, result) { 12 | console.log(result.length) 13 | }) 14 | console.timeEnd('async') 15 | // IO完成之前还可以做别的事 16 | console.log('hello geekbang') 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/async/a. nonblocking/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "async-io", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "example.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "glob": "^7.1.4" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/async/b. callback/callback-hell.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 在异步串行任务的情况下代码会变得非常的层层叠叠 3 | */ 4 | 5 | interview(function (err, res) { 6 | if (err) { 7 | console.log('cry at 1') 8 | return; 9 | } 10 | interview(function (err, res) { 11 | if (err) { 12 | console.log('cry at 2') 13 | return; 14 | } 15 | interview(function (err, res) { 16 | if (err) { 17 | console.log('cry at 3') 18 | return; 19 | } 20 | console.log('smile') 21 | }) 22 | }) 23 | }) 24 | 25 | 26 | 27 | function interview(callback) { 28 | setTimeout(() => { 29 | if (Math.random() > 0.2) { 30 | callback(null, 'success') 31 | 32 | } else { 33 | // throw new Error('fail'); 34 | callback(new Error('fail')) 35 | } 36 | 37 | }, 500) 38 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/async/b. callback/error-first.js: -------------------------------------------------------------------------------- 1 | /** 2 | * try catch只能抓到一个调用堆栈内,即一个事件循环里的错误 3 | */ 4 | // try { 5 | interview(function (err, res) { 6 | if (err) { 7 | console.log('cry') 8 | return; 9 | } 10 | console.log('smile') 11 | }) 12 | 13 | // } catch (e) { 14 | // console.log('cry') 15 | // } 16 | 17 | 18 | 19 | function interview(callback) { 20 | 21 | setTimeout(() => { 22 | if (Math.random() > 0.2) { 23 | callback(null, 'success') 24 | 25 | } else { 26 | // throw new Error('fail'); 27 | callback(new Error('fail')) 28 | } 29 | 30 | }, 500) 31 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/async/c. promise/1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * promise的状态转换以及通过then获取内容 3 | */ 4 | const promise = new Promise((resolve, reject) => { 5 | setTimeout(function () { 6 | resolve(3); 7 | // reject(new Error(4)) 8 | }, 500) 9 | }) 10 | 11 | promise 12 | .then(function (result) { 13 | console.log(result) 14 | }) 15 | // .catch(function (err) { 16 | 17 | // }) 18 | 19 | setTimeout(() => { 20 | console.log(promise) 21 | }, 800) -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/async/c. promise/2. PromiseLink.js: -------------------------------------------------------------------------------- 1 | /** 2 | * promise的状态转换以及通过then获取内容 3 | */ 4 | const promise = new Promise((resolve, reject) => { 5 | setTimeout(function () { 6 | reject(new Error(4)) 7 | }, 500) 8 | }) 9 | 10 | promise 11 | // .then(function (result) { 12 | // console.log(result) 13 | // }) 14 | .catch(function (err) { 15 | return 1 16 | }) 17 | 18 | 19 | setTimeout(() => { 20 | console.log(promise); 21 | }, 800) -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/async/c. promise/3. PromiseLinkPromise.js: -------------------------------------------------------------------------------- 1 | /** 2 | * promise的链式调用 3 | */ 4 | 5 | interview(1) 6 | .then(()=> { 7 | return interview(2); 8 | }) 9 | .then(()=> { 10 | return interview(3); 11 | }) 12 | .then(()=> { 13 | if (Math.random() > 0.1) { 14 | const error = new Error('keyboard') 15 | error.round = 'keyboard' 16 | throw error 17 | } 18 | }) 19 | .catch((err)=> { 20 | console.log('cry at ' + err.round) 21 | }) 22 | 23 | 24 | 25 | 26 | 27 | 28 | function interview(round) { 29 | return new Promise((resolve, reject) => { 30 | setTimeout(()=> { 31 | if (Math.random() < 0.2) { 32 | const error = new Error('failed'); 33 | error.round = round; 34 | reject(error); 35 | 36 | } else { 37 | resolve('success'); 38 | } 39 | }, 500) 40 | }) 41 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/commonjs/commonjs初探/index.js: -------------------------------------------------------------------------------- 1 | console.log('start require'); 2 | require('./lib') 3 | console.log('end require'); -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/commonjs/commonjs初探/lib.js: -------------------------------------------------------------------------------- 1 | console.log('this is module'); 2 | 3 | exports.geekbang = { 'hello': 'haha' } 4 | 5 | exports.tencent = function () { 6 | console.log('good') 7 | } 8 | 9 | module.exports = function () { 10 | console.log('hello geekbang'); 11 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/commonjs/eventemitter/geektime.js: -------------------------------------------------------------------------------- 1 | const EventEmitter = require('events').EventEmitter; 2 | 3 | class Geektime extends EventEmitter { 4 | constructor() { 5 | super(); 6 | 7 | setInterval(() => { 8 | this.emit('newlesson', { 9 | price: Math.random() * 100 10 | }) 11 | }, 3000) 12 | } 13 | } 14 | 15 | module.exports = new Geektime; -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/commonjs/eventemitter/index.js: -------------------------------------------------------------------------------- 1 | // 把抛事件的模块封装起来 2 | // 强调抛事件这种模式更适合底层模块往外传递信息 3 | const geektime = require('./geektime'); 4 | 5 | geektime.on('newlesson', ({ price }) => { 6 | console.log('yeah! new lesson') 7 | if (price < 80) { 8 | console.log('buy') 9 | } 10 | }) 11 | 12 | 13 | setTimeout(() => { 14 | // 需要注意的是,EventEmitter如果添加了过多的监听器,Node.js觉得你有内存泄漏嫌疑,会抛出一个warning。 15 | // 用以下这句则可以消除这个限制 16 | // geektime.setMaxListeners(200); 17 | for (let i = 0; i < 100; i++) { 18 | geektime.on('newlesson', ({ price }) => { 19 | }) 20 | } 21 | }, 10000) -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/commonjs/用commonjs优化石头剪刀布游戏/index.js: -------------------------------------------------------------------------------- 1 | 2 | const game = require('./game.js') 3 | 4 | var winCount = 0; 5 | // 获取进程的标准输入 6 | process.stdin.on('data', (buffer) => { 7 | // 回调的是buffer,需要处理成string 8 | const action = buffer.toString().trim(); 9 | const result = game(action); 10 | if (result == 1) { 11 | winCount++ 12 | if (winCount == 3) { 13 | console.log('我不玩儿了!哼!'); 14 | process.exit() 15 | } 16 | } 17 | }) -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/http/express/http/game.js: -------------------------------------------------------------------------------- 1 | module.exports = function (playerAction) { 2 | // 计算电脑出的东西 3 | var computerAction; 4 | var random = Math.random() * 3 5 | if (random < 1) { 6 | computerAction = 'rock' 7 | // console.log('电脑出了石头') 8 | 9 | } else if (random > 2) { 10 | computerAction = 'scissor' 11 | // console.log('电脑出了剪刀') 12 | 13 | } else { 14 | computerAction = 'paper' 15 | // console.log('电脑出了布') 16 | 17 | } 18 | 19 | if (computerAction == playerAction) { 20 | return 0; 21 | 22 | } else if ( 23 | (computerAction == 'rock' && playerAction == 'scissor') || 24 | (computerAction == 'scissor' && playerAction == 'paper') || 25 | (computerAction == 'paper' && playerAction == 'rock') 26 | ) { 27 | return -1; 28 | 29 | } else { 30 | return 1; 31 | } 32 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/http/express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "dependencies": { 7 | "express": "^4.17.1" 8 | }, 9 | "devDependencies": {}, 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "author": "", 14 | "license": "ISC" 15 | } 16 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/http/koa/http/game.js: -------------------------------------------------------------------------------- 1 | module.exports = function (playerAction) { 2 | // 计算电脑出的东西 3 | var computerAction; 4 | var random = Math.random() * 3 5 | if (random < 1) { 6 | computerAction = 'rock' 7 | // console.log('电脑出了石头') 8 | 9 | } else if (random > 2) { 10 | computerAction = 'scissor' 11 | // console.log('电脑出了剪刀') 12 | 13 | } else { 14 | computerAction = 'paper' 15 | // console.log('电脑出了布') 16 | 17 | } 18 | 19 | if (computerAction == playerAction) { 20 | return 0; 21 | 22 | } else if ( 23 | (computerAction == 'rock' && playerAction == 'scissor') || 24 | (computerAction == 'scissor' && playerAction == 'paper') || 25 | (computerAction == 'paper' && playerAction == 'rock') 26 | ) { 27 | return -1; 28 | 29 | } else { 30 | return 1; 31 | } 32 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/http/koa/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "dependencies": { 7 | "koa": "^2.10.0", 8 | "koa-mount": "^4.0.0" 9 | }, 10 | "devDependencies": {}, 11 | "scripts": { 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "author": "", 15 | "license": "ISC" 16 | } 17 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/http/石头剪刀布/game.js: -------------------------------------------------------------------------------- 1 | module.exports = function (playerAction) { 2 | if (['rock', 'scissor', 'paper'].indexOf(playerAction) == -1) { 3 | throw new Error('invalid playerAction'); 4 | } 5 | // 计算电脑出的东西 6 | var computerAction; 7 | var random = Math.random() * 3 8 | if (random < 1) { 9 | computerAction = 'rock' 10 | 11 | } else if (random > 2) { 12 | computerAction = 'scissor' 13 | 14 | } else { 15 | computerAction = 'paper' 16 | 17 | } 18 | 19 | if (computerAction == playerAction) { 20 | return 0; 21 | 22 | } else if ( 23 | (computerAction == 'rock' && playerAction == 'scissor') || 24 | (computerAction == 'scissor' && playerAction == 'paper') || 25 | (computerAction == 'paper' && playerAction == 'rock') 26 | ) { 27 | return -1; 28 | 29 | } else { 30 | return 1; 31 | } 32 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/rpc/buffer/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const protobuf = require('protocol-buffers'); 3 | 4 | // 根据协议,编译出一个js逻辑对象,里面包含encode和decode函数 5 | // 实际写web服务器的时候,注意这个操作可以直接在进程启动就做 6 | // 否则在http处理过程里做的话,是一次不必要的性能消耗 7 | const schemas = protobuf(fs.readFileSync(`${__dirname}/test.proto`)); 8 | 9 | const buffer = 10 | schemas.Course.encode({ 11 | id: 4, 12 | name: 'hh', 13 | lesson: [] 14 | }) 15 | console.log( 16 | buffer 17 | ); 18 | console.log( 19 | schemas.Course.decode(buffer) 20 | ); -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/rpc/buffer/test.proto: -------------------------------------------------------------------------------- 1 | message Course { 2 | required float id = 1; 3 | required string name = 2; 4 | repeated Lesson lesson = 3; 5 | } 6 | 7 | message Lesson { 8 | required float id = 1; 9 | required string title = 2; 10 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/rpc/duplex/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "duplex", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "client.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/rpc/half-duplex/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "duplex", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "client.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/初试&石头剪刀布游戏/index.js: -------------------------------------------------------------------------------- 1 | console.log('hello world') 2 | 3 | console.log(Date) 4 | console.log(Math) 5 | 6 | console.log(setTimeout) 7 | console.log(setInterval) 8 | // console.log(requestAnimationFrame) 9 | 10 | // console.log(document) 11 | 12 | console.log(__dirname) 13 | console.log(__filename) 14 | 15 | console.log(process) -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter2/第二章:技术预研篇.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter2/第二章:技术预研篇.pdf -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/index.js: -------------------------------------------------------------------------------- 1 | const koa = require('koa'); 2 | const fs = require('fs'); 3 | const mount = require('koa-mount'); 4 | const static = require('koa-static'); 5 | 6 | const app = new koa(); 7 | 8 | app.use( 9 | static(__dirname + '/source/') 10 | ); 11 | 12 | app.use( 13 | mount('/', async (ctx) => { 14 | ctx.body = fs.readFileSync(__dirname + '/source/index.htm', 'utf-8') 15 | }) 16 | ); 17 | 18 | 19 | // app.listen(4000); 20 | module.exports = app; -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/code.f041ed7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/code.f041ed7.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/code2.484bdd7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/code2.484bdd7.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/logo.522f12a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/logo.522f12a.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/page1-img1.a023db4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/page1-img1.a023db4.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/page1-img2.b42f242.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/page1-img2.b42f242.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/page1-img3.41e010c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/page1-img3.41e010c.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/page2-bg.af9a743.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/page2-bg.af9a743.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/page2-word5.1645448.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/page2-word5.1645448.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/page3-img1.65fa93c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/page3-img1.65fa93c.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/page3-img2.cbced1f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/page3-img2.cbced1f.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/page3-img3.59afeb0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/page3-img3.59afeb0.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/page4-big.3e14a6f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/page4-big.3e14a6f.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/page4-small.5da02ba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/page4-small.5da02ba.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/page5-img1.bbbbe4a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/page5-img1.bbbbe4a.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/page5-img2.73774ee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/page5-img2.73774ee.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/saved_resource(1).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/saved_resource(2).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
我们在线,来聊聊吧
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/saved_resource(3).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/saved_resource(4).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
您好,当前有专业客服人员在线,让我们来帮助您吧。
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/saved_resource(5).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/saved_resource(6).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
avatar
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/saved_resource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/1.download/source/static/shadow.4c5d43f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/1.download/source/static/shadow.4c5d43f.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/detail.proto: -------------------------------------------------------------------------------- 1 | message Column { 2 | required int32 id = 1; 3 | required string column_cover = 2; 4 | required string column_title = 3; 5 | required string column_subtitle = 4; 6 | required string author_name = 5; 7 | required string author_intro = 6; 8 | required string column_intro = 7; 9 | required string column_unit = 8; 10 | required uint32 sub_count = 9; 11 | required string update_frequency = 10; 12 | required uint32 column_price = 11; 13 | optional uint32 column_price_market = 12; 14 | repeated Article articles = 13; 15 | } 16 | message Article { 17 | required uint32 id = 1; 18 | required bool is_video_preview = 2; 19 | required string article_title = 3; 20 | } 21 | 22 | message ColumnResponse { 23 | required Column column = 1; 24 | repeated Column recommendColumns = 2; 25 | } 26 | message ColumnRequest { 27 | required int32 columnid = 1; 28 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/index.js: -------------------------------------------------------------------------------- 1 | const mount = require('koa-mount'); 2 | const static = require('koa-static') 3 | const app = new (require('koa')); 4 | const rpcClient = require('./client'); 5 | const template = require('./template'); 6 | 7 | const detailTemplate = template(__dirname + '/template/index.html'); 8 | 9 | app.use(mount('/static', static(`${__dirname}/source/static/`))) 10 | 11 | app.use(async (ctx) => { 12 | if (!ctx.query.columnid) { 13 | ctx.status = 400; 14 | ctx.body = 'invalid columnid'; 15 | return 16 | } 17 | 18 | const result = await new Promise((resolve, reject) => { 19 | 20 | rpcClient.write({ 21 | columnid: ctx.query.columnid 22 | }, function (err, data) { 23 | err ? reject(err) : resolve(data) 24 | }) 25 | }) 26 | 27 | ctx.status = 200; 28 | 29 | ctx.body = detailTemplate(result); 30 | }) 31 | 32 | // app.listen(3000) 33 | 34 | module.exports = app; -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/source/static/2aa01da86c8fb550b32c79f8ca4f67b0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/2.detail/source/static/2aa01da86c8fb550b32c79f8ca4f67b0.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/source/static/42db8ef7b28bcdc26410141dd97b8178.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/2.detail/source/static/42db8ef7b28bcdc26410141dd97b8178.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/source/static/995176c4b4cb6c197414430998ad8c9b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/2.detail/source/static/995176c4b4cb6c197414430998ad8c9b.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/source/static/c674eb1df43af0f1bd2f73f629b532fd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/2.detail/source/static/c674eb1df43af0f1bd2f73f629b532fd.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/source/static/cb0daf759635bacb07aed0e1cec43561.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/2.detail/source/static/cb0daf759635bacb07aed0e1cec43561.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/source/static/eb6bf600f044f7d21f241eb8d6ed0439.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/2.detail/source/static/eb6bf600f044f7d21f241eb8d6ed0439.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/source/static/saved_resource(1).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/source/static/saved_resource(2).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
我们在线,来聊聊吧
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/source/static/saved_resource(3).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/source/static/saved_resource(4).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
您好,当前有专业客服人员在线,让我们来帮助您吧。
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/source/static/saved_resource(5).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/source/static/saved_resource(6).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
avatar
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/source/static/saved_resource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/2.detail/template/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const vm = require('vm'); 3 | 4 | const templateCache = {}; 5 | 6 | const templateContext = vm.createContext({ 7 | include: function (name, data) { 8 | const template = templateCache[name] || createTemplate(name) 9 | return template(data); 10 | } 11 | }); 12 | 13 | function createTemplate(templatePath) { 14 | 15 | templateCache[templatePath] = vm.runInContext( 16 | `(function (data) { 17 | with (data) { 18 | return \`${fs.readFileSync(templatePath, 'utf-8')}\` 19 | } 20 | })`, 21 | templateContext 22 | ); 23 | 24 | return templateCache[templatePath] 25 | } 26 | 27 | module.exports = createTemplate -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const app = new (require('koa')); 3 | const mount = require('koa-mount'); 4 | const static = require('koa-static'); 5 | const graphqlHTTP = require('koa-graphql'); 6 | 7 | 8 | app.use( 9 | // 给koa-graphql传一个graphql的协议文件,就会自动帮你生成graphql-api 10 | mount('/api', graphqlHTTP({ 11 | schema: require('./schema') 12 | })) 13 | 14 | ) 15 | 16 | app.use( 17 | mount('/static', static(`${__dirname}/source/static`)) 18 | ) 19 | 20 | app.use( 21 | mount('/', async (ctx) => { 22 | ctx.status = 200; 23 | 24 | ctx.body = fs.readFileSync(`${__dirname}/source/index.htm`, 'utf-8') 25 | }) 26 | ) 27 | 28 | module.exports = app; -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "dependencies": { 7 | "graphql": "^14.5.8", 8 | "koa": "^2.10.0", 9 | "koa-graphql": "^0.8.0", 10 | "koa-mount": "^4.0.0", 11 | "koa-static": "^5.0.0" 12 | }, 13 | "devDependencies": {}, 14 | "scripts": { 15 | "test": "echo \"Error: no test specified\" && exit 1" 16 | }, 17 | "author": "", 18 | "license": "ISC" 19 | } 20 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/schema/comment.gql: -------------------------------------------------------------------------------- 1 | type Comment { 2 | id: Int 3 | avatar: String 4 | name: String 5 | isTop: Boolean 6 | content: String 7 | publishDate: String 8 | commentNum: Int 9 | praiseNum: Int 10 | } 11 | 12 | type Query { 13 | comment: [Comment] 14 | } 15 | 16 | type Mutation { 17 | praise(id: Int): Int 18 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/schema/comment.proto: -------------------------------------------------------------------------------- 1 | message Comment { 2 | required int32 id = 1; 3 | required string avatar = 2; 4 | required string name = 3; 5 | required bool isTop = 4; 6 | required string content = 5; 7 | required string publishDate = 6; 8 | required int32 commentNum = 7; 9 | required int32 praiseNum = 8; 10 | } 11 | 12 | message CommentListResponse { 13 | repeated Comment comments = 1; 14 | } 15 | message CommentListRequest { 16 | repeated int32 columnid = 1; 17 | } 18 | 19 | message PraiseRequest { 20 | required int32 commentid = 1; 21 | } 22 | message PraiseResponse { 23 | required int32 commentid = 1; 24 | required int32 praiseNum = 2; 25 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/0c54aa0c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/0c54aa0c.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/132: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/132 -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/23479d05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/23479d05.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/29841bda.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/29841bda.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/2a4170c2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/2a4170c2.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/3edaec82.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/3edaec82.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/46a7ef4e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/46a7ef4e.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/61dfc022.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/61dfc022.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/74cf4934.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/74cf4934.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/765c1325.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/765c1325.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/7913cdb0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/7913cdb0.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/7c12fcc3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/7c12fcc3.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/83a02223.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/83a02223.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/8b51021d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/8b51021d.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/951a1a46.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/951a1a46.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/a576bfce.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/a576bfce.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/a8bb42c0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/a8bb42c0.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/f6695148.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/3.play/source/static/f6695148.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/saved_resource(1).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/saved_resource(2).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
我们在线,来聊聊吧
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/saved_resource(3).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/saved_resource(4).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
您好,当前有专业客服人员在线,让我们来帮助您吧。
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/saved_resource(5).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/saved_resource(6).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
avatar
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/3.play/source/static/saved_resource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/browser/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | mode: 'development', 3 | devtool: false, 4 | entry: __dirname + '/index.jsx', 5 | output: { 6 | filename: 'main.js', 7 | path: __dirname + '/../node/source/' 8 | }, 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.jsx$/, use: { 13 | loader: 'babel-loader', 14 | options: { 15 | presets: ['@babel/preset-react'] 16 | } 17 | } 18 | } 19 | ] 20 | } 21 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/app.jsx: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const Container = require('../component/container') 3 | 4 | module.exports = function (reactData) { 5 | return { }} 8 | sort={() => { }} 9 | /> 10 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/get-data.js: -------------------------------------------------------------------------------- 1 | const listClient = require('./list-client'); 2 | 3 | module.exports = async function (sortType = 0, filtType = 0) { 4 | 5 | // 使用微服务拉取数据 6 | const data = await new Promise((resolve, reject) => { 7 | listClient.write({ 8 | sortType, 9 | filtType 10 | 11 | }, function (err, res) { 12 | err ? reject(err) : resolve(res.columns); 13 | }) 14 | }); 15 | 16 | return data 17 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/list.proto: -------------------------------------------------------------------------------- 1 | message Column { 2 | required int32 id = 1; 3 | required string column_cover = 2; 4 | required string column_title = 3; 5 | required string column_subtitle = 4; 6 | required string author_name = 5; 7 | required string author_intro = 6; 8 | required string column_intro = 7; 9 | required string column_unit = 8; 10 | required uint32 sub_count = 9; 11 | required string update_frequency = 10; 12 | required uint32 column_price = 11; 13 | required uint32 type = 12; 14 | optional uint32 column_price_market = 13; 15 | repeated Article articles = 14; 16 | } 17 | message Article { 18 | required uint32 id = 1; 19 | required bool is_video_preview = 2; 20 | required string article_title = 3; 21 | } 22 | 23 | message ListResponse { 24 | repeated Column columns = 1; 25 | } 26 | message ListRequest { 27 | required int32 sortType = 1; 28 | required int32 filtType = 2; 29 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/2703e65de1b7699fffa1754c80985eb5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/2703e65de1b7699fffa1754c80985eb5.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/2d5e1c53fd7aa2a8f7663db0dae0ee12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/2d5e1c53fd7aa2a8f7663db0dae0ee12.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/42db8ef7b28bcdc26410141dd97b8178.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/42db8ef7b28bcdc26410141dd97b8178.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/4d544deddd94e30924f840eb8b28f48b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/4d544deddd94e30924f840eb8b28f48b.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/5ad916cc2f38a4e85e261930c38492fd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/5ad916cc2f38a4e85e261930c38492fd.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/5ececab2885832a6ef22d1c3b3e61e35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/5ececab2885832a6ef22d1c3b3e61e35.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/7503b89359b2920c5ad4312a23652cab.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/7503b89359b2920c5ad4312a23652cab.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/937c6584122951abcc85f4781028f5b9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/937c6584122951abcc85f4781028f5b9.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/ab5a43490b577940c9e937461b54b563.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/ab5a43490b577940c9e937461b54b563.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/b683240befccbdcaa86da8f382d3a11a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/b683240befccbdcaa86da8f382d3a11a.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/c674eb1df43af0f1bd2f73f629b532fd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/c674eb1df43af0f1bd2f73f629b532fd.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/ca39e9384b7793c4713dcc762da5f5c0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/ca39e9384b7793c4713dcc762da5f5c0.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/dfe48389682b96854d36e161b6e8e487.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/dfe48389682b96854d36e161b6e8e487.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/dfe9e621882fc283612f4f4deb77d1db.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/dfe9e621882fc283612f4f4deb77d1db.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/ed2d0aa1e881ee055ba14f58c9603fe0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/ed2d0aa1e881ee055ba14f58c9603fe0.jpg -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/mactalk.8a01bbc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/mactalk.8a01bbc.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/newcomer-benefits.d8ec0db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/newcomer-benefits.d8ec0db.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/qrcode.bc44c82.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/qrcode.bc44c82.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/saved_resource(1).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/saved_resource(2).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
我们在线,来聊聊吧
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/saved_resource(3).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/saved_resource(4).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
您好,当前有专业客服人员在线,让我们来帮助您吧。
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/saved_resource(5).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/saved_resource(6).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
avatar
-------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/saved_resource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/source/student-certificate.2a355a2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/4.list/node/source/student-certificate.2a355a2.png -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/4.list/node/template.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const vm = require('vm'); 3 | const path = require('path') 4 | 5 | const templateContext = vm.createContext({}); 6 | // const renderList = createTemplate(__dirname + '/index.htm') 7 | 8 | function createTemplate(templatePath) { 9 | return vm.runInContext( 10 | `(function render(template) { 11 | return function (data) { 12 | with (data) { 13 | return \`${fs.readFileSync(templatePath, 'utf-8')}\` 14 | } 15 | } 16 | })`, 17 | templateContext 18 | )(function (relativePath, data) { 19 | return createTemplate(path.dirname(templatePath) + '/' + relativePath)(data); 20 | }); 21 | } 22 | 23 | module.exports = createTemplate 24 | // console.log(renderList({ courses: listData })); -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/backend/comment-list.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const protobuf = require('protocol-buffers'); 3 | const commentSchemas = protobuf( 4 | fs.readFileSync(`${__dirname}/../3.play/schema/comment.proto`) 5 | ); 6 | 7 | // 假数据 8 | const commentData = require('./mockdata/comment'); 9 | 10 | /** 11 | * 服务端的编解包逻辑 12 | */ 13 | const server = require('./lib/geeknode-rpc-server')(commentSchemas.CommentListRequest, commentSchemas.CommentListResponse); 14 | 15 | server 16 | .createServer((request, response) => { 17 | response.end({ comments: commentData }); 18 | }) 19 | .listen(4001, ()=> { 20 | console.log('rpc server listened: 4001') 21 | }); -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/backend/comment-praise.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const protobuf = require('protocol-buffers'); 3 | const commentSchemas = protobuf( 4 | fs.readFileSync(`${__dirname}/../3.play/schema/comment.proto`) 5 | ); 6 | 7 | // 假数据 8 | const commentData = require('./mockdata/comment'); 9 | 10 | /** 11 | * 服务端的编解包逻辑 12 | */ 13 | const server = require('./lib/geeknode-rpc-server')(commentSchemas.PraiseRequest, commentSchemas.PraiseResponse); 14 | 15 | server 16 | .createServer((request, response) => { 17 | const commentid = request.body.commentid; 18 | const comment = commentData.filter(comment => comment.id == commentid)[0]; 19 | let praiseNum = 0; 20 | 21 | if (comment) { 22 | comment.praiseNum++; 23 | praiseNum = comment.praiseNum; 24 | } 25 | response.end({ 26 | commentid, 27 | praiseNum 28 | }); 29 | }) 30 | .listen(4002, ()=> { 31 | console.log('rpc server listened: 4002') 32 | }); -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/backend/detail.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const protobuf = require('protocol-buffers'); 3 | const schemas = protobuf( 4 | fs.readFileSync(`${__dirname}/../2.detail/detail.proto`) 5 | ); 6 | 7 | // 假数据 8 | const columnData = require('./mockdata/column') 9 | 10 | /** 11 | * 服务端的编解包逻辑 12 | */ 13 | const server = require('./lib/geeknode-rpc-server')(schemas.ColumnRequest, schemas.ColumnResponse); 14 | 15 | server 16 | .createServer((request, response) => { 17 | // 因为都是假数据,这里就没有使用栏目id。真实项目会拿这个columnid去请求数据库 18 | const columnid = request.body; 19 | 20 | // 直接返回假数据 21 | response.end({ 22 | column: columnData[0], 23 | recommendColumns: [columnData[1], columnData[2]] 24 | }); 25 | }) 26 | .listen(4000, ()=> { 27 | console.log('rpc server listened: 4000') 28 | }); -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/backend/mockdata/comment.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | id: 1, 4 | avatar: 'https://static001.geekbang.org/account/avatar/00/0f/52/62/1b3ebed5.jpg', 5 | name: '僵尸浩', 6 | isTop: true, 7 | content: '哈哈哈哈', 8 | publishDate: '今天', 9 | commentNum: 10, 10 | praiseNum: 5 11 | }, 12 | { 13 | id: 2, 14 | avatar: 'https://static001.geekbang.org/account/avatar/00/0f/52/62/1b3ebed5.jpg', 15 | name: '极客主编', 16 | isTop: true, 17 | content: '我来送大礼了!!', 18 | publishDate: '上周', 19 | commentNum: 10, 20 | praiseNum: 2 21 | }, 22 | { 23 | id: 3, 24 | avatar: 'https://static001.geekbang.org/account/avatar/00/0f/52/62/1b3ebed5.jpg', 25 | name: '极客老板', 26 | isTop: true, 27 | content: '我来发股票了!!!', 28 | publishDate: '十年前', 29 | commentNum: 10, 30 | praiseNum: 0 31 | } 32 | ] -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter3", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "bff": "node entry.js", 8 | "microservice": "node server.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@babel/core": "^7.6.4", 14 | "@babel/preset-react": "^7.6.3", 15 | "babel-loader": "^8.0.6", 16 | "babel-preset-react": "^6.24.1", 17 | "babel-register": "^6.26.0", 18 | "easy_sock": "^0.3.8", 19 | "graphql": "^14.5.8", 20 | "koa": "^2.10.0", 21 | "koa-graphql": "^0.8.0", 22 | "koa-mount": "^4.0.0", 23 | "koa-static": "^5.0.0", 24 | "protocol-buffers": "^4.1.0", 25 | "react": "^16.10.2", 26 | "react-dom": "^16.10.2" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/readme.md: -------------------------------------------------------------------------------- 1 | # 先跑npm run microservice 2 | # 再跑npm run bff 3 | # 访问demo页 4 | 1. http://localhost:3000/download/ 5 | 2. http://localhost:3000/detail/?columnid=233 6 | 3. http://localhost:3000/play/ 7 | 4. http://localhost:3000/list/ -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/server.js: -------------------------------------------------------------------------------- 1 | require('./backend/comment-list') 2 | require('./backend/comment-praise') 3 | require('./backend/detail') 4 | require('./backend/list') -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter3/第三章:项目开发篇.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter3/第三章:项目开发篇.pdf -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/caddon/binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | 'targets': [{ 3 | 'target_name': 'test', 4 | 'sources': [ './index.cc' ] 5 | }] 6 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/caddon/build/Release/.deps/Release/test.node.d: -------------------------------------------------------------------------------- 1 | cmd_Release/test.node := c++ -bundle -undefined dynamic_lookup -Wl,-no_pie -Wl,-search_paths_first -mmacosx-version-min=10.10 -arch x86_64 -L./Release -stdlib=libc++ -o Release/test.node Release/obj.target/test/index.o 2 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/caddon/build/Release/obj.target/test/index.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter4/caddon/build/Release/obj.target/test/index.o -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/caddon/build/Release/test.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter4/caddon/build/Release/test.node -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/caddon/build/binding.Makefile: -------------------------------------------------------------------------------- 1 | # This file is generated by gyp; do not edit. 2 | 3 | export builddir_name ?= ./build/. 4 | .PHONY: all 5 | all: 6 | $(MAKE) test 7 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/caddon/index.cc: -------------------------------------------------------------------------------- 1 | // hello.cc 2 | #include 3 | 4 | namespace demo { 5 | 6 | using v8::FunctionCallbackInfo; 7 | using v8::Isolate; 8 | using v8::Local; 9 | using v8::NewStringType; 10 | using v8::Object; 11 | using v8::String; 12 | using v8::Value; 13 | 14 | void Method(const FunctionCallbackInfo& args) { 15 | Isolate* isolate = args.GetIsolate(); 16 | args.GetReturnValue().Set(String::NewFromUtf8( 17 | isolate, "world", NewStringType::kNormal).ToLocalChecked()); 18 | } 19 | 20 | void Initialize(Local exports) { 21 | NODE_SET_METHOD(exports, "hello", Method); 22 | } 23 | 24 | NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize) 25 | 26 | } // namespace demo -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/caddon/index.js: -------------------------------------------------------------------------------- 1 | const test = require('bindings')('test'); 2 | 3 | console.log( 4 | test.hello() 5 | ); -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/caddon/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter4", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "bindings": { 8 | "version": "1.5.0", 9 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", 10 | "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", 11 | "requires": { 12 | "file-uri-to-path": "1.0.0" 13 | } 14 | }, 15 | "file-uri-to-path": { 16 | "version": "1.0.0", 17 | "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", 18 | "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/caddon/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter4", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bindings": "^1.5.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.so 3 | *.o 4 | *.exe 5 | a.out 6 | tmp 7 | log 8 | *.log 9 | build 10 | node_modules 11 | bower_components 12 | .deps 13 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/.jshintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | 4 | "curly": true, 5 | "latedef": true, 6 | "quotmark": true, 7 | "undef": true, 8 | "unused": true, 9 | "trailing": true 10 | } 11 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/codecs/node-protobuf.js: -------------------------------------------------------------------------------- 1 | var protobuf = require('../modules/node-protobuf'); 2 | 3 | var Schema = new protobuf(require('fs').readFileSync('./user.desc')); 4 | 5 | module.exports = { 6 | init: function() { 7 | }, 8 | encode: function(obj) { 9 | return Schema.serialize(obj, "tk.tewi.Data"); 10 | }, 11 | decode: function(data) { 12 | return Schema.parse(data, "tk.tewi.Data"); 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/codecs/protobufjs.js: -------------------------------------------------------------------------------- 1 | var protobufjs = require('protobufjs'); 2 | 3 | var builder = protobufjs.loadProtoFile('./user.proto'); 4 | var User = builder.build('Data'); 5 | 6 | module.exports = { 7 | init: function() { 8 | }, 9 | encode: function(obj) { 10 | var user = new User(); 11 | for (var k in obj) { 12 | user[k] = obj[k]; 13 | } 14 | return user.encode().toBuffer(); 15 | }, 16 | decode: function(data) { 17 | return User.decode(data); 18 | }, 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/codecs/protocol-buffers.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var protocolBuffers = require('protocol-buffers'); 3 | 4 | var Schema = protocolBuffers(fs.readFileSync('./user.proto')); 5 | 6 | module.exports = { 7 | init: function() { 8 | }, 9 | encode: function(obj) { 10 | return Schema.Data.encode(obj); 11 | }, 12 | decode: function(data) { 13 | return Schema.Data.decode(data); 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/input.json: -------------------------------------------------------------------------------- 1 | { 2 | "sender": "shanqingfeng", 3 | "recipient": "hello my name is ...", 4 | "message": "hello my name is ..." 5 | } 6 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/.gitattributes: -------------------------------------------------------------------------------- 1 | text eol=lf -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/.npmignore: -------------------------------------------------------------------------------- 1 | build -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "0.12" 5 | - "4.6.0" 6 | - "6.7.0" 7 | 8 | before_install: 9 | - npm install --production 10 | - npm install mocha 11 | 12 | env: 13 | - CXX=g++-4.8 14 | 15 | addons: 16 | apt: 17 | sources: 18 | - ubuntu-toolchain-r-test 19 | packages: 20 | - g++-4.8 21 | - libprotobuf-dev 22 | 23 | sudo: false 24 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/Gruntfile.js: -------------------------------------------------------------------------------- 1 | /*global module:true*/ 2 | module.exports = function(grunt) { 3 | // Project configuration. 4 | grunt.initConfig({ 5 | 6 | release: { 7 | options: { 8 | npm: true, 9 | tagName: "v<%= version %>", 10 | commitMessage: "Released v<%= version %>", 11 | tagMessage: "Tagged v<%= version %>", 12 | github: { 13 | repo: "fuwaneko/node-protobuf", 14 | accessTokenVar: "GH_ACCESS_TOKEN" 15 | } 16 | } 17 | } 18 | 19 | }); 20 | 21 | grunt.loadNpmTasks("grunt-release"); 22 | }; 23 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/generate-descriptors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for proto in `find . -iname '*.proto' -not -path './node_modules/*'`; do 4 | proto=${proto:2} 5 | protoc --proto_path=./ --include_imports=true --descriptor_set_out=${proto%.*}.desc ${proto} 6 | done 7 | 8 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/lp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #[ -z $LIBPROTOBUF ] && echo `pkg-config --variable=prefix protobuf` || echo $LIBPROTOBUF 3 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/lpb_release/lib/libprotobuf.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/lpb_release/lib/libprotobuf.lib -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-protobuf", 3 | "version": "1.4.3", 4 | "description": "A Node.js protocol buffer wrapper", 5 | "author": "Dmitry Gorbunov = 0.12.0" 15 | ], 16 | "licence": "MIT", 17 | "devDependencies": { 18 | "grunt": "^1.0.0", 19 | "grunt-release": "^0.14.0", 20 | "mocha": "^3.1.0" 21 | }, 22 | "scripts": { 23 | "test": "./node_modules/.bin/mocha ./test/test.js -R spec", 24 | "format": "for source in src/* protobuf.js; do clang-format -style=file -i $source; done" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/run_leak.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | node --expose-gc src/leak.js -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/src/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | using namespace google::protobuf; 20 | using namespace v8; 21 | using namespace node; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/src/init.cpp: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "native.h" 3 | 4 | void init(Local exports) { NativeProtobuf::Init(exports); } 5 | 6 | NODE_MODULE(protobuf, init) 7 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/src/native.h: -------------------------------------------------------------------------------- 1 | #ifndef NATIVE_H 2 | #define NATIVE_H 3 | 4 | #include "common.h" 5 | 6 | class NativeProtobuf : public Nan::ObjectWrap { 7 | public: 8 | static void Init(Local exports); 9 | NativeProtobuf(FileDescriptorSet *descriptors, bool preserve_int64); 10 | 11 | DescriptorPool pool; 12 | std::vector info; 13 | bool preserve_int64; 14 | 15 | private: 16 | DynamicMessageFactory factory; 17 | static NAN_METHOD(New); 18 | static NAN_METHOD(Parse); 19 | static NAN_METHOD(ParseWithUnknown); 20 | static NAN_METHOD(Serialize); 21 | static NAN_METHOD(Info); 22 | }; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/src/serialize.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZE_H 2 | #define SERIALIZE_H 3 | 4 | #include "common.h" 5 | 6 | void SerializeField(google::protobuf::Message *message, const Reflection *r, 7 | const FieldDescriptor *field, Local val, 8 | bool preserve_int64); 9 | int SerializePart(google::protobuf::Message *message, Local subj, 10 | bool preserve_int64); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/test/perf/perfTest.desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/test/perf/perfTest.desc -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/test/perf/perfTest.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message PerfTest { 4 | optional uint64 uint64Field = 1; 5 | optional uint32 uint32Field = 2; 6 | optional string stringField = 3; 7 | optional float floatField = 4; 8 | optional SomeEnum enumField = 5; 9 | optional Data messageField = 6; 10 | optional bool boolField = 7; 11 | 12 | enum SomeEnum { 13 | FIRST = 0; 14 | SECOND = 1; 15 | THIRD = 2; 16 | } 17 | } 18 | 19 | message Data { 20 | required string field1 = 1; 21 | required string field2 = 2; 22 | required string field3 = 3; 23 | } 24 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/test/perf/points.desc: -------------------------------------------------------------------------------- 1 | 2 | Y 3 | test/perf/points.proto" 4 | Point 5 | i ( 6 | j (" 7 | Points 8 | points ( 2.Point -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/test/perf/points.proto: -------------------------------------------------------------------------------- 1 | message Point { 2 | required fixed32 i = 1; 3 | required fixed32 j = 2; 4 | } 5 | message Points { 6 | repeated Point points = 1; 7 | } 8 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/test/test.desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/test/test.desc -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/test/test.proto: -------------------------------------------------------------------------------- 1 | package tk.tewi; 2 | 3 | message Test { 4 | required int64 n64 = 1; 5 | required string name = 2; 6 | optional string value = 3; 7 | optional Data data = 4; 8 | enum Type { 9 | DEFAULT = 1; 10 | SPECIFIC = 2; 11 | } 12 | optional Type type = 5 [default = DEFAULT]; 13 | repeated int32 r = 6 [packed=true]; 14 | } 15 | 16 | message Data { 17 | required string sender = 1; 18 | required string recipient = 2; 19 | required string message = 3; 20 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/test/testUnknown.desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/test/testUnknown.desc -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/modules/node-protobuf/test/testUnknown.proto: -------------------------------------------------------------------------------- 1 | package tk.tewi; 2 | 3 | message Test { 4 | required int64 n64 = 1; 5 | required string name = 2; 6 | optional string value = 3; 7 | optional Data data = 4; 8 | enum Type { 9 | DEFAULT = 1; 10 | SPECIFIC = 2; 11 | } 12 | optional Type type = 5 [default = DEFAULT]; 13 | repeated int32 r = 6 [packed=true]; 14 | optional string iDontBelong = 7; 15 | } 16 | 17 | message Data { 18 | required string sender = 1; 19 | required string recipient = 2; 20 | required string message = 3; 21 | } 22 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-serialization-benchmark", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "lint": "jshint ." 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "jshint": "^2.8.0", 14 | "pomelo-protobuf": "^0.4.0", 15 | "protobufjs": "^4.1.3", 16 | "protocol-buffers": "^3.1.3", 17 | "pson": "^2.0.0", 18 | "thrift": "^0.9.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/user.desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter4/node-serial-benchmark/user.desc -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/user.proto: -------------------------------------------------------------------------------- 1 | message Test { 2 | required int64 n64 = 1; 3 | required string name = 2; 4 | optional string value = 3; 5 | optional Data data = 4; 6 | enum Type { 7 | DEFAULT = 1; 8 | SPECIFIC = 2; 9 | } 10 | optional Type type = 5 [default = DEFAULT]; 11 | repeated int32 r = 6 [packed=true]; 12 | } 13 | 14 | message Data { 15 | required string sender = 1; 16 | required string recipient = 2; 17 | required string message = 3; 18 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/node-serial-benchmark/user.thrift: -------------------------------------------------------------------------------- 1 | struct User { 2 | 1: string name1234567, 3 | 2: i32 age1234567, 4 | 3: i32 sex1234567, 5 | 4: string msg1234567, 6 | } 7 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/process/app.js: -------------------------------------------------------------------------------- 1 | const http = require('http'); 2 | 3 | // console.log(11112222); 4 | module.exports = http.createServer((req, res) => { 5 | res.writeHead(200, { 6 | 'Content-Type': 'text/plain' 7 | }); 8 | res.end('hello world'); 9 | while (true) { } 10 | }).listen(3000, () => { 11 | console.log('listened 3000') 12 | }) -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter4/第四章:性能调优篇.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter4/第四章:性能调优篇.pdf -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/backend/comment-list.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const protobuf = require('protocol-buffers'); 3 | const commentSchemas = protobuf( 4 | fs.readFileSync(`${__dirname}/../proto/comment.proto`) 5 | ); 6 | 7 | // 假数据 8 | const commentData = require('./mockdata/comment'); 9 | 10 | /** 11 | * 服务端的编解包逻辑 12 | */ 13 | const server = require('./lib/geeknode-rpc-server')(commentSchemas.CommentListRequest, commentSchemas.CommentListResponse); 14 | 15 | server 16 | .createServer((request, response) => { 17 | response.end({ comments: commentData }); 18 | }) 19 | .listen(4001, ()=> { 20 | console.log('commentlist rpc server listened: 4001') 21 | }); -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/backend/comment-praise.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const protobuf = require('protocol-buffers'); 3 | const commentSchemas = protobuf( 4 | fs.readFileSync(`${__dirname}/../proto/comment.proto`) 5 | ); 6 | 7 | // 假数据 8 | const commentData = require('./mockdata/comment'); 9 | 10 | /** 11 | * 服务端的编解包逻辑 12 | */ 13 | const server = require('./lib/geeknode-rpc-server')(commentSchemas.PraiseRequest, commentSchemas.PraiseResponse); 14 | 15 | server 16 | .createServer((request, response) => { 17 | const commentid = request.body.commentid; 18 | const comment = commentData.filter(comment => comment.id == commentid)[0]; 19 | let praiseNum = 0; 20 | 21 | if (comment) { 22 | comment.praiseNum++; 23 | praiseNum = comment.praiseNum; 24 | } 25 | response.end({ 26 | commentid, 27 | praiseNum 28 | }); 29 | }) 30 | .listen(4002, ()=> { 31 | console.log('praise rpc server listened: 4002') 32 | }); -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/backend/detail.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const protobuf = require('protocol-buffers'); 3 | const schemas = protobuf( 4 | fs.readFileSync(`${__dirname}/proto/detail.proto`) 5 | ); 6 | 7 | // 假数据 8 | const columnData = require('./mockdata/column') 9 | 10 | /** 11 | * 服务端的编解包逻辑 12 | */ 13 | const server = require('./lib/geeknode-rpc-server')(schemas.ColumnRequest, schemas.ColumnResponse); 14 | 15 | server 16 | .createServer((request, response) => { 17 | // 因为都是假数据,这里就没有使用栏目id。真实项目会拿这个columnid去请求数据库 18 | const columnid = request.body; 19 | 20 | // 直接返回假数据 21 | response.end({ 22 | column: columnData[0], 23 | recommendColumns: [columnData[1], columnData[2]] 24 | }); 25 | }) 26 | .listen(4000, ()=> { 27 | console.log('detail server listened: 4000') 28 | }); -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/backend/mockdata/comment.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | id: 1, 4 | avatar: 'https://static001.geekbang.org/account/avatar/00/0f/52/62/1b3ebed5.jpg', 5 | name: '僵尸浩', 6 | isTop: true, 7 | content: '哈哈哈哈', 8 | publishDate: '今天', 9 | commentNum: 10, 10 | praiseNum: 5 11 | }, 12 | { 13 | id: 2, 14 | avatar: 'https://static001.geekbang.org/account/avatar/00/0f/52/62/1b3ebed5.jpg', 15 | name: '极客主编', 16 | isTop: true, 17 | content: '我来送大礼了!!', 18 | publishDate: '上周', 19 | commentNum: 10, 20 | praiseNum: 2 21 | }, 22 | { 23 | id: 3, 24 | avatar: 'https://static001.geekbang.org/account/avatar/00/0f/52/62/1b3ebed5.jpg', 25 | name: '极客老板', 26 | isTop: true, 27 | content: '我来发股票了!!!', 28 | publishDate: '十年前', 29 | commentNum: 10, 30 | praiseNum: 0 31 | } 32 | ] -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/backend/proto/detail.proto: -------------------------------------------------------------------------------- 1 | message Column { 2 | required int32 id = 1; 3 | required string column_cover = 2; 4 | required string column_title = 3; 5 | required string column_subtitle = 4; 6 | required string author_name = 5; 7 | required string author_intro = 6; 8 | required string column_intro = 7; 9 | required string column_unit = 8; 10 | required uint32 sub_count = 9; 11 | required string update_frequency = 10; 12 | required uint32 column_price = 11; 13 | optional uint32 column_price_market = 12; 14 | repeated Article articles = 13; 15 | } 16 | message Article { 17 | required uint32 id = 1; 18 | required bool is_video_preview = 2; 19 | required string article_title = 3; 20 | } 21 | 22 | message ColumnResponse { 23 | required Column column = 1; 24 | repeated Column recommendColumns = 2; 25 | } 26 | message ColumnRequest { 27 | required int32 columnid = 1; 28 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/backend/run.js: -------------------------------------------------------------------------------- 1 | // require('./backend/comment-list') 2 | // require('./backend/comment-praise') 3 | // require('./backend/article') 4 | require('./detail') 5 | require('./article') -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "refactor", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "easy_sock": "^0.3.8", 13 | "koa": "^2.11.0", 14 | "koa-mount": "^4.0.0", 15 | "memory-fs": "^0.5.0", 16 | "mkdirp": "^0.5.1", 17 | "protocol-buffers": "^4.1.0", 18 | "request": "^2.88.0", 19 | "text-loader": "0.0.1", 20 | "webpack": "^4.41.2" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/readme.md: -------------------------------------------------------------------------------- 1 | * 目录结构 2 | * backend 后端服务内容 3 | * business 业务配置中心,模拟云函数架构存储函数内容的地方 4 | * server 服务端运行逻辑 5 | * workspace 模拟开发者工作空间 6 | 7 | * 运行方式 8 | 先打开终端运行 9 | ``` 10 | node server/test.js 11 | ``` 12 | 13 | 再打开另一个终端运行 14 | ``` 15 | node backend/run.js 16 | ``` 17 | 18 | 然后打开浏览器访问`http://localhost:3000/play?columnid=1` -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/server/create-template.js: -------------------------------------------------------------------------------- 1 | const vm = require('vm'); 2 | 3 | const templateContext = vm.createContext({}); 4 | 5 | function createTemplate(templateContent) { 6 | 7 | return vm.runInContext( 8 | `(function (data) { 9 | with (data) { 10 | return \`${templateContent}\` 11 | } 12 | })`, 13 | templateContext 14 | ); 15 | } 16 | 17 | module.exports = createTemplate -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/server/requestors/http.js: -------------------------------------------------------------------------------- 1 | const request = require('request'); 2 | 3 | let url = ''; 4 | module.exports = { 5 | compile: function (config) { url = config.url }, 6 | request: async function (data) { 7 | 8 | return await new Promise((resolve, reject) => { 9 | request(url, (err, data) => { 10 | err ? reject(err) : resolve(data.body); 11 | }) 12 | }) 13 | } 14 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/server/test.js: -------------------------------------------------------------------------------- 1 | const server = require('./run') 2 | const fs = require('fs'); 3 | 4 | (async function () { 5 | 6 | const data = await new Promise((resolve) => { 7 | fs.readFile( 8 | __dirname + '/../business/play/data.js', "utf-8", 9 | function (err, data) { 10 | resolve(data); 11 | } 12 | ) 13 | }) 14 | const template = await new Promise((resolve) => { 15 | fs.readFile( 16 | __dirname + '/../business/play/template.tpl', "utf-8", 17 | function (err, data) { 18 | resolve(data); 19 | } 20 | ) 21 | }) 22 | 23 | server({ 24 | '/play': { 25 | data, 26 | template 27 | } 28 | }); 29 | })() -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/workspace/build.js: -------------------------------------------------------------------------------- 1 | const uploader = require('./uploader'); 2 | 3 | uploader( 4 | 'play', 5 | __dirname + '/src/page.data.js', 6 | __dirname + '/src/play.template.html' 7 | ) -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/workspace/src/page.data.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | column: { 3 | protocol: 'geek-rpc', 4 | 5 | ip: '127.0.0.1', 6 | 7 | port: 4000, 8 | 9 | protobufFile: require(`${__dirname}/proto/detail.proto`), 10 | 11 | requestStruct: 'ColumnRequest', 12 | responseStruct: 'ColumnResponse', 13 | 14 | then(res) { 15 | return res.column; 16 | } 17 | }, 18 | articleList: { 19 | protocol: 'http', 20 | 21 | url: 'http://127.0.0.1:4003', 22 | 23 | before: function (data) { 24 | return data; 25 | }, 26 | 27 | then: function (res) { 28 | return JSON.parse(res).data.list; 29 | }, 30 | 31 | catch: function () { 32 | 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/workspace/src/proto/detail.proto: -------------------------------------------------------------------------------- 1 | message Column { 2 | required int32 id = 1; 3 | required string column_cover = 2; 4 | required string column_title = 3; 5 | required string column_subtitle = 4; 6 | required string author_name = 5; 7 | required string author_intro = 6; 8 | required string column_intro = 7; 9 | required string column_unit = 8; 10 | required uint32 sub_count = 9; 11 | required string update_frequency = 10; 12 | required uint32 column_price = 11; 13 | optional uint32 column_price_market = 12; 14 | repeated Article articles = 13; 15 | } 16 | message Article { 17 | required uint32 id = 1; 18 | required bool is_video_preview = 2; 19 | required string article_title = 3; 20 | } 21 | 22 | message ColumnResponse { 23 | required Column column = 1; 24 | repeated Column recommendColumns = 2; 25 | } 26 | message ColumnRequest { 27 | required int32 columnid = 1; 28 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/chapter5/第五章:框架和工程化篇.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/2021重新整理前的老版本/chapter5/第五章:框架和工程化篇.pdf -------------------------------------------------------------------------------- /2021重新整理前的老版本/lottery/index.js: -------------------------------------------------------------------------------- 1 | const list = [ 2 | "Objectivezt", 3 | "田大头", 4 | "Geek_d4bf9b", 5 | "筑梦师刘渊", 6 | "数字Gannon", 7 | "🌊", 8 | "朋克是夏天的冰镇雪碧", 9 | "許敲敲", 10 | "tuyu", 11 | "Middleware", 12 | "menghai", 13 | "小北", 14 | "Sky-fly", 15 | "渭河", 16 | "micstone", 17 | "Mr-L.x.D..☻", 18 | "阿秀", 19 | "葛维维", 20 | "许童童", 21 | "1024", 22 | "Serendipity", 23 | "莫奈", 24 | "九", 25 | "Glee", 26 | "如也", 27 | "忘了i.", 28 | "刘彪" 29 | ] 30 | 31 | console.log('恭喜以下几位同学'); 32 | for (let i = 0; i < 3; i++) { 33 | const random = Math.floor(Math.random() * list.length); 34 | 35 | console.log(list[random]); 36 | 37 | list[random] = list[list.length - 1]; 38 | list.length--; 39 | } -------------------------------------------------------------------------------- /2021重新整理前的老版本/readme.md: -------------------------------------------------------------------------------- 1 | # 浏览指引 2 | 3 | 1. 第二章里,每一个小文件夹都是一个demo 4 | 2. 第三章里,整个第三章是一个完整项目,请观看第三章的readme来确定启动方式 5 | 3. 第四章里,每一个小文件夹都是一个demo 6 | 4. 第五章里,整个第五章是一个完整项目,请观看第五章的readme来确定启动方式 -------------------------------------------------------------------------------- /section10/index.js: -------------------------------------------------------------------------------- 1 | const game = require('./game.js') 2 | 3 | var winCount = 0; 4 | // 获取进程的标准输入 5 | process.stdin.on('data', (buffer) => { 6 | // 回调的是buffer,需要处理成string 7 | const action = buffer.toString().trim(); 8 | const result = game(action); 9 | 10 | // 如果结果是玩家胜利 11 | if (result == 1) { 12 | // 记录胜利次数 13 | winCount++ 14 | // 如果达到3 15 | if (winCount == 3) { 16 | console.log('我不玩儿了!哼!'); 17 | process.exit() 18 | } 19 | } 20 | }) -------------------------------------------------------------------------------- /section12/geektime.js: -------------------------------------------------------------------------------- 1 | const EventEmitter = require('events').EventEmitter; 2 | 3 | class Geektime extends EventEmitter { 4 | constructor() { 5 | super(); 6 | 7 | setInterval(() => { 8 | this.emit('newlesson', { 9 | price: Math.random() * 100 10 | }) 11 | }, 3000) 12 | } 13 | } 14 | 15 | module.exports = new Geektime; -------------------------------------------------------------------------------- /section12/index.js: -------------------------------------------------------------------------------- 1 | // 把抛事件的模块封装起来 2 | // 强调抛事件这种模式更适合底层模块往外传递信息 3 | const geektime = require('./geektime'); 4 | 5 | geektime.on('newlesson', ({ price }) => { 6 | console.log('yeah! new lesson') 7 | if (price < 80) { 8 | console.log('buy') 9 | } 10 | }) 11 | 12 | 13 | setTimeout(() => { 14 | // 需要注意的是,EventEmitter如果添加了过多的监听器,Node.js觉得你有内存泄漏嫌疑,会抛出一个warning。 15 | // 用以下这句则可以消除这个限制 16 | // geektime.setMaxListeners(200); 17 | for (let i = 0; i < 100; i++) { 18 | geektime.on('newlesson', ({ price }) => { 19 | }) 20 | } 21 | }, 10000) -------------------------------------------------------------------------------- /section13/glob.js: -------------------------------------------------------------------------------- 1 | const glob = require('glob'); 2 | 3 | console.time('sync') 4 | const result = glob.sync(__dirname + '/**/*') 5 | console.timeEnd('sync') 6 | console.log(result.length) 7 | 8 | 9 | 10 | console.time('async') 11 | const result2 = glob(__dirname + '/**/*', function (err, result) { 12 | console.log(result.length) 13 | }) 14 | console.timeEnd('async') 15 | // IO完成之前还可以做别的事 16 | console.log('hello geekbang') -------------------------------------------------------------------------------- /section13/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "async-io", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "example.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "glob": "^7.1.4" 13 | } 14 | } -------------------------------------------------------------------------------- /section14/callback-hell.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 在异步串行任务的情况下代码会变得非常的层层叠叠 3 | */ 4 | 5 | interview(function (err, res) { 6 | if (err) { 7 | console.log('cry at 1') 8 | return; 9 | } 10 | interview(function (err, res) { 11 | if (err) { 12 | console.log('cry at 2') 13 | return; 14 | } 15 | interview(function (err, res) { 16 | if (err) { 17 | console.log('cry at 3') 18 | return; 19 | } 20 | console.log('smile') 21 | }) 22 | }) 23 | }) 24 | 25 | 26 | 27 | function interview(callback) { 28 | setTimeout(() => { 29 | if (Math.random() > 0.2) { 30 | callback(null, 'success') 31 | 32 | } else { 33 | // throw new Error('fail'); 34 | callback(new Error('fail')) 35 | } 36 | 37 | }, 500) 38 | } -------------------------------------------------------------------------------- /section14/error-first.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 如同视频课程所说 3 | * try catch只能抓到一个调用堆栈内,即一个事件循环里的错误 4 | * 因此此处使用try catch是无效的。 5 | * 6 | * error-first规范即是约定好如果该异步任务出错了 7 | * 错误会在第一个参数里回调出来。 8 | * 9 | */ 10 | // try { 11 | interview(function (err, res) { 12 | if (err) { 13 | console.log('cry') 14 | return; 15 | } 16 | console.log('smile') 17 | }) 18 | 19 | // } catch (e) { 20 | // console.log('cry') 21 | // } 22 | 23 | 24 | 25 | function interview(callback) { 26 | 27 | setTimeout(() => { 28 | if (Math.random() > 0.2) { 29 | callback(null, 'success') 30 | 31 | } else { 32 | // throw new Error('fail'); 33 | callback(new Error('fail')) 34 | } 35 | 36 | }, 500) 37 | } -------------------------------------------------------------------------------- /section16/1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * promise的状态转换以及通过then获取内容 3 | */ 4 | const promise = new Promise((resolve, reject) => { 5 | setTimeout(function () { 6 | resolve(3); 7 | // reject(new Error(4)) 8 | }, 500) 9 | }) 10 | 11 | promise 12 | .then(function (result) { 13 | console.log(result) 14 | }) 15 | // .catch(function (err) { 16 | 17 | // }) 18 | 19 | setTimeout(() => { 20 | console.log(promise) 21 | }, 800) -------------------------------------------------------------------------------- /section16/2.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * promise的状态转换以及通过then获取内容 4 | */ 5 | const promise = new Promise((resolve, reject) => { 6 | setTimeout(function () { 7 | reject(new Error(4)) 8 | }, 500) 9 | }) 10 | 11 | promise 12 | // .then(function (result) { 13 | // console.log(result) 14 | // }) 15 | .catch(function (err) { 16 | return 1 17 | }) 18 | 19 | 20 | setTimeout(() => { 21 | console.log(promise); 22 | }, 800) -------------------------------------------------------------------------------- /section16/3.PromiseLink.js: -------------------------------------------------------------------------------- 1 | /** 2 | * promise的链式调用 3 | * 4 | * 每次.then和.catch返回都是创建了一个新的Promise 5 | */ 6 | interview(1) 7 | .then(() => { 8 | return interview(2); 9 | }) 10 | .then(() => { 11 | return interview(3); 12 | }) 13 | .then(() => { 14 | if (Math.random() > 0.1) { 15 | const error = new Error('keyboard') 16 | error.round = 'keyboard' 17 | throw error 18 | } 19 | }) 20 | .catch((err) => { 21 | console.log('cry at ' + err.round) 22 | }) 23 | 24 | 25 | 26 | 27 | 28 | 29 | function interview(round) { 30 | return new Promise((resolve, reject) => { 31 | setTimeout(() => { 32 | if (Math.random() < 0.2) { 33 | const error = new Error('failed'); 34 | error.round = round; 35 | reject(error); 36 | 37 | } else { 38 | resolve('success'); 39 | } 40 | }, 500) 41 | }) 42 | } -------------------------------------------------------------------------------- /section19/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | hello geekbang! 5 | 6 | -------------------------------------------------------------------------------- /section19/index.js: -------------------------------------------------------------------------------- 1 | const http = require('http'); 2 | const fs = require('fs'); 3 | 4 | http 5 | .createServer(function (req, res) { 6 | if (req.url == '/favicon.ico') { 7 | res.writeHead(200); 8 | res.end(); 9 | return; 10 | } 11 | 12 | res.writeHead(200); 13 | fs.createReadStream(__dirname + '/index.html') 14 | .pipe(res); 15 | }) 16 | .listen(3000); -------------------------------------------------------------------------------- /section20/game.js: -------------------------------------------------------------------------------- 1 | module.exports = function (playerAction) { 2 | if (['rock', 'scissor', 'paper'].indexOf(playerAction) == -1) { 3 | throw new Error('invalid playerAction'); 4 | } 5 | // 计算电脑出的东西 6 | var computerAction; 7 | var random = Math.random() * 3 8 | if (random < 1) { 9 | computerAction = 'rock' 10 | 11 | } else if (random > 2) { 12 | computerAction = 'scissor' 13 | 14 | } else { 15 | computerAction = 'paper' 16 | 17 | } 18 | 19 | if (computerAction == playerAction) { 20 | return 0; 21 | 22 | } else if ( 23 | (computerAction == 'rock' && playerAction == 'scissor') || 24 | (computerAction == 'scissor' && playerAction == 'paper') || 25 | (computerAction == 'paper' && playerAction == 'rock') 26 | ) { 27 | return -1; 28 | 29 | } else { 30 | return 1; 31 | } 32 | } -------------------------------------------------------------------------------- /section21/game.js: -------------------------------------------------------------------------------- 1 | module.exports = function (playerAction) { 2 | // 计算电脑出的东西 3 | var computerAction; 4 | var random = Math.random() * 3 5 | if (random < 1) { 6 | computerAction = 'rock' 7 | // console.log('电脑出了石头') 8 | 9 | } else if (random > 2) { 10 | computerAction = 'scissor' 11 | // console.log('电脑出了剪刀') 12 | 13 | } else { 14 | computerAction = 'paper' 15 | // console.log('电脑出了布') 16 | 17 | } 18 | 19 | if (computerAction == playerAction) { 20 | return 0; 21 | 22 | } else if ( 23 | (computerAction == 'rock' && playerAction == 'scissor') || 24 | (computerAction == 'scissor' && playerAction == 'paper') || 25 | (computerAction == 'paper' && playerAction == 'rock') 26 | ) { 27 | return -1; 28 | 29 | } else { 30 | return 1; 31 | } 32 | } -------------------------------------------------------------------------------- /section21/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "section21", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.17.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /section22/game.js: -------------------------------------------------------------------------------- 1 | module.exports = function (playerAction) { 2 | // 计算电脑出的东西 3 | var computerAction; 4 | var random = Math.random() * 3 5 | if (random < 1) { 6 | computerAction = 'rock' 7 | // console.log('电脑出了石头') 8 | 9 | } else if (random > 2) { 10 | computerAction = 'scissor' 11 | // console.log('电脑出了剪刀') 12 | 13 | } else { 14 | computerAction = 'paper' 15 | // console.log('电脑出了布') 16 | 17 | } 18 | 19 | if (computerAction == playerAction) { 20 | return 0; 21 | 22 | } else if ( 23 | (computerAction == 'rock' && playerAction == 'scissor') || 24 | (computerAction == 'scissor' && playerAction == 'paper') || 25 | (computerAction == 'paper' && playerAction == 'rock') 26 | ) { 27 | return -1; 28 | 29 | } else { 30 | return 1; 31 | } 32 | } -------------------------------------------------------------------------------- /section22/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "section22", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "koa": "^2.13.1", 13 | "koa-mount": "^4.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /section24/buffer.js: -------------------------------------------------------------------------------- 1 | const buffer1 = Buffer.from('geekbang'); 2 | const buffer2 = Buffer.from([1, 2, 3, 4]); 3 | 4 | const buffer3 = Buffer.alloc(20); 5 | 6 | console.log(buffer1); 7 | console.log(buffer2); 8 | console.log(buffer3); 9 | 10 | buffer2.writeInt8(12, 1); 11 | console.log(buffer2); 12 | buffer2.writeInt16LE(512, 2); 13 | console.log(buffer2); -------------------------------------------------------------------------------- /section24/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "section24", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "buffer.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "protocol-buffers": "^4.2.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /section24/protobuf.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const protobuf = require('protocol-buffers'); 3 | 4 | // 根据协议,编译出一个js逻辑对象,里面包含encode和decode函数 5 | // 实际写web服务器的时候,注意这个操作可以直接在进程启动就做 6 | // 否则在http处理过程里做的话,是一次不必要的性能消耗 7 | const schemas = protobuf(fs.readFileSync(`${__dirname}/test.proto`)); 8 | 9 | const buffer = 10 | schemas.Course.encode({ 11 | id: 4, 12 | name: 'hh', 13 | lesson: [] 14 | }) 15 | console.log( 16 | buffer 17 | ); 18 | console.log( 19 | schemas.Course.decode(buffer) 20 | ); -------------------------------------------------------------------------------- /section24/test.proto: -------------------------------------------------------------------------------- 1 | message Course { 2 | required float id = 1; 3 | required string name = 2; 4 | repeated Lesson lesson = 3; 5 | } 6 | 7 | message Lesson { 8 | required float id = 1; 9 | required string title = 2; 10 | } -------------------------------------------------------------------------------- /section25/simplex/client.js: -------------------------------------------------------------------------------- 1 | const net = require('net'); 2 | 3 | const socket = new net.Socket({}); 4 | 5 | socket.connect({ 6 | host: '127.0.0.1', 7 | port: 4000 8 | }) 9 | 10 | socket.write('good morning geekbang'); -------------------------------------------------------------------------------- /section25/simplex/server.js: -------------------------------------------------------------------------------- 1 | const net = require('net'); 2 | 3 | const server = net.createServer((socket)=> { 4 | socket.on('data', function(buffer) { 5 | console.log(buffer, buffer.toString()) 6 | }) 7 | }); 8 | 9 | server.listen(4000); -------------------------------------------------------------------------------- /section25/本节的例子需要启动node client.js和node server.js两个node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section25/本节的例子需要启动node client.js和node server.js两个node -------------------------------------------------------------------------------- /section27/index.js: -------------------------------------------------------------------------------- 1 | const koa = require('koa'); 2 | const fs = require('fs'); 3 | const mount = require('koa-mount'); 4 | const static = require('koa-static'); 5 | 6 | const app = new koa(); 7 | 8 | app.use( 9 | static(__dirname + '/source/') 10 | ); 11 | 12 | app.use( 13 | mount('/', async (ctx) => { 14 | ctx.body = fs.readFileSync(__dirname + '/source/index.htm', 'utf-8') 15 | }) 16 | ); 17 | 18 | 19 | // app.listen(4000); 20 | module.exports = app; -------------------------------------------------------------------------------- /section27/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "section27", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "koa": "^2.13.1", 13 | "koa-mount": "^4.0.0", 14 | "koa-static": "^5.0.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /section27/source/static/code.f041ed7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/code.f041ed7.png -------------------------------------------------------------------------------- /section27/source/static/code2.484bdd7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/code2.484bdd7.png -------------------------------------------------------------------------------- /section27/source/static/logo.522f12a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/logo.522f12a.png -------------------------------------------------------------------------------- /section27/source/static/page1-img1.a023db4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/page1-img1.a023db4.png -------------------------------------------------------------------------------- /section27/source/static/page1-img2.b42f242.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/page1-img2.b42f242.png -------------------------------------------------------------------------------- /section27/source/static/page1-img3.41e010c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/page1-img3.41e010c.png -------------------------------------------------------------------------------- /section27/source/static/page2-bg.af9a743.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/page2-bg.af9a743.png -------------------------------------------------------------------------------- /section27/source/static/page2-word5.1645448.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/page2-word5.1645448.png -------------------------------------------------------------------------------- /section27/source/static/page3-img1.65fa93c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/page3-img1.65fa93c.png -------------------------------------------------------------------------------- /section27/source/static/page3-img2.cbced1f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/page3-img2.cbced1f.png -------------------------------------------------------------------------------- /section27/source/static/page3-img3.59afeb0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/page3-img3.59afeb0.png -------------------------------------------------------------------------------- /section27/source/static/page4-big.3e14a6f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/page4-big.3e14a6f.png -------------------------------------------------------------------------------- /section27/source/static/page4-small.5da02ba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/page4-small.5da02ba.png -------------------------------------------------------------------------------- /section27/source/static/page5-img1.bbbbe4a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/page5-img1.bbbbe4a.png -------------------------------------------------------------------------------- /section27/source/static/page5-img2.73774ee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/page5-img2.73774ee.png -------------------------------------------------------------------------------- /section27/source/static/saved_resource(1).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /section27/source/static/saved_resource(2).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
我们在线,来聊聊吧
-------------------------------------------------------------------------------- /section27/source/static/saved_resource(3).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /section27/source/static/saved_resource(4).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
您好,当前有专业客服人员在线,让我们来帮助您吧。
-------------------------------------------------------------------------------- /section27/source/static/saved_resource(5).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /section27/source/static/saved_resource(6).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
avatar
-------------------------------------------------------------------------------- /section27/source/static/saved_resource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /section27/source/static/shadow.4c5d43f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section27/source/static/shadow.4c5d43f.png -------------------------------------------------------------------------------- /section29/index.js: -------------------------------------------------------------------------------- 1 | const user = { 2 | name: ' -------------------------------------------------------------------------------- /section30/node-client/template/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const vm = require('vm'); 3 | 4 | const templateCache = {}; 5 | 6 | const templateContext = vm.createContext({ 7 | include: function (name, data) { 8 | const template = templateCache[name] || createTemplate(name) 9 | return template(data); 10 | } 11 | }); 12 | 13 | function createTemplate(templatePath) { 14 | 15 | templateCache[templatePath] = vm.runInContext( 16 | `(function (data) { 17 | with (data) { 18 | return \`${fs.readFileSync(templatePath, 'utf-8')}\` 19 | } 20 | })`, 21 | templateContext 22 | ); 23 | 24 | return templateCache[templatePath] 25 | } 26 | 27 | module.exports = createTemplate -------------------------------------------------------------------------------- /section30/node-client/本目录属于Node页面服务,也就是BFF架构下Node.js主要发挥的部分: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section30/node-client/本目录属于Node页面服务,也就是BFF架构下Node.js主要发挥的部分 -------------------------------------------------------------------------------- /section30/启动方式: 进入client目录和server目录分别启动node进程,然后浏览器访问 localhost:3000?column=3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section30/启动方式: 进入client目录和server目录分别启动node进程,然后浏览器访问 localhost:3000?column=3 -------------------------------------------------------------------------------- /section32/1/index.js: -------------------------------------------------------------------------------- 1 | const query = require('./query'); 2 | 3 | query('{ hello }').then(res=> { 4 | console.log(res); 5 | }) -------------------------------------------------------------------------------- /section32/1/query.js: -------------------------------------------------------------------------------- 1 | var { graphql, buildSchema } = require('graphql'); 2 | 3 | // Construct a schema, using GraphQL schema language 4 | var schema = buildSchema(` 5 | type Query { 6 | hello: String 7 | } 8 | `); 9 | 10 | // The root provides a resolver function for each API endpoint 11 | var root = { 12 | hello: () => { 13 | return 'Hello world!'; 14 | }, 15 | }; 16 | 17 | 18 | module.exports = function(query) { 19 | // Run the GraphQL query '{ hello }' and print out the response 20 | return graphql(schema, query, root).then((response) => { 21 | return response; 22 | }); 23 | } -------------------------------------------------------------------------------- /section32/2/schema.js: -------------------------------------------------------------------------------- 1 | const { graphql, buildSchema } = require('graphql'); 2 | 3 | const schema = buildSchema(` 4 | type Comment { 5 | id: Int 6 | avatar: String 7 | name: String 8 | isTop: Boolean 9 | content: String 10 | publishDate: String 11 | commentNum: Int 12 | praiseNum: Int 13 | } 14 | type Query { 15 | comment: [Comment] 16 | } 17 | `) 18 | 19 | schema.getQueryType().getFields().comment.resolve = () => { 20 | return [{ 21 | id: 1, 22 | avatar: "https://static001.geekbang.org/account/avatar/00/0f/52/62/1b3ebed5.jpg", 23 | name: "僵尸浩", 24 | isTop: true, 25 | content: "哈哈哈哈", 26 | publishDate: "今天", 27 | commentNum: 10, 28 | praiseNum: 5 29 | }] 30 | } 31 | 32 | module.exports = schema; -------------------------------------------------------------------------------- /section32/2/server.js: -------------------------------------------------------------------------------- 1 | const app = new (require('koa')); 2 | const graphqlHTTP = require('koa-graphql'); 3 | 4 | 5 | app.use( 6 | graphqlHTTP({ 7 | schema: require('./schema') 8 | }) 9 | ) 10 | 11 | app.listen(3000); -------------------------------------------------------------------------------- /section32/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "section32", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "graphql": "^15.5.1", 13 | "koa": "^2.13.1", 14 | "koa-graphql": "^0.9.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /section33/mock-database.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 1: { 3 | id: 1, 4 | avatar: 'https://static001.geekbang.org/account/avatar/00/0f/52/62/1b3ebed5.jpg', 5 | name: '僵尸浩', 6 | isTop: true, 7 | content: '哈哈哈哈', 8 | publishDate: '今天', 9 | commentNum: 10, 10 | praiseNum: 5 11 | }, 12 | 2: { 13 | id: 2, 14 | avatar: 'https://static001.geekbang.org/account/avatar/00/0f/52/62/1b3ebed5.jpg', 15 | name: '极客主编', 16 | isTop: true, 17 | content: '我来送大礼了!!', 18 | publishDate: '上周', 19 | commentNum: 10, 20 | praiseNum: 2 21 | }, 22 | 3: { 23 | id: 3, 24 | avatar: 'https://static001.geekbang.org/account/avatar/00/0f/52/62/1b3ebed5.jpg', 25 | name: '极客老板', 26 | isTop: true, 27 | content: '我来发股票了!!!', 28 | publishDate: '十年前', 29 | commentNum: 10, 30 | praiseNum: 0 31 | } 32 | } -------------------------------------------------------------------------------- /section33/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "section33", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "graphql": "^15.5.1", 13 | "koa": "^2.13.1", 14 | "koa-graphql": "^0.9.0", 15 | "koa-mount": "^4.0.0", 16 | "koa-static": "^5.0.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /section33/schema.js: -------------------------------------------------------------------------------- 1 | const { graphql, buildSchema } = require('graphql'); 2 | const mockDatabase = require('./mock-database') 3 | 4 | const schema = buildSchema(` 5 | type Comment { 6 | id: Int 7 | avatar: String 8 | name: String 9 | isTop: Boolean 10 | content: String 11 | publishDate: String 12 | commentNum: Int 13 | praiseNum: Int 14 | } 15 | type Query { 16 | comment: [Comment] 17 | } 18 | type Mutation { 19 | praise(id: Int): Int 20 | } 21 | `) 22 | 23 | schema.getQueryType().getFields().comment.resolve = () => { 24 | return Object.keys(mockDatabase).map(key=> { 25 | return mockDatabase[key]; 26 | }) 27 | } 28 | schema.getMutationType().getFields().praise.resolve = (args0, { id }) => { 29 | mockDatabase[id].praiseNum++; 30 | 31 | return mockDatabase[id].praiseNum 32 | } 33 | 34 | module.exports = schema; -------------------------------------------------------------------------------- /section33/server.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const app = new (require('koa')); 3 | const mount = require('koa-mount'); 4 | const static = require('koa-static'); 5 | const graphqlHTTP = require('koa-graphql'); 6 | 7 | 8 | app.use( 9 | // 给koa-graphql传一个graphql的协议文件,就会自动帮你生成graphql-api 10 | mount('/api', graphqlHTTP({ 11 | schema: require('./schema') 12 | })) 13 | 14 | ) 15 | 16 | app.use( 17 | mount('/static', static(`${__dirname}/source/static`)) 18 | ) 19 | 20 | app.use( 21 | mount('/', async (ctx) => { 22 | ctx.status = 200; 23 | 24 | ctx.body = fs.readFileSync(`${__dirname}/source/index.htm`, 'utf-8') 25 | }) 26 | ) 27 | 28 | // module.exports = app; 29 | app.listen(3000) -------------------------------------------------------------------------------- /section33/source/static/0c54aa0c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/0c54aa0c.jpg -------------------------------------------------------------------------------- /section33/source/static/132: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/132 -------------------------------------------------------------------------------- /section33/source/static/23479d05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/23479d05.jpg -------------------------------------------------------------------------------- /section33/source/static/29841bda.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/29841bda.jpg -------------------------------------------------------------------------------- /section33/source/static/2a4170c2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/2a4170c2.jpg -------------------------------------------------------------------------------- /section33/source/static/3edaec82.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/3edaec82.jpg -------------------------------------------------------------------------------- /section33/source/static/46a7ef4e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/46a7ef4e.jpg -------------------------------------------------------------------------------- /section33/source/static/61dfc022.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/61dfc022.jpg -------------------------------------------------------------------------------- /section33/source/static/74cf4934.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/74cf4934.jpg -------------------------------------------------------------------------------- /section33/source/static/765c1325.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/765c1325.jpg -------------------------------------------------------------------------------- /section33/source/static/7913cdb0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/7913cdb0.jpg -------------------------------------------------------------------------------- /section33/source/static/7c12fcc3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/7c12fcc3.jpg -------------------------------------------------------------------------------- /section33/source/static/83a02223.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/83a02223.jpg -------------------------------------------------------------------------------- /section33/source/static/8b51021d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/8b51021d.jpg -------------------------------------------------------------------------------- /section33/source/static/951a1a46.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/951a1a46.jpg -------------------------------------------------------------------------------- /section33/source/static/a576bfce.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/a576bfce.jpg -------------------------------------------------------------------------------- /section33/source/static/a8bb42c0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/a8bb42c0.jpg -------------------------------------------------------------------------------- /section33/source/static/f6695148.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section33/source/static/f6695148.jpg -------------------------------------------------------------------------------- /section33/source/static/saved_resource(1).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /section33/source/static/saved_resource(2).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
我们在线,来聊聊吧
-------------------------------------------------------------------------------- /section33/source/static/saved_resource(3).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /section33/source/static/saved_resource(4).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
您好,当前有专业客服人员在线,让我们来帮助您吧。
-------------------------------------------------------------------------------- /section33/source/static/saved_resource(5).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /section33/source/static/saved_resource(6).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
avatar
-------------------------------------------------------------------------------- /section33/source/static/saved_resource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /section35/index.js: -------------------------------------------------------------------------------- 1 | require("@babel/register")({ 2 | presets: ['@babel/preset-react'] 3 | }) 4 | const ReactDOMServer = require('react-dom/server'); 5 | 6 | console.log( 7 | ReactDOMServer.renderToString( 8 | require('./index.jsx') 9 | ) 10 | ) -------------------------------------------------------------------------------- /section35/index.jsx: -------------------------------------------------------------------------------- 1 | const React = require('react'); 2 | 3 | class App extends React.Component { 4 | 5 | render() { 6 | return ( 7 |

8 | ) 9 | } 10 | } 11 | 12 | module.exports = -------------------------------------------------------------------------------- /section35/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "section35", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@babel/core": "^7.15.0", 13 | "@babel/preset-react": "^7.14.5", 14 | "@babel/register": "^7.15.3", 15 | "react": "^17.0.2", 16 | "react-dom": "^17.0.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /section36/backend.js: -------------------------------------------------------------------------------- 1 | require('./backend/server'); -------------------------------------------------------------------------------- /section36/backend/list.proto: -------------------------------------------------------------------------------- 1 | message Column { 2 | required int32 id = 1; 3 | required string column_cover = 2; 4 | required string column_title = 3; 5 | required string column_subtitle = 4; 6 | required string author_name = 5; 7 | required string author_intro = 6; 8 | required string column_intro = 7; 9 | required string column_unit = 8; 10 | required uint32 sub_count = 9; 11 | required string update_frequency = 10; 12 | required uint32 column_price = 11; 13 | required uint32 type = 12; 14 | optional uint32 column_price_market = 13; 15 | repeated Article articles = 14; 16 | } 17 | message Article { 18 | required uint32 id = 1; 19 | required bool is_video_preview = 2; 20 | required string article_title = 3; 21 | } 22 | 23 | message ListResponse { 24 | repeated Column columns = 1; 25 | } 26 | message ListRequest { 27 | required int32 sortType = 1; 28 | required int32 filtType = 2; 29 | } -------------------------------------------------------------------------------- /section36/browser/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | mode: 'development', 3 | devtool: false, 4 | entry: __dirname + '/index.jsx', 5 | output: { 6 | filename: 'main.js', 7 | path: __dirname + '/../node/source/' 8 | }, 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.jsx$/, use: { 13 | loader: 'babel-loader', 14 | options: { 15 | presets: ['@babel/preset-react'] 16 | } 17 | } 18 | } 19 | ] 20 | } 21 | } -------------------------------------------------------------------------------- /section36/node/app.jsx: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const Container = require('../component/container.jsx') 3 | 4 | module.exports = function (reactData) { 5 | return { }} 8 | sort={() => { }} 9 | /> 10 | } -------------------------------------------------------------------------------- /section36/node/get-data.js: -------------------------------------------------------------------------------- 1 | const listClient = require('./list-client'); 2 | 3 | module.exports = async function (sortType = 0, filtType = 0) { 4 | 5 | // 使用微服务拉取数据 6 | const data = await new Promise((resolve, reject) => { 7 | listClient.write({ 8 | sortType, 9 | filtType 10 | 11 | }, function (err, res) { 12 | err ? reject(err) : resolve(res.columns); 13 | }) 14 | }); 15 | 16 | return data 17 | } -------------------------------------------------------------------------------- /section36/node/list.proto: -------------------------------------------------------------------------------- 1 | message Column { 2 | required int32 id = 1; 3 | required string column_cover = 2; 4 | required string column_title = 3; 5 | required string column_subtitle = 4; 6 | required string author_name = 5; 7 | required string author_intro = 6; 8 | required string column_intro = 7; 9 | required string column_unit = 8; 10 | required uint32 sub_count = 9; 11 | required string update_frequency = 10; 12 | required uint32 column_price = 11; 13 | required uint32 type = 12; 14 | optional uint32 column_price_market = 13; 15 | repeated Article articles = 14; 16 | } 17 | message Article { 18 | required uint32 id = 1; 19 | required bool is_video_preview = 2; 20 | required string article_title = 3; 21 | } 22 | 23 | message ListResponse { 24 | repeated Column columns = 1; 25 | } 26 | message ListRequest { 27 | required int32 sortType = 1; 28 | required int32 filtType = 2; 29 | } -------------------------------------------------------------------------------- /section36/node/source/2703e65de1b7699fffa1754c80985eb5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/2703e65de1b7699fffa1754c80985eb5.jpg -------------------------------------------------------------------------------- /section36/node/source/2d5e1c53fd7aa2a8f7663db0dae0ee12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/2d5e1c53fd7aa2a8f7663db0dae0ee12.jpg -------------------------------------------------------------------------------- /section36/node/source/42db8ef7b28bcdc26410141dd97b8178.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/42db8ef7b28bcdc26410141dd97b8178.jpg -------------------------------------------------------------------------------- /section36/node/source/4d544deddd94e30924f840eb8b28f48b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/4d544deddd94e30924f840eb8b28f48b.jpg -------------------------------------------------------------------------------- /section36/node/source/5ad916cc2f38a4e85e261930c38492fd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/5ad916cc2f38a4e85e261930c38492fd.jpg -------------------------------------------------------------------------------- /section36/node/source/5ececab2885832a6ef22d1c3b3e61e35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/5ececab2885832a6ef22d1c3b3e61e35.png -------------------------------------------------------------------------------- /section36/node/source/7503b89359b2920c5ad4312a23652cab.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/7503b89359b2920c5ad4312a23652cab.jpg -------------------------------------------------------------------------------- /section36/node/source/937c6584122951abcc85f4781028f5b9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/937c6584122951abcc85f4781028f5b9.jpg -------------------------------------------------------------------------------- /section36/node/source/ab5a43490b577940c9e937461b54b563.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/ab5a43490b577940c9e937461b54b563.jpg -------------------------------------------------------------------------------- /section36/node/source/b683240befccbdcaa86da8f382d3a11a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/b683240befccbdcaa86da8f382d3a11a.jpg -------------------------------------------------------------------------------- /section36/node/source/c674eb1df43af0f1bd2f73f629b532fd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/c674eb1df43af0f1bd2f73f629b532fd.jpg -------------------------------------------------------------------------------- /section36/node/source/ca39e9384b7793c4713dcc762da5f5c0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/ca39e9384b7793c4713dcc762da5f5c0.jpg -------------------------------------------------------------------------------- /section36/node/source/dfe48389682b96854d36e161b6e8e487.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/dfe48389682b96854d36e161b6e8e487.jpg -------------------------------------------------------------------------------- /section36/node/source/dfe9e621882fc283612f4f4deb77d1db.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/dfe9e621882fc283612f4f4deb77d1db.jpg -------------------------------------------------------------------------------- /section36/node/source/ed2d0aa1e881ee055ba14f58c9603fe0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/ed2d0aa1e881ee055ba14f58c9603fe0.jpg -------------------------------------------------------------------------------- /section36/node/source/mactalk.8a01bbc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/mactalk.8a01bbc.png -------------------------------------------------------------------------------- /section36/node/source/newcomer-benefits.d8ec0db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/newcomer-benefits.d8ec0db.png -------------------------------------------------------------------------------- /section36/node/source/qrcode.bc44c82.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/qrcode.bc44c82.png -------------------------------------------------------------------------------- /section36/node/source/saved_resource(1).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /section36/node/source/saved_resource(2).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
我们在线,来聊聊吧
-------------------------------------------------------------------------------- /section36/node/source/saved_resource(3).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /section36/node/source/saved_resource(4).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
您好,当前有专业客服人员在线,让我们来帮助您吧。
-------------------------------------------------------------------------------- /section36/node/source/saved_resource(5).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /section36/node/source/saved_resource(6).html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
avatar
-------------------------------------------------------------------------------- /section36/node/source/saved_resource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /section36/node/source/student-certificate.2a355a2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/node/source/student-certificate.2a355a2.png -------------------------------------------------------------------------------- /section36/node/template.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const vm = require('vm'); 3 | const path = require('path') 4 | 5 | const templateContext = vm.createContext({}); 6 | // const renderList = createTemplate(__dirname + '/index.htm') 7 | 8 | function createTemplate(templatePath) { 9 | return vm.runInContext( 10 | `(function render() { 11 | return function (data) { 12 | with (data) { 13 | return \`${fs.readFileSync(templatePath, 'utf-8')}\` 14 | } 15 | } 16 | })`, 17 | templateContext 18 | )(function (relativePath, data) { 19 | return createTemplate()(data); 20 | }); 21 | } 22 | 23 | module.exports = createTemplate 24 | // console.log(renderList({ courses: listData })); -------------------------------------------------------------------------------- /section36/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@babel/core": "^7.15.0", 13 | "@babel/preset-react": "^7.14.5", 14 | "@babel/register": "^7.15.3", 15 | "easy_sock": "^0.4.1", 16 | "koa": "^2.13.1", 17 | "koa-mount": "^4.0.0", 18 | "koa-static": "^5.0.0", 19 | "protocol-buffers": "^4.2.0", 20 | "react": "^17.0.2", 21 | "react-dom": "^17.0.2" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /section36/server.js: -------------------------------------------------------------------------------- 1 | require('@babel/register')({ 2 | presets: ['@babel/preset-react'] 3 | }); 4 | require('./node') -------------------------------------------------------------------------------- /section36/启动方式:分别启动server.js和backend.js,然后浏览器访问 localhost:3000?column=3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section36/启动方式:分别启动server.js和backend.js,然后浏览器访问 localhost:3000?column=3 -------------------------------------------------------------------------------- /section41/binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | 'targets': [{ 3 | 'target_name': 'test', 4 | 'sources': [ './index.cc' ] 5 | }] 6 | } -------------------------------------------------------------------------------- /section41/build/Release/.deps/Release/test.node.d: -------------------------------------------------------------------------------- 1 | cmd_Release/test.node := c++ -bundle -undefined dynamic_lookup -Wl,-no_pie -Wl,-search_paths_first -mmacosx-version-min=10.10 -arch x86_64 -L./Release -stdlib=libc++ -o Release/test.node Release/obj.target/test/index.o 2 | -------------------------------------------------------------------------------- /section41/build/Release/obj.target/test/index.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section41/build/Release/obj.target/test/index.o -------------------------------------------------------------------------------- /section41/build/Release/test.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section41/build/Release/test.node -------------------------------------------------------------------------------- /section41/build/binding.Makefile: -------------------------------------------------------------------------------- 1 | # This file is generated by gyp; do not edit. 2 | 3 | export builddir_name ?= ./build/. 4 | .PHONY: all 5 | all: 6 | $(MAKE) test 7 | -------------------------------------------------------------------------------- /section41/index.cc: -------------------------------------------------------------------------------- 1 | // hello.cc 2 | #include 3 | 4 | namespace demo { 5 | 6 | using v8::FunctionCallbackInfo; 7 | using v8::Isolate; 8 | using v8::Local; 9 | using v8::NewStringType; 10 | using v8::Object; 11 | using v8::String; 12 | using v8::Value; 13 | 14 | void Method(const FunctionCallbackInfo& args) { 15 | Isolate* isolate = args.GetIsolate(); 16 | args.GetReturnValue().Set(String::NewFromUtf8( 17 | isolate, "world", NewStringType::kNormal).ToLocalChecked()); 18 | } 19 | 20 | void Initialize(Local exports) { 21 | NODE_SET_METHOD(exports, "hello", Method); 22 | } 23 | 24 | NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize) 25 | 26 | } // namespace demo -------------------------------------------------------------------------------- /section41/index.js: -------------------------------------------------------------------------------- 1 | const test = require('bindings')('test'); 2 | 3 | console.log( 4 | test.hello() 5 | ); -------------------------------------------------------------------------------- /section41/node-serial-benchmark/.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.so 3 | *.o 4 | *.exe 5 | a.out 6 | tmp 7 | log 8 | *.log 9 | build 10 | node_modules 11 | bower_components 12 | .deps 13 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/.jshintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | 4 | "curly": true, 5 | "latedef": true, 6 | "quotmark": true, 7 | "undef": true, 8 | "unused": true, 9 | "trailing": true 10 | } 11 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/codecs/node-protobuf.js: -------------------------------------------------------------------------------- 1 | var protobuf = require('../modules/node-protobuf'); 2 | 3 | var Schema = new protobuf(require('fs').readFileSync('./user.desc')); 4 | 5 | module.exports = { 6 | init: function() { 7 | }, 8 | encode: function(obj) { 9 | return Schema.serialize(obj, "tk.tewi.Data"); 10 | }, 11 | decode: function(data) { 12 | return Schema.parse(data, "tk.tewi.Data"); 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/codecs/protobufjs.js: -------------------------------------------------------------------------------- 1 | var protobufjs = require('protobufjs'); 2 | 3 | var builder = protobufjs.loadProtoFile('./user.proto'); 4 | var User = builder.build('Data'); 5 | 6 | module.exports = { 7 | init: function() { 8 | }, 9 | encode: function(obj) { 10 | var user = new User(); 11 | for (var k in obj) { 12 | user[k] = obj[k]; 13 | } 14 | return user.encode().toBuffer(); 15 | }, 16 | decode: function(data) { 17 | return User.decode(data); 18 | }, 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/codecs/protocol-buffers.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var protocolBuffers = require('protocol-buffers'); 3 | 4 | var Schema = protocolBuffers(fs.readFileSync('./user.proto')); 5 | 6 | module.exports = { 7 | init: function() { 8 | }, 9 | encode: function(obj) { 10 | return Schema.Data.encode(obj); 11 | }, 12 | decode: function(data) { 13 | return Schema.Data.decode(data); 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/input.json: -------------------------------------------------------------------------------- 1 | { 2 | "sender": "shanqingfeng", 3 | "recipient": "hello my name is ...", 4 | "message": "hello my name is ..." 5 | } 6 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/.gitattributes: -------------------------------------------------------------------------------- 1 | text eol=lf -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/.npmignore: -------------------------------------------------------------------------------- 1 | build -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "0.12" 5 | - "4.6.0" 6 | - "6.7.0" 7 | 8 | before_install: 9 | - npm install --production 10 | - npm install mocha 11 | 12 | env: 13 | - CXX=g++-4.8 14 | 15 | addons: 16 | apt: 17 | sources: 18 | - ubuntu-toolchain-r-test 19 | packages: 20 | - g++-4.8 21 | - libprotobuf-dev 22 | 23 | sudo: false 24 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/Gruntfile.js: -------------------------------------------------------------------------------- 1 | /*global module:true*/ 2 | module.exports = function(grunt) { 3 | // Project configuration. 4 | grunt.initConfig({ 5 | 6 | release: { 7 | options: { 8 | npm: true, 9 | tagName: "v<%= version %>", 10 | commitMessage: "Released v<%= version %>", 11 | tagMessage: "Tagged v<%= version %>", 12 | github: { 13 | repo: "fuwaneko/node-protobuf", 14 | accessTokenVar: "GH_ACCESS_TOKEN" 15 | } 16 | } 17 | } 18 | 19 | }); 20 | 21 | grunt.loadNpmTasks("grunt-release"); 22 | }; 23 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/generate-descriptors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for proto in `find . -iname '*.proto' -not -path './node_modules/*'`; do 4 | proto=${proto:2} 5 | protoc --proto_path=./ --include_imports=true --descriptor_set_out=${proto%.*}.desc ${proto} 6 | done 7 | 8 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/lp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #[ -z $LIBPROTOBUF ] && echo `pkg-config --variable=prefix protobuf` || echo $LIBPROTOBUF 3 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/lpb_release/lib/libprotobuf.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section41/node-serial-benchmark/modules/node-protobuf/lpb_release/lib/libprotobuf.lib -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-protobuf", 3 | "version": "1.4.3", 4 | "description": "A Node.js protocol buffer wrapper", 5 | "author": "Dmitry Gorbunov = 0.12.0" 15 | ], 16 | "licence": "MIT", 17 | "devDependencies": { 18 | "grunt": "^1.0.0", 19 | "grunt-release": "^0.14.0", 20 | "mocha": "^3.1.0" 21 | }, 22 | "scripts": { 23 | "test": "./node_modules/.bin/mocha ./test/test.js -R spec", 24 | "format": "for source in src/* protobuf.js; do clang-format -style=file -i $source; done" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/run_leak.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | node --expose-gc src/leak.js -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/src/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | using namespace google::protobuf; 20 | using namespace v8; 21 | using namespace node; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/src/init.cpp: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "native.h" 3 | 4 | void init(Local exports) { NativeProtobuf::Init(exports); } 5 | 6 | NODE_MODULE(protobuf, init) 7 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/src/native.h: -------------------------------------------------------------------------------- 1 | #ifndef NATIVE_H 2 | #define NATIVE_H 3 | 4 | #include "common.h" 5 | 6 | class NativeProtobuf : public Nan::ObjectWrap { 7 | public: 8 | static void Init(Local exports); 9 | NativeProtobuf(FileDescriptorSet *descriptors, bool preserve_int64); 10 | 11 | DescriptorPool pool; 12 | std::vector info; 13 | bool preserve_int64; 14 | 15 | private: 16 | DynamicMessageFactory factory; 17 | static NAN_METHOD(New); 18 | static NAN_METHOD(Parse); 19 | static NAN_METHOD(ParseWithUnknown); 20 | static NAN_METHOD(Serialize); 21 | static NAN_METHOD(Info); 22 | }; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/src/serialize.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZE_H 2 | #define SERIALIZE_H 3 | 4 | #include "common.h" 5 | 6 | void SerializeField(google::protobuf::Message *message, const Reflection *r, 7 | const FieldDescriptor *field, Local val, 8 | bool preserve_int64); 9 | int SerializePart(google::protobuf::Message *message, Local subj, 10 | bool preserve_int64); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/test/perf/perfTest.desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section41/node-serial-benchmark/modules/node-protobuf/test/perf/perfTest.desc -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/test/perf/perfTest.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | var p = require("../../protobuf"); 3 | var desc = fs.readFileSync(__dirname + "/perfTest.desc"); 4 | var pb = new p(desc); 5 | 6 | var message = { 7 | uint64Field: Date.now(), 8 | uint32Field: Date.now() / 1000, 9 | stringField: 'sample string value', 10 | floatField: 1.23456789012345, 11 | enumField: 'THIRD', 12 | boolField: true, 13 | messageField: { 14 | field1: 'value1', 15 | field2: 'value2', 16 | field3: 'value3' 17 | } 18 | }; 19 | 20 | console.log('serializing and parsing a message 1,000,000 times...'); 21 | 22 | console.time('serialize'); 23 | for (var i = 0; i < 1000000; i++) { 24 | var serPB = pb.serialize(message, 'PerfTest'); 25 | } 26 | console.timeEnd('serialize'); 27 | 28 | var buffer = pb.serialize(message, 'PerfTest'); 29 | console.time('parse'); 30 | for (var i = 0; i < 1000000; i++) { 31 | var deserPB = pb.parse(buffer, 'PerfTest'); 32 | } 33 | console.timeEnd('parse'); 34 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/test/perf/perfTest.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message PerfTest { 4 | optional uint64 uint64Field = 1; 5 | optional uint32 uint32Field = 2; 6 | optional string stringField = 3; 7 | optional float floatField = 4; 8 | optional SomeEnum enumField = 5; 9 | optional Data messageField = 6; 10 | optional bool boolField = 7; 11 | 12 | enum SomeEnum { 13 | FIRST = 0; 14 | SECOND = 1; 15 | THIRD = 2; 16 | } 17 | } 18 | 19 | message Data { 20 | required string field1 = 1; 21 | required string field2 = 2; 22 | required string field3 = 3; 23 | } 24 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/test/perf/points.desc: -------------------------------------------------------------------------------- 1 | 2 | Y 3 | test/perf/points.proto" 4 | Point 5 | i ( 6 | j (" 7 | Points 8 | points ( 2.Point -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/test/perf/points.proto: -------------------------------------------------------------------------------- 1 | message Point { 2 | required fixed32 i = 1; 3 | required fixed32 j = 2; 4 | } 5 | message Points { 6 | repeated Point points = 1; 7 | } 8 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/test/test.desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section41/node-serial-benchmark/modules/node-protobuf/test/test.desc -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/test/test.proto: -------------------------------------------------------------------------------- 1 | package tk.tewi; 2 | 3 | message Test { 4 | required int64 n64 = 1; 5 | required string name = 2; 6 | optional string value = 3; 7 | optional Data data = 4; 8 | enum Type { 9 | DEFAULT = 1; 10 | SPECIFIC = 2; 11 | } 12 | optional Type type = 5 [default = DEFAULT]; 13 | repeated int32 r = 6 [packed=true]; 14 | } 15 | 16 | message Data { 17 | required string sender = 1; 18 | required string recipient = 2; 19 | required string message = 3; 20 | } -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/test/testUnknown.desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section41/node-serial-benchmark/modules/node-protobuf/test/testUnknown.desc -------------------------------------------------------------------------------- /section41/node-serial-benchmark/modules/node-protobuf/test/testUnknown.proto: -------------------------------------------------------------------------------- 1 | package tk.tewi; 2 | 3 | message Test { 4 | required int64 n64 = 1; 5 | required string name = 2; 6 | optional string value = 3; 7 | optional Data data = 4; 8 | enum Type { 9 | DEFAULT = 1; 10 | SPECIFIC = 2; 11 | } 12 | optional Type type = 5 [default = DEFAULT]; 13 | repeated int32 r = 6 [packed=true]; 14 | optional string iDontBelong = 7; 15 | } 16 | 17 | message Data { 18 | required string sender = 1; 19 | required string recipient = 2; 20 | required string message = 3; 21 | } 22 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-serialization-benchmark", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "lint": "jshint ." 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "jshint": "^2.8.0", 14 | "pomelo-protobuf": "^0.4.0", 15 | "protobufjs": "^4.1.3", 16 | "protocol-buffers": "^3.1.3", 17 | "pson": "^2.0.0", 18 | "thrift": "^0.9.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /section41/node-serial-benchmark/user.desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/section41/node-serial-benchmark/user.desc -------------------------------------------------------------------------------- /section41/node-serial-benchmark/user.proto: -------------------------------------------------------------------------------- 1 | message Test { 2 | required int64 n64 = 1; 3 | required string name = 2; 4 | optional string value = 3; 5 | optional Data data = 4; 6 | enum Type { 7 | DEFAULT = 1; 8 | SPECIFIC = 2; 9 | } 10 | optional Type type = 5 [default = DEFAULT]; 11 | repeated int32 r = 6 [packed=true]; 12 | } 13 | 14 | message Data { 15 | required string sender = 1; 16 | required string recipient = 2; 17 | required string message = 3; 18 | } -------------------------------------------------------------------------------- /section41/node-serial-benchmark/user.thrift: -------------------------------------------------------------------------------- 1 | struct User { 2 | 1: string name1234567, 3 | 2: i32 age1234567, 4 | 3: i32 sex1234567, 5 | 4: string msg1234567, 6 | } 7 | -------------------------------------------------------------------------------- /section41/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter4", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "bindings": { 8 | "version": "1.5.0", 9 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", 10 | "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", 11 | "requires": { 12 | "file-uri-to-path": "1.0.0" 13 | } 14 | }, 15 | "file-uri-to-path": { 16 | "version": "1.0.0", 17 | "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", 18 | "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /section41/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter4", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bindings": "^1.5.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /section42/app.js: -------------------------------------------------------------------------------- 1 | const http = require('http'); 2 | 3 | // console.log(11112222); 4 | module.exports = http.createServer((req, res) => { 5 | res.writeHead(200, { 6 | 'Content-Type': 'text/plain' 7 | }); 8 | res.end('hello world'); 9 | while (true) { } 10 | }).listen(3000, () => { 11 | console.log('listened 3000') 12 | }) -------------------------------------------------------------------------------- /section50-54/backend/comment-list.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const protobuf = require('protocol-buffers'); 3 | const commentSchemas = protobuf( 4 | fs.readFileSync(`${__dirname}/../proto/comment.proto`) 5 | ); 6 | 7 | // 假数据 8 | const commentData = require('./mockdata/comment'); 9 | 10 | /** 11 | * 服务端的编解包逻辑 12 | */ 13 | const server = require('./lib/geeknode-rpc-server')(commentSchemas.CommentListRequest, commentSchemas.CommentListResponse); 14 | 15 | server 16 | .createServer((request, response) => { 17 | response.end({ comments: commentData }); 18 | }) 19 | .listen(4001, ()=> { 20 | console.log('commentlist rpc server listened: 4001') 21 | }); -------------------------------------------------------------------------------- /section50-54/backend/comment-praise.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const protobuf = require('protocol-buffers'); 3 | const commentSchemas = protobuf( 4 | fs.readFileSync(`${__dirname}/../proto/comment.proto`) 5 | ); 6 | 7 | // 假数据 8 | const commentData = require('./mockdata/comment'); 9 | 10 | /** 11 | * 服务端的编解包逻辑 12 | */ 13 | const server = require('./lib/geeknode-rpc-server')(commentSchemas.PraiseRequest, commentSchemas.PraiseResponse); 14 | 15 | server 16 | .createServer((request, response) => { 17 | const commentid = request.body.commentid; 18 | const comment = commentData.filter(comment => comment.id == commentid)[0]; 19 | let praiseNum = 0; 20 | 21 | if (comment) { 22 | comment.praiseNum++; 23 | praiseNum = comment.praiseNum; 24 | } 25 | response.end({ 26 | commentid, 27 | praiseNum 28 | }); 29 | }) 30 | .listen(4002, ()=> { 31 | console.log('praise rpc server listened: 4002') 32 | }); -------------------------------------------------------------------------------- /section50-54/backend/detail.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const protobuf = require('protocol-buffers'); 3 | const schemas = protobuf( 4 | fs.readFileSync(`${__dirname}/proto/detail.proto`) 5 | ); 6 | 7 | // 假数据 8 | const columnData = require('./mockdata/column') 9 | 10 | /** 11 | * 服务端的编解包逻辑 12 | */ 13 | const server = require('./lib/geeknode-rpc-server')(schemas.ColumnRequest, schemas.ColumnResponse); 14 | 15 | server 16 | .createServer((request, response) => { 17 | // 因为都是假数据,这里就没有使用栏目id。真实项目会拿这个columnid去请求数据库 18 | const columnid = request.body; 19 | 20 | // 直接返回假数据 21 | response.end({ 22 | column: columnData[0], 23 | recommendColumns: [columnData[1], columnData[2]] 24 | }); 25 | }) 26 | .listen(4000, ()=> { 27 | console.log('detail server listened: 4000') 28 | }); -------------------------------------------------------------------------------- /section50-54/backend/mockdata/comment.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | id: 1, 4 | avatar: 'https://static001.geekbang.org/account/avatar/00/0f/52/62/1b3ebed5.jpg', 5 | name: '僵尸浩', 6 | isTop: true, 7 | content: '哈哈哈哈', 8 | publishDate: '今天', 9 | commentNum: 10, 10 | praiseNum: 5 11 | }, 12 | { 13 | id: 2, 14 | avatar: 'https://static001.geekbang.org/account/avatar/00/0f/52/62/1b3ebed5.jpg', 15 | name: '极客主编', 16 | isTop: true, 17 | content: '我来送大礼了!!', 18 | publishDate: '上周', 19 | commentNum: 10, 20 | praiseNum: 2 21 | }, 22 | { 23 | id: 3, 24 | avatar: 'https://static001.geekbang.org/account/avatar/00/0f/52/62/1b3ebed5.jpg', 25 | name: '极客老板', 26 | isTop: true, 27 | content: '我来发股票了!!!', 28 | publishDate: '十年前', 29 | commentNum: 10, 30 | praiseNum: 0 31 | } 32 | ] -------------------------------------------------------------------------------- /section50-54/backend/proto/detail.proto: -------------------------------------------------------------------------------- 1 | message Column { 2 | required int32 id = 1; 3 | required string column_cover = 2; 4 | required string column_title = 3; 5 | required string column_subtitle = 4; 6 | required string author_name = 5; 7 | required string author_intro = 6; 8 | required string column_intro = 7; 9 | required string column_unit = 8; 10 | required uint32 sub_count = 9; 11 | required string update_frequency = 10; 12 | required uint32 column_price = 11; 13 | optional uint32 column_price_market = 12; 14 | repeated Article articles = 13; 15 | } 16 | message Article { 17 | required uint32 id = 1; 18 | required bool is_video_preview = 2; 19 | required string article_title = 3; 20 | } 21 | 22 | message ColumnResponse { 23 | required Column column = 1; 24 | repeated Column recommendColumns = 2; 25 | } 26 | message ColumnRequest { 27 | required int32 columnid = 1; 28 | } -------------------------------------------------------------------------------- /section50-54/backend/run.js: -------------------------------------------------------------------------------- 1 | // require('./backend/comment-list') 2 | // require('./backend/comment-praise') 3 | // require('./backend/article') 4 | require('./detail') 5 | require('./article') -------------------------------------------------------------------------------- /section50-54/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "refactor", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "easy_sock": "^0.3.8", 13 | "koa": "^2.11.0", 14 | "koa-mount": "^4.0.0", 15 | "memory-fs": "^0.5.0", 16 | "mkdirp": "^0.5.1", 17 | "protocol-buffers": "^4.1.0", 18 | "request": "^2.88.0", 19 | "text-loader": "0.0.1", 20 | "webpack": "^4.41.2" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /section50-54/readme.md: -------------------------------------------------------------------------------- 1 | * 目录结构 2 | * backend 后端服务内容 3 | * business 业务配置中心,模拟云函数架构存储函数内容的地方 4 | * server 服务端运行逻辑 5 | * workspace 模拟开发者工作空间 6 | 7 | * 运行方式 8 | 先打开终端运行 9 | ``` 10 | node server/test.js 11 | ``` 12 | 13 | 再打开另一个终端运行 14 | ``` 15 | node backend/run.js 16 | ``` 17 | 18 | 然后打开浏览器访问`http://localhost:3000/play?columnid=1` -------------------------------------------------------------------------------- /section50-54/server/create-template.js: -------------------------------------------------------------------------------- 1 | const vm = require('vm'); 2 | 3 | const templateContext = vm.createContext({}); 4 | 5 | function createTemplate(templateContent) { 6 | 7 | return vm.runInContext( 8 | `(function (data) { 9 | with (data) { 10 | return \`${templateContent}\` 11 | } 12 | })`, 13 | templateContext 14 | ); 15 | } 16 | 17 | module.exports = createTemplate -------------------------------------------------------------------------------- /section50-54/server/requestors/http.js: -------------------------------------------------------------------------------- 1 | const request = require('request'); 2 | 3 | let url = ''; 4 | module.exports = { 5 | compile: function (config) { url = config.url }, 6 | request: async function (data) { 7 | 8 | return await new Promise((resolve, reject) => { 9 | request(url, (err, data) => { 10 | err ? reject(err) : resolve(data.body); 11 | }) 12 | }) 13 | } 14 | } -------------------------------------------------------------------------------- /section50-54/server/test.js: -------------------------------------------------------------------------------- 1 | const server = require('./run') 2 | const fs = require('fs'); 3 | 4 | (async function () { 5 | 6 | const data = await new Promise((resolve) => { 7 | fs.readFile( 8 | __dirname + '/../business/play/data.js', "utf-8", 9 | function (err, data) { 10 | resolve(data); 11 | } 12 | ) 13 | }) 14 | const template = await new Promise((resolve) => { 15 | fs.readFile( 16 | __dirname + '/../business/play/template.tpl', "utf-8", 17 | function (err, data) { 18 | resolve(data); 19 | } 20 | ) 21 | }) 22 | 23 | server({ 24 | '/play': { 25 | data, 26 | template 27 | } 28 | }); 29 | })() -------------------------------------------------------------------------------- /section50-54/workspace/build.js: -------------------------------------------------------------------------------- 1 | const uploader = require('./uploader'); 2 | 3 | uploader( 4 | 'play', 5 | __dirname + '/src/page.data.js', 6 | __dirname + '/src/play.template.html' 7 | ) -------------------------------------------------------------------------------- /section50-54/workspace/src/page.data.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | column: { 3 | protocol: 'geek-rpc', 4 | 5 | ip: '127.0.0.1', 6 | 7 | port: 4000, 8 | 9 | protobufFile: require(`${__dirname}/proto/detail.proto`), 10 | 11 | requestStruct: 'ColumnRequest', 12 | responseStruct: 'ColumnResponse', 13 | 14 | then(res) { 15 | return res.column; 16 | } 17 | }, 18 | articleList: { 19 | protocol: 'http', 20 | 21 | url: 'http://127.0.0.1:4003', 22 | 23 | before: function (data) { 24 | return data; 25 | }, 26 | 27 | then: function (res) { 28 | return JSON.parse(res).data.list; 29 | }, 30 | 31 | catch: function () { 32 | 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /section50-54/workspace/src/proto/detail.proto: -------------------------------------------------------------------------------- 1 | message Column { 2 | required int32 id = 1; 3 | required string column_cover = 2; 4 | required string column_title = 3; 5 | required string column_subtitle = 4; 6 | required string author_name = 5; 7 | required string author_intro = 6; 8 | required string column_intro = 7; 9 | required string column_unit = 8; 10 | required uint32 sub_count = 9; 11 | required string update_frequency = 10; 12 | required uint32 column_price = 11; 13 | optional uint32 column_price_market = 12; 14 | repeated Article articles = 13; 15 | } 16 | message Article { 17 | required uint32 id = 1; 18 | required bool is_video_preview = 2; 19 | required string article_title = 3; 20 | } 21 | 22 | message ColumnResponse { 23 | required Column column = 1; 24 | repeated Column recommendColumns = 2; 25 | } 26 | message ColumnRequest { 27 | required int32 columnid = 1; 28 | } -------------------------------------------------------------------------------- /section8/index.js: -------------------------------------------------------------------------------- 1 | console.log('hello world!'); 2 | 3 | console.log(Date); 4 | console.log(Math); 5 | 6 | console.log(setTimeout); 7 | console.log(setInterval); 8 | // console.log(requestAnimationFrame) 9 | console.log(setImmediate); 10 | 11 | console.log(__filename); 12 | console.log(__dirname); 13 | 14 | console.log(process); -------------------------------------------------------------------------------- /section9/index.js: -------------------------------------------------------------------------------- 1 | console.log('start require'); 2 | var lib = require('./lib') 3 | 4 | console.log('end require', lib); 5 | 6 | // 参见lib.js注释里的知识点1 7 | console.log(lib.tencent); 8 | 9 | // 参见lib.js注释里的知识点2 10 | // require返回的对象,和lib.js里的exports对象属于同一个引用 11 | // 因此此处加的属性能在里面体现出来。 12 | lib.additional = 'test' -------------------------------------------------------------------------------- /section9/lib.js: -------------------------------------------------------------------------------- 1 | console.log('this is module'); 2 | 3 | exports.geekbang = { 'hello': 'haha' } 4 | 5 | exports.tencent = function () { 6 | console.log('good') 7 | } 8 | 9 | // 知识点1:对module.exports赋值,exports对象就不再是外面require所得到的结果了。 10 | // 我在视频里采用的说法是“覆盖exports”其实不算非常严谨。 11 | // 因为exports变量本身还是存在的 12 | module.exports = function () { 13 | console.log('hello geekbang'); 14 | } 15 | 16 | // 知识点2:外部拿到require调用的结果和这里的exports对象是同一个引用 17 | setTimeout(()=> { 18 | // 验证index.js里加的additional属性是否生效 19 | // 用于确定外部require到的对象和此处的exports是否是同一个属性 20 | console.log(exports) 21 | }, 2000) 22 | 23 | 24 | // 视频中我建议大家使用webpack命令辅助理解commonjs 25 | // 但目前2021年最新版本的webpack已经不能直接使用我在视频里提到的命令了 26 | // 但大家可以改用webpack --devtool=inline-source-map --mode=development --target=node ./index.js -------------------------------------------------------------------------------- /第一章:课程介绍.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/第一章:课程介绍.pdf -------------------------------------------------------------------------------- /第三章:项目开发篇.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/第三章:项目开发篇.pdf -------------------------------------------------------------------------------- /第二章:技术预研篇.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/第二章:技术预研篇.pdf -------------------------------------------------------------------------------- /第五章:框架和工程化篇.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/第五章:框架和工程化篇.pdf -------------------------------------------------------------------------------- /第四章:性能调优篇.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-nodejs/4a82570d64e157226caccf3e8323cc4078d763b7/第四章:性能调优篇.pdf --------------------------------------------------------------------------------