Skip to content
This repository was archived by the owner on Apr 28, 2022. It is now read-only.

How to load from node_modules vs. script tag #582

Closed
wearhere opened this issue Sep 26, 2018 · 8 comments
Closed

How to load from node_modules vs. script tag #582

wearhere opened this issue Sep 26, 2018 · 8 comments

Comments

@wearhere
Copy link

wearhere commented Sep 26, 2018

Hey folks, is it possible to load this as a module, from node_modules, and if so, how? I can't find any documentation for doing so either in this repo or on your website, there's just directions for loading it using a script tag.

My use case is within a Chrome extension, where I must package all scripts with the extension and I can't append script tags to the page without polluting the page.

It looks like it should be possible to load this as a module given that it is packaged as UMD and published to npm, but I don't know how to initialize the module i.e. what is the replacement for analytics.load("YOUR_WRITE_KEY"); analytics.page();? When I try doing

const analytics = require('analytics.js');
analytics.load("MY_WRITE_KEY");

I get an error about load not being defined.

I know that my bundler is properly configured to load from node_modules so that is not the problem.

I would also like to verify the following:

  • If I load this as a module vs. a script tag, will it attempt to append any other script tags to the page? Hopefully no.
  • If I load this as a module, do I need to custom-build that module to include only the integrations I use and if so how? Distributed JS is bloated for no reason #519 and linked issues make me suspicious.
@benjaminhoffman
Copy link

have you tried looking into this as a solution: https://www.npmjs.com/package/@segment/snippet

@wearhere
Copy link
Author

wearhere commented Sep 26, 2018

Hey @benjaminhoffman, thanks for your response. Unfortunately it looks like that package merely generates JS equivalent to the script tag, as can be seen in this RunKit I created from the package's documentation: https://runkit.com/wearhere/runkit-npm-segment-snippet. Among other possible downsides, that snippet modifies the window to assign window.analytics which I do not wish to do since my extension is loading into a third-party page.

@LoiKos
Copy link

LoiKos commented Dec 7, 2018

+1
It would be awesome to get the cdn as npm package. He may need some rewrite on analytics.min.js (cdn). With framework like React, import feel more convenient as <script> dependencies and we don't need to modify the window.

@KevinBrogan
Copy link

I haven't looked into the require side of module loading, but you can use define.amd just fine.

window.define=function(dependencies,factory){ ...your define function... }

// analytics.load("MY_WRITE_KEY");
// all analytics.load does is write a script tag to the page. You can do this in html instead of javascript if you wish.

// const scriptTag = document.createElement('script');
// scriptTag.src = `'//cdn.segment.com/analytics.js/v1/${MY_WRITE_KEY}/analytics.min.js`;
// document.head.appendChild(scriptTag);

// Once the analytics library is loaded, it will call define([],factory). Your define library needs to figure out a module name for the factory function as analytics doesn't provide one.

// My library is called like this:
define.load('analytics',`//cdn.segment.com/analytics.js/v1/${MY_WRITE_KEY}/analytics.min.js`);

// you then use define yourself...
define(['analytics'],function(analytics)
{
    analytics.page();
});

@wearhere
Copy link
Author

wearhere commented May 6, 2019

Hey @KevinBrogan, without knowing too much about AMD, it looks like that snippet still presumes that Amplitude is being loaded using a script tag? I see how that snippet lets Amplitude be referenced after load as if it were a module (e.g. with whatever name you like), but my specific concern is where that module is coming from—I wish it to be loaded from node_modules. I've updated the issue's title to clarify that, thanks.

@wearhere wearhere changed the title How to load as module vs. as script tag How to load from npm vs. as script tag May 6, 2019
@wearhere wearhere changed the title How to load from npm vs. as script tag How to load from node_modules vs. as script tag May 6, 2019
@wearhere wearhere changed the title How to load from node_modules vs. as script tag How to load from node_modules vs. script tag May 6, 2019
@kylemh
Copy link

kylemh commented Dec 18, 2019

So at Acorns, we've been using

import analytics from 'analytics.js';

export const install = (apiKey = process.env.SEGMENT_WRITE_KEY) => {
  analytics.initialize({
    'Segment.io': {
      apiKey,
    },
  });
  return analytics;
};

export default install();

and then you can import the module like so:

import analytics from 'background/analytics.js';

Unfortunately, one downside (among others) we've just come across is that this repo is somehow leveraging an older version of analytics.js-core, and I'm not sure where we can control the version to integrate with Cloud Connections... sooo...

It looks like the old implementation from Segment's Chrome Extension package advertises their recommendation for using analytics-node: https://community.segment.com/t/k96ww9

Although there's also this bit of information on executing the snippet via tabs.executeScript() on this Stackoverflow answer.

It would be nice if there was an officially recommended strategy advertised on current documentation.

@corytheboyd
Copy link

corytheboyd commented Feb 11, 2020

Throwing in my +1 for this issue.

I noticed that simply using the analytics-node package instead of the analytics.js build from the CDN is omitting browser IP and user-agent metadata from context on events. Sure, one could fill that context in manually but that defeats the point of deferring this logic to the canonical SDK.

Furthermore there is documentation suggesting that pages include JavaScript that invokes the user identify function in all authenticated pages, but what if the application is not rendered server-side? The state of Segment’s JavaScript SDK publishing feels a bit antiquated and I can’t help but feel like I am doing something wrong by using what is documented as the Node.js SDK in web frontends. What is preventing the publishing of the web SDK as an npm package for this purpose? I don’t want my products ability to load be at the mercy of a third-party CDN if I can avoid it.

Would love to hear from the core team about this decision, and help however I can if it’s a matter of needed contribution from the community.

Edit
I found this comment in a similar issue which states they the bundle is dynamically built based on the integrations used by the project: #598 (comment)

Knowing that I can see the case for needing to fetch the script dynamically. I don’t know if I agree with the approach, but I also recognize that I am making this judgement from the perspective of my fairly trivial Segment integration. In my mind, I should be able to to extend the Segment SDK manually based on what I know my needs are, as once this basic integration is set up I know it will not change.

@pooyaj
Copy link
Contributor

pooyaj commented Jul 17, 2020

Just closing the loop on this. As mentioned above, for the time being using CDN is the recommended approach, as the script generated dynamically with app the settings etc. If still like to go for an npm package, I recommend checking out this example

@pooyaj pooyaj closed this as completed Jul 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants