{"id":16473150,"url":"https://github.com/binki/turbogrunt","last_synced_at":"2026-05-13T15:43:57.394Z","repository":{"id":143134275,"uuid":"45960486","full_name":"binki/turbogrunt","owner":"binki","description":"A one-liner Gruntfile is a Gruntfile one line too long","archived":false,"fork":false,"pushed_at":"2015-11-11T06:25:05.000Z","size":0,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-11T02:24:35.893Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/binki.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-11T04:53:28.000Z","updated_at":"2015-11-11T04:53:50.000Z","dependencies_parsed_at":"2023-03-16T16:55:53.890Z","dependency_job_id":null,"html_url":"https://github.com/binki/turbogrunt","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binki%2Fturbogrunt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binki%2Fturbogrunt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binki%2Fturbogrunt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binki%2Fturbogrunt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/binki","download_url":"https://codeload.github.com/binki/turbogrunt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241111783,"owners_count":19911560,"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":[],"created_at":"2024-10-11T12:25:32.162Z","updated_at":"2026-05-13T15:43:52.365Z","avatar_url":"https://github.com/binki.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"A basic conventional minimal way to write Gruntfiles that allows tasks\nto be added for you by the integration packages you depend on in\n`package.json` `devDependencies`. Unfortunately, using requires the\nfollowing boilerplate in your `Gruntfile.js`, though even so the\nGruntfile is probably a legitimate place to put project-specific\nconfiguration.\n\n# Usage\n\nThere are two scenarios of turbogrunt usage. Your package can consume\nturbogrunt to simplify its Gruntfile. Your package may be a grunt\nintegration package which provides information that turbogrunt\nconsumes.\n\n## Consumer\n\nThe point of consuming turbogrunt is to simplify your Gruntfile. In\nsome cases, you may be able to reduce your Gruntfile to a one-liner:\n\n```JavaScript\nmodule.exports = require('turbogrunt');\n```\n\nAs you may want to customize things, you may implement the callback as\nfollows:\n\n```JavaScript\nmodule.exports = function (grunt) {\n  /*\n   * Second argument is merged into the grunt.initConfig()\n   * call. package.json is already passed to initConfig\n   * for you.\n   */\n  require('turbogrunt')(\n    grunt,\n    {\n      uglify: {\n        options: {\n          banner: '/* hi from Gruntfile */'\n        }\n      }\n    });\n  grunt.registerTask('eat', function () { console.log('eating food'); });\n};\n```\n\n## Provider\n\nA package which needs to inject itself into Gruntfile configuration is\na provider. turbogrunt uses a very crude means of identifying\nproviders. Every project listed under `devDependencies` with `grunt`\nother than the exact string `grunt` is considered a provider.\n\n1. All providers must be compatible with `grunt.loadNpmTasks()`.  If\n   your package does not actually provide any grunt tasks, that means\n   it must ship with a `tasks` directory (otherwise grunt will throw\n   an error “Local Npm module \"mygruntintegration\" not found. Is it\n   installed?”. To accomplish this, create a file named `tasks/.keep`\n   and commit it to your VCS.\n\n2. Providers should be `require()`able. turbogrunt will look for a\n   `defaultTasks` property of exports which should be an array of\n   tasks that the `default` task should be made to depend on. All\n   providers’ listed `defaultTasks` will be set as the dependency of\n   the turbogrunt-created `default` task without regard for ordering.\n\n   For example, if your grunt integration provider is for a framework\n   that relies on uglify, you might have the following in main:\n\n   ```JavaScript\n   module.exports = {\n     defaultTasks: ['uglify']\n   };\n   ```\n\n   There is no requirement that your integration package provide the\n   task itself. However, note that if your integration provider\n   package intends to reference tasks provided by another package, it\n   must list that package in `dependencies` (not merely in\n   `devDependencies`) because to be available. And, for now, you must\n   solve the [problem of indirect tasks\n   inclusion](https://github.com/gruntjs/grunt/issues/696) by using\n   gruntcollections. To do so, in your `package.json`’s `keywords`\n   key, append `gruntcollection`. This will make grunt try to load all\n   of your package’s dependencies as grunt modules. Thus, if you need\n   to actually depend on any packages which do not have a “tasks”\n   directory, you must create a proxy package with a `tasks/.keep`\n   file which depends on your dependencies and re-exports them to your\n   package. Simple, eh?\n\n# Rationale\n\nWhen a project buys into a framework, that shouldn’t mean copying and\npasting boilerplate code around. Instead you should write only that\nwhich is specific to your project. Everything else is just noise. If\nthe arrangement of files in your project follows a convention that\nsome framework recognizes, then let’s try to avoid copy/pasting around\nboilerplate glue code. `$ frameworkname init` begone!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinki%2Fturbogrunt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbinki%2Fturbogrunt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinki%2Fturbogrunt/lists"}