Code Monkey home page Code Monkey logo

builder's Introduction

SystemJS

Gitter Backers on Open Collective Sponsors on Open Collective Downloads on JS Delivr

SystemJS is a hookable, standards-based module loader. It provides a workflow where code written for production workflows of native ES modules in browsers (like Rollup code-splitting builds), can be transpiled to the System.register module format to work in older browsers that don't support native modules, running almost-native module speeds while supporting top-level await, dynamic import, circular references and live bindings, import.meta.url, module types, import maps, integrity and Content Security Policy with compatibility in older browsers back to IE11.

Sponsors

Support SystemJS by becoming a sponsor. Your logo will show up here with a link to your website.

Backers

Thank you to all our backers! ๐Ÿ™ [Become a backer]

Overview

1. s.js minimal production loader

The minimal 2.8KB s.js production loader includes the following features:

  • Loads System.register modules, the CSP-compatible SystemJS module format.
  • Support for loading bare specifier names with import maps via <script type="systemjs-importmap">.
  • Supports hooks for loader customization.

2. system.js loader

The 4.2KB system.js loader adds the following features in addition to the s.js features above:

3. system-node.cjs loader

The system-node.cjs loader is a version of SystemJS build designed to run in Node.js, typically for workflows where System modules need to be executed on the server like SSR. It has the following features:

  • Loading System modules from disk (via file:// urls) or the network, with included caching that respects the Content-Type header.
  • Import Maps (via the applyImportMap api).
  • Tracing hooks and registry deletion API for reloading workflows.
  • Loading global modules with the included global loading extra.

Loading CommonJS modules is not currently supported in this loader and likely won't be. If you find you need them it is more advisable to use Node.js native module support where possible instead of the SystemJS Node.js loader.

Extras

The following pluggable extras can be dropped in with either the s.js or system.js loader:

  • AMD loading support (through Window.define which is created).
  • Named register supports System.register('name', ...) named bundles which can then be imported as System.import('name') (as well as AMD named define support)
  • Dynamic import maps support. This is currently a potential new standard feature.

The following extras are included in system.js loader by default, and can be added to the s.js loader for a smaller tailored footprint:

  • Global loading support for loading global scripts and detecting the defined global as the default export. Useful for loading common library scripts from CDN like System.import('//unpkg.com/lodash').
  • Module Types .css, .wasm, .json module type loading support in line with the existing modules specifications.

Since all loader features are hookable, custom extensions can be easily made following the same approach as the bundled extras. See the hooks documentation for more information.

SystemJS Babel

To support easy loading of TypeScript or ES modules in development SystemJS workflows, see the SystemJS Babel Extension.

SystemJS does not support direct integration with the native ES module browser loader because there is no way to share dependencies between the module systems. For extending the functionality of the native module loader in browsers, see ES module Shims, which like SystemJS, provides workflows for import maps and other modules features, but on top of base-level modules support in browsers, which it does using a fast Wasm-based source rewriting to remap module specifiers.

Performance

SystemJS is designed for production modules performance roughly only around a factor of 1.5 times the speed of native ES modules, as seen in the following performance benchmark, which was run by loading 426 javascript modules (all of @babel/core) on a Macbook pro with fast wifi internet connection. Each test was the average of five page loads in Chrome 80.

Tool Uncached Cached
Native modules 1668ms 49ms
SystemJS 2334ms 81ms

Getting Started

Introduction video.

The systemjs-examples repo contains a variety of examples demonstrating how to use SystemJS.

Installation

npm install systemjs

Documentation

Example Usage

Loading a System.register module

You can load System.register modules with a script element in your HTML:

<script src="system.js"></script>
<script type="systemjs-module" src="/js/main.js"></script>
<script type="systemjs-module" src="import:name-of-module"></script>

Loading with System.import

You can also dynamically load modules at any time with System.import():

System.import('/js/main.js');

where main.js is a module available in the System.register module format.

Bundling workflow

For an example of a bundling workflow, see the Rollup Code Splitting starter project - https://github.com/rollup/rollup-starter-code-splitting.

Note that when building System modules you typically want to ensure anonymous System.register statements like:

System.register([], function () { ... });

are emitted, as these can be loaded in a way that behaves the same as normal ES modules, and not named register statements like:

System.register('name', [], function () { ... });

While these can be supported with the named register extension, this approach is typically not recommended for modern modules workflows.

Import Maps

Say main.js depends on loading 'lodash', then we can define an import map:

<script src="system.js"></script>
<script type="systemjs-importmap">
{
  "imports": {
    "lodash": "https://unpkg.com/[email protected]/lodash.js"
  }
}
</script>
<!-- Alternatively:
<script type="systemjs-importmap" src="path/to/map.json" crossorigin="anonymous"></script>
-->
<script type="systemjs-module" src="/js/main.js"></script>

IE11 Support

IE11 continues to be fully supported, provided the relevant polyfills are available.

The main required polyfill is a Promise polyfill. If using import maps a fetch polyfill is also needed.

Both of these can be loaded conditionally using for example using Bluebird Promises and the GitHub Fetch Polyfill over Unpkg:

<script>
  if (typeof Promise === 'undefined')
    document.write('<script src="https://unpkg.com/[email protected]/js/browser/bluebird.core.min.js"><\/script>');
  if (typeof fetch === 'undefined')
    document.write('<script src="https://unpkg.com/[email protected]/dist/fetch.umd.js"><\/script>');
</script>

located before the SystemJS script itself. The above will ensure these polyfills are only fetched for older browsers without Promise and fetch support.

Note on Import Maps Support in IE11

When using external import maps (those with src="" attributes), there is an IE11-specific workaround that might need to be used. Browsers should not make a network request when they see <script type="systemjs-importmap" src="/importmap.json"></script> during parsing of the initial HTML page. However, IE11 does so. Codesandbox demonstration

Normally this is not an issue, as SystemJS will make an additional request via fetch/xhr for the import map. However, a problem can occur when the file is cached after the first request, since the first request caused by IE11 does not send the Origin request header by default. If the request requires CORS, the lack of an Origin request header causes many web servers (including AWS Cloudfront) to omit the response CORS headers. This can result in the resource being cached without CORS headers, which causes the later SystemJS fetch() to fail because of CORS checks.

This can be worked around by adding crossorigin="anonymous" as an attribute to the <script type="systemjs-importmap"> script.

Community Projects

A list of projects that use or work with SystemJS in providing modular browser workflows. Post a PR.

  • beyondjs.com -TypeScript first meta-framework for universal microfrontends/micronservices.
  • esm-bundle - list of System.register versions for major libraries, including documentation on how to create a System.register bundle for any npm package.
  • es-dev-server - A web server for developing without a build step.
  • import map overrides - Dynamically inject an import map stored in local storage so that you can override the URL for any module. Can be useful for running development modules on localhost against the server.
  • js-env - Collection of development tools providing a unified workflow to write JavaScript for the web, node.js or both at the same time.
  • jspm.org - Package manager for native modules, using SystemJS for backwards compatibility.
  • single-spa - JavaScript framework for front-end microservices.
  • systemjs-webpack-interop - npm lib for setting webpack public path and creating webpack configs that work well with SystemJS.
  • @wener/system - hooks to make System works with npm registry & package.json}

