Giter Club home page Giter Club logo

brewer.js's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

jfrux qinliang760

brewer.js's Issues

Problem with resolving LESS importation tree

This bug concerns the automated actualization of compiled files from a set of LESS files referencing each other. It was noticed that if fileA "imports" fileB using the normal @import LESS directive, the output is correct, but the brewer make and brewer watch commands don't associate changes from fileB to the need to recompile fileA, which works nicely for other parsers.

The problem is indeed that we detect the importation tree and verify modification time based on our own # import directive, made up for coffeescript/javascript/etc family (because they don't have this concept; the closest is commonjs modules). There is no workaround, unless we change the way imports are handled for CSS-like languages.

Last hurdle I see for my implementation...

Is it possible for this to concat files that use different compilers?
For instance:

application.js

#import ["common.coffee","jquery.js"]

Ideally, the parser could identify the files provided and precompile them before bundling them.

Could we maybe add this to the File class to identify if there should be a precompile event prior to bundling?
Or is this already implemented and I'm just not seeing it?

It just seems like the Brewfile has to explicitly define which folders process coffee, and which ones process js, etc.?

Reversed imported files (in some cases)

As was reported by @compressed in #24:

One other question I have now in regards to the import line. I was playing around with importing some JS files from bootstrap. Does the import abide by the ordering of the files in the import? For instance, in my application.js (bundle) I have this:

// import ["jquery.js","bootstrap-tooltip.js","bootstrap-popover.js"]

but when I look at build/js/application.js (after running brake all) the code appears in the opposite order (popover first, then tooltip, then jquery last). Is that expected? I'd want JQuery first, followed by tooltip and then popover.

0.5 Roadmap

Server

A nice enhancement to the project, given we're going for the "tasking" features (see last section) for 0.5, would be that Brewer.js be able to "serve" assets. Also, a local webserver could also provide a graphical interface to manage Brewer.js projects. There should therefore be a system Node.js daemon (and child worker processes that handle serving files and the graphical web interface for Brewer.js)

Deployment

Deployment tasks (pushing to S3, (S)FTP, or Git) could be added to enhance the workflow.

Templates

Different options could be available for using and manipulating templates:

  • Brewer.js comes with included templates.
  • The user could have a .brewer_templates directory in his/her home folder.
  • The user could use or install templates from the web.

Templates should be prepared for different kind of projects that would benefit from Brewer.js (web site, static web site, Node.js project /w documentation).

Assets et al.

Interesting additions would be :

  • Gzip compression ahead-of-time of CSS and JS bundles
  • Image embedding in CSS
  • Image spriting
  • Docco documentation generation
  • Jekyll/Gollum static site generation

Also, when specifying paths to assets, it would be nice to allow globs in addition to folders.

Tasks

Every directive specified in a Brewfile could be viewed as expressions of structure or of "things to do", i.e. tasks. css, js barely express structure. less, stylus, coffeescript, etc. express structure, but also tasks (compilation). bundler express mainly tasks, just like some of the new directives from the ideas given here, such as serve, deploy, etc. Keeping this in mind, one should be able to organize tasks into higher level ones, using a task directive.

Can‘t import subfolder files in vendor directory on windows os

// in coffee/home.coffee
// import ["jquery", "chosen/chosen.jquery.js"]

The chosen/chosen.jquery.js file can't be imported on windowsos
Is not nodejs can not access file with '' as path separator on windows os ?

As a temporary solution, i change src/lib/file.js:168 to

