These are chat archives for systemjs/systemjs

21st
Sep 2015
Logan Smyth
@loganfsmyth
Sep 21 2015 00:24

@guybedford I'm curious, is there a standard way to essentially wrap a module? Conceptually I guess that'd mean generating a dynamic

export * from 'mod';
export {default as default} from 'mod';

type module

Jayson Harshbarger
@Hypercubed
Sep 21 2015 07:46
@loganfsmyth Maybe similar to my question here: https://groups.google.com/forum/#!topic/systemjs/FH1reibV924

JSPM already generates some sort of wrapper file like:

export * from "registry:module@version/file";
export {default} from "registry:module@version/file";

I wonder how we can alter that? In my case I want to add var __useDefault = true.

Maybe should have been posted to JSPM chat
Vamsi Ampolu
@vamsiampolu
Sep 21 2015 10:15
I am trying out Systemjs for the browser,how can/should I use map config for npm modules?
carlosagsmendes
@carlosagsmendes
Sep 21 2015 11:37
Hi I want to create a failing test for the builder. But I don't know how to run the existing tests. Can someone help?
carlosagsmendes
@carlosagsmendes
Sep 21 2015 11:54
Apparently the test scripts are broken
"scripts": {
    "test:accept-source-maps": "UPDATE_EXPECTATIONS=true mocha test/sourcemaps.js",
    "test:traceur": "cd test && node run-build.js && open test-build.html && open test-sfx.html",
    "test:babel": "cd test && node run-build.js babel && open test-build.html && open test-sfx.html",
    "test": "mkdir -p test/output && ./node_modules/.bin/mocha"
  },
Guy Bedford
@guybedford
Sep 21 2015 13:01
@loganfsmyth there is actually an alias feature in SystemJS that is equivalent to the above syntax without having to write it. But it doesn't let you modify the wrapper. Does that sound like what you were after?
@carlosagsmendes npm test
carlosagsmendes
@carlosagsmendes
Sep 21 2015 13:31
@guybedford I get this:

λ npm test

systemjs-builder@0.14.3 test D:\Repos\tmp\builder
mkdir -p test/output && ./node_modules/.bin/mocha

The syntax of the command is incorrect.
npm ERR! Test failed. See above for more details.

Guy Bedford
@guybedford
Sep 21 2015 13:33
sounds like a windows compatibility issue, you should be able to rewrite that to work on windows though
carlosagsmendes
@carlosagsmendes
Sep 21 2015 13:50
it works fine on mac
Logan Smyth
@loganfsmyth
Sep 21 2015 16:50
@guybedford Yeah I don't think an alias will work. I guess I'll take a step back and ask my higher-level question, are there any modules that you know of that try to do dependency introspection/injection? I don't love rewire, and have a custom little thing I've written for CommonJS, but I was trying to figure out if there was something I could get the same behavior in SystemJS. Since SystemJS exports are live and can be updated, it seems like you could use that as a way to override exports during testing.
Guy Bedford
@guybedford
Sep 21 2015 16:51
@loganfsmyth it sounds like you might want the System.delete, System.get and System.set APIs
  var m = System.get(System.normalizeSync('module/name'))
  var newM = System.newModule({
    exportName: m.exportName,
    anotherExport: 'value'
  });
System.set(System.normalizeSync('module/name'), newM);
there is an issue though, and that is that any modules already importing that module won't get updated with the new values
so you have to force-reload all parents with dependency analysis
certainly tooling would be useful here, it touches on hot reloading too
Logan Smyth
@loganfsmyth
Sep 21 2015 16:53
So what I have in my ES6 modules in CommonJS right now is basically
import SomeThing, {EXPORTS} from 'mod';

EXPORTS.default.set(function fakeDefault(){});

SomeThing();

EXPORTS.default.restore();
so each module exposes an export that allows introspection/override of exports
Seems like I could get the same from SystemJS by replacing register with something like
function newRegister(fn){
    return function (exp){
        var exports = Object.create(null);
        var overrides = Object.create({});
        var EXPORTS = {};
        exp('EXPORTS', EXPORTS);

        function sendExports(){
            var obj = {};
            for (var key in overrides) obj[key] = overrides[key];
            exp(obj);
        }

        function ensureDefined(key){
            if (key in EXPORTS) return;

            EXPORTS[key] = {
                get: function(){
                    return overrides[key];
                },
                set: function(val){
                    overrides[key] = value;
                    exp(key, val);
                },
                restore: function(){
                    delete overrides[key];
                    exp(key, overrides[key]);
                }
            };
        }

        return fn(function(obj, value){
            if (typeof obj === 'string'){
                var key = obj;
                obj = {}
                obj[key] = value;
            }

            Object.keys(obj).forEach(function(key, value){
                ensureDefined(key);
            });

            Object.keys(obj).forEach(function(key, value){
                exports[key] = value;
            });

            sendExports();
        });
    };
}
Guy Bedford
@guybedford
Sep 21 2015 16:54
@loganfsmyth ES modules themselves are static - there is no way to update export values externally
but you can actually do it internally from the module itself
Logan Smyth
@loganfsmyth
Sep 21 2015 16:55
yeah, that alternative is there definitely, I'm thinking about writing a Babel plugin to inject the EXPORTS into each module
Guy Bedford
@guybedford
Sep 21 2015 16:55
it may help if you can explain the use case
Logan Smyth
@loganfsmyth
Sep 21 2015 16:56
with CommonJS I can do it without that, just exploring options
Guy Bedford
@guybedford
Sep 21 2015 16:56
remember it's not about what's possible in the current implementation, but what's possible in the spec
Logan Smyth
@loganfsmyth
Sep 21 2015 16:56
mostly testing
yeah, I know, rewriting during transpilation is probably the only option in the long run
otherwise the module API would have to expose some introspection hooks for the import and export tables of each module
Guy Bedford
@guybedford
Sep 21 2015 16:58
we have introspection hooks
you can iterate modules in the registry and set and get modules from the registry
but it requires dependency analysis when setting a module to ensure its value is pushed into all importers
the current implementation doesn't provide a nice iteration, but it's in the spec definitely
the dependency analysis problem is big though, Ive brought it up in whatwg/loader#51
Logan Smyth
@loganfsmyth
Sep 21 2015 17:05
Yeah, I thought about it more last night after posting my question and I think realistically there are parts of what I'm trying to achieve that don't fit with the behavior of live-bindings anyway, so we'll see.
Guy Bedford
@guybedford
Sep 21 2015 17:08
sure, I'm happy to suggest approaches further as well if you want to share more information about the use case
btw always great to see you on here :)
Logan Smyth
@loganfsmyth
Sep 21 2015 17:22
Yeah haven't seen you in ages :) Are you still in SF these days?
Guy Bedford
@guybedford
Sep 21 2015 19:47
@loganfsmyth have been living in Cape Town, which would explain why! Do hope to make a trip over again soon though.
Logan Smyth
@loganfsmyth
Sep 21 2015 20:25
ahh cool, yeah I wasn't if you'd gone back.
Davis Kim
@davis
Sep 21 2015 21:27
@guybedford what's the best way to make a plugin install its dependencies?
Guy Bedford
@guybedford
Sep 21 2015 21:45
@davis is this a jspm question?
Davis Kim
@davis
Sep 21 2015 21:45
may..bee...?
meomix brought it up last week, but basically i want it so that my plugin can install its dependencies (handlebars) when you do a jspm install hbs
and so how should i configure my plugin so that it does this/
Guy Bedford
@guybedford
Sep 21 2015 21:46
so you can just include the dependencies in the package.json
is it not already working like that though?
Davis Kim
@davis
Sep 21 2015 22:00
i don't think so
i have
  "jspm": {
    "main": "hbs",
    "directories": {},
    "dependencies": {
      "handlebars": "github:components/handlebars.js@^4.0.2"
    },
    "devDependencies": {
      "babel": "npm:babel-core@^5.4.3",
      "babel-runtime": "npm:babel-runtime@^5.4.3",
      "core-js": "npm:core-js@^0.9.10"
    }
  }
