Giter VIP home page Giter VIP logo

builder's Introduction

SystemJS Build Tool Build Status Support

This project has been deprecated as of SystemJS 2.0. It will continue to support SystemJS 0.21 legacy builds though. Instead, Rollup code splitting builds are encouraged.

SystemJS Builder 0.16 release notes

Note for SystemJS 0.19 support use SystemJS Builder 0.15

Provides a single-file build for SystemJS of mixed-dependency module trees.

Builds ES6 into ES5, CommonJS, AMD and globals into a single file in a way that supports the CSP SystemJS loader as well as circular references.

Example

app.js

import $ from "./jquery.js";
export var hello = 'es6';

jquery.js

define(function() {
  return 'this is jquery';
});

Will build the module app into a bundle containing both app and jquery defined through System.register calls.

Circular references and bindings in ES6, CommonJS and AMD all behave exactly as they should, including maintaining execution order.

Documentation

API Reference

Usage

Install

npm install systemjs-builder

Basic Use

Ensure that the transpiler is installed separately (npm install babel-core here).

var path = require("path");
var Builder = require('systemjs-builder');

// optional constructor options
// sets the baseURL and loads the configuration file
var builder = new Builder('path/to/baseURL', 'path/to/system/config-file.js');

builder
.bundle('local/module.js', 'outfile.js')
.then(function() {
  console.log('Build complete');
})
.catch(function(err) {
  console.log('Build error');
  console.log(err);
});

Setting Configuration

Configuration can be injected via builder.config:

builder.config({
  map: {
    'a': 'b.js'
  }
});
builder.build('a');

To load custom configuration files use builder.loadConfig:

// `builder.loadConfig` will load config from a file containing `System.config({...})`
builder.loadConfig('./cfg.js')
.then(function() {
  // ready to build
});

Multiple config calls can be run, which will combine into the loader configuration.

Resetting Configuration

To reset the loader state and configuration use builder.reset().

When config was passed into the new Builder(baseURL, configFile) constructor, the config will be reset to this exact configFile state.

Self-Executing (SFX) Bundles

To make a bundle that is independent of the SystemJS loader entirely, we can make SFX bundles:

builder.buildStatic('myModule.js', 'outfile.js', options);

This bundle file can then be included with a <script> tag, and no other dependencies would need to be included in the page. You'll likely want your module to export a global variable when loaded from a script tag, and this can be configured via globalName. For example

builder.buildStatic('src/NavBar.js', 'dist/NavBarStaticBuild.js', {
  globalName: 'NavBar'
});

will cause the output of your module to be assigned to a global variable named NavBar. If you're making a static bundle, while excluding certain dependencies, those dependencies will of course need to have already been loaded on your page, with their own global variables exported. You can match these global variables up with your needed dependencies with globalDeps. For example

builder.buildStatic('src/NavBar.js - react', 'dist/NavBarStaticBuild.js', {
  globalName: 'NavBar',
  globalDeps: {
    'react': 'React'
  }
});

will create a static build of NavBar—without React—which, when loaded via a script tag, exports an eponymous global variable, and assumes the existence of a React global variable, which will be used for the react dependency.

This would support users with a setup of

<script src='path/to/react.min.js'></script>
<script src='path/to/NavBarStaticBuild.js'></script>

Note that another way of excluding react would be with externals.

builder.buildStatic('src/NavBar.js', 'dist/NavBarStaticBuild.js', {
  externals: ['react'],
  globalName: 'NavBar',
  globalDeps: {
    'react': 'React'
  }
});

This would also exclude react but, if react defined any dependencies which NavBar also defined, those dependencies would be included in the build.

Of course the above explanations involving globalDeps and globalName only apply to when your end user loads the static file from a script tag. Since the output is (by default, see below) UMD, a script loader like SystemJS or requireJS would process it as configured, or via AMD respectively.

By default, the Traceur or Babel runtime are automatically included in the SFX bundle if needed. To exclude the Babel or Traceur runtime set the runtime build option to false:

builder.buildStatic('myModule.js', 'outfile.js', { runtime: false });

SFX Format

SFX bundles can also be output as a custom module format - amd, cjs or es6 for consumption in different environments.

This is handled via the format (previously sfxFormat) option:

builder.buildStatic('myModule.js', 'outfile.js', { format: 'cjs' });

The first module used as input (myModule.js here) will then have its exports output as the CommonJS exports of the whole SFX bundle itself when run in a CommonJS environment.

Adapter Modules

To have globals like jQuery not included, and included in a separate script tag, set up an adapter module something like:

jquery.js

module.exports = window.jQuery;

Minification & Source Maps

As well as an options.config parameter, it is also possible to specify minification and source maps options:

builder.bundle('myModule.js', 'outfile.js', { minify: true, sourceMaps: true, config: cfg });

Compile time with source maps can also be improved with the lowResSourceMaps option, where the mapping granularity is per-line instead of per-character:

builder.bundle('myModule.js', 'outfile.js', { sourceMaps: true, lowResSourceMaps: true });

Minification Options

  • mangle, defaults to true.
  • globalDefs, object allowing for global definition assignments for dead code removal.
builder.bundle('myModule.js', 'outfile.js', { minify: true, mangle: false, globalDefs: { DEBUG: false } });

SourceMap Options

  • sourceMaps, Either boolean value (enable/disable) or string value 'inline' which will inline the SourceMap data as Base64 data URI right in the generated output file (never use in production). (Default is false)
  • sourceMapContents, Boolean value that determines if original sources shall be directly included in the SourceMap. Using inline source contents generates truely self contained SourceMaps which will not need to load the external original source files during debugging. (Default is false; when using sourceMaps='inline' it defaults true)

In-Memory Builds

Leave out the outFile option to run an in-memory build:

builder.bundle('myModule.js', { minify: true }).then(function(output) {
  output.source;    // generated bundle source
  output.sourceMap; // generated bundle source map
  output.modules;   // array of module names defined in the bundle
});

The output object above is provided for all builds, including when outFile is set.

output.modules can be used to directly populate SystemJS bundles configuration.

Ignore Resources

If loading resources that shouldn't even be traced as part of the build (say an external import), these can be configured with:

builder.config({
  meta: {
    'resource/to/ignore.js': {
      build: false
    }
  }
});

Overriding Fetch

The framework fetch function can be overridden in order to provide the source for a file manually. This is useful if you want to pre-process the source of a file before using the builder.

var mySource = 'import * from foo; var foo = "bar";'; // get source as a string
builder.bundle('foo.js', {
  fetch: function (load, fetch) {
    if (load.name.indexOf('foo.js') !== -1) {
      return mySource;
    } else {
      // fall back to the normal fetch method
      return fetch(load);
    }
  }
});

The load variable describes the file that is trying to be loaded. This is called once for every file that is trying to be fetched, including dependencies.

The fetch function should return a string.

Bundle Arithmetic

Both builder.build and builder.buildStatic support bundle arithmetic expressions. This allows for the easy construction of custom bundles.

There is also a builder.trace for building direct trace tree objects, which can be directly passed into builder.bundle or builder.buildStatic.

Example - Arithmetic Expressions

In this example we build all our application code in app/ excluding the tree app/corelibs:

var Builder = require('systemjs-builder');

var builder = new Builder({
  baseURL: '...',
  map: {
  } // etc. config
});

builder.bundle('app/* - app/corelibs.js', 'output-file.js', { minify: true, sourceMaps: true });

Example - Common Bundles

To build the dependencies in common between two modules, use the & operator:

builder.bundle('app/page1.js & app/page2.js', 'common.js');

We can then exclude this common bundle in future builds:

builder.bundle('app/componentA.js - common.js', { minify: true, sourceMaps: true });

Example - Third-Party Dependency Bundles

Build a bundle of all dependencies of the app/ package excluding anything from app/ itself.

For this we can use the [module] syntax which represents a single module instead of all its dependencies as well:

builder.bundle('app/**/* - [app/**/*]', 'dependencies.js', { minify: true, sourceMaps: true });

The above means take the tree of app and all its dependencies, and subtract just the modules in app, thus leaving us with just the tree of dependencies of the app package.

Example - Multiple Common Bundles

Parentheses are supported, so the following would bundle everything in common with page1 and page2, and also everything in common between page3 and page4:

builder.bundle('(app/page1.js & app/page2.js) + (app/page3.js & app/page4.js)', 'common.js');

Example - Direct Trace API

Instead of using the arithmetic syntax, we can construct the trace ourselves.

In this example we build app/first and app/second into two separate bundles, while creating a separate shared bundle:

var Builder = require('systemjs-builder');

var builder = new Builder({
  // ...
});

Promise.all([builder.trace('app/first.js'), builder.trace('app/second.js')])
.then(function(trees) {
  var commonTree = builder.intersectTrees(trees[0], trees[1]);
  return Promise.all([
    builder.bundle(commonTree, 'shared-bundle.js'),
    builder.bundle(builder.subtractTrees(trees[0], commonTree), 'first-bundle.js'),
    builder.bundle(builder.subtractTrees(trees[1], commonTree), 'second-bundle.js')
  ]);
});

License

MIT

builder's People

Contributors

adamburgess avatar ainscore avatar alexisvincent avatar arackaf avatar asapach avatar caseyhoward avatar casperlamboo avatar ccantill avatar chrmod avatar crisptrutski avatar cxres avatar dristic avatar fdintino avatar fictitious avatar frankwallis avatar gcnm-pgeil avatar guybedford avatar insidewhy avatar joeldenning avatar jrauschenbusch avatar lookfirst avatar markstickley avatar meomix avatar munter avatar ntag avatar papandreou avatar thomas-darling avatar typhonrt avatar vladima avatar zenorbi 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

builder's Issues

Better error messages

We need to catch all errors and ensure we inlude the name of the module and file name that cased the error.

6to5 support

If System.parser is set to 6to5, then we should use 6to5 to do the bundling generation.

Builder as a class

We should change builder itself to be a class that is created with config, so that we don't pollute the global build environment.

Unable to read dependency when using 6to5

jspm bundle-sfx lib/app

Output:

     Building the single-file sfx bundle for lib/app...

err  Error: Error loading "angular" at file:/Users/sekibomazic/projects/es6/angular-es6-jspm/angular.js
     Error loading "angular" from "lib/app" at file:/Users/sekibomazic/projects/es6/angular-es6-jspm/lib/app.js
     ENOENT, open '/Users/sekibomazic/projects/es6/angular-es6-jspm/angular.js'

You can see app.js here: https://github.com/SekibOmazic/angular-es6-jspm/blob/master/lib/app.js

My settings:
jspm 0.11.1
[email protected]
[email protected]
[email protected]

Builder dies on with "Unexpected token import "

Problem:
When i run builder.build, the process fails. The builder configuration mimics my webapp config which loads my modules just fine in browser. I'm running in Windows 8.

More Info:
My local webapp is able to load with this configuration:

<script src="bower_components/traceur/traceur.js"></script>
<script src="bower_components/es6-module-loader/dist/es6-module-loader.js"></script>
<script src="bower_components/system.js/dist/system.js"></script>
<script>
      System.config({
        baseURL: '/bower_components/',
        map: {
          vue: 'vue/dist/vue'
        },
        paths: {
          'app/*': '/scripts/*.js'
        }
      });

      System.import('app/main').catch(console.error.bind(console));
</script>

The builder is set up like this:

gulp.task('sys-build', function() {
  var builder = require('systemjs-builder');
  var path = require('path');

  builder.build('app/main', {
    baseURL: path.resolve('app/bower_components'),
    map: {
      vue: 'vue/dist/vue'
    },
    paths: {
      'app/*': path.resolve('app/scripts/*.js')
    }
  }, 'app/.out/sys-build-test.js')
  .then(function() {
    console.log('Build complete');
  })
  .catch(function(err) {
    console.log('Build error');
    console.log(err);
  });
});

Error:

C:\Users\Johnathon\Projects\my-projectA-name>gulp sys-build                                                           
[06:57:56] Using gulpfile ~\Projects\my-projectA-name\gulpfile.js                                                     
[06:57:56] Starting 'sys-build'...                                                                                    
[06:57:56] Finished 'sys-build' after 188 ms                                                                          
Build error                                                                                                           
[ 'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:1:1: Unexpected token import',
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:1:8: Semi-colon expected',    
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:2:1: Unexpected token import',
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:2:8: Semi-colon expected',    
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:2:15: Semi-colon expected',   
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:2:20: Semi-colon expected',   
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:3:1: Unexpected token import',
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:3:8: Semi-colon expected',    
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:3:10: Semi-colon expected',   
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:3:15: Semi-colon expected',   
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:4:1: Unexpected token import',
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:4:8: Semi-colon expected',    
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:4:16: Semi-colon expected',   
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:4:21: Semi-colon expected',   
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:5:1: Unexpected token import',
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:5:8: Semi-colon expected',    
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:5:19: Semi-colon expected',   
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:5:24: Semi-colon expected',   
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:7:1: Unexpected token export',
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:7:8: Semi-colon expected',    
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:7:8: Unexpected token default'
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:7:16: Semi-colon expected',   
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:7:24: Unexpected token (',    
  'C:\\Users\\Johnathon\\Projects\\my-projectA-name\\app\\scripts\\massagers/default.js:7:25: Unexpected token data' ]

I have tried to come up with a generic test environment to reproduce this and I can't seem to (possible file name length problem?). Also, when I rerun this repeatedly, it will fail in different files. All of the imports and exports in these files work just fine in browser. Also, adding meta for es6 doesn't seem to help. The modules inside of app/scripts are ES6.

I don't even know where to begin debugging this.

TypeError: Cannot read property 'parameters' of undefined with Knockout library

Hi,
I have been experimenting with systemjs-builder, with an existing application that up to now has been using browserify. With systemjs-builder v0.5.0, I am getting an error [TypeError: Cannot read property 'parameters' of undefined] if I reference (require) the knockout library in my app. I have reproduced the error in a minimal version below:

"use strict"
var ko = require('knockout')

var program = function program() {}

program.prototype.run = function () {
   console.log('program:run')
}

exports.program = program

and to build it

 var builder = require('systemjs-builder')

 builder.build('app', 'outfile.js', {
      config: {
        map: {
          'knockout': 'knockout-latest',
        },
//        meta: { 'knockout': { build:false} }
      }
    })
    .then(function() {
      console.log('Build complete')
    })
    .catch(function(err) {
      console.log('Build error')
      console.error(err);
    })

This assumes that knockout-latest.js is in the same folder as the app.js file for simplicity.

If instead of using the "map" configuration, I comment out the map and comment in the "meta" to exclude knockout (as if it was external) then it completes the build.

I would like to be able to include knockout in my bundle, but am unsure how to track down the error (there is no stack trace). Is this an error in detecting the module format (knockout looks perhaps to have a non-standard "factory" function and in some of my testing I have observed systemjs-builder can be sensitive to this when detecting the module format - though this could be red-herring...) or something more fundamental?

--philip

Module module not declared as a dependency

I have a plugin to precompile Ractive components:

var Load = require('ractive-load');
var Ractive = require('ractive');

exports.translate = function(load) {
    load.source = 'module.exports = ' + JSON.stringify(load.source);
    return Load(load.address).then(function(c) {
        Ractive.components['ract-teste'] = c;
    });
}

In browser all is working but when I try to bundle i get:
captura de tela de 2015-01-14 03 43 37

I installed both ractive and ractive-load from npm (npm:ractive and npm:ractive-load). When I try to use github:ractivejs/ractive-load i get:
captura de tela de 2015-01-14 03 42 24

Optimization build functions

Automated two-layer and three-layer bundling into separate files given the a list of modules for each page of the app.

Readme.md - IE8 support

I think the actual output differs to what the Readme says. Also, instead of ES5 it's even ES3. That right?

Plugin reduce hook

For asset builds we will need an ability to get a "reduce" hook across a plugin per layer:

export function reduce(sources) {
  return Promise.resolve(sources.reduce(function(sourceA, sourceB) {
    return sourceA + sourceB;
  }));
}

Allows compression techniques, headers and footers, like are needed for CSS bundling.

How to load built file containing AMD modules

<script src="/bower_components/traceur-runtime/traceur-runtime.js"></script>
<script src="/bower_components/es6-module-loader/dist/es6-module-loader.js"></script>
<script src="/bower_components/system.js/dist/system.js"></script>
<script src="/systemjs-build/my-module.js"></script>
<script>
    System.import('app/my-module').then(function (module) {
        new module.q();
    });
</script>

Here is the code being loaded from my bundle file, /systemjs-build/my-module.js:

"format register";

System.register("app/name", [], function($__0) {
  "use strict";
  var __moduleName = "app/name";
  var $__default;
  return {
    exports: {
      get default() {
        return $__default;
      },
      set default(value) {
        $__default = value;
      }
    },
    execute: function() {
      $__default = 'Bob';
    }
  };
});

define("app-amd/age", function () {
    return 1;
});


System.register("app/my-module", ["./name", "../app-amd/age"], function($__0) {
  "use strict";
  var __moduleName = "app/my-module";
  var q;
  return {
    exports: {
      get q() {
        return q;
      },
      set q(value) {
        q = value;
      }
    },
    execute: function() {
      ;
      ;
      q = (function() {
        var q = function q() {
          console.log($__0[0]["default"], $__0[1]["default"]);
          console.log('this is an es6 class!');
        };
        return ($traceurRuntime.createClass)(q, {}, {});
      }());
    }
  };
});

I am getting the following error:

Uncaught ReferenceError: define is not defined

I imagined that AMD define would be converted into System.register by the build process. Given that’s not the case, how am I supposed to handle this?

Not able to create bundle with builder when I import json file

When I import json file (e.g. import abc from './abc.json!') in my code I am not able to build bundle with builder as I am getting below error.

NOTE: I am not getting any error when I am using jspm command e.g. jspm bundle-sfx app/bootstrap build.js and bundle is created successfully.

Gulp Task Code:

var builder = require('systemjs-builder');
builder.reset();

builder.loadConfig('./src/jspm.conf.js')
    .then(function() {
        builder.loader.baseURL = path.resolve('./src/');
        builder.buildSFX('app/bootstrap', paths.tmp.scripts + 'bootstrap.js', { sourceMaps: true, config: {sourceRoot: 'src/.tmp/scripts/'} })
            .then(function() {
                return cb();
            })
            .catch(function(ex) {
                cb(new Error(ex));
            });
    });

Error:

Error: Error loading "app/components/employee/fixtures/employee_1.json!github:systemjs/[email protected]" at <unknown>
Error loading "app/components/employee/fixtures/employee_1.json!github:systemjs/[email protected]" from "app/bootstrap" at file:/Users/martinmicunda/projects/employee-scheduling/ui/src/app/bootstrap.js
Error loading "github:systemjs/[email protected]" at github:systemjs/[email protected]
Only file URLs of the form file: allowed running in Node.
    at /Users/martinmicunda/projects/employee-scheduling/ui/gulpfile.js:295:24
    at promiseHandle (/Users/martinmicunda/projects/employee-scheduling/ui/node_modules/systemjs-builder/node_modules/traceur/bin/traceur.js:1874:20)
    at /Users/martinmicunda/projects/employee-scheduling/ui/node_modules/systemjs-builder/node_modules/traceur/bin/traceur.js:1868:9
    at flush (/Users/martinmicunda/projects/employee-scheduling/ui/node_modules/systemjs-builder/node_modules/traceur/bin/traceur.js:1672:7)
    at process._tickCallback (node.js:419:13)

Documentation broken

The examples "Exclusion" and "Common Libraries" are not correct anymore:

i.e.

  builder.trace('app/first')
  .then(function(tree) {
    firstTree = tree;

    return builder.trace('app/second');
  })

must now be

  builder.trace('app/first')
  .then(function(trace) {
    firstTree = trace.tree;

    return builder.trace('app/second');
  })

A noob question about building for production

Hello there. Firstly, absolutely amazing work on JSPM and SystemJS. I've only just got started using JSPM and SystemJS and, so far in my development, they've been fantastic and so easy to use and understand.

I hope you don't mind me asking some noob questions around SystemJS and the best way to build my app for production. I love simplicity and clarity and I'm trying my best to come up with a nice structure, development environment and simple build process.

Firstly, I have my app structure something like this:

app/
  packages/
  config.js
  index.html
  main.js
  style.css
  ...
builder.js
package.json
server.js

I have a basic Express based server that serves the front end as well as providing some JSON APIs which is in the root at server.js. I then have my SystemJS Builder script in the root as builder.js and inside the app/ folder is the front end stuff, including where JSPM puts the packages (in my case in the app/packages folder and the SystemJS configuration file at app/config.js.

The app/index.html file looks like this:

<!DOCTYPE html>
<html>
<head>
  <title>Development</title>
</head>
<body>
  <script src="packages/system.js"></script>
  <script src="config.js"></script>
  <script>
    System.baseURL = '/';
    System.import('main');
  </script>
</body>
</html>

The app/config.js file looks like this:

System.config({
  "paths": {
    "*": "*.js",
    "app/*": "/*.js",
    "github:*": "packages/github/*.js",
    "css": "packages/github/systemjs/[email protected]",
    "json": "packages/github/systemjs/[email protected]"
  }
});

System.config({
  "map": {
    "jquery": "github:components/[email protected]",
    "plugin-css": "github:systemjs/[email protected]",
    "plugin-image": "github:systemjs/plugin-image@master",
    "plugin-json": "github:systemjs/[email protected]",
    "plugin-text": "github:systemjs/[email protected]"
  }
});

So far so good, or at least I think? Everything seems to run fine in development (please tell me if any of this is already fishy, I want to learn!) ...and now I want to know how to build this app ready for production.

I don't really know the best way to go about this with SystemJS Builder. Would I direct the builder to build into a separate build folder (like build/)? From what I could see, I still need to include the packages/system.js library in the index.html for the build? Is there any options to include the SystemJS library as well into my build outfile so I just can include a single script in my build's index.html file?

What is the best way to approach a successful build the right way using SystemJS Builder? I'm quite used to Webpack just bundling everything into a single bundle.js file and my build directory just has a simple index.html that references that bundle.js file and that's that. Is there anyway of achieving something similar with SystemJS Builder, where it'll include all the CSS (which I'm loading as a module using the plugin), the SystemJS library and my app code into a single minified JS file that I can simply include with a <script> tag?

Or am I just approaching all of this completely wrong (I fully accept that I am!)

I just want to do it right :)