return match[1].replace(/\//, '\\\\') + recurse(_data.slice(match[0].length + match.index));

0.4 Roadmap

We should reduce the number of classes and just increase the diversity of the vocabulary.

Removing the Package class

We need a Project class. The Package class existed only to accommodate de distinction between JavaScript and CSS bundles, and their distinctive needs. If we make the bundling process a separate thing, packages can be removed, and there would be only sources and projects.

(Almost) everything as sources

Sources can provide source files and encapsulate their own compilation process to provide different representations of source files. This concept of source is the same as before. Staying functionally compatible, though the nomenclature would need revision, the separate entity that generate bundled (and potentially compressed) assets could be thought of as a particular case of sources. It just interacts more tightly with the project to find files that match an access path and a type to aggregate bundled assets. Vendor libraries are also just sources, only more static.

New ideas

New kinds of sources and operations could include :

  • images and sprites
  • code inline documentation (docco-style)
  • javascript templates and compilation (for bundling and exchange)
  • static site generator (a la Jekyll)

Brewfile

The Brewfile is currently used to specify only the structure of a project. It could also be used to specify tasks and task-groups, such as what other build systems out there do (make, cake, rake).

Formulae Support

Brewer.js Formulae

Brewer.js Formulae are a easy way, for users of Brewer.js, to install vendor libraries
into their project. Formulae can easily be added to this directory and immediately
available to Brewer.js users, by forking the project, adding a formula and making a pull
request to merge in your new-born formula.

Structure of a formula

A formula file can include one or more formulae, tightly related to each other. For example,
the jquery.coffee formula file contains a jquery formula and a jquery-dev formula.This is the directive that starts off the definition of a formula

formula '<formula_name>', ->

Within the body of this formula definition, the following methods can be used:

@urls

Required. This tells Brewer.js at what URL it can download the library. This can be in one of three
forms. The first is through the use of a function that takes a single argument, a version. This version
is an object that can be coerced to its string representation. It also contain its major, minor,
patch and tag components (assuming [major].[minor].[patch]-[tag])

  @urls (v) ->
    "https://ajax.googleapis.com/ajax/libs/jquery/#{v}/jquery.js"

The second form is through an object, with keys being either versions, version ranges or the 'latest'
keyword. The values can be a URL string or a function, like above:

  @urls
    "latest": "https://github.com/jquery/jquery/tarball/master"
    "1.X.X": (v) ->
      v = if v.patch is '0' then "#{v.major}.#{v.minor}" else v
      "https://github.com/jquery/jquery/tarball/#{v}"

The last, and the simplest, is a single URL string in an anonymous function:

  @urls -> 'https://raw.github.com/douglascrockford/JSON-js/master/json2.js'

In fact, this is the same form as the first. We just simply didn't take the version into account.

@exports

Required. This tells Brewer.js how it should interact with a staged vendor library. A vendor
library could contain, like in the case of bootstrap, a mix of javascript and less files. For that case,
a formula for bootstrap could contain the following snippet:

  @exports ->
    @javascript './js'
    @less './less',  {prefix: 'styles'}
    @main 'less', './less/bootstrap.less'

This shows a few characteristics of an @exports directive. First, @exports is followed by an anonymous
function, whose body will specify the individual directories to include, using the @dir directive. This
function receives a single argument: the installed version. This allows the function body to vary its
the structure of the vendor library according to the version installed.
The @main directive is used to specify a main source file (for a particular type) for the vendor library. It
has the form @main(<type>, <relative path>). For the case above, it adds a shorter access path
of simply bootstrap, pointing to the file located at ./less/bootstrap.less. @less, @javascript (and
friends) have the form of @<source_type>(<relative path>, [<options>]). They are meant to look a lot like
the sources found in a package. Each of those will be added as sources in the project packages, thus
the resemblance. The trailing options object can provide the following values:

  • prefix

    This value will be prepended when calculating the access path of files contained in the directory. For
    example, using the snippet above, assuming the @exports directive is contain in a bootstrap formula, the
    file alerts.less found in the ./less directory would have an access path of bootstrap/styles/alerts.

  • main

    This value is simply a path pointing to a file (relative to the path of the directory, not to that of the
    vendor library). If prefix was provided, like in the case above it, it specifies what file should be
    pointed to by the access path of <project name>/<prefix>. Otherwise, it specifies the file pointed by
    <project name>. Without the prefix option, this is equivalent to the @main directive.

    For some really simple formulae, the @exports directive can be of another form, which is:

  @exports <type>, <option>
  # equivalent to
  @exports ->
    @<type> '.', <option>

This implies that the whole vendor library is added as a single source, of the type provided, with the given
options.

@install

This is the directive that specify how to install the vendor library. It takes a single argument: an anonymous
function called when installing the library. This function receives the installed version as its only argument.
In the function body, a couple of methods are made available:

  • @stage(<path>, [<new name>])

    This method takes the path provided as the first argument and puts it in the staged vendor library, under a
    new name if <new name> is provided.

  • @deflate(<path>, <compression>, <callback>)

    This method takes a path and decompresses it using the compression provided (can be either zip, tar,
    tar.gz or tar.bz2). When it finishes, it invokes the callback with the list of files extracted as
    argument.

    More methods will be made available to the installer body as the needs emerge.

@versions

What versions are available, if applicable. This can be in the form of an object, mapping versions to md5
checksums, for better reliability. The versions must comply to semantic versioning:

  @versions '1.6.4', '1.7.1'
  @versions
    '1.6.4': 'be5cda8fa534e4db49425efbbf36c565'
    '1.7.1': '273e017fd0bef143258516bdee173a1e'

@homepage

This helps keep track of homepages for the installed vendor libraries. It has the form of @homepage(<url>)

@doc

This function can be in either of the forms allowed by @urls. It is used to keep
track of where to find proper documentation for the installed vendor libraries.

Explore!

Feel free to glimpse through the existing example to get a better understanding of formulae, and how you can
roll your own! Current work is going on in the 0.4 branch (previously the formula branch, but it has been merged in view of the upcoming 0.4 release).

Cannot read property 'prototype' of undefined

Hi!

Installation goes fine but when running "brake init", it throws the following stack trace:

$ brake init
Info Writing Brewfile
Info Making initial folder structure

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
TypeError: Cannot read property 'prototype' of undefined
    at /usr/local/lib/node_modules/brewer/lib/extensions/iced-coffee-script.js:4:199
    at /usr/local/lib/node_modules/brewer/lib/extensions/iced-coffee-script.js:12:5
    at Object.<anonymous> (/usr/local/lib/node_modules/brewer/lib/extensions/iced-coffee-script.js:58:4)
    at Object.<anonymous> (/usr/local/lib/node_modules/brewer/lib/extensions/iced-coffee-script.js:62:4)
    at Module._compile (module.js:441:26)
    at Object..js (module.js:459:10)
    at Module.load (module.js:348:31)
    at Function._load (module.js:308:12)
    at Module.require (module.js:354:17)
    at require (module.js:370:17)
$ npm --versions
{ node: '0.6.15',
  v8: '3.6.6.24',
  ares: '1.7.5-DEV',
  uv: '0.6',
  openssl: '0.9.8k',
  npm: '1.1.16' }
$ uname -a
Linux laptop 2.6.32-41-generic #89-Ubuntu SMP Fri Apr 27 22:18:56 UTC 2012 x86_64 GNU/Linux

Can't generate compressed output file

Hi, this looks like a really awesome project, just what I was looking for!

However, I seem to be having an issue running even the most simple example (css or js).

I set up a repo here: https://github.com/compressed/test-brewer.

When I run "brake all" in the command line this is what I get:

[master][~/Documents/web/test-brewer] brake all
Info Finished making styles package

which proceeds to make a vendor directory and that's it. No .cache folder or any output in the build dir. Can you help point me to what I'm missing?

Thanks!

Version info:

├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected] extraneous
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │   └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │   └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│   └─┬ [email protected]
│     └── [email protected]

Too many open files

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
Error: EMFILE, too many open files 'assets/src/_cache/common.js'
    at Object.openSync (fs.js:230:18)
    at Object.readFileSync (fs.js:120:15)
    at Object.checksumSync (/usr/local/lib/node_modules/brewer/lib/util.js:17:19)
    at File.stamp (/usr/local/lib/node_modules/brewer/lib/file.js:128:35)
    at File.watch (/usr/local/lib/node_modules/brewer/lib/file.js:99:14)
    at /usr/local/lib/node_modules/brewer/lib/package.js:226:35
    at Array.0 (/usr/local/lib/node_modules/brewer/lib/package.js:229:12)
    at EventEmitter._tickCallback (node.js:192:40)

Feature to specify specific files to watch?

I know this isn't "sprockets" but it would be nice to be able to use it similar to sprockets since it's Node instead of Ruby...

Ideally, if I could setup a specific asset like in Rails Asset Pipeline like "app/assets/javascripts/application.js" and "app/assets/stylesheets/stylesheets/application.css" and put some base @import directives in it, then those files could also contain @import directives and it would branch out from there.

Then, I'd like a place to specify the final package file + minified as such ./public/assets/javascripts/application.js / application.min.js and ./public/assets/stylesheets/application.css / application.min.css respectively.

I'm not barking orders, I'd love it if I could help implement some of these things.
If these don't seem like reasonable expectations of this particular bundler then I understand! :X

Importation directives

Related to #3, but in a more general sense, the whole mecanism for importation and bundling (a concept only relevant to bundled web assets) should be reworked, I think to be more robust and factored out of the main Package class to a more specific class, maybe something like AssetPackage.

Editing files in Vim breaks 'watch' command

I've got a project containing only coffeescript files. Whenever I edit the files in Vim (in this case the file "Condition.coffee"), the 'watch' command appears to try and monitor all of vim's transient save files. As a result, brake tries to work with files that have vanished since it first discovered them. The result is that the file count goes up and then a crash occurs.

Info Watching project /Users/zack/bugdemo
Compiled coffee/Condition.coffee
Info Watching 13 files
Info coffee/Condition.coffee removed
Info coffee/Condition.coffee removed
Compiled coffee/Condition.coffee
Compiled coffee/Condition.coffee
Info Watching 14 files
Info Watching 26 files
Info coffee/Condition.coffee removed
Info coffee/Condition.coffee removed

events.js:66
throw arguments[1]; // Unhandled 'error' event
^
Error: ENOENT, lstat 'coffee/Condition.coffee~'

This behavior does not occur when I use sublime text 2 to edit the code.

OS X 10.7
Node 0.8.9
brake 0.3.7

