{"id":15672970,"url":"https://github.com/kt3k/bulbo","last_synced_at":"2025-05-06T22:09:42.160Z","repository":{"id":3255353,"uuid":"48881381","full_name":"kt3k/bulbo","owner":"kt3k","description":":tropical_drink: Generate your static site with gulp plugins!","archived":false,"fork":false,"pushed_at":"2025-02-21T08:07:13.000Z","size":2425,"stargazers_count":17,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-06T22:09:25.875Z","etag":null,"topics":["build","bulbo","cli","dev-env","dev-server","frontend","static-site-generator","watch"],"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/kt3k.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,"zenodo":null}},"created_at":"2016-01-01T15:22:37.000Z","updated_at":"2025-04-09T10:10:47.000Z","dependencies_parsed_at":"2024-06-19T16:03:28.961Z","dependency_job_id":"18c2cbc7-80ee-459b-807b-2800ee44d191","html_url":"https://github.com/kt3k/bulbo","commit_stats":{"total_commits":423,"total_committers":5,"mean_commits":84.6,"dds":"0.20330969267139476","last_synced_commit":"6c607326a6ee1d60f64973b34592253481b24cb2"},"previous_names":[],"tags_count":51,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kt3k%2Fbulbo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kt3k%2Fbulbo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kt3k%2Fbulbo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kt3k%2Fbulbo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kt3k","download_url":"https://codeload.github.com/kt3k/bulbo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252776599,"owners_count":21802469,"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":["build","bulbo","cli","dev-env","dev-server","frontend","static-site-generator","watch"],"created_at":"2024-10-03T15:34:29.408Z","updated_at":"2025-05-06T22:09:41.855Z","avatar_url":"https://github.com/kt3k.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bulbo v8.0.2\n\n\u003e Generate your static site with gulp plugins!\n\n\u003cimg width=\"100\" src=\"https://kt3k.github.io/bulbo/media/logo.svg\" /\u003e\n\n[![ci](https://github.com/kt3k/bulbo/actions/workflows/ci.yml/badge.svg)](https://github.com/kt3k/bulbo/actions/workflows/ci.yml)\n\n# Features\n\n- **Compatible with gulp plugins** - you can use any gulp plugins in bulbo\n- **Server and Watcher included** - you don't need to set up a dev server, bulbo\n  does it for you\n- **Flexible** - bulbo doesn't assume any directory structure, you can configure\n  anything\n- **Easy syntax** - see the getting started guide\n\n# Install\n\n    npm install --save-dev bulbo\n\n# Getting started\n\nFirst you need to set up `bulbofile.js` like the following.\n\n```js\nconst bulbo = require(\"bulbo\");\nconst asset = bulbo.asset;\n\n// copy css\nasset(\"source/**/*.css\");\n```\n\nThe above means that `'source/**/*.css'` is asset and which will be copied to\nthe destination directory (default: `build`).\n\n## Change destination\n\nIf you want to change the destination you can do it with `bulbo.dest` method\n\n```js\nbulbo.dest(\"output\");\n```\n\n## Browserify\n\nIf you need to bundle your scripts with `browserify` you can set up it like the\nfollowing:\n\n```js\nconst bundler = require(\"bundle-through\");\n\n// build js\nasset(\"source/page/*.js\")\n  .base(\"source\")\n  .watch(\"source/**/*.js\")\n  .pipe(bundler());\n```\n\n- `.base('source')` means the base path of your glob pattern\n  (`source/page/*.js`) is `source`.\n- `.watch('source/**/*.js')` means that this build process watches the files\n  `source/**/*.js`, not only `source/page/*.js`\n- `.pipe(bundler())` registers `bundler()` as the transform. `bundler()`\n  transforms all files into the bundles using `browserify`. See\n  [the document](https://github.com/kt3k/bundle-through) for details.\n\n## Building html from layout and page source\n\nTo build html from layout tempate, set up it like the following:\n\n```js\nconst frontMatter = require('gulp-front-matter')\nconst wrap = require('gulp-wrap')\n\n// html\nasset('source/*.html')\n.pipe(frontMatter())\n.pipe(wrap(data =\u003e fs.readFileSync('source/layouts/' + data.file.frontMatter.layout).toString())))\n```\n\n- `.pipe(frontMatter())` means it extracts the frontmatter from the file.\n- `.pipe(wrap(...))` means it renders its html using layour file under the\n  `source/layouts/`.\n  - The layout file name is specified by `layout` property of the frontmatter.\n\n## Excluding some patterns\n\nTo exclude some patterns, use `!` operator.\n\n```js\n// others\nasset(\"source/**/*\", \"!source/**/*.{js,css,html,lodash}\");\n```\n\nThe above copies all assets under `source` except `.js`, `.css`, `.html` or\n`.lodash` files.\n\nThe resulting `bulbofile.js` looks like the following:\n\n```js\nconst bulbo = require('bulbo')\nconst asset = bulbo.asset\n\nconst bundler = require('bundle-through')\nconst frontMatter = require('gulp-front-matter')\nconst wrap = require('gulp-wrap')\n\nbulbo.dest('output')\n\n// css\nasset('source/**/*.css')\n\n// js\nasset('source/page/*.js')\n.base('source')\n.watch('source/**/*.js')\n.pipe(bundler())\n\n// html\nasset('source/*.html')\n.pipe(frontMatter())\n.pipe(wrap(data =\u003e fs.readFileSync('source/layouts/' + data.file.frontMatter.layout).toString())))\n\n// others\nasset('source/**/*', '!source/**/*.{js,css,html,lodash}')\n```\n\nAnd then `bulbo serve` command starts the server.\n\n    $ bulbo serve\n    bulbo [01:33:38] Using: /Users/kt3k/tmp/long-dream-core/bulbofile.js\n    bulbo [01:33:39] serving\n    bulbo [01:33:39] Reading: site/**/*.js\n    bulbo [01:33:39] Reading: src/infrastructure/infrastructure.js\n    bulbo [01:33:39] Reading: site/*.html\n    bulbo [01:33:39] Reading: site/data/**/*.*\n    bulbo [01:33:39] Reading: site/img/**/*.*\n    bulbo [01:33:39] Reading: site/css/**/*.*\n    bulbo [01:33:39] Server started at: http://0.0.0.0:7100/\n    bulbo [01:33:39] See debug page is: http://0.0.0.0:7100/__bulbo__\n    bulbo [01:33:39] Ready: site/**/*.js\n    bulbo [01:33:39] Ready: src/infrastructure/infrastructure.js\n    bulbo [01:33:39] Ready: site/*.html\n    bulbo [01:33:39] Ready: site/img/**/*.*\n    bulbo [01:33:39] Ready: site/css/**/*.*\n    bulbo [01:33:39] Ready: site/data/**/*.*\n\nAnd the following builds all the given assets and saves them to `build/`\ndirectory.\n\n    $ bulbo build\n    bulbo [12:04:19] Using: /Users/kt3k/tmp/long-dream-core/bulbofile.js\n    bulbo [12:04:20] building\n    bulbo [12:04:25] done\n\n# API reference\n\n```js\nconst bulbo = require(\"bulbo\");\n```\n\n## bulbo.asset(...paths)\n\n- @param {string[]} paths The glob pattern(s)\n\nThis registers the glob pattern as the asset source.\n\nExample:\n\n```js\nbulbo.asset(\"src/js/**/*.js\");\n```\n\nExample:\n\n```js\nbulbo.asset(\"src/feature1/*.html\", \"src/feature2/*.html\");\n```\n\n## bulbo.asset().assetOptions(opts)\n\n- @param {Object} [opts] The options\n\nThis passes the option to asset globing.\n\nExample:\n\n```js\nbulbo.asset(\"src/js/**/*.js\")\n  .assetOptions({ read: false });\n```\n\nThe above doesn't read actual file contents when being built. This is useful\nwhen you use the transform which doesn't require the file contents.\n\n## bulbo.asset(...).base(path)\n\n- @param {string} path The base path of the asset glob\n\nThis sets the base path of the asset glob.\n\nThe base path is automatically chosen from your glob pattern. If you want change\nthe default base path you can change it calling this method.\n\nExample:\n\n```js\nbulbo.asset(\"src/img/**/*.*\"); // `src/img/foo.png` is copied to `build/foo.png` because the base path of this glob is `src/img` by default.\n\nbulbo.asset(\"src/img/**/*.*\").base(\"src\"); // but in this case, copied to `build/img/foo.png`\n```\n\n## bulbo.asset(...).watch(glob)\n\n- @param {string|string[]} glob The path(s) to watch\n\nThis sets the watch path(s) of the asset. If no watch paths are set, the bulbo\nwatches the same paths as the asset's source paths.\n\nExample:\n\n```js\nbulbo\n  .asset(\"src/js/pages/*.js\")\n  .watch(\"src/js/**/*.js\") // Watches all js files under `src/js`, though build entry poits are only js files under `src/js/pages`.\n  .pipe(through2.obj((file, enc, callback) =\u003e {\n    file.contents = browserify(file.path).bundle();\n    callback(null, file);\n  }));\n```\n\n## bulbo.asset(...).watchOptions(opts)\n\n- @param {object} opts The options to pass to chokidar (the watcher library)\n\nThis options is passed to chokidar's watch option. You can modify the behaviour\nof the internal chokidar as you want.\n\n## bulbo.dest(path)\n\n- @param {String} path\n\nThis sets the build destination. (The default is `build`)\n\nExample:\n\n```js\nbulbo.dest(\"dist\");\n```\n\n## bulbo.port(port)\n\n- @param {Number} port\n\nThis sets the port number of the asset server. (The default is `7100`.)\n\nExample:\n\n```js\nbulbo.port(7500);\n```\n\n## bulbo.base(base)\n\n- @param {string} base\n\nThis sets the default base path for all the assets.\n\nExample:\n\n```js\nbulbo.base(\"source\");\n\nbulbo.asset(\"source/news/**/*.md\");\nbulbo.asset(\"source/events/**/*.md\");\n\nbulbo.dest(\"build\");\n```\n\nThe above assets build to `build/news/**/*.md` and `build/events/**/*.md`\nrespectively.\n\n## bulbo.loggerTitle(title)\n\n- @param {string} title The title of the logger\n\nThis sets the logger title.\n\n```js\nbulbo.loggerTitle(\"myapp\");\n```\n\nThen the console looks like the below:\n\n    $ bulbo serve\n    bulbo [21:22:38] Using: /Users/kt3k/t/bulbo/demo/bulbofile.js\n    myapp [21:22:38] serving\n    myapp [21:22:38] Reading: ../test/fixture/**/*.js\n    myapp [21:22:38] Reading: ../test/fixture/**/*.css\n    myapp [21:22:38] Server started at: http://localhost:7100/\n    myapp [21:22:38] See debug info at: http://localhost:7100/__bulbo__\n    myapp [21:22:38] Ready: ../test/fixture/**/*.css\n    myapp [21:22:44] Ready: ../test/fixture/**/*.js\n\n## bulbo.addMiddleware(middleware)\n\n- @param {Function} middleware\n\nAdds the connect compiliant middleware to the server.\n\nExample:\n\n```js\nconst livereload = require(\"connect-livereload\");\n\nbulbo.addMiddleware(() =\u003e livereload());\n```\n\n# Commands\n\n`npm install -g bulbo` installs command `bulbo`. Which supports 2 subcommands\n`build` and `serve`.\n\n## bulbo build\n\nThis builds all the registered assets into the destination directory. The\ndefualt destination is `build`. The path is configurable by `bulbo.dest(path)`\nin bulbofile.\n\n## bulbo serve\n\nThis starts the local server which serves all the registered assets on it. The\ndefault port is `7100`. The number is configurable by `bulbo.port(number)` in\nbulbofile.\n\n`bulbo` command without arguments also does the same as `bulbo serve`. You can\njust simply call `bulbo` to start bulbo server.\n\nThe bulbo server has builtin debug url at `0.0.0.0:7100/__bulbo__`. You can find\nthere all the available paths (assets) on the server. It's useful for debugging\nthe asset stream.\n\n![](https://kt3k.github.io/bulbo/media/ss.png)\n\n# Recipes\n\n## Use es6 in bulbofile\n\nYou can enable es2015 syntax by renaming `bulbofile.js` to `bulbofile.babel.js`\nand adding `babel-register` as dependency.\n\n    npm install --save-dev babel-register babel-preset-es2015\n\nYou also need to set up `.babelrc` as follows:\n\n```json\n{\n  \"presets\": [\n    \"es2015\"\n  ]\n}\n```\n\n## Use CoffeeScript in bulbofile\n\nYou need to rename bulbofile.js to bulbofile.coffee and install coffeescript\ndependency:\n\n    npm install --save-dev coffee-script\n\nAnd your bulbofile.coffee looks like the following:\n\n```coffee\nasset = require('bulbo').asset\n\nthrough2 = require 'through2'\nbrowserify = require 'browserify'\nfrontMatter = require 'gulp-front-matter'\nwrap = require 'gulp-wrap'\n\nasset 'source/**/*.css'\nasset 'source/**/*'\nasset '!source/**/*.{js,css,html,lodash}'\n\nasset 'source/page/*.js'\n.watch 'source/**/*.js'\n.pipe through2.obj (file, enc, callback) -\u003e\n\n  file.contents = browserify(file.path).bundle()\n  callback null, file\n\nasset 'source/*.html'\n.pipe frontMatter()\n.pipe wrap (data) =\u003e\n  fs.readFileSync(\"source/layouts/#{ data.file.frontMatter.layout }\").toString()\n```\n\n## Uglify scripts only when it's production build\n\nUse `gulp-if`:\n\n```js\nconst gulpif = require('gulp-if')\nconst uglify = require('gulp-uglify')\n\nconst PRODUCTION_BUILD = process.NODE_ENV === 'production'\n\nasset('source/**/*.js')\n.pipe(gulpif(PRODUCTION_BUILD, uglify())\n```\n\nThis uglifies the scripts only when the variable NODE_ENV is `'production'`.\n\nOr alternatively use `through2`:\n\n```js\nconst through2 = require(\"through2\");\nconst uglify = require(\"gulp-uglify\");\n\nconst PRODUCTION_BUILD = process.NODE_ENV === \"production\";\n\nasset(\"source/**/*.js\")\n  .pipe(PRODUCTION_BUILD ? uglify() : through2.obj());\n```\n\n## Want to render my contents with template engine _XXXX_\n\nUse `gulp-wrap` and the `engine` option:\n\n```js\nconst wrap = require(\"gulp-wrap\");\nconst frontMatter = require(\"gulp-front-matter\");\n\nasset(\"source/**/*.html\")\n  .pipe(frontMatter())\n  .pipe(wrap({ src: \"source/layout.nunjucks\" }, null, { engine: \"nunjucks\" }));\n```\n\n_**Note**_ You need to `npm install nunjucks` in this case.\n\nThis example wraps your html in the nunjucks template. The contents of each html\nfile is refereced by `contents` and the front matter by `file.frontMatter`.\n\n## Watch different paths from source path.\n\nUse `watch` option in the asset options.\n\n```js\nasset(\"source/page/*.js\")\n  .watch(\"source/**/*.js\");\n```\n\nThis is useful when the entrypoints of the asset and the actual source files are\ndifferent. For example, if you use browserify to bunble your scripts, your\nentrypoints are bundle's entrypoint files but you need to watch all of your\nsource files which form the bundles.\n\n# Extension API\n\n`bulbo` can be used as internal engine of your own static site generator.\n\nThe example looks like the following:\n\nindex.js:\n\n```js\nconst bulbo = require('bulbo')\n\nbulbo.asset(...).pipe(...) // Some preset settings are here.\n\nmodule.exports = bulbo\n```\n\nbin/index.js\n\n```js\nconst bulbo = require(\"bulbo\");\n\nbulbo.cli.liftoff(\"mycommand\", { configIsOptional: true }).then((bulbo) =\u003e {\n  bulbo.build();\n});\n```\n\nand bin/index.js works as static site generator cli with some asset building\npreset.\n\n$ node bin/index.js\n\nThis builds preset assets without your configuration. This is useful if you want\nto share the same bulbo setting across the projects.\n\n## bulbo.cli.liftoff(name, options)\n\n- @param {string} name The command (module) name\n- @param {object} options The options\n- @param {boolean} [options.configIsOptional] True iff the config is optional.\n  Default is false.\n- @return {Promise}\n\nThis set up your module using `liftoff`. This returns a promise which is\nresolved by the your own module. Your module needs to implement `setLogger`\nmethod. It is recommended you expose bulbo module instance as your module\ninterface.\n\nThis does not take care of cli options. It is recommended to use with option\nparsers like `minimist`, `minimisted` etc.\n\n# License\n\nMIT\n\n# Release history\n\n- 2022-03-14 v8.0.1 Remove minirocket dependency.\n- 2022-03-14 v8.0.0 Clean up. Support only Node \u003e=14.\n- 2018-06-09 v7.0.1 Add middleware support. Drop Node 4 support.\n- 2017-04-26 v6.13.0 Update debug page design.\n- 2017-04-26 v6.11.0 Add config extension types.\n- 2017-04-26 v6.10.0 Update cli.liftoff util.\n- 2017-04-25 v6.9.0 loggerTitle method.\n- 2017-04-23 v6.8.0 Serve index.html.\n- 2017-04-12 v6.7.0 Improve error logging.\n- 2016-12-29 v6.5.0 Fix windows issues.\n- 2016-12-28 v6.4.0 Update vinyl-serve.\n- 2016-10-28 v6.3.0 Add base method.\n- 2016-10-11 v6.2.4 Update minirocket.\n- 2016-09-18 v6.2.1 Update vinyl-serve.\n- 2016-09-05 v6.2.0 Add extension API.\n- 2016-09-05 v6.1.5 Refactoring (use minirocket).\n- 2016-05-08 v6.1.0 Better error handling.\n- 2016-05-01 v6.0.0 Remove asset().build() DSL verb.\n- 2016-04-29 v5.1.1 Change the architecture. Use the same transform for an asset\n  while watching.\n- 2016-04-19 v4.2.3 Auto cloning feature of piped transform\n- 2016-04-18 v4.1.0 Update vinyl-serve to v2.0.0 (fixed bug of serving data)\n- 2016-04-17 v4.0.3 Update vinyl-serve to v1.3.4 (fixed bug of binary data\n  handling)\n- 2016-04-16 v4.0.2 Fix loading bug.\n- 2016-04-14 v4.0.0 Update DSL.\n- 2016-04-13 v3.0.0 Update DSL.\n- 2016-01-09 v1.0.2 Improved server start time.\n- 2016-01-08 v1.0.1 Fixed build file number limit bug.\n- 2016-01-03 v1.0.0 Initial release.\n\n# Dev info\n\n## Architecture\n\nBulbo = `vinyl-fs` + `js-liftoff` + `stream-splicer` + `vinyl-serve` + Bulbo DSL\n\n- `vinyl-fs` is the same as `gulp.src()` and `gulp.dest()`. Bulbo uses it for\n  creating file streams and saving them.\n- `js-liftoff` is a magical tool for creating CLI tool which is configurable by\n  its DSL script, in this case like bulbofile.js.\n- `stream-splicer` is used for creating a linear pipeline of transforms of the\n  assets.\n- `vinyl-serve` is a simple server which consumes readable vinyl streams and\n  serves the files in them.\n\n## Model\n\nBulbo has the only one model `Asset` which represents a group of assets and its\ntransform.\n\n## Application layer\n\nBulbo has 3 application layer classes, `AssetServer` `AssetBuilder` and\n`AssetService`\n\n## Bulbo DSL\n\nBulbo DSL is implemented in `bulbo.js` (the module interface) and `AssetFacade`\nclass.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkt3k%2Fbulbo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkt3k%2Fbulbo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkt3k%2Fbulbo/lists"}