Skip to content

Naming a constructor PS breaks the javascript#3533

Merged
natefaubion merged 1 commit intopurescript:masterfrom
mhcurylo:naming-a-constructor-PS-brakes-the-javascript
Mar 26, 2019
Merged

Naming a constructor PS breaks the javascript#3533
natefaubion merged 1 commit intopurescript:masterfrom
mhcurylo:naming-a-constructor-PS-brakes-the-javascript

Conversation

@mhcurylo
Copy link
Copy Markdown
Contributor

@mhcurylo mhcurylo commented Feb 9, 2019

I have fixed the PS constructor braking the exports by changing the IIFE argument from exports to the PS module object.
There are no automated tests for the psc-bundle and I have not added one. Maybe they should be introduced?
Fragment of an output is:

function(PS) {
  // Generated by purs version 0.12.2
  "use strict";
  var exports = PS["Effect.Console"] = PS["Effect.Console"] || {};
  var $foreign = PS["Effect.Console"];
  var Data_Show = PS["Data.Show"];
  var Data_Unit = PS["Data.Unit"];
  var Effect = PS["Effect"];
  exports["log"] = $foreign.log;
})(PS); 

@mhcurylo mhcurylo changed the title Naming a constructor PS breaks the javascrip Naming a constructor PS breaks the javascript Feb 9, 2019
@hdgarrood
Copy link
Copy Markdown
Contributor

I agree that having some tests would be good. Are you volunteering to add some? I'm very happy to help if you have any questions.

@mhcurylo
Copy link
Copy Markdown
Contributor Author

It sounds like morning fun if we do not mind me taking some time. An outline:

  1. Example directory for purs files in tests/purs/bundle directory.
  2. A module TestPscBundle.hs in /tests/ directory.
  3. Similar setup as the compiler tests but using the psc-bundle.
    As an alternative, we could add an annotation 'use-bundle' to the compiler tests and keep the examples in there. I think it might be mixing concerns though.

@hdgarrood
Copy link
Copy Markdown
Contributor

I think a tests/purs/bundle directory sounds great.

@hdgarrood
Copy link
Copy Markdown
Contributor

(Fixes #3505)

@mhcurylo mhcurylo force-pushed the naming-a-constructor-PS-brakes-the-javascript branch 2 times, most recently from 105cd48 to 38a0b55 Compare March 2, 2019 13:35
@mhcurylo
Copy link
Copy Markdown
Contributor Author

mhcurylo commented Mar 2, 2019

@hdgarrood
Test added.
I have exported the common functions between compiler and bundle tests to TestUtils.
One problem I see is that in order to increase bundle coverage we would have to manually implement js scenarios. With the current solution (test vs compiled purescript code) - some code will be unreachable.
For now, it fixes the problem and adds coverage.
Please review.

Copy link
Copy Markdown
Contributor

@hdgarrood hdgarrood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I still need to get my head around the actual changes but in the meantime, here's a few minor comments.

@hdgarrood
Copy link
Copy Markdown
Contributor

One problem I see is that in order to increase bundle coverage we would have to manually implement js scenarios. With the current solution (test vs compiled purescript code) - some code will be unreachable.

This doesn't bother me, I think what we have here is fine for now.

@mhcurylo mhcurylo force-pushed the naming-a-constructor-PS-brakes-the-javascript branch from 38a0b55 to 83be18c Compare March 8, 2019 06:24
@mhcurylo
Copy link
Copy Markdown
Contributor Author

mhcurylo commented Mar 8, 2019

Thanks for all the minor comments, they are applied.

@hdgarrood
Copy link
Copy Markdown
Contributor

hdgarrood commented Mar 15, 2019

I've now reviewed this properly and it looks good to me, although I have one small suggestion. Instead of e.g.

  var exports = PS["Effect.Console"] = PS["Effect.Console"] || {};

could we perhaps generate

  var exports = PS["Effect.Console"] || {};
  PS["Effect.Console"] = exports;

which I think should be equivalent, but is a bit clearer?

@hdgarrood
Copy link
Copy Markdown
Contributor

Oh and one more: how about using $PS as the name of the argument for the IIFE function for each module in the output? Then we should be able to avoid collisions with names from PureScript values entirely, rather than relying on slightly arcane details of JS scoping in cases of collisions.

@mhcurylo mhcurylo force-pushed the naming-a-constructor-PS-brakes-the-javascript branch 3 times, most recently from 365e458 to 7f273f6 Compare March 16, 2019 11:05
@mhcurylo
Copy link
Copy Markdown
Contributor Author

All suggestions included in the PR.
I have changed the generated JS.
I have changed the default namespace to $PS (inside the bundle action in the app) as suggested.
It would not solve the issue by itself - a namespace provided to the bundler could still interfere with a constructor if they shared names.
Thus I have changed the name of the test and included a pragma to configure namespace provided to the bundler so that the test is still testing what it should (the case where the namespace is the same as the constructor).

@hdgarrood
Copy link
Copy Markdown
Contributor

Sorry, I should have been clearer: what I mean is that the default bundle namespace should continue to be PS, but the name given to the argument of each iife for each module should be something which couldn’t clash with any purescript name. So for example you might get

var PS = PS || {};
function($PS) {
  // Generated by purs version 0.12.2
  "use strict";
  var exports = $PS["Effect.Console"] = $PS["Effect.Console"] || {};
  var $foreign = $PS["Effect.Console"];
  var Data_Show = $PS["Data.Show"];
  var Data_Unit = $PS["Data.Unit"];
  var Effect = $PS["Effect"];
  exports["log"] = $foreign.log;
})(PS);

So the namespace object is always referred to as $PS inside each iife, regardless of the namespace CLI option. I’d prefer to leave the tests as they were before.

@mhcurylo
Copy link
Copy Markdown
Contributor Author

Oh, that sounds reasonable.
All changes are reverted/made.

The only difference to the example is in the namespace declaration.
Instead of the proposed

var PS = PS || {};

it is

var PS = {};

as it was before.
The semantics are different when a namespace is shared across bundles.
Which one should we go with?

@hdgarrood
Copy link
Copy Markdown
Contributor

Yes, thanks, I think the initial namespace declaration should stay as it is, var PS = {};. (I couldn't be bothered to check how it is currently and so I made a guess which obviously has turned out to be incorrect.)

Did you make a commit locally which you haven't pushed yet? It looks like there aren't any new commits to this branch since my last review comment.

@mhcurylo mhcurylo force-pushed the naming-a-constructor-PS-brakes-the-javascript branch from 76ffbd0 to 9f6ccdf Compare March 17, 2019 11:30
@mhcurylo
Copy link
Copy Markdown
Contributor Author

I have rebased and pushed.
Everything is up to date.

@mhcurylo mhcurylo force-pushed the naming-a-constructor-PS-brakes-the-javascript branch from 9f6ccdf to aa843df Compare March 17, 2019 11:38
@hdgarrood
Copy link
Copy Markdown
Contributor

The moduleExports declaration doesn't seem to have changed?

@mhcurylo mhcurylo force-pushed the naming-a-constructor-PS-brakes-the-javascript branch from aa843df to 9a0e9c9 Compare March 17, 2019 19:06
@mhcurylo
Copy link
Copy Markdown
Contributor Author

Thanks for noticing.
Somewhat I did not read the moduleExports comment.
Now it is addressed.

Introduced test for psc-bundle.

 reference
Copy link
Copy Markdown
Contributor

@hdgarrood hdgarrood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@mhcurylo
Copy link
Copy Markdown
Contributor Author

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants