{"id":21862789,"url":"https://github.com/xunuoi/node-bigpipe","last_synced_at":"2025-04-14T19:43:15.565Z","repository":{"id":143897438,"uuid":"48615388","full_name":"xunuoi/node-bigpipe","owner":"xunuoi","description":"A super easy, lightweight Bigpie Module for Nodejs,  Express,  Sails, ThinkJS with good intergration for web framework","archived":false,"fork":false,"pushed_at":"2018-06-27T09:26:33.000Z","size":91,"stargazers_count":77,"open_issues_count":1,"forks_count":2,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-09T13:42:05.113Z","etag":null,"topics":["backend","bigpipe","node-bigpipe","pagelet","pipe","thinkjs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xunuoi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-26T15:36:37.000Z","updated_at":"2023-11-03T17:12:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"f8adb97e-8fb8-4ec7-95b5-cce224609717","html_url":"https://github.com/xunuoi/node-bigpipe","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xunuoi%2Fnode-bigpipe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xunuoi%2Fnode-bigpipe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xunuoi%2Fnode-bigpipe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xunuoi%2Fnode-bigpipe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xunuoi","download_url":"https://codeload.github.com/xunuoi/node-bigpipe/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248949333,"owners_count":21188055,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","bigpipe","node-bigpipe","pagelet","pipe","thinkjs"],"created_at":"2024-11-28T03:17:16.924Z","updated_at":"2025-04-14T19:43:15.542Z","avatar_url":"https://github.com/xunuoi.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [![node-bigpipe](https://raw.githubusercontent.com/xunuoi/node-bigpipe/master/meta/logo.png)](https://github.com/xunuoi/node-bigpipe) node-bigpipe \n\n\n[![NPM version](https://img.shields.io/npm/v/node-bigpipe.svg?style=flat-square)](http://badge.fury.io/js/node-bigpipe)\u003cimg src=\"https://raw.githubusercontent.com/xunuoi/node-bigpipe/master/meta/build.png?style=flat-square\" width=\"90\" alt=\"Build status\" /\u003e\n\n\n### Introduction\n- Bigpie module for nodejs, web frameworks like Express, Sails, ThinkJS\n- Only 3 Simple API: `start`, `pipe`, `end`, very light and transparent\n- Based on `Promise`, easy to use and control\n\n\n### Install\n- Backend side: `npm install node-bigpipe --save-dev`\n- Frontend side: Involve the `jQuery` and `bro.bigpipe.js` scripts into html. Or `require('node-bigpipe/static/bro.bigpipe')` by `webpack/browserify`.\n- **You can write the Frontend js code by yourself, make sure to match the `Bigpipe` API of Backend.**\n\n\n### Usage\n\nIn Backend, you should use `node-bigpipe` to create a bigpipe for response. \nIn Frontend, you can use `bro.bigpipe.js`, or use your own js code to call the `bigpipe` from Backend.\n\nStep:\n* require the `node-bigpipe` module by `var Bigpipe = require('node-bigpipe').Bigpipe`\n* Create an Bigpipe by `var bigpipe = new Bigpipe('pipeName', req, res)`\n* Use `start` api to ouput the pipe and render the unclosed base html frame\n* Use `pipe` api to transport to browser the array composed by pipe blocks you created \n* Use `end` api to finish this bigpipe\n* More detail in Example\n\n**\\*Note:**\n\u003cbr\u003e\nIf you use `nginx/apache`, please check the server `buffer` config .\nIf the response size is small, the nginx won't send pagelet, it will save in its buffer for final response. But you can **close nginx buffer/gzip** to show the bigpipe effect obviously like this:\n\n```bash\nlocation / {\n    gzip  off;\n    fastcgi_buffer_size 0k;\n    proxy_buffering off;\n\n    ...\n}\n```\n\n\n\n\n### Backend API\n- `bigpipe.start(viewPath, [data])`: Start render, `viewPath` can be a basic html template\n- `bigpipe.pipe(promiseList)`：begin to transport the pipe into reponse\n- `bigpipe.end([onEndFn])`： finish the pipe\n- `bigpipe.render(selector, htmlData)`： Similar with `$(selector).html(htmlData)` in browser, set the dom html content \n- `bigpipe.append(selector, htmlData)`： Similar with `$(selector).append(htmlData)`, append the dom element content\n- `bigpipe.fire(eventName, data)`: Trigger the event which subscribed in Front End. The event should is used to process the data transported by bigpipe. You can use `on` api to subscribe the event in Frontend js.\n\n### Frontend js(Browser) API\n- `bigpipe.on(eventName).then(data=\u003e{ // deal with data ...  })`: Subscribe the eventName, you can use callback function in `then` API to process data.\n- `bigpie.fire/render/append` Set the dom content, Same with mentioned above in Backend API.\n\n\n### Examples\n\n- Create a pagelet and return a Promise\n\nThe implementation will be put into the tagPagelet, bp\n\n```Javascript\n// Here the `bigpipe` parameter is injected by `start` API automatically.\nfunction tagPagelet(bigpipe){\n\n    return new Promise((resolve, reject)=\u003e{\n        let rdata = {\n            'tag': 'your data'\n        }\n\n        // simulate the asynchronous response\n        setTimeout(()=\u003e{\n            let html = '\u003cdiv\u003e\u003cspan\u003eTagA\u003c/span\u003e\u003cspan\u003eTagB\u003c/span\u003e\u003cspan\u003eTagC\u003c/span\u003e\u003cspan\u003eTagD\u003c/span\u003e\u003c/div\u003e'\n\n            let pipeData = {\n                'html': html,\n                'message': 'for tag pipe html',\n                'css': ['a.css'],\n                'js': ['b.js'],\n            }\n            // Here the `tag` event names will subscribed by Frontend js code.\n            // Here you can use `render`, `append`, `fire`, it depends on your Backend code\n            bigpipe.fire('tag', pipeData)\n            resolve()\n        }, 3000)\n    })\n}\n\n```\n\n- In Backend controller, start the pipe\n\n```Javascript\n\n    index (req, res, next, page=1){\n        let bigpipe = new Bigpipe('karatBP', req, res)\n\n        /**\n         * `bigpipe.start` will inject the _bigpipe_id into the template `data`, So Frontend js can get the `id` by `new Bigpipe('{{_bigpipe_id}}')`\n         * And in Frontend js, it will export a object named by `_bigpipe_id`. for Example, here will create the window.karatBP object in browser js.\n         */\n        \n        bigpipe.start('view/home')\n        .pipe([\n            articlePagelet,\n            tagPagelet,\n            \n            // other ...\n        ])\n        .end()\n    },\n\n```\n\n- Front End\n\n```Html\n\u003cscript type=\"text/javascript\"\u003e\n\n// This method will automatically export a object `karatBP` in window. And the `_bigpipe_id` shoud match the definition in backend \nnew Bigpipe('karatBP')\n\n\n// You can also use the `_bigpipe_id` parameter from backend by defaultl below:\n// new Bigpipe('{{_bigpipe_id}}')\n\n\u003c/script\u003e\n```\n\n### Full Demo Code\n\n- Full Backend demo code in `demo/DemoController.js`：\n\n```Javascript\n\nvar Bigpipe = require('node-bigpipe').Bigpipe\n\n// this is a pagelet for pipe, you should return a promise in the pagelet-function.\nfunction tagPagelet(bigpipe){\n    return new Promise((resolve, reject)=\u003e{\n        let rdata = {\n            'tag': 'your data'\n        }\n\n        // simulate the asynchronous response, it may be replaced by DB/IO/NETWORK and other async operations.\n        setTimeout(()=\u003e{\n            let html = '\u003cdiv\u003e\u003cspan\u003eTagA\u003c/span\u003e\u003cspan\u003eTagB\u003c/span\u003e\u003cspan\u003eTagC\u003c/span\u003e\u003cspan\u003eTagD\u003c/span\u003e\u003c/div\u003e'\n\n            let pipeData = {\n                'html': html,\n                'message': 'for tag pipe html'\n                'css': ['a.css'],\n                'js': ['b.js'],\n            }\n            // here the `tag` match the event in frontend. You can use the bigpipe by `on('tag')` in Frontend js code.\n            bigpipe.fire('tag', pipeData)\n            resolve()\n        }, 3000)\n    })\n}\n\n\n// another pagelet\nfunction articlePagelet(bigpipe){\n    return new Promise((resolve, reject)=\u003e{\n        let rdata = {\n            'article': 'your data'\n        }\n\n        bigpipe.res.render('view/article', rdata, (err, html)=\u003e{\n\n            // Here you can use `render`, `append`, `fire`\n            bigpipe.render('.wrap \u003e .content', html)\n            resolve()\n\n        })\n    })\n}\n\n\n// here the `index` fn should be bound in router so it can be views by url\n// the `view/home` is the basic html template, you can define some container div/elements in this html.\nexport default {\n\n    index (req, res, next, page=1){\n        let bigpipe = new Bigpipe('karatBP', req, res)\n\n        bigpipe.start('view/home')\n        .pipe([\n            articlePagelet,\n            tagPagelet,\n            \n            // other pagelet...\n        ])\n        .end()\n    },\n}\n```\n\n- Full Frontend demo code\n```HTML\n\u003c!-- If you want, you can write your own Frontend js to replace `jquery` and `bro.bigpipe` here. --\u003e\n\u003cscript type=\"text/javascript\" src=\"/static/jquery.min.js\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\" src=\"/static/bro.bigpipe.js\"\u003e\u003c/script\u003e\n\n\u003c!-- Here will use the bigpipe object transported from Backend --\u003e\n\u003cscript type=\"text/javascript\"\u003e\n\n// The `karatBP` is the bigpipe-id, it should match the Backend definition. Or you can use '{{_bigpipe_id}}' directly.\nvar karatBP = new Bigpipe('karatBP')\n\n// You can subscribe the events which match the backend API `fire`, like fire('tag', data), then you can `on('tag')` in FE js.\nkaratBP.on('tag')\n.then(function (pageletData) {\n    console.log(pageletData)\n    $('#tag').html(pageletData.html)\n})\n\n\u003c/script\u003e\n```\n\n### Support for ThinkJS\n\nDifference of usage in Backend:\n\n* Put an additional param `this` into `new Bigpipe()`, like `new Bigpipe('xxxBP', http.req, http.res, this)`\n* Other APIs keep SAME with above usage\n* More About ThinkJS: [https://thinkjs.org](https://thinkjs.org)\n\n\n\n```Javascript\n\nexport default class extends Base {\n  indexAction(){\n    let http = this.http;\n\n    // Put an additional param: `this`\n    let bigpipe = new Bigpipe('thinkBP', http.req, http.res, this)\n\n    // `start` method use default ThinkJS template path: index.html\n    // Or bigpipe.sart('xxx') to specific some html template file\n    bigpipe.start()\n    .pipe([\n        tagPagelet,\n        articlePagelet\n        \n        // other pagelet...\n    ])\n    .end()\n    // Other APIs keep same with above usage.\n \n  }\n}\n```\n\n\n### More\n\nPlease check the demo code in `demo` folder in the repository. And the Frontend js code is in `static` folder.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxunuoi%2Fnode-bigpipe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxunuoi%2Fnode-bigpipe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxunuoi%2Fnode-bigpipe/lists"}