SystemJS builder halts on files with byte order marks

First, I quickly wanted to say that I know I've been raising quite a few issues/questions and I appreciate all the help. Please let me know any areas where you may be looking for specific contributions to the project because I'd love to chip in.

Back to the issue at hand: If I have the following modules...

// a.js
define(['b'], function(b){
   console.log('this is a')
});
// b.js
define([], function(){
   console.log('this is b')
});
// builder.js
var builder = require('systemjs-builder');

builder.build('a', {}, 'built.js')
    .then(function() {
        console.log('Build complete');
    })
    .catch(function(err) {
        console.log('Build error', err);
    });

And I run node builder

I get a Build complete but the file does not contain the module b.

If I remove the BOM (byte order mark) on files a.js and b.js and rerun node builder, everything is as I would expect (includes both modules).

Here is the output of built.js in both cases:

// Incorrect built.js - files with BOM
"format register";

System.register("a", [], false, function(__require, __exports, __module) {
  System.get("@@global-helpers").prepareGlobal(__module.id, []);
  (function() {  define(['b'], function(b){
          console.log('this is a')
      });
  }).call(System.global);  return System.get("@@global-helpers").retrieveGlobal(__module.id, false);
});
// Correct built.js - files without BOM
"format register";

(function() {
function define(){};  define.amd = {};
  System.register("b", [], false, function(__require, __exports, __module) {
    return (function() {
      console.log('this is b');
    }).call(this);
  });
  })();
