Giter VIP home page Giter VIP logo

modules-webmake's Introduction

*nix build status Windows build status Transpilation status npm version

modules-webmake

Bundle CommonJS/Node.js modules for web browsers.

Webmake allows you to organize JavaScript code for the browser the same way as you do for Node.js.

  • Work with best dependency management system that JavaScript currently has.
  • Easily, without boilerplate, reuse your modules in any environment that runs JavaScript.
    No matter if it's a server, client (any web browser) any other custom environment as e.g. Adobe Photoshop, or let's say your dishwasher if it speaks JavaScript.
  • Require CSS and HTML files same way. Webmake allows you to require them too, which makes it a full stack modules bundler for a web browser.

Files support can be extended to any other format that compiles to one of .js, .json, .css or .html. See custom extensions for more information.

For a more in depth look into JavaScript modules and the reason for Webmake, see the slides from my presentation at Warsaw's MeetJS: JavaScript Modules Done Right

If you wonder how Webmake compares with other solutions, see comparison section

How does dependency resolution work?

As it has been stated, Webmake completely follows Node.js in that

Let's say in package named foo you have following individual module files:

add.js

module.exports = function () {
  var sum = 0, i = 0, args = arguments, l = args.length;
  while (i < l) sum += args[i++];
  return sum;
};

increment.js

var add = require("./add");
module.exports = function (val) { return add(val, 1); };

program.js

var inc = require("./increment");
var a = 1;
inc(a); // 2

Let's pack program.js with all it's dependencies so it will work in browsers:

$ webmake program.js bundle.js

The generated file bundle.js now contains the following:

(function (modules) {
  // about 60 lines of import/export path resolution logic
})({
  foo: {
    "add.js": function (exports, module, require) {
      module.exports = function () {
        var sum = 0, i = 0, args = arguments, l = args.length;
        while (i < l) sum += args[i++];
        return sum;
      };
    },
    "increment.js": function (exports, module, require) {
      var add = require("./add");
      module.exports = function (val) { return add(val, 1); };
    },
    "program.js": function (exports, module, require) {
      var inc = require("./increment");
      var a = 1;
      inc(a); // 2
    }
  }
})("foo/program");

When loaded in browser, program.js module is executed immediately.

Working with HTML and CSS

Technically you can construct whole website that way:

body.html

<h1>Hello from NodeJS module</h1>
<p><a href="https://github.com/medikoo/modules-webmake">See Webmake for more details</a></p>

style.css

body {
  font-family: Arial, Helvetica, sans-serif;
}
h1,
p {
  margin: 20px;
}
p.footer {
  font-size: 14px;
}

program.js

document.title = "Hello from NodeJS module";

require("./style");

document.body.innerHTML = require("./body");

var footer = document.body.appendChild(document.createElement("p"));
footer.className = "footer";
footer.innerHTML = "Generated by Webmake!";

Bundle it

$ webmake program.js bundle.js

See it working, by including it within document as such:

<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<body>
  <script src="bundle.js"></script>
</body>

Installation

$ npm install -g webmake

Usage

From the shell:

$ webmake [options] <input> [<output>]

input - Path to the initial module that should be executed when script is loaded.
output - (optional) Filename at which browser ready bundle should be saved. If not provided generated bundle is streamed to stdout.

Options

name string

Name at which program should be exposed in your namespace. Technically just assigns exported module to global namespace.

amd string

Expose bundle as AMD module. If used together with name option, module will be defined with provided name.

cjs string

Expose bundle as CJS module.

include string

Additional module(s) that should be included but due specific reasons are not picked by parser (can be set multiple times)

ext string

Additional extensions(s) that should be used for modules resolution from custom formats e.g. coffee-script or yaml.
See extensions section for more info.

sourceMap boolean (command line: sourcemap)

Include source maps, for easier debugging. Source maps work very well in WebKit and Chrome's web inspector. Firefox's Firebug however has some issues.

ignoreErrors boolean (command line: ignore-errors)

Ignore not parsable require paths (e.g. require('./lang/' + lang)) or not polyfilled native modules requires (e.g. require('fs')) if any.
Dynamic paths in require calls are considered a bad practice and won't be possible with upcoming ES6 modules standard. Still if we deal with modules that do that, we can workaround it by turning this option on, and including missing modules with include option.

useStrict boolean (command line: use-strict)

Enforce strict mode globally. Mind that by default in node.js environment CJS modules are not executed in strict mode. Relying on that feature may rise incompatibility issues in corner case scenarios.

cache boolean programmatical usage only

Cache files content and its calculated dependencies. On repeated request only modified files are re-read and parsed.
Speeds up re-generation of Webmake bundle, useful when Webmake is bound to server process, see below example.
Highly recommended if extensions are used. Defaults to false.

transform function programmatical usage only