Install Fails on OSX 10.8.2 and brake watch doesn't include new files

Just ran an install on my OSX 10.8.2 machine and after the install "completes" running brake from the command line doesn't work (brake: command not found). You have to run brake using the full path which is something like /usr/local/share/npm/bin/brake

Also, when you run /usr/local/share/npm/bin/brake watch it does not add any new files even if you do a brake clean on the directory. In my case I was trying to add javascript with various names and all access permissions to no avail. The brake watch command did notice file changes, just not new files.

Versions:
npm 1.20
node v0.8.17

Compression/Build

brake watch should only build the uncompressed output. When several large files are produced, compression slows down the automatic reloading experience.

Latest Uglify-JS is incompatible

I was able to use 'npm install -g uglify-js@1' and get the previous version which appears to be fine. Here's the error generated by using v2.x:

/nodejs/lib/node_modules/brewer/lib/extensions/javascript.js:36
gen_code = uglify.gen_code, ast_squeeze = uglify.ast_squeeze, ast_mang
^
TypeError: Cannot read property 'gen_code' of undefined
at JavascriptPackage.compressFile.compress (/nodejs/lib/node_modules/brewer/lib/extensions/javascript.js:36:26)
at File.project (/nodejs/lib/node_modules/brewer/lib/file.js:89:16)
at File.read (/nodejs/lib/node_modules/brewer/lib/file.js:283:16)
at fs.readFile (fs.js:176:14)
at Object.oncomplete (fs.js:297:15)

Maximum call stack size exceeded

When building documentation assets and compressing CSS, we get that message

/Users/mathieudamours/development/node/brewer/node_modules/ncss/lib/parser.js:275
        if (KEYWORDS.indexOf(t) >= 0) q(t);
                     ^
RangeError: Maximum call stack size exceeded

Add Merge & Minify

Combine (merge) & minify files to one "big" file.

Specify list of files list in Brewfile and merge it defined one. Eg.:

javascript 'package_name', ->
  @options {build: './build', compress: true}

  @bundles 'home', 'products'

  @coffeescript './coffee'
  @js './vendor'

  @package 'home'
  @package 'products'

  # OR

  @package 'home', 'products'

Create file ./build/package_name.min.js with merged home and product.

Maybe add support "package" directory but:

However, if you provide directories, how do you deal with the ordering of files that are found within? If files depend on one another, you probably need them inserted in the concatenated file in a certain order, so you would need a mechanism to specify the order of files found in a given dir. Obviously, you wouldn't need this when manually providing files since you provide the order just by doing so.

BUG: dot in bundles

javascript 'scripts', {build: './build/js'} ->
    @bundles 'home', 'products', 'jquery.pjax'

    @coffeescript './coffee', {output: './js'}
    @js './vendor'
/usr/lib/node_modules/brewer/lib/file.js:156
          if ((match = _data.match(regexp)) == null) return '';
                             ^
TypeError: Cannot call method 'match' of undefined
    at /usr/lib/node_modules/brewer/lib/file.js:156:30
    at File.readImportedPaths (/usr/lib/node_modules/brewer/lib/file.js:159:25)
    at File.importedPaths (/usr/lib/node_modules/brewer/lib/file.js:181:36)
    at File.<anonymous> (/usr/lib/node_modules/brewer/lib/file.js:191:23)
    at File.imports (/usr/lib/node_modules/brewer/lib/file.js:198:12)
    at /usr/lib/node_modules/brewer/lib/file.js:223:21
    at /usr/lib/node_modules/brewer/lib/file.js:211:13
    at File.dependOnImports (/usr/lib/node_modules/brewer/lib/file.js:231:14)
    at JavascriptPackage.<anonymous> (/usr/lib/node_modules/brewer/lib/package.js:101:18)
    at JavascriptPackage.emit (events.js:67:17)

fs.stat.name causing a problem on windows

First i use 'brake scripts' on windows os, i received this:

path.js:204
throw new TypeError('Arguments to path.join must be strings');
^
TypeError: Arguments to path.join must be strings
at f (path.js:204:15)
at Object.filter (native)
at exports.join (path.js:209:40)
at Walker. (C:\Users***\npm\node_modules\brewer\lib\source.js:116:17)
at Walker.EventEmitter.emit (events.js:98:17)
at C:\Users***\npm\node_modules\brewer\node_modules\walker\lib\walker.js:98:12
at Object.oncomplete (fs.js:93:15)

source.js:116 is

walker.on('file', function(root, stat) {
  var fpath;
  fpath = join(root.slice(rpath.length + 1), stat.name);

I console.log stat.name, found stat has no [name] attribute, i use Windows 7(x86)
then, i delete the stat.name arg, found that it can also work well

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.