Compatibility with Webpack

Code-splitting builds on top of native ES modules, like Rollup offers, are an alternative to the Webpack-style chunking approach - offering a way to utilize the native module loader for loading shared and dynamic chunks instead of using a custom registry and loader as Webpack bundles include. Scope-level optimizations can be performed on ES modules when they are combined, while ensuring no duplicate code is loaded through dynamic loading and code-sharing in the module registry, using the features of the native module loader and its dynamic runtime nature.

systemjs-webpack-interop is a community-maintained npm library that might help you get webpack and systemjs working well together.

As of [email protected], it is now possible to compile webpack bundles to System.register format, by modifying your webpack config:

{
  output: {
    libraryTarget: 'system', 
  }
}

If using webpack@<5, the following config is needed to avoid rewriting references to the global System variable:

{
  module: {
    rules: [
      { parser: { system: false } }
    ]
  }
}

Using npm packages

Third party libraries and npm packages may be used as long as they are published in a supported module format. For packages that do not exist in a supported module format, here is a list of github repos that publish System.register versions of popular third party libraries (such as react, react-dom, rxjs, etc).

Contributing to SystemJS

Project bug fixes and changes are welcome for discussion, provided the project footprint remains minimal.

Task running is handled by Chomp (https://chompbuild.com).

To run the tests:

npm install -g chomp
chomp test

Changes

For the changelog, see CHANGELOG.md.

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

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.

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

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.

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.

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]

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.

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)

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.

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'));
  });
  })();

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 :)

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

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.

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?

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.

Full source maps for builds

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

asset compilation

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

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.

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.

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]

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');
  })

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.

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.

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?

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?

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
    });
});

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.

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!

6to5 support

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

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

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.

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.

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.

Building css

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

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.