Comparing version 1.0.4 to 2.0.1
{ | ||
"name": "builder", | ||
"description": "Liberal JavaScript DOM builder", | ||
"version": "1.0.4", | ||
"url": "https://github.com/eastridge/builder/", | ||
"author": "Ryan Eastridge <ryan@eastridge.me>", | ||
"licenses": [{ | ||
"type": "MIT", | ||
"url": "http://creativecommons.org/licenses/MIT/" | ||
}], | ||
"version": "2.0.1", | ||
"description": "An NPM-based task runner", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/eastridge/builder.git" | ||
"url": "https://github.com/FormidableLabs/builder.git" | ||
}, | ||
"author": "Ryan Roemer <ryan.roemer@formidablelabs.com>", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "http://github.com/eastridge/builder/issues" | ||
"url": "https://github.com/FormidableLabs/builder/issues" | ||
}, | ||
"main": "./builder.js" | ||
} | ||
"homepage": "https://github.com/FormidableLabs/builder", | ||
"scripts": { | ||
"builder:lint-server": "eslint --color -c .eslintrc-server lib bin", | ||
"builder:lint": "npm run builder:lint-server", | ||
"builder:check": "npm run builder:lint" | ||
}, | ||
"bin": { | ||
"builder": "bin/builder.js" | ||
}, | ||
"dependencies": { | ||
"async": "^1.4.2", | ||
"chalk": "^1.1.1", | ||
"js-yaml": "^3.4.3", | ||
"lodash": "^3.10.1" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^1.7.3", | ||
"eslint-config-defaults": "^7.0.1", | ||
"eslint-plugin-filenames": "^0.1.2" | ||
} | ||
} |
353
README.md
@@ -0,66 +1,311 @@ | ||
[![Travis Status][trav_img]][trav_site] | ||
Builder | ||
======= | ||
Liberal JavaScript DOM builder | ||
npm install builder | ||
Builder is a task runner. | ||
element = Builder(tag_name, attributes = {}, elements = [], content = '', callback) | ||
------- | ||
Accepts a variable number of arguments which may be: | ||
Builder is an enhancement to `npm run TASK`. | ||
- Hashes of attributes | ||
- Elements | ||
- Strings of content | ||
- Arrays (which can be nested) of any of the above | ||
- Function to call, which can return any of the above | ||
Builder is a meta-tool for all your common build, quality, and test tasks. | ||
All HTML5 tag names are available as functions on the Builder object which will generate the corresponding element. For maximum readability when generating multiple elements it can be useful to call a function with Builder as the context. | ||
## Overview | ||
# using Builder | ||
div = Builder 'div', className: 'tasty' | ||
ul = Builder.ul Builder.li 'Item One' | ||
# calling a function with Builder as the context | ||
table = (-> | ||
@table cellpadding: 0, cellspacing: 0, | ||
@tbody( | ||
@tr( | ||
@td 'Cell One' | ||
@td 'Cell Two' | ||
) | ||
) | ||
).call Builder | ||
Builder.document | ||
---------------- | ||
If no document is present in the global scope (i.e. on Node), you can explicitly set the document element: | ||
At a high level `builder` is a tool for consuming `package.json` `scripts` | ||
commands, providing sensible / flexible defaults, and support various scenarios | ||
("archetypes") for your common use cases across multiple projects. | ||
jsdom = require 'jsdom' | ||
Builder = require 'builder' | ||
window = jsdom.createWindow() | ||
Builder.document = window.document | ||
div = Builder.div() | ||
Builder is not opinionated, although archetypes _are_ and typically dictate | ||
file structure, standard configurations, and dev workflows. Builder supports | ||
this in an agnostic way, providing essentially the following: | ||
Builder.$ | ||
--------- | ||
Setting $ on Builder will make Builder return a wrapped object containing the element (i.e. a jQuery/Zepto/Ender array). Builder will always look inside these objects for the actual elements so in practice you can use them as if they were the Element objects, with the added benefit of attaching event handlers inline, etc: | ||
Builder.$ = jQuery | ||
list = (-> | ||
@ul @li @a('Link',href:'#').click -> | ||
).call Builder | ||
* `NODE_PATH`, `PATH` enhancements to run, build, import from archetypes so | ||
dependencies and configurations don't have to be installed directly in a | ||
root project. | ||
* A task runner capable of single tasks (`run`) or multiple concurrent tasks | ||
(`concurrent`). | ||
* An intelligent merging of `package.json` `scripts` tasks. | ||
Backbone | ||
-------- | ||
To use in a [Backbone](http://documentcloud.github.com/backbone/) project, include builder.js then: | ||
... and that's about it! | ||
BuilderView = Backbone.View.extend Builder | ||
MyView = BuilderView.extend | ||
render: -> | ||
@el.appendChild @ul li 'Item One' | ||
Ender | ||
----- | ||
When including builder in an Ender build, it becomes available as $.builder: | ||
### Usage | ||
div = $.builder 'div' | ||
To start using builder, install and save `builder` and any archetypes you | ||
intend to use. We'll use the [builder-react-component][] archetype as an | ||
example. | ||
#### Global Install | ||
For ease of use, one option is to globally install `builder` and locally install | ||
archetypes: | ||
```sh | ||
$ npm install -g builder | ||
$ npm install --save builder-react-component | ||
``` | ||
Like a global install of _any_ Node.js meta / task runner tool (e.g., `eslint`, | ||
`mocha`, `gulp`, `grunt`) doing a global install is painful because: | ||
* You are tied to _just one_ version of the tool for all projects. | ||
* You must also globally install the tool in CI, on servers, etc. | ||
... so instead, we **strongly recommend** a local install described in the | ||
next section! | ||
#### Local Install | ||
To avoid tying yourself to a single, global version of `builder`, the option | ||
that we endorse is locally installing both `builder` and archetypes: | ||
```sh | ||
$ npm install --save builder builder-react-component | ||
``` | ||
However, to call `builder` from the command line you will either need to | ||
augment your `PATH` variable with a shell configuration (Mac/Linux) like: | ||
```sh | ||
export PATH="${PATH}:./node_modules/.bin" | ||
``` | ||
or call the longer `./node_modules/.bin/builder` instead of `builder` from the | ||
command line. | ||
#### Configure, Install | ||
After `builder` is available, you can edit `.builderrc` like: | ||
```yaml | ||
--- | ||
archetypes: | ||
- builder-react-component | ||
``` | ||
to bind archetypes. | ||
At this point, `builder` can build any production tasks, as only production | ||
`dependencies` of archetypes are installed. However, if you are in a | ||
**development** or CI environment, an additional manual step is needed to | ||
install the `devDependencies` of all the archetypes: | ||
```sh | ||
$ builder install | ||
``` | ||
... and from here you are set for `builder`-controlled meta goodness! | ||
#### Builder Commands | ||
Display help. | ||
```sh | ||
$ builder help | ||
``` | ||
Install archetype `devDependencies`. | ||
```sh | ||
$ builder install | ||
``` | ||
Run a single `package.json` `scripts` task. | ||
```sh | ||
$ builder run foo-task | ||
``` | ||
Run multiple `package.json` `scripts` tasks. | ||
```sh | ||
$ builder concurrent foo-task bar-task baz-task | ||
``` | ||
## Tasks | ||
The underyling concept here is that `builder` `script` commands simply _are_ | ||
NPM-friendly `package.json` `script` commands. Pretty much anything that you | ||
can execute with `npm run FOO` can be executed with `builder run FOO`. | ||
Builder can run 1+ tasks based out of `package.json` `scripts`. For a basic | ||
scenario like: | ||
```js | ||
{ | ||
"scripts": { | ||
"foo": "echo FOO", | ||
"bar": "echo BAR" | ||
} | ||
} | ||
``` | ||
Builder can run these tasks individually: | ||
```sh | ||
$ builder run foo | ||
$ builder run bar | ||
``` | ||
Sequentially via `||` or `&&` shell helpers: | ||
```sh | ||
$ builder run foo && builder run bar | ||
``` | ||
Concurrently via the Builder built-in `concurrent` command: | ||
```sh | ||
$ builder concurrent foo bar | ||
``` | ||
With `concurrent`, all tasks continue running until they all complete _or_ | ||
any task exits with a non-zero exit code, in which case all still alive tasks | ||
are killed and the Builder process exits with the error code. | ||
## Archetypes | ||
Archetypes deal with common scenarios for your projects. Like: | ||
* [builder-react-component][]: A React component | ||
* A React application server | ||
* A Chai / jQuery / VanillaJS widget | ||
Archetypes typically provide: | ||
* A `package.json` with `builder`-friendly `script` tasks. | ||
* Dependencies and dev dependencies to build, test, etc. | ||
* Configuration files for all `script` tasks. | ||
In most cases, you won't need to override anything. But, if you do, pick the | ||
most granular `scripts` command in the archetype you need to override and | ||
define _just that_ in your project's `package.json` `script` section. Copy | ||
any configuration files that you need to tweak and re-define the command. | ||
### Task Resolution | ||
The easiest bet is to just have _one_ archetype per project. But, multiple are | ||
supported. In terms of `scripts` tasks, we end up with the following example: | ||
``` | ||
ROOT/package.json | ||
ROOT/node_modules/ARCHETYPE_ONE/package.json | ||
ROOT/node_modules/ARCHETYPE_TWO/package.json | ||
``` | ||
Say we have a `.builderrc` like: | ||
```yaml | ||
--- | ||
archetypes: | ||
- ARCHETYPE_ONE | ||
- ARCHETYPE_TWO | ||
``` | ||
The resolution order for a `script` task (say, `foo`) present in all three | ||
`package.json`'s would be the following: | ||
* Look through `ROOT/package.json` then the configured archetypes in _reverse_ | ||
order: `ARCHETYPE_TWO/package.json`, then `ARCHETYPE_ONE/package.json` for | ||
a matching task `foo` | ||
* If found `foo`, check if it is a "passthrough" task, which means it delegates | ||
to a later instance -- basically `"foo": "builder run foo"`. If so, then look | ||
to next instance of task found in order above. | ||
### Special Archetype Tasks | ||
Archetypes use conventional `scripts` task names, except for the following | ||
special cases: | ||
* `"npm:postinstall"` | ||
* `"npm:preversion"` | ||
* `"npm:version"` | ||
* `"npm:test"` | ||
These tasks are specifically actionable during the `npm` lifecycle, and | ||
consequently, the archetype mostly ignores those for installation by default, | ||
offering them up for actual use in _your_ project. | ||
As an **additional restriction**, non-`npm:FOO`-prefixed tasks with the same | ||
name (e.g., `FOO`) _may_ call then `npm:`-prefixed task, but _not_ the other | ||
way around. So | ||
```js | ||
// Good / OK | ||
"npm:test": "builder run test-frontend", | ||
"test": "builder run npm:test", | ||
// Bad | ||
"npm:test": "builder run test", | ||
"test": "builder run test-frontend", | ||
``` | ||
## Tips, Tricks, & Notes | ||
### Project Root | ||
Builder uses some magic to enhance `NODE_PATH` to look in the root of your | ||
project (normal) and in the installed modules of builder archetypes. This | ||
latter path enhancement sometimes throws tools / libraries for a loop. We | ||
recommend using `require.resolve("LIBRARY_OR_REQUIRE_PATH")` to get the | ||
appropriate installed file path to a dependency. | ||
This comes up in situations including: | ||
* Webpack loaders | ||
* Karma included files | ||
The other thing that comes up in our Archetype configuration file is the | ||
general _requirement_ that builder is running from the project root, not | ||
relative to an archetype. However, some libraries / tools will interpret | ||
`"./"` as relative to the _configuration file_ which may be in an archetype. | ||
So, for these instances and instances where you typically use `__dirname`, | ||
an archetype may need to use `process.cwd()` and be constrained to **only** | ||
ever running from the project root. Some scenarios where the `process.cwd()` | ||
path base is necessary include: | ||
* Webpack entry points, aliases | ||
* Karma included files (that cannot be `require.resolve`-ed) | ||
### Other Process Execution | ||
The execution of tasks generally must _originate_ from Builder, because of all | ||
of the environment enhancements it adds. So, for things that themselves exec | ||
or spawn processes, like `concurrently`, this can be a problem. Typically, you | ||
will need to have the actual command line processes invoked _by_ Builder. | ||
### Terminal Color | ||
Builder uses `exec` under the hood with piped `stdout` and `stderr`. Programs | ||
typically interpret the piped environment as "doesn't support color" and | ||
disable color. Consequently, you typically need to set a "**force color**" | ||
option on your executables in `scripts` commands if they exist. | ||
### Why Exec? | ||
So, why `exec` and not `spawn` or something similar that has a lot more process | ||
control and flexibility? The answer lies in the fact that most of what Builder | ||
consumes is shell strings to execute, like `script --foo --bar "Hi there"`. | ||
_Parsing_ these arguments into something easily consumable by `spawn` and always | ||
correct is quite challenging. `exec` works easily with straight strings, and | ||
since that is the target of `scripts` commands, that is what we use for Builder. | ||
### Versions v1, v2, v3 | ||
The `builder` project effectively starts at `v2.x.x`. Prior to that Builder was | ||
a small DOM utility that fell into disuse, so we repurposed it for a new | ||
wonderful destiny! But, because we follow semver, that means everything starts | ||
at `v2` and as a helpful tip / warning: | ||
> Treat `v2.x` as a `v0.x` release | ||
We'll try hard to keep it tight, but at our current velocity there are likely | ||
to be some bumps and API changes that won't adhere strictly to semver until | ||
things settle down in `v3.x`-on. | ||
[builder-react-component]: https://github.com/FormidableLabs/builder-react-component | ||
[trav_img]: https://api.travis-ci.org/FormidableLabs/builder.svg | ||
[trav_site]: https://travis-ci.org/FormidableLabs/builder |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
27332
12
538
0
0
312
4
3
4
3
+ Addedasync@^1.4.2
+ Addedchalk@^1.1.1
+ Addedjs-yaml@^3.4.3
+ Addedlodash@^3.10.1
+ Addedansi-regex@2.1.1(transitive)
+ Addedansi-styles@2.2.1(transitive)
+ Addedargparse@1.0.10(transitive)
+ Addedasync@1.5.2(transitive)
+ Addedchalk@1.1.3(transitive)
+ Addedescape-string-regexp@1.0.5(transitive)
+ Addedesprima@4.0.1(transitive)
+ Addedhas-ansi@2.0.0(transitive)
+ Addedjs-yaml@3.14.1(transitive)
+ Addedlodash@3.10.1(transitive)
+ Addedsprintf-js@1.0.3(transitive)
+ Addedstrip-ansi@3.0.1(transitive)
+ Addedsupports-color@2.0.0(transitive)