(function() {
function define(){};  define.amd = {};
  System.register("a", ["b"], false, function(__require, __exports, __module) {
    return (function(b) {
      console.log('this is a');
    }).call(this, __require('b'));
  });
  })();

Auto-include runtime for bundle sfx

There should be an option for bundle sfx, that detects if Traceur or Babel runtime is needed in the generated output, and automatically includes it if the bundle if so.

traceur-runtime as a dependency for ES6 bundles

Bundling works great! However, when bundling/building ES6 modules, the traceur-runtime needs to be manually injected into the page.

Could there possibly be an option to include the traceur-runtime as part of the bundle, or have it load as a dependency of the bundle automatically?

Thanks!

Option to configure module output

The default is instantiate. Should it be possible to build to AMD/CommonJS, as per the Traceur modules option?

If so, what do you think the API should look like, and would it be trivial? Happy to give it a go, if this is what we want.

nested mappings

heya,

is this supposed to work with nested maps?

e.g.

{
  "map": {
    "version-1": {
      "blah": "[email protected]"
    },
    "version-2": {
      "blah": "[email protected]"
    }
  }
}

this simple case works with system.js clientside but throws a build error on build:

[TypeError: Cannot read property 'blah' of undefined]

Bundling global dependencies issue.

@guybedford

The system.js is super-convenient due to its ability to load any module and automatically resolve its format. Awesome.

When system.js loads different modules as different files which is pretty good for development - everything works perfect and no other configuration is even required aside from setting the paths for third-party dependencies. All things "just work".

There are problems though when trying to "bundle" everything for optimized production usage. Issue raised when moved the medium-sized Angular app to using ES6 with Traceur and ES6 Module Loader and tried to prepare the combined/concat-ted build file.

I would like to use SystemJS bundled in production too, so that I don't have to deal with AMD/etc at all. Calling System.import(...) works just fine for me and nowadays seems to be recommended approach according to your article (Dynamic Workflow 4).

Now, the issue.
While in dev, if I refer to dependency like

import angular from 'angular';

// The `angular` is what it should be here, things work and everyone is happy.
angular.module(...);

When I use systemjs-builder to create a bundle though (my app imports the angular and that gets into the bundle too, which is OK), the result of import looks like

import angular from 'angular';

// angular == { angular: Object, ng339: 3 }

For me, it seems like systemjs-builder might have something like shim config missing (like we do for RequireJS). After intensive googling, no ways to provide any kind of shim config for build were found. Maybe there is some other way to configure that for builder? Or am I missing something?

So, basically the questions are:

  • How systemjs-builder is different from just SystemJS loader and why it changes the format my module is being imported? Is this expected behavior? - SystemJS seems to somehow know in development what is getting exported from "global" module.
  • How to configure that? Some systemjs-builder tweak or some configuration option?
  • Any pointers to some other options on how to solve this?

Thanks in advance.

Global stubs for compileSFX

It would be nice to be able to specify specific modules which should delegate to globals, and their associated globals when building.

These modules would be excluded from the build, and they would then be shimmed into the global versions.

The shimming itself could be through a stub register:

System.register('github:angular/angular-bower/angular', [], false, function(require) {
  return angular;
});

To get to this, we could add a globalStubs config option just for the compileSFX function, as an object containing module: global key value pairs.

Weird issue with a simple plugin

I've created a very simple plugin that compiles Lo-Dash templates:

import _ from 'underscore';

export function translate(load) {
  return 'module.exports = ' + _.template(load.source).source + ';';
}

I manually set the path:

module.exports = function(grunt) {
    var local = path.join.bind(path, __dirname);
    var done = this.async();

    builder.build('src/main', {
      baseURL: local('../'),

      paths: {
        underscore: 'node_modules/lodash/dist/lodash.js',
        tmpl: 'src/plugins/lodash.js'
      }
    }, local('../prod/app.js'))
    .then(done).catch(done);
};

I get the error:

Warning: Execution must define a Module instance Use --force to continue.

So I commented out the inclusion of lodash in my plugin and then it "works" although, I have to return an empty string... which is not ideal. Any idea on how I can fix this.

I'll update the issue if I figure it out.

Full source maps for builds

Support picking up and then re-mapping the source maps from individual files through into the concat build.

Output to memory

I don't see a howto, but hopefully there is a way to output to a memory object rather than a file in the FS. Or perhaps an option to set an output filesystem that could be a memory FS.

No System.Register for certain libraries

If I let the builder auto determine format, or if i specify format amd in the meta, then the builder doesn't insert System.register into some libraries when it is building the output. Instead it wipes out the original library code for amd (setting the meta to format: cjs for them does seem to work).

One library I have noticed this in is Reqwest. I have updated my test project to import at https://github.com/outdooricon/my-projectA-name. https://github.com/outdooricon/my-projectA-name/blob/master/app/.out/sys-build-test.js reflects the build output including that library inside. To run the builder, gulp sys-build.

Babel self-contained option

We need a builder option to enable the self-contained runtime mode for 6to5.

It should allow a customizable runtime "package name" where to find the 6to5 runtime package.

Then this should be on by default.

Bundle CSS assets

I noticed that text dependencies do get bundled, but it seems like CSS dependencies don't.

Is there any plan to bundle CSS dependencies? What would it take to do that?

systemjs-builder install old dependencies

I have upgraded my systemjs-builder to 0.4.5 but when I run jspm install it always install old version of dependencies under jspm_packages folder.

es6-module-loader - v0.9.4 -> it should install v0.10.0
systemjs - v0.9.3 -> its should install v0.10.2

I have deleted jspm_packages folder couple times and then run jspm install but it always add old dependencies to jspm_packages folder. Is there any cache that I need to delete as I can see that node_modules/systemjs-builder/node_modules contains correct version of dependencies.

Building css

Is it possible to get outfile.css for css moudles as for js? (and shared css modules as well)

asset compilation

The next update to the builder needs to include the ability to have asset types and build outputs.

Automate build gulp workflow with systemjs-builder

Hi,

I am trying to automated my workflow to build bundle with gulp but I am getting 2 errors and I wasn't sure where to post this question so I have opened new issue.

Issue 1:
As I mentioned early I try automated my workflow with gulp that use systemjs-builder for bundle task. I don't want to manually add maps, version etc. to builder.build() (see gulpfile.js below) as I think this configuration doesn't belong to gulpfile.js so I put them into jspm.conf.js (systemjs doing the same thing). The problem is that I was not able to figure out how to load this file with System.config in jspm.conf.js (see what I would like to use) because when I require('./jspm.conf.js') in gulpfile I am getting ReferenceError: System is not defined which make sense as System is part of systemjs so I export config stuff (see what I am using now) and this works fine where I run my gulp task however if I run jspm install it always overwrite jspm.conf.js and add System.config which I can't load into Builder.build(). Also if I make any manual changes in jspm.conf.js and then I run jspm install my changes are overwrite and this can possible cause an issue in future when somebody else try clone my repo and run jspm install then my manual changes will be gone and overwrite.

Basically what I am trying to do is get running gulp bundle task with systemjs-builder and keep to config systemjs data out of the gulpfile.js in jspm.conf.js. I am not sure if that make sense for you :)

gulpfile.js

gulp.task('scripts', 'Compile JS files into the app.js', function (cb) {
    var config = require('./jspm.conf.js');
    var builder = require('systemjs-builder');

    builder.build('src/app/bootstrap',
        config,
        paths.tmp.scripts + 'app.js')
            .then(cb)
            .catch(function(ex) {
                cb(new Error(ex));
            });
});

jspm.conf.js
what I am using now

(function() {
  var config = {
    "paths": {
      "*": "*.js",
      "npm:*": "jspm_packages/npm/*.js",
      "github:*": "jspm_packages/github/*.js"
    },
    // any map config
    map: {
      "angular": "github:angular/bower-angular@^1.3.2",
      "angular-animate": "github:angular/bower-angular-animate@^1.3.2",
      "github:angular/[email protected]": {
        "angular": "github:angular/bower-angular@^1.3.2"
      }
    },
    "versions": {
      "github:angular/bower-angular": "1.3.2",
      "github:angular/bower-angular-animate": "1.3.2"
    }
  };

  module.exports = config;
})();

what I would like to use

System.config({
  "paths": {
    "*": "*.js",
    "github:*": "jspm_packages/github/*.js"
  }
});

System.config({
  "map": {
    "angular": "github:angular/bower-angular@^1.3.2",
    "angular-animate": "github:angular/bower-angular-animate@^1.3.2",
    "github:angular/[email protected]": {
      "angular": "github:angular/bower-angular@^1.3.2"
    }
  }
});

System.config({
  "versions": {
    "github:angular/bower-angular": "1.3.2",
    "github:angular/bower-angular-animate": "1.3.2"
  }
});

My project structure:

my-project/ 
  |- src/                 --> all source code files
  |  |- .tmp/
  |  |  |- scripts
  |  |  |  |- app.js        --> bundle file
  |  |- app/                 --> angularJS 
  |  |  |- bootstrap.js        --> main app file (bootsrap angular app)
  |  |  |- index.html
  |- jspm.config.js     
  |- gulpfile.js
  |- package.json

index.html

<script src="../../jspm_packages/traceur-runtime.src.js"></script>
<script src="../../jspm_packages/es6-module-loader.src.js"></script>
<script src="../../jspm_packages/system.src.js"></script>
 <script src=".tmp/scripts/app.js"></script>

</script>
   System.import('src/app/bootstrap').then(function(m) {
     console.log(m);
   }, console.error.bind(console));
</script>

package.json

.....
all classic npm package stuff and at the end jspm
...
  "jspm": {
    "name": "angular-seed",
    "configFile": "jspm.conf.js",
    "dependencies": {
      "angular": "^1.3.2",
      "angular-animate": "^1.3.2"
    }
  }

issue 2:
I am getting below error when I am importing angular-animate . If I comment out import 'angular-animate' then angular is loading without any problem (I tried debug the issue but I couldn't figure out that)

Note: angular-animate had dependency on angular as you can see in jspm.conf.js

Error in browser console:

Uncaught SyntaxError: Unexpected token <
Error evaluating http://localhost:8000/angular.js          es6-module-loader.src.js:1141

src/app/bootstrap.js

import 'angular';
import 'angular-animate';       ---> this is throwing error

angular.element(document).ready(function () {
    angular.bootstrap(document, ['app'], {
        //strictDi: true
    });
});

Running into problem rerunning the builder within Gulp context

I'm not really sure where to turn with this issue. I'm running the builder as a task in gulp when i start up my server. Works great, no problem on start. However, when the same builder task gets triggered after a filechange (gulp.watch), it dies. Here's my task (pretty basic):

  var builder = require('systemjs-builder');
  var path = require('path');

  builder.build('index', {
    baseURL: path.resolve('app/.out/scripts'),
    map: {
      moment: 'bower/moment/moment',
      reqwest: 'bower/reqwest/reqwest',
      string: 'bower/string/lib/string',
      underscore: 'bower/underscore/underscore',
      vue: 'bower/vue/dist/vue'
    },
    paths: {
      'bower/*': path.resolve('app/bower_components/*.js')
    }
  }, 'app/.out/scripts/all.js')
  .then(function() {
    console.log('SystemJS Build complete');
    cb();
  })
  .catch(function(err) {
    console.log('SystemJS Build error');
    console.log(err.stack);
    cb();
  });

Here's my error:

TypeError: Cannot read property 'type' of undefined
    at ScopeTransformer.AMDDefineRegisterTransformer.transformCallExpression (C:\Users\Johnathon\Projects\remote-node-jobs\node_modules\systemjs-builder\compilers\amd.js:176:14)
    at CallExpression.transform (eval at <anonymous> (C:\Users\Johnathon\Projects\remote-node-jobs\node_modules\systemjs-builder\node_modules\traceur\src\node\traceur.js:25:17), <anonymous>:5463:26)
    at ScopeTransformer.transformAny (eval at <anonymous> (C:\Users\Johnathon\Projects\remote-node-jobs\node_modules\systemjs-builder\node_modules\traceur\src\node\traceur.js:25:17), <anonymous>:11765:27)
    at ScopeTransformer.transformExpressionStatement (eval at <anonymous> (C:\Users\Johnathon\Projects\remote-node-jobs\node_modules\systemjs-builder\node_modules\traceur\src\node\traceur.js:25:17), <anonymous>:12040:29)
    at ExpressionStatement.transform (eval at <anonymous> (C:\Users\Johnathon\Projects\remote-node-jobs\node_modules\systemjs-builder\node_modules\traceur\src\node\traceur.js:25:17), <anonymous>:5828:26)
    at ScopeTransformer.transformAny (eval at <anonymous> (C:\Users\Johnathon\Projects\remote-node-jobs\node_modules\systemjs-builder\node_modules\traceur\src\node\traceur.js:25:17), <anonymous>:11765:27)
    at ScopeTransformer.transformList (eval at <anonymous> (C:\Users\Johnathon\Projects\remote-node-jobs\node_modules\systemjs-builder\node_modules\traceur\src\node\traceur.js:25:17), <anonymous>:11772:32)
    at ScopeTransformer.transformScript (eval at <anonymous> (C:\Users\Johnathon\Projects\remote-node-jobs\node_modules\systemjs-builder\node_modules\traceur\src\node\traceur.js:25:17), <anonymous>:12287:33)
    at Script.transform (eval at <anonymous> (C:\Users\Johnathon\Projects\remote-node-jobs\node_modules\systemjs-builder\node_modules\traceur\src\node\traceur.js:25:17), <anonymous>:6410:26)
    at ScopeTransformer.transformAny (eval at <anonymous> (C:\Users\Johnathon\Projects\remote-node-jobs\node_modules\systemjs-builder\node_modules\traceur\src\node\traceur.js:25:17), <anonymous>:11765:27)

All of the modules have been pre-compiled using traceur into amd, so it's using the amdcompiler. I've been diving into the code and have noticed that in compileLoad, the amdCompiler.compile promise callback for then isn't reached as many times during watch as it is during the server start. If you could point me to some good debugging spots, that would really help. It's going to be hard to give you an envinronment to reproduce in this case...

UglifyJS fail using jspm bundle --minify but succeeds without minification

I'm experiencing a problem when running jspm bundle. I have created the following test file and placed it in app/jspm-test. This snippet replicates the problem section of code in a large asm.js project. It is valid Javascript syntax.

function k(ra){throw ra;}var n=void 0,r=!0,t=null,A=!1;

If I run jspm bundle app/jspm-test build/jspm-test.bundle.js the bundle succeeds.

$ jspm bundle app/jspm-test public/build/jspm-test.bundle.js
     Building the bundle tree for app/jspm-test...
ok   Built into public/build/jspm-test.bundle.js with source maps, unminified.

However, when I add the --minify flag, we get a failure in uglifyjs.

$ jspm bundle app/jspm-test public/build/jspm-test.bundle.js --minify
     Building the bundle tree for app/jspm-test...

err  Error
         at new JS_Parse_Error (/usr/local/lib/node_modules/jspm/node_modules/uglify-js/lib/parse.js:189:18)
         at js_error (/usr/local/lib/node_modules/jspm/node_modules/uglify-js/lib/parse.js:197:11)
         at croak (/usr/local/lib/node_modules/jspm/node_modules/uglify-js/lib/parse.js:657:9)
         at token_error (/usr/local/lib/node_modules/jspm/node_modules/uglify-js/lib/parse.js:665:9)
         at unexpected (/usr/local/lib/node_modules/jspm/node_modules/uglify-js/lib/parse.js:671:9)
         at expr_atom (/usr/local/lib/node_modules/jspm/node_modules/uglify-js/lib/parse.js:1167:9)
         at maybe_unary (/usr/local/lib/node_modules/jspm/node_modules/uglify-js/lib/parse.js:1328:19)
         at expr_ops (/usr/local/lib/node_modules/jspm/node_modules/uglify-js/lib/parse.js:1363:24)
         at maybe_conditional (/usr/local/lib/node_modules/jspm/node_modules/uglify-js/lib/parse.js:1368:20)
         at maybe_assign (/usr/local/lib/node_modules/jspm/node_modules/uglify-js/lib/parse.js:1392:20)

If I bundle without --minify and then manually run uglifyjs I get the same error, but with more detail:

$ uglifyjs jspm-test.bundle.js -m -o test.min.js
Parse error at jspm-test.bundle.js:8,7
Unexpected token: keyword (var)
Error
    at new JS_Parse_Error (/usr/local/lib/node_modules/uglify-js/lib/parse.js:189:18)
    at js_error (/usr/local/lib/node_modules/uglify-js/lib/parse.js:197:11)
    at croak (/usr/local/lib/node_modules/uglify-js/lib/parse.js:657:9)
    at token_error (/usr/local/lib/node_modules/uglify-js/lib/parse.js:665:9)
    at unexpected (/usr/local/lib/node_modules/uglify-js/lib/parse.js:671:9)
    at expr_atom (/usr/local/lib/node_modules/uglify-js/lib/parse.js:1167:9)
    at maybe_unary (/usr/local/lib/node_modules/uglify-js/lib/parse.js:1328:19)
    at expr_ops (/usr/local/lib/node_modules/uglify-js/lib/parse.js:1363:24)
    at maybe_conditional (/usr/local/lib/node_modules/uglify-js/lib/parse.js:1368:20)
    at maybe_assign (/usr/local/lib/node_modules/uglify-js/lib/parse.js:1392:20)

The unminified bundle output appears as so:

"format register";

System.register("app/jspm-test", [], false, function(__require, __exports, __module) {
  System.get("@@global-helpers").prepareGlobal(__module.id, []);
  (function() {
    (function k(ra) {
      throw ra;
    }, var n = void 0,
        r = !0,
        t = null,
        A = !1;, this["n"] = n;, this["r"] = r;, this["t"] = t;, this["A"] = A;);
  }).call(System.global);
  return System.get("@@global-helpers").retrieveGlobal(__module.id, false);
});

//# sourceMappingURL=jspm-test.bundle.js.map

Line 8 }, var n = void 0, is the problem as it's not valid Javascript syntax. I believe this was generated by the SystemJS builder. Am I correct in this thinking? If so, it seems like a bug? Or is SystemJS leveraging some other library to do this generation and the bug lies there? Any suggestions on workaround or fix? Thanks!

This is jspm 0.10.6, uglifyjs 2.4.16, systemjs-builder 0.5.3.

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.