These are chat archives for stealjs/steal

17th
Feb 2016
Dovid Bleier
@dbleier
Feb 17 2016 15:34

in development I have

import Map from 'can/map/';
import 'can/map/define/';
import services from 'menuboard-manager/config/services/';
const Config = Map.extend({
      define: {
        mac: {
            get() {
                var mac = services.getService('storage').get('mac');
                return mac;
            }
        },
    }
});

which works perfectly

in production the var = mac.. turns into
 var mac = _services['default'].getService('storage').get('mac');
which crashes because `_services['default'] returns an empty obj with no getService function
hence I get
Potentially unhandled rejection 2 TypeError: _services.default.getService is not a function (WARNING: non-Error used)(anonymous function) @ steal.js:143report @ steal.js:170flush @ steal.js:193
2016-02-17 17:28:40.649 steal.js:143 TypeError: _services.default.getService is not a function
at get (index.js:8683)
at ObservedInfo.can.simpleExtend.getValueAndBind (index.js:3137)
at on [as _on] (index.js:3478)
at null.<anonymous> (index.js:3394)
at null._bindsetup (index.js:3247)
at can.bindAndSetup [as bind] (index.js:2712)
at Function.can.Compute.temporarilyBind (index.js:3489)
at can.simpleExtend.get (index.js:3416)
at Object.compute (index.js:3536)
at can.Map.can.Construct.extend.___get (index.js:4245)(anonymous function) @ steal.js:143report @ steal.js:171flush @ steal.js:193
Kevin Phillips
@phillipskevin
Feb 17 2016 15:43
what does services look like?
Dovid Bleier
@dbleier
Feb 17 2016 15:44
in production or development?
Kevin Phillips
@phillipskevin
Feb 17 2016 15:45
the code I mean
development is fine
Dovid Bleier
@dbleier
Feb 17 2016 15:47
currently
import Map from 'can/map/';
import storage from 'menuboard-manager/utils/storage/';
import systemTime from 'menuboard-manager/utils/systemTime/';
import { logger } from 'menuboard-manager/utils/logger/';
import parser from 'menuboard-manager/utils/parser/';
import network from 'menuboard-manager/sssp/network/';
import localtime from 'menuboard-manager/sssp/time/';

const Services = Map.extend({
    storage:  storage,
    clock: systemTime,
    logger: logger,
    parser: parser,
    mac: network,
    localtime: localtime,
    getService(service) {
        return this[service];
    }
});

const services = new Services();

export default services;
originally I was not using Map, just a pojo, but when it wasn't working tried using Map, but ideally prefer pojo since it does not need to be observable
Kevin Phillips
@phillipskevin
Feb 17 2016 15:51
hmm, are you doing anything with services in you System config?
Dovid Bleier
@dbleier
Feb 17 2016 15:52
where?
Kevin Phillips
@phillipskevin
Feb 17 2016 15:52
your package.json if you’re using the npm plugin
Dovid Bleier
@dbleier
Feb 17 2016 15:53
no, why would I need to? I created the services module with the donejs generator
Kevin Phillips
@phillipskevin
Feb 17 2016 15:53
you wouldn't
I’m just trying to figure out why it would be an empty object
dylanrtt
@dylanrtt
Feb 17 2016 15:54
@dbleier config.attr('mac') seems to be getting read before the 'default' export from the services module has resolved because of the circular dependency. I suspect that this is because the module that reads mac does not import both system and config so it resolves immediately after config resolves without waiting for services
Dovid Bleier
@dbleier
Feb 17 2016 15:56
@dylanrtt there shouldn't be a circular dependency here as config imports services but services does NOT import config
dylanrtt
@dylanrtt
Feb 17 2016 15:56
maybe it imports it indirectly?
Dovid Bleier
@dbleier
Feb 17 2016 15:57
so services should resolve all dependencies before getting called by config
hmmm
could be, some of the modules services imports do import config
however
the module requesting the mac service is not imported by any of these modules, so they should have resolved first
it does import config before services, but I thought order of imports doesn't matter
and this all works in development
dylanrtt
@dylanrtt
Feb 17 2016 16:02
the order that modules are imported can often be different in production than development
the order you import them in another module probably shouldn't matter in this case
you may still have a mistake in the loading order even though it works in dev
Dovid Bleier
@dbleier
Feb 17 2016 16:05
ok
looking up the call change, what's ultimately calling the function is the renderer for the stache template
(btw re my issue from yesterday, I changed around my whole stache-vm-can-connect relationship to avoid the post processing I was doing and giving me so much trouble and now that works a lot smoother)
will stache rendering start before dependencies are resolved?
dylanrtt
@dylanrtt
Feb 17 2016 16:10
not necessarily. it depends on the module that initiates the render
Dovid Bleier
@dbleier
Feb 17 2016 16:10
it's a component's vm
but there is an import for services in app.js, even though app.js isn't using services (did previously and didn't remove it)
how can I track this down?
dylanrtt
@dylanrtt
Feb 17 2016 16:13
Does app.js also import config?
Dovid Bleier
@dbleier
Feb 17 2016 16:14
no
dylanrtt
@dylanrtt
Feb 17 2016 16:14
try adding it
Dovid Bleier
@dbleier
Feb 17 2016 16:15
didn't help
dylanrtt
@dylanrtt
Feb 17 2016 16:16
If app.js imports services only, services would eventually import config (indirectly) which would then try to import services... where it would be undefined because it was imported first, then app.js could resolve early and render without config having ever resolved fully, so the render could start early that way
Dovid Bleier
@dbleier
Feb 17 2016 16:17
so I should try taking both out
dylanrtt
@dylanrtt
Feb 17 2016 16:17
well it sounds like the template needs them to all be resolved first
Dovid Bleier
@dbleier
Feb 17 2016 16:18
yeah, I tried taking services out of app.js and it crashed another module
which calls config in a value: function
dylanrtt
@dylanrtt
Feb 17 2016 16:21
assuming your app.js initiates the render, importing config and services first should probably have worked... strange
importing the other modules in app.js that are related in the circular dependency might be required
Dovid Bleier
@dbleier
Feb 17 2016 16:25
would it make a difference if the services define in the production index.js is below the modules requesting it?
and app is defined just after services
dylanrtt
@dylanrtt
Feb 17 2016 16:29
I don't think the definition order matters as much as the import order, but it's based on the import order through analysis
Dovid Bleier
@dbleier
Feb 17 2016 16:30
I just stepped thru the code and the services define is getting called before the request for mac
dylanrtt
@dylanrtt
Feb 17 2016 16:31
so importing mac in app.js (and possibly a few other imports) may work
depending on the complexity of your circular imports, you may just need to import them all in app.js
Dovid Bleier
@dbleier
Feb 17 2016 16:32
that sort of defeats the purpose of config and services to hid these things via SOC
need to run out now, be back in about 1.5hrs
dylanrtt
@dylanrtt
Feb 17 2016 16:35
well it's not much of a stretch for app.js to have knowledge of the app's modules
Dovid Bleier
@dbleier
Feb 17 2016 16:35
if you have any ideas, pls leave them here
hmmm
dylanrtt
@dylanrtt
Feb 17 2016 16:35
I would give that a go and see if it works
Dovid Bleier
@dbleier
Feb 17 2016 16:35
ok, I try it
Dovid Bleier
@dbleier
Feb 17 2016 17:39
@dylanrtt I tried importing all modules into app.js and it didn't help. Any other ideas?
dylanrtt
@dylanrtt
Feb 17 2016 17:40
@dbleier that behavior is unexpected. I think I'm out of ideas
dylanrtt
@dylanrtt
Feb 17 2016 17:45
are you able to see that config and service modules have both resolved in your app.js before you render the template?
Dovid Bleier
@dbleier
Feb 17 2016 18:12
so I see that config and services defines are both called before mac is called
however config define is called before services
so it seems that the _services var (which is in closure vis-a-vis the mac function) in config is not getting updated after the services define runs
Dovid Bleier
@dbleier
Feb 17 2016 18:21
well, in an act of desperation, I removed the services import from config and imported the needed services directly and that got me past mac failing
but pushed the same issue to another service module
so it would seem that for all my services that the services module calls, I will have to import the other services directly
thus removing all of the circular dependencies :(
perhaps at some point @matthewp can chime in about how to deal with circular dependencies or perhaps with steal production it is not possible
Matthew Phillips
@matthewp
Feb 17 2016 18:30
you can have circular dependencies
you just can't use them in defining a module
if that makes sense
Dovid Bleier
@dbleier
Feb 17 2016 18:30
no, pls explain
Matthew Phillips
@matthewp
Feb 17 2016 18:30
if not, it's a bug
Dovid Bleier
@dbleier
Feb 17 2016 18:31
"you just can't use them in defining a module" -- pls explain what you mean
Matthew Phillips
@matthewp
Feb 17 2016 18:32
i mean you can't export a function
and then use that function when defining another module
import foo from 'foo'; foo()
can't do that
but you could do
export function something() { foo(); }
err sorry that's not true
export function something() { foo.bar(); }
it's possible we have a bug here though
I'd file an issue on steal-tools
we might not be building out circular refs correctly
Alex
@whitecolor
Feb 17 2016 18:35
@matthewp Matthew, what about may babel-runtime question? var _regenerator = require('babel-runtime/regenerator'); should I elaborate more?
Dovid Bleier
@dbleier
Feb 17 2016 18:35
ok, it seems that when _x = _interopRequireDefault(_mod/x); runs before x has been defined, it sets it to an empty obj
and then when x is defined the _x in the modules depending on _x don't get updated
Matthew Phillips
@matthewp
Feb 17 2016 18:36
@whitecolor yeah please do, i think you asked that to me privately
maybe someone else will know if i do not
Alex
@whitecolor
Feb 17 2016 18:37
@matthewp I wan't to use async/await on the client
have you ever tried or wanted to do this?
babel allow to do this using babel-runtime
Matthew Phillips
@matthewp
Feb 17 2016 18:39
I don't write code with es6 personally
yes, i know about the runtime
I think for traceur we add it in the build, but maybe not for babel...
Alex
@whitecolor
Feb 17 2016 18:40
I use babel 6 and pre-transpile files on server (with watchalive)
Matthew Phillips
@matthewp
Feb 17 2016 18:41
do you use steal-tools to do the transpiling?
Alex
@whitecolor
Feb 17 2016 18:41
With files that have async/awaittranspiled code contains var _regenerator = require('babel-runtime/regenerator');
So it tries to require it from client
Matthew Phillips
@matthewp
Feb 17 2016 18:41
oh, babel adds that?
Alex
@whitecolor
Feb 17 2016 18:43
yes, I think because it wouldn't like to include full code in every file code that enables such things (for example async/await)
Matthew Phillips
@matthewp
Feb 17 2016 18:44
yeah, so if you know where that file is
you can add a paths config
to get it
Alex
@whitecolor
Feb 17 2016 18:44
it then requires many files
Matthew Phillips
@matthewp
Feb 17 2016 18:44
i don't know where the script is
Alex
@whitecolor
Feb 17 2016 18:45
I thought maybe use https://babeljs.io/docs/usage/polyfill/ somehow
but I don't get how
usually people now use browserfiy and have not probelem with workflow
Matthew Phillips
@matthewp
Feb 17 2016 18:46
dist/polyfill.js
set up a paths for this
is what i would try
Alex
@whitecolor
Feb 17 2016 18:47
what paths?
Matthew Phillips
@matthewp
Feb 17 2016 18:47
i would set a paths for babel-runtime/regenerator
to that babel-polyfill/dist/polyfill.js
Alex
@whitecolor
Feb 17 2016 18:48
to dist/polyfill.js?
Matthew Phillips
@matthewp
Feb 17 2016 18:48
yeah, if that's the same thign
assuming it is
Alex
@whitecolor
Feb 17 2016 18:49
but var _regenerator = require('babel-runtime/regenerator');
it will not return _regenerator
dylanrtt
@dylanrtt
Feb 17 2016 18:55
@dbleier could you make some sort of tree/diagram representing all of your circular dependencies? I can't seem to reproduce your issue from what you've said so far, so if there is a bug (which it sounds like there is), it probably has to do with the complexity of your situation
Matthew Phillips
@matthewp
Feb 17 2016 18:55
Ok, that makes sense
that is what you should be requiring then
@whitecolor if you figure it out let me know
I'd like to publish a module, maybe something like steal-babel-runtime
that makes this automatic
Dovid Bleier
@dbleier
Feb 17 2016 18:57
I filed an issue on steal-tools
ok, I'll try to put together a diagram
Matthew Phillips
@matthewp
Feb 17 2016 19:03
thanks!
Alex
@whitecolor
Feb 17 2016 19:28
@matthewp figured it out, need to include polyfill it will enable window.regeneratorRuntime and then apply "transform-async-to-generator" plugin while babel transfrom
but what to do in production, include polyfill there too?
Dovid Bleier
@dbleier
Feb 17 2016 19:45
@dylanrtt I created a diagram of the circular dependencies (png). how can I share it with you?
dylanrtt
@dylanrtt
Feb 17 2016 19:46
a link perhaps?
straight lines represent direct imports
curved lines are via the services.getService
these are just the circular dependencies, there are other modules (for components) that import config and services and use the other services via them
double-headed arrows mean both modules import each other
dylanrtt
@dylanrtt
Feb 17 2016 20:32
@dbleier I'm surprised I wasn't able to reproduce this earlier because I just narrowed it down to a simple example. I will post on the issue
Dovid Bleier
@dbleier
Feb 17 2016 20:32
ok, cool
thanks
Dovid Bleier
@dbleier
Feb 17 2016 21:11
ready for the next one?
how can I get a handle to my viewmodels from the console?
no debugger
and $('my-component').viewModel() won't work since the components aren't loading
also is there a debug mode in production? meaning that console.log statement to detail what steal is doing?
I am using steal, not steal.production if that helps
Mohamed Cherif Bouchelaghem
@cherifGsoul
Feb 17 2016 21:24
@dbleier $('html').viewModel()?
Dovid Bleier
@dbleier
Feb 17 2016 21:26
good thought but just returns an empty map
Mohamed Cherif Bouchelaghem
@cherifGsoul
Feb 17 2016 21:31
is the component already rendered?
Dovid Bleier
@dbleier
Feb 17 2016 21:32
no, that's the problem. somewhere steal is dying before the render
Dovid Bleier
@dbleier
Feb 17 2016 21:39
well I something evil :evil
in app.js init() I dump references to all my modules into a global var
just for debugging purposed