Provide a transform middleware. transform callback would be called on each module, with arguments: absolute filename and file code (as it is in origin file, before any internal transformations). If source module is meant to be processed by one of the extensions, you'll receive origin code before extension logic is applied, and you must return code that's valid for extension processor. So e.g. if you transform LESS code, you need to return valid LESS code

If you're interested only in applying transform to e.g. js files, be sure to filter your actions on basis of filename, and return code as you received if non transforms should be applied

In case of asynchronous operations, promise maybe returned, but it has to be promise that origins from deferred package.

webmake(programPath, { transform: function (filename, code) {
  return transformCode(code)
} }

transformCode function should return either plain transformed code string, or an object, with code and sourceMap properties, if we want to accompany our transform with a sourceMap.

Programmatically:

webmake(programPath[, options][, callback]);

webmake by default returns generated source to callback, but if output path is provided as one of the options, then source will be automatically saved to file

Development with Webmake

Currently best way is to use Webmake programmatically and setup a static-file server to generate bundle on each request. Webmake is fast, so it's acceptable approach even you bundle hundreds of modules at once.

You can setup simple static server as it's shown in following example script.
Example also uses node-static module to serve other static files (CSS, images etc.) if you don't need it, just adjust code up to your needs.

// Dependencies:
var createServer = require("http").createServer;
var staticServer = require("node-static").Server;
var webmake = require("webmake");

// Settings:
// Project path:
var projectPath = "/Users/open-web-user/Projects/Awesome";
// Public folder path (statics)
var staticsPath = projectPath + "/public";
// Path to js program file
var programPath = projectPath + "/lib/public/main.js";
// Server port:
var port = 8000;
// Url at which we want to serve generated js file
var programUrl = "/j/main.js";

// Setup statics server
staticServer = new staticServer(staticsPath);

// Initialize http server
createServer(function (req, res) {
  // Start the flow (new Stream API demands that)
  req.resume();
  // Respond to request
  req.on("end", function () {
    if (req.url === programUrl) {
      // Generate bundle with Webmake

      // Send headers
      res.writeHead(200, {
        "Content-Type": "application/javascript; charset=utf-8",
        // Do not cache generated bundle
        "Cache-Control": "no-cache"
      });

      var time = Date.now();
      webmake(programPath, { sourceMap: true, cache: true }, function (err, content) {
        if (err) {
          console.error("Webmake error: " + err.message);
          // Expose eventual error brutally in browser
          res.end(
            "document.write('<div style=\"font-size: 1.6em; padding: 1em;" +
              " text-align: left; font-weight: bold; color: red;" +
              " position: absolute; top: 1em; left: 10%; width: 80%;" +
              " background: white; background: rgba(255,255,255,0.9);" +
              " border: 1px solid #ccc;\"><div>Could not generate " +
              programUrl +
              "</div><div style=\"font-size: 0.8em; padding-top: 1em\">" +
              err.message.replace(/'/g, "\\'") +
              "</div></div>');"
          );
          return;
        }

        // Send script
        console.log("Webmake OK (" + ((Date.now() - time) / 1000).toFixed(3) + "s)");
        res.end(content);
      });
    } else {
      // Serve static file
      staticServer.serve(req, res);
    }
  });
}).listen(port);
console.log("Server started");

Using Webmake with Express or Connect

See webmake-middleware prepared by Gilles Ruppert.

Using Webmake with Grunt

See grunt-webmake prepared by Sakata Makoto.

Working with other module systems

When you work with old school scripts or framework that uses different modules system, then you'd rather just bundle needed utilities (not whole application) and expose them to global scope.

Webassemble written by Ken Chen provides a convinient way to expose different packages, written CJS style, to outer scripts. It automatically creates one entry package that does the job and is used as a starting point for a Webmake bundle.

Extensions

Extensions published on NPM

JS
JSON
CSS

Submit any missing extension via new issue form.

Using extensions with Webmake

Install chosen extension:

EXT should be replaced by name of available extension of your choice.

$ npm install webmake-EXT

If you use global installation of Webmake, then extension also needs to be installed globally:

$ npm install -g webmake-EXT

When extension is installed, you need to ask Webmake to use it:

$ webmake --ext=EXT program.js bundle.js

Same way if used programmatically:

webmake(inputPath, { ext: "EXT" }, cb);

Multiple extensions can be used together:

$ webmake --ext=EXT --ext=EXT2 program.js bundle.js

Programmatically:

webmake(inputPath, { ext: ["EXT", "EXT2"] }, cb);

Writing an extension for a new format

Prepare a webmake-* NPM package (replace '*' with name of your extension), where main module is configured as in following example:

// Define a file extension of a new format, can be an array e.g. ['sass', 'scss']
exports.extension = "coffee";

// Which type is addressed by extension (can be either 'js', 'json', 'css' or 'html')
exports.type = "js";

// Define a compile function, that for given source code, produces valid body of a JavaScript module:
exports.compile = function (source, options) {
  // Return plain object, with compiled body assigned to `code` property.
  return { code: compile(source) };

  // If compilation for some reason is asynchronous then assign promise
  // (as produced by deferred library) which resolves with expected code body
  return { code: compileAsync(source) };

  // If custom format provides a way to calculate a source map and `sourceMap` options is on
  // it's nice to generate it:
  var data, map, code;
  if (options.sourceMap) {
    data = compile(source, { sourceMap: true });

    // Include original file in the map.
    map = JSON.parse(data.sourceMap);
    map.file = options.generatedFilename;
    map.sources = [options.localFilename];
    map.sourcesContent = [source];
    map = JSON.stringify(map);

    return { code: code, sourceMap: map };
  }
};

Providing extensions programmatically

Extension doesn't need to be installed as package, you may pass it programmatically:

webmake(
  inputPath,
  {
    ext: {
      name: "coffee-script",
      extension: "coffee",
      type: "js",
      compile: function (source, options) {
        /* ... */
      }
    }
  },
  cb
);

See below writing extensions section to see how to configure fully working extensions

Writing extesions for either JSON, CSS or HTML

Be sure to state the right type, and return string that reflects addressed format (not JavaScript code) e.g. extension for CSS:

exports.extension = "less";
exports.type = "css";
exports.compile = function (source, options) {
  return { code: compileToCSS(source) }; // `compileToCSS` returns plain CSS string
};

Publish it and refer to Using extensions section for usage instructions.
Finally if everything works, please let me know, so I can update this document with link to your extension.

Comparison with other solutions

AMD

AMD is different format, and although most popular loader for AMD is named RequireJS it works very differently from require as introduced earlier with CommonJS (one that Webmake handles).

Main idea behind AMD is that dependencies are resolved asynchronously (in contrary to synchronous resolution in case of CommonJS format). Sounds promising, but does it really make things better? Cause of waterfall nature of resolution and large number of HTTP requests not necessary. See benchmark that compares resolution speed of both formats when used in development mode.

Agreed advantage of AMD that attributes to its success is that in it's direct form works in a browser (it doesn't require any server setup), that is hard to achieve with CJS style (but not impossible). Still due to large number of requests such approach is usually not suitable for production and it appears it's also not that performant in development mode.

Quirks of AMD style is that it requires you to wrap all your modules with function wrappers, its modules are not runnable in direct form in Node.js and dependency resolution rules are basic and limited if you compare it with design of node.js + npm ecosystem.

Browserify and other CJS bundlers

Browserify is most popular CJS bundler, and shares very similar idea. The subtle difference is that Browserify is about porting code as written for node.js to web browser, so apart of resolving dependencies and bundling the code it struggles to bring what is needed and possible from Node.js API to the browser.

Webmake cares only about bringing node.js modules format to other environments. Conceptually it's addition to ECMAScript and not port of node.js to browser. It makes node.js modules format runnable in any environment that speaks at least ECMAScript 3. You can bundle with Webmake for Browser, TV, Adobe Photoshop or maybe a modern dishwasher.

When comparing with other CJS bundlers, main difference would be that Webmake completely follows resolution logic as it works in node.js. It resolves both packages and modules exactly as node.js, and it doesn't introduce any different ways to do that. Thanks to that, you can be sure that your modules are runnable in it's direct form both on server and client-side.

Other important difference is that Webmake doesn't do full AST scan to parse require's out of modules, it relies on find-requires module, which does only what's necessary to resolve dependencies list, and that makes it a noticeably faster solution.

ES6 modules

Soon to be released, native JavaScript modules spec shares the main concept with CommmonJS. Thanks to that eventual transition will be easy and can be fully automated. First transpilers are already here.

As soon as the standard will be finalized, implemented in first engines and possibly adapted by node.js Webmake will support it natively as well, then in a same way it will bundle it either for the sake of a bundle or for any ECMAScript 3+ environment that won't take it in natural way.

Current limitations of Webmake

The application calculates dependencies via static analysis of source code (with the help of the find-requires module). So in some edge cases not all require calls can be found. You can workaround that with help of include option

Only relative paths and outer packages paths are supported, following will work:

require("./module-in-same-folder");
require("./module/path/deeper");
require("./some/very/very/very/long" + "/module/path");
require("../../module-path-up"); // unless it doesn't go out of package scope
require("other-package");
require("other-package/lib/some-module");

But this won't:

require("/Users/foo/projects/awesome/my-module");

Different versions of same package will collide:
Let's say, package A uses version 0.2 of package C and package B uses version 0.3 of the same package. If both package A and B are required, package B will most likely end up buggy. This is because webmake will only bundle the version that was called first. So in this case package B will end up with version 0.2 instead of 0.3.

Tests

$ npm test

Proud list of SPONSORS!

@puzrin (Vitaly Puzrin) member of Nodeca

Vitaly pushed forward development of support for JSON files, extensions functionality, along with webmake-yaml extension. Vitaly is a member of a team that is behind js-yaml JavaScript YAML parser and dumper, and powerful social platform Nodeca. Big Thank You Vitaly!

Contributors

  • @Phoscur (Justus Maier)
    • Help with source map feature
  • @jaap3 (Jaap Roes)
    • Documentation quality improvements

'Issue 2198: @sourceURL doesn't work in eval() in some cases'

modules-webmake's People

Contributors

jaap3 avatar lucjan avatar medikoo avatar

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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

modules-webmake's Issues

Parse error for scripts with a shebang

Webmake is currently unable to parse scripts with a shebang (#!/usr/bin/env node).

While I would agree entirely that this should never be necessary (command line scripts should only be a tiny wrapper that calls something require-able), there are poorly packaged modules out there which get this wrong.

Any thoughts on whether webmake should support this? How easy would this be to add?

Thanks.

Include paths

It would be very nice to have a --includePath option for e.g. lib files (at least for the command line version of webmake).

Example:

$ = require("jquery");

webmake would first look for jquery.js in the current directory and if it isn't there, webmake would look in the directory specified with

--includePath path/to/libdir

jquery include broken in latest webmake

Hi there,

we have a project using [email protected] and client-side jquery that broke in webmake@latest because it no longer finds the include path.

Working under 0.3.12:

folder structure:
node_modules
---> jquery with commonjs wrapper
require('jquery');

In @latest it complains

Error: Module 'jquery' not found

I need the client-side jquery but for testing purposes I tried 'npm install jquery' based on the tip given in another issue but in @0.3.12 I get

TypeError: Not supported require call: ''./jsdom/level' + level + '/' + feature'

and in @latest I get

Not parsable require call (ignored): `'./jsdom/level' + level + '/' + feature` at /home/dev/test/node_modules/jquery/node_modules/jsdom/lib/jsdom.js:35
Not parsable require call (ignored): `__dirname + "/../selectors/index"` at /home/dev/test/node_modules/jquery/node_modules/jsdom/lib/jsdom/browser/index.js:70
Webmake returned Error: Module 'node-htmlparser/lib/node-htmlparser' not found, as required in '/home/dev/test/node_modules/jquery/node_modules/jsdom/lib/jsdom/browser/index.js'
Not parsable require call (ignored): `n` at /home/dev/test/node_modules/jquery/node_modules/contextify/node_modules/bindings/bindings.js:76

Is there a bug here or am I doing something wrong? Thanks

Code Splitting

GWT has a cool feature named Code Splitting which loads parts of the code on demand. This is also appliable for webmake.

Here my idea:

// a.js:
var b = require("b");
// ...
bindEventHandlerForSomeRarEvent(function() {
  // the magic keyword "process.nextTick", which behaves normally in node.js
  // but so some special thing in webmake
  process.nextTick(function(err) {
    // Some code loading err handler
    // err is undefined in node.js
    if(err) { /* ... */ }
    var c = require("c"); // really big libary, which is only needed in this rar case
    // ...
  });
});

webmake core would provide the magic process.nextTick function to the compiled code.
process.nextTick do this in the compiled code:

  • store the callback function
  • adds a script tag to the document
  • the script contains JSONP
  • callback function (JSONP) adds some new modules to the context
  • and calls the stored callback function.
  • in case of an error (ex. timeout) the stored callback function is called with some kind of error parameter

Here is a quick hint on the compiled files:

// output.js
( /* core code */
({
  "a": function(/* ... */, process) {
     // a.js:
     var b = require("b");
     // ...
     bindEventHandlerForSomeRarEvent(function() {
       // the magic keyword, which behaves normally in node.js
       // but so some special thing in webmake
       process.nextTick(function(err) {
         // Some code loading err handler
         // err is undefined in node.js
         if(err) { /* ... */ }
         var c = require("c"); // really big libary, 
               // which is only needed in this rar case
         // ...
       });
     });
  },
  "b": function /* content of b.js */
  // here is no "c": !!
  // which saves bandwidth
// may be named "a.output.js":
webmake_magic_jsonp_function( // the jsonp callback function
"a", // origin of code loading (used for identifing the stored function)
{
  "c": function(/* ... */, process) {
    // the content of the big libary
  },
  "d": function(/* ... */, process) {
    // d.js is here a dependency of c.js (optional)
  }
}

This feature may makes the compile process a big complexer.

It may be useful for:

  • loading parts of your webapp when accessing them
  • loading polyfills only when necessary
  • decrease startup time

Native module errors are still fatal, even with ignoreErrors

With webmake 0.3.23, a native module still causes a fatal error, even with ignoreErrors.

In this particular case I am trying to create a test runner using chai. Chai uses a try-catch around require('buffer'), so I want to ignore the error in webmake and leave this for chai to catch at runtime.

According to the docs, this should work as I desire...

ignoreErrors boolean (command line: ignore-errors)

Ignore not parsable require paths (e.g. require('./lang/' + lang)) or not polyfilled native modules requires (e.g. require('fs')) if any.

Thanks.

Ability to validate or transform each included file

For a side project, I'm running the bundled code through a JS syntax checker to catch errors before they get to the browser. The problem is, the line numbers are off because it isn't checking the individual files.

Is it possible to have a function called for each file webmake comes across (new / modified if cached: true), to do some kind of application-level validation? If not, I have a couple thoughts.

  1. Add a validate option that takes a callback that returns a true if the file is valid, or a string/Error/object if not, which indicates the problem
  2. Add a transform option that takes a callback that returns the actual code to use by webmake

For what I'm doing, the former is fine, but the latter is more general (and slightly more complex in implementation). In either case, if an error is raised, that can be passed to err in webmake's callback.

Is this already possible or in the roadmap? If not, what are your thoughts?

Local modules and stdin causes webmake to hang

Hi.

When using webmake with input from stdin, it hangs if any local modules are required.

For example:

// foo.js
require('./bar');

Using the files as normal works:

webmake foo.js

But using stdin causes webmake to hang indefinitely.

cat foo.js | webmake

I did a bit of debugging on this and it appears to be searching for [cwd]/:stdin:/bar.js. It tries all the extensions and then hangs.

I guess there are two unrelated bugs here, it hangs if the file is not found, and it doesn't search the right path when loading from stdin.

Thanks.
Simon

Allow explicit replacement of modules

Given two module names, webmake should be able to include the second instead of the first. This way serverside modules can be easily get a more fitting counterpart on the browserside.
Also webmake could read a new custom directory like browser_modules to use those instead of their node_modules counterparts.

Does not work on Windows

On my test project, I get the following error:

Fatal error: Module '..srcuser.js' not found, as required in 'c:\[snip]\dest\output-pre.js'

The contents of output-pre.js is:

// ----- Exports from _assets/example/src/main.js -----

// ----- Exports from _assets/example/src/user.js -----
exports.User = require('..\src\user.js').User;

Of course, backslash is the escape character in Javascript strings, so the above should, I suppose, read ..\\src\\user.js.

Thoughts?

Asynchronous extension compiler

Have you given any thought to allowing asynchronous extensions? After looking through the code it doesn't seem to be possible unless I'm missing something, which is possible.

Wrong transformation for empty module for special case

  1. Download the sample - http://content.screencast.com/users/miherlosev/folders/TestCafe/media/4814bdd8-ea5c-42dd-b642-ff5bf16542c8/babel-runtime-core-js_2.zip?downloadOnly=true.
  2. Install node modules and run the gulp task.
  3. Inspect /processed/index.js. It contains strange code:
    "es6.object.to-string.js": function (exports, module, require) { [object Object] },
  4. The code has been generated for the module 'babel-runtime\node_modules\core-js\library\modules\es6.object.to-string.js' which is empty.

Simple for empty module all works good.

Register extensions without their own npm module

It would be really nice to be able to register extensions without having to publish them on NPM.

Syntax might be to add an object to the extensions array, like:

webmake('input.js', {
  exts: [
    'coffee', // Uses webmake-coffee
    {
      extension: 'eco',
      compile: function(src, options) {/* eco -> js */}
    }
  ]
}, callback);

No need for compile overhead in dev mode

Is it possible to reduce the compile overhead in development by serving the raw files?
This may be possible if require(...) do a blocking ajax request with eval.
Maybe a small server-side node.js proxy can do the path resolution, if not possible on client-side.

Support Node.js environment in a bundle

It's to allow possibility to run bundles in Node.js environment with use of Node's native modules

Currently such bundles can be created with ignoreErrors option, but they won't work as internal require mechanism won't fallback to native require in case of native modules.

Best solution is probably to introduce --node option, through which we can explicitly state that we want to run result in node environment.

solution comparison

README/wiki should have a comparison to.. browserify, requirejs, etc
What are the goals, the advantages, the trade-offs

Otherwise I might be just stubborn, but I see no point in changing my current setup.

Path of initial script has 2 leading /

I am using webmake on the cli. This is the command I'm using:

webmake app/main.js build.js

The output of the buildfile is along these lines:

(function(modules) {
  // webmake code
})
(
  // my modules
)
("//path/to/main.js");

This fails. When I manually edit the path on the last line to "/path/to/main.js", it all works fine.

I had a bit of a look around the webmake source:

The issue happens in the parser.js#readInput() method where the path is created. The name var is set to / and the separator is set to / as well, which leads to the wrong path.

I installed webmake with the dev dependencies to run the tests. This is the output:

info it worked if it ends with ok
verbose cli [ 'node', '/usr/local/bin/npm', 'test' ]
info using [email protected]
info using [email protected]
verbose /usr/local/bin/node node symlink
verbose config file /Users/gillesruppert/.npmrc
verbose config file /usr/local/etc/npmrc
verbose config file /usr/local/lib/node_modules/npm/npmrc
verbose caching /usr/local/lib/node_modules/webmake/package.json
verbose run-script [ 'pretest', 'test', 'posttest' ]
info pretest [email protected]
info test [email protected]
verbose unsafe-perm in lifecycle true
silly exec sh "-c" "node ./node_modules/tad/bin/tad lib"
silly spawning [ 'sh',
silly spawning   [ '-c', 'node ./node_modules/tad/bin/tad lib' ],
silly spawning   '/usr/local/lib/node_modules/webmake' ]
info [email protected] Failed to exec test script
ERR! [email protected] test: `node ./node_modules/tad/bin/tad lib`
ERR! `sh "-c" "node ./node_modules/tad/bin/tad lib"` failed with 1
ERR! 
ERR! Failed at the [email protected] test script.
ERR! This is most likely a problem with the webmake package,
ERR! not with npm itself.
ERR! Tell the author that this fails on your system:
ERR!     node ./node_modules/tad/bin/tad lib
ERR! You can get their info via:
ERR!     npm owner ls webmake
ERR! There is likely additional logging output above.
ERR! 
ERR! System Darwin 11.4.0
ERR! command "node" "/usr/local/bin/npm" "test"
ERR! cwd /usr/local/lib/node_modules/webmake
ERR! node -v v0.6.18
ERR! npm -v 1.1.21
ERR! code ELIFECYCLE
ERR! message [email protected] test: `node ./node_modules/tad/bin/tad lib`
ERR! message `sh "-c" "node ./node_modules/tad/bin/tad lib"` failed with 1
ERR! errno {}
verbose exit [ 1, true ]

I'm on OSX with node 0.6.18, npm 1.1.21 and webmake 0.3.9.

Is this a known issue? I can currently hack my way around by changing the path, but since I don't know webmake in detail I'm likely missing some edge cases.

Lazy-loading modules?

I have been using AMD modules and curl.js for a while, one great argument for this setup is that I can load a module depending on user-interaction( mobile devices especially). This has been the main reason why I have not transited to the use of webmake.

Is there some way to simulate lazy-loading cleaning using webmake?

Thanks

Cannot bundle module 'promise'

1)Download sample - http://content.screencast.com/users/miherlosev/folders/TestCafe/media/83a40b2d-b64c-4aef-b32d-acced9cbe07c/webmake_promise.zip?downloadOnly=true
2)Extract, install modules, run gulp task
3)Get error:

Cannot require "domain" (as in 'c:\Bugs\webmake_promise\node_modules\promise\node_modules\asap\raw.js'). Native node.js modules are not ported to client-side. You can however provide an alternative version of this module in your node_modules path, it will be picked up by Webmake.

Improve shell script arguments handling

When switching on ignoreErrors with --ignoreerrors, an ENOENT error occurs.
Without the --ignoreerrors, everything is working fine.

Example:

mkdir -p ./build/httpdocs/js
webmake --ext=coffee --ignoreerrors ./src/js/gui/passdeposit.coffee ./build/httpdocs/js/passdeposit.js

results in

/usr/local/lib/node_modules/webmake/node_modules/deferred/lib/_ext.js:71
            throw this.value;
                      ^
Error: ENOENT, open '/Users/max/Desktop/PassDeposit/build/httpdocs/js/passdeposit.js'

sourceURL of an eval should refer to the compiled code, not the source

With the sourceMap option enabled, modules-webmake sets the sourceURL to the source filename. For a plain file being included directly this is ok, but for any compiled, minified or otherwise translated file, this is incorrect. The sourceURL gives a name to the code inside the eval, which is not necessarily the same as the actual source- that is defined in the base64 sourceMappingURL.

This confuses browsers and gives inconsistent results. The correct source filename/line number is shown in the console, but upon clicking this, Chromium will go to that line number in the eval code, which is wrong. Refreshing whilst on the source display for that file will cause it to reload and display the real source. For reference I am using Chromium 25.

There needs to be a way for extension functions to specify a different the eval filename if the code is being translated in any way.

Thanks.

Ignore error "Native node.js modules are not ported to client-side." when ignoreErrors is set

When trying to require nodejs native modules the error "Native node.js modules are not ported to client-side." is thrown and compilation fails.

This makes it impossible to use some libraries:

For example sjcl (Stanford Javascript Crypto Library) checks for the presence of the nodejs crypto module in the following way:

if (typeof module !== 'undefined' && module.exports &&
    (crypt = require('crypto')) && crypt.randomBytes) {
    [...]
} else if (window && Uint32Array) {
    [...]
}

When the native node module is not available, browser functions are used.

Therefore, including a nodejs native module should not lead to an error, especially not when ignoreErrors is set. It should rather lead to a warning.

require('blabla/file.json') does not work

It seems requiring a JSON file is not a working case of the require shim.
It's called with a relative path, not absolute like explained in your README.

$ webmake index.js dist/tld.js

/usr/local/lib/node_modules/webmake/node_modules/deferred/lib/_ext.js:76
                throw this.value;
                          ^
Error: Module '/Users/oncletom/workspace/tld.js/src/rules.json' not found, as required in '/Users/oncletom/workspace/tld.js/index.js'
    at /usr/local/lib/node_modules/webmake/lib/parser.js:159:13
    at Function.exports._onresolve.then (/usr/local/lib/node_modules/webmake/node_modules/deferred/lib/_ext.js:61:14)
    at Object.Deferred.resolve (/usr/local/lib/node_modules/webmake/node_modules/deferred/lib/deferred.js:118:26)
    at dirExists (/usr/local/lib/node_modules/webmake/lib/parser.js:37:7)
    at Object.oncomplete (fs.js:297:15)
$ ls src/
rules-legacy.json rules.json

Requires local installation

This:

npm install -g webmake
touch foo.js
webmake foo.js

produces the following output:

/Users/ice/.local/lib/node_modules/webmake/node_modules/deferred/_ext.js:75
            throw this.value;
                      ^
TypeError: Cannot read property 'length' of null
    at Object.<anonymous> (/Users/ice/.local/lib/node_modules/webmake/lib/parser.js:233:27)
    at Function.exports._onresolve.then (/Users/ice/.local/lib/node_modules/webmake/node_modules/deferred/_ext.js:60:18)
    at Object.Deferred._settle (/Users/ice/.local/lib/node_modules/webmake/node_modules/deferred/deferred.js:80:26)
    at Object.Deferred.resolve (/Users/ice/.local/lib/node_modules/webmake/node_modules/deferred/deferred.js:123:15)
    at Function.exports._onresolve.then (/Users/ice/.local/lib/node_modules/webmake/node_modules/deferred/_ext.js:64:4)
    at Object.Deferred._settle (/Users/ice/.local/lib/node_modules/webmake/node_modules/deferred/deferred.js:80:26)
    at Object.Deferred.resolve (/Users/ice/.local/lib/node_modules/webmake/node_modules/deferred/deferred.js:123:15)
    at Function.exports._onresolve.then (/Users/ice/.local/lib/node_modules/webmake/node_modules/deferred/_ext.js:67:3)
    at Object.Deferred._settle (/Users/ice/.local/lib/node_modules/webmake/node_modules/deferred/deferred.js:80:26)
    at Object.Deferred.reject (/Users/ice/.local/lib/node_modules/webmake/node_modules/deferred/deferred.js:131:15)

The problem is solved with npm install webmake.

Make package name relative

In the example given in the readme, we have the following file structure:

foo/
foo/add.js
foo/increment.js
foo/program.js

The main package name is foo/program.

When i compile my package, the name is an absolute path to the entry program. How do i make it relative like the example in the readme?

Allow extensions

As requested in #14, allow extensions. It should be doable with reasonable effort in v0.3.

cant find module although module is their

C:\projects\nodeProject>webmake map.js bmap.js

d:\Users\admin\AppData\Roaming\npm\node_modules\webmake\node_modules\deferred_e
xt.js:75
throw this.value;
^
Error: Module './lib-cov/cheerio' not found, as required in 'C:\projects\nodePro
ject\node_modules\cheerio\index.js'
at resolveExtTypePath (d:\Users\admin\AppData\Roaming\npm\node_modules\webma
ke\lib\parser.js:323:11)
at d:\Users\admin\AppData\Roaming\npm\node_modules\webmake\lib\parser.js:316
:12
at Function.exports._onresolve.then (d:\Users\admin\AppData\Roaming\npm\node
_modules\webmake\node_modules\deferred_ext.js:60:18)
at Object.Deferred._settle (d:\Users\admin\AppData\Roaming\npm\node_modules
webmake\node_modules\deferred\deferred.js:80:26)
at Object.Deferred.reject (d:\Users\admin\AppData\Roaming\npm\node_modules\w
ebmake\node_modules\deferred\deferred.js:131:15)
at Function.exports._onresolve.then (d:\Users\admin\AppData\Roaming\npm\node
_modules\webmake\node_modules\deferred_ext.js:46:21)
at Object.Deferred._settle (d:\Users\admin\AppData\Roaming\npm\node_modules
webmake\node_modules\deferred\deferred.js:80:26)
at Object.Deferred.reject (d:\Users\admin\AppData\Roaming\npm\node_modules\w
ebmake\node_modules\deferred\deferred.js:131:15)
at d:\Users\admin\AppData\Roaming\npm\node_modules\webmake\lib\parser.js:83:
16
at Object.oncomplete (fs.js:107:15)

When run on lower versions of node throws not so meaningful error

Hi,

I've just ran webmake on node 0.6.10 and it threw me this error:

[Error: Module 'C:\Users\makowska\Dropbox\SPPundefinedclient\index' not found, a
s required in 'C:\Users\makowska\Dropbox\SPP\client.js']

Could you improve it to more meaningful message like "Webmake doesn't support this version of node. Please upgrade"?

Some additional info:

Error doesn't show when run on 8.16.
Requiring code looks like this: var start = require('./client/index');

cheers,
Adrian

Support for punycode

I have a library which uses punycode on the client - https://github.com/insin/validators - which I'm trying to move away from manual bundling.

The library which was added to Node.js core - https://github.com/bestiejs/punycode.js - also works on the client, so I currently add punycode to my package.json dependencies and bundle from node_modules/punycode.

Is there a workaround to make modules-webmake bundle punycode from node_modules/punycode when available instead of throwing this error?

Error: Cannot require "punycode". Native node.js modules are not ported to client-side.

Can't set global export name programmatically ('name' option)

Hi,

I'm trying to pass options to webmake to set the exposed variable name but it doesn't work :

var webmake = require('webmake');

webmake('index.js', {
  name: 'SomeName', // Should export the module to 'window.SomeName' but doesn't
  output: 'dist/some-name.js'
});

});

Then when I include dist/some-name.js in an HTML page it says that SomeName not defined.

What am I doing wrong ?

require('.') does not work

I'm not sure if this it the correct behaivior, as i have not read the CommonJs specification.

var xyz = require('.'); // does not work
var xyz = require('./index'); // works
var xyz = require('./index.js'); // works

how to exclude native modules

I'm testing your build tool and got stuck on how to exclude native modules.
The problem is that in node.js I need to require('http') or 'https' depending on configuration parameters. When used from a webclient I need to include my own Ajax library. How do you achieve that ?

Directory paths as input?

I did not find a link to a forum so I hope its ok to post here. Is it possible to configure webmake to use a directory path, i.e "/templates", "assets/js"? I think it might get weary to input 7 or 8 file-names on the command line for webmake to bundle. Thanks

Enforced strict mode

Is there any way to automatically enforce strict mode in all modules without the need of writing "use strict" everywhere?

I think we need that feature, because It's still possible to unintentionally pollute the global scope - the beauty of CommonJS is gone in that case.

be able to exclude libraries

i have been using https://github.com/azer/onejs for a few projects and being able to exclude is very nice, especially when having dependencies like underscore.

i am just removing underscore manually from the webmake output for now, but this would be nice and seems like it would come up often (assuming my use of webmake isn't unintended...)

i like the vision of webmake. keep it up!

Support input from stdin

I have a script which uses webmake to create a single HTML file for running all my tests in the browser.
This script automatically creates the 'main' bundle file with require() statements for all the test files.

Unfortunately, since webmake does not support input from stdin, this file has to be created as an intermediate js file, rather than just creating the single HTML output that I desire.

webassemble has to use a similar setup.

Please could webmake be changed to allow passing input directly through stdin (or as a string in the API).

Thanks.

Doesn't work again

git clone git://github.com/Raynos/ncore.git
npm install
make webmake
firefox /test/browser.html

See errors in console :(

scope is undefined
    build = scope[name]; (line 20)

External sourcemaps

Please consider adding support for external sourcemaps.
In detail: Create both out.js and out.js.map with something like

webmake --sourcemap out.js.map in.js out.js

External sourcemaps are needed for postprocessing the output of webmake, e.g. with uglifyjs.

uglifyjs webmake-out.js --source-map out.js.map --in-source-map webmake-out.js.amp > uglifyjs-out.js

uglifyjs takes an input sourcemap with the --in-source-map option.

Additionally, external sourcemaps should make the "eval" statements (containing code and sourcemaps) unnecessary.

Programmatically api does not compile relative paths correctly

webmake("./index.js", function(err, source) { ... }); // does not work
// workarounds:
webmake("../mydirname/index.js", function(err, source) { ... }); // does work
webmake(__dirname + "/index.js", function(err, source) { ... }); // does work

The first one compiles to stuff like this: (missing 'i')

".": {
  // ...
  "ndex.js": function(...) { ... }
})
("./ndex");

Errors in extensions are not returned to webmake

I'm using webmake with (a customized) webmake-sass (to allow scss, see acdaniel/webmake-sass#2).

If there is an error in the compilation, the error is not returned to webmake and the css does not make it's way into the bundled JS file.

$ echo "\$bg:'#fff'; body {background:\$bad-bg;}" > style.scss
$ echo "require('./style')" > app.js
$ webmake --ext=sass app.js | grep 'style.scss' -A 4

                "style.scss": {
                        "value": {

                        }
                }

The following error should be returned: source string:1: error: unbound variable $bad-bg.

webmake-sass (and webmake-less, for that matter) can reject the promise, but in cases where there is an error, it is not handled by webmake -- looking at the console, everything appears to be OK.

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.