statgen / locuszoom

A Javascript/d3 embeddable plugin for interactively visualizing statistical genetic data from customizable sources.
https://statgen.github.io/locuszoom/
MIT License
154 stars 29 forks source link

Failing dependency on Q when using LocusZoom in React #152

Closed gijskant closed 5 years ago

gijskant commented 5 years ago

Problem

When embedding LocusZoom in a React app, building or starting the app results in an error:

Module not found: Can't resolve 'Q' in '/home/gijs/src/locus-zoom-react/node_modules/locuszoom/dist'

Locuszoom is imported as a node dependency: "locuszoom": "^0.8.2". The problem seems to be in the module header as defined in wrapper.txt, where the dependency is named Q, while node uses q to refer to the module.

Steps to reproduce the issue

npx create-react-app locus-zoom-react
cd locus-zoom-react
yarn
yarn add locuszoom

Edit src/App.js:

import React, { Component } from 'react';
import './App.css';
import LocusZoom from 'locuszoom';
import '../node_modules/locuszoom/dist/locuszoom.css';

class App extends Component {

    chromosome = 20;
    regionStart = 21705659;
    regionEnd = 21718486;

    componentDidMount() {
        const url = "http://portaldev.sph.umich.edu/api/v1/";
        let data_sources = new LocusZoom.DataSources();
        data_sources.add("assoc", ["AssociationLZ", {url: url + 'statistic/single/', params: {analysis: 45, id_field: 'variant'}}]);
        data_sources.add("ld", ["LDLZ", {url: url + "pair/LD/", params: { pvalue_field: "pvalue|neglog10_or_100" }}]);
        data_sources.add("gene", ["GeneLZ", { url: url + "annotation/genes/", params: {source: 2} }]);
        data_sources.add("recomb", ["RecombLZ", { url: url + "annotation/recomb/results/", params: {source: 15} }]);
        data_sources.add("constraint", ["GeneConstraintLZ", { url: "http://exac.broadinstitute.org/api/constraint" }]);

        let initialState = { chr: this.chromosome, start: this.regionStart, end: this.regionEnd };
        let layout = LocusZoom.Layouts.get("plot", "standard_association", {state: initialState});
        layout.dashboard = LocusZoom.Layouts.get("dashboard", "region_nav_plot");

        LocusZoom.populate("#lz-plot", data_sources, layout);
    }

    render() {
        const region = `${this.chromosome}:${this.regionStart}-${this.regionEnd}`;
        return (
            <div className="App">
                <main className="App-main">
                    <div id="lz-plot" className="lz-container-responsive" data-region={region} />
                </main>
            </div>
        );
    }
}

export default App;

Run:

yarn start

Error:

Failed to compile.

./node_modules/locuszoom/dist/locuszoom.app.js
Module not found: Can't resolve 'Q' in '/home/gijs/src/locus-zoom-react/node_modules/locuszoom/dist'

Proposed solution

The problem is solved when changing 'Q' to 'q' on line 5 in node_modules/locuszoom/dist/locuszoom.app.js.

Solution in the source: change line 3 in assets/js/app/wrapper.txt to:

        define(["d3", "q"], function(d3, Q){  // amd
abought commented 5 years ago

Thanks for the report! Relatively few of our users use a build pipeline, and as a result the importable functionality is under-tested.

I've added the suggested change to a branch in progress; will merge and mark fixed once I have a chance to test this out in a vue app I'm working on.

gijskant commented 5 years ago

Thanks for the quick response! Good luck with all development work.

abought commented 5 years ago

One other note that you may find helpful:

If your custom plot uses the LocusZoom "download image" button feature, it may break when using asset concatenation with the CSS. See #125 for details.

Please let us know if you find any other quirks when using React with LZ.js!

abought commented 5 years ago

No further response. I'll close this ticket for now, but let us know how this turned out- we're quite open to improving our module support going forward. (many of our older usages were based on globals)