Guy Bedford
@guybedford
Sep 21 2015 22:00
oh I remember - the issue was you want to do require('handlebars') from within the template right?
Davis Kim
@davis
Sep 21 2015 22:01
ahh, yes
my plugin looks like this:
export function translate(load) {
  console.log('compiling template:', load.name);
  load.source = 'module.exports = require(\'handlebars\').compile(\'' + load.source
  .replace(/'/g, '\\\'')
  .replace(/[\f]/g, '\\f')
  .replace(/[\b]/g, '\\b')
  .replace(/[\n]/g, '\\n')
  .replace(/[\t]/g, '\\t')
  .replace(/[\r]/g, '\\r')
  .replace(/[\u2028]/g, '\\u2028')
  .replace(/[\u2029]/g, '\\u2029') + '\');';
}
so yes, from the thing that gets exported, it does a reuqire('handlebars')
Guy Bedford
@guybedford
Sep 21 2015 22:01
so you just want...
export function translate(load) {
  console.log('compiling template:', load.name);
  return this.normalize('handlebars', __moduleName)
  .then(function(handlebarsModuleNormalized) {
    return 'module.exports = require(\'' + handlebarsModuleNormalized +  '\').compile(\'' + load.source
    .replace(/'/g, '\\\'')
    .replace(/[\f]/g, '\\f')
    .replace(/[\b]/g, '\\b')
    .replace(/[\n]/g, '\\n')
    .replace(/[\t]/g, '\\t')
    .replace(/[\r]/g, '\\r')
    .replace(/[\u2028]/g, '\\u2028')
    .replace(/[\u2029]/g, '\\u2029') + '\');';
  });
}
also you should do a return '...' instead of setting load.source
ooo actually you should also be compiling in the translate function
otherwise there is no builder support for templates
which is bad
Davis Kim
@davis
Sep 21 2015 22:06
compiling in the translate function?
Guy Bedford
@guybedford
Sep 21 2015 22:07
yes, so the translate function should really just be along the lines of
import handlebars from 'handlebars';
export function translate(load) {
  return handlebars.compile(load.source);
}
and if you need the handlebars runtime for the template then do something like
Davis Kim
@davis
Sep 21 2015 22:08
hm, i had that long time ago, that was my first attempt at making the plugin, i'll try that again
Guy Bedford
@guybedford
Sep 21 2015 22:09
  return 'import handlebars from 'handlebars/runtime'
   + 'export default ' + handlebars.compile(load.source);';
with the normalize trick as well above of course
Davis Kim
@davis
Sep 21 2015 22:09
got it, will try that
Guy Bedford
@guybedford
Sep 21 2015 22:09
you want the handlebars.compile to output a string
ok you probably want handlebars.precompile there
Davis Kim
@davis
Sep 21 2015 22:10
maybe i'll need to use handlebars.precompile
heh jynx!
i'll look into it. thanks!
Guy Bedford
@guybedford
Sep 21 2015 22:10
then you want to wrap it with its own hydration code
which you manage as a string module wrapper as well
etc etc
sure, no problem, just let me know if you need any more help
Davis Kim
@davis
Sep 21 2015 22:11
will do. ty
Sean Anderson
@MeoMix
Sep 21 2015 22:23
Question... I get different results when I use "baseURL" vs "baseUrl" in my config file... is that intentional?
oh, maybe I'm being stupid.
and baseUrl isn't being seen.
Davis Kim
@davis
Sep 21 2015 22:48
@guybedford what does normalizing do?
and is that related to making jspm install hbs install handlebars as well?
Davis Kim
@davis
Sep 21 2015 23:33
what's the best way to bundle code in such a way that it gets exposed on the global object
so that people can use
<script src="hello.js"></script>
<script>Hello();</script>
i tried bundle-sfx, but that didn't do it
Davis Kim
@davis
Sep 21 2015 23:41
do i just add a System.import to hello.js?
Vamsi Ampolu
@vamsiampolu
Sep 21 2015 23:53
how do i setup a systemjs config.js to import npm modules,should I use system-npm?