Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

urllib not set and exception thrown when using nodejs version but bundled into web app using webpack #43

Open
aappddeevv opened this issue Jun 17, 2017 · 8 comments

Comments

@aappddeevv
Copy link

aappddeevv commented Jun 17, 2017

urllib is not set when using new CRMWebAPI({APIUrl: '...'}} and causes an exception to be thrown in

CRMWebAPI.prototype._GetHttpRequestHTTPS = function (config, method, url, payload, callback) {
		var parsed_url = this.urllib.parse(url);

If webpack is bundling, it appears that even if its running in the browser, crmwebapi thinks its running undre node.

@aappddeevv aappddeevv changed the title urlib not set and exception thrown when using nodejs version but bundled into web app using webpack urllib not set and exception thrown when using nodejs version but bundled into web app using webpack Jun 18, 2017
@aappddeevv
Copy link
Author

aappddeevv commented Sep 12, 2017

I've not found a workaround after trying some webpack trickery as the init function directly references modules in the init part of the script to determine if its running under node. If it only mentioned module and exports in the module init portion we would be ok I think. It appears to be an unnecessary dependency on module/exports variables as you could just check to see if the two parameters are not-nil.

@davidyack
Copy link
Owner

@aappddeevv sorry I didn't see this one come in previously, do you have a small project that demonstrates the problem that you could share?

@aappddeevv
Copy link
Author

I don't. I only have a huge project really. I tried using a webpack hack that works with other libraries that have the same problem:

 {
                test: /CRMWebAPI/,
                use: "imports-loader?define=>false,exports=>false,this=>window"
            }

But the issues was the unnecessary test against exports/module inside the init function. I think you can just test for the two parameters.

@aappddeevv
Copy link
Author

aappddeevv commented Oct 8, 2017

I think script-loader may work for webpack and js. It evaluates an imported module as a string using eval() which should remove any vestiges of modules/exports from the UMD module evaluation inside the eval....however this does not seem to translate into typescript well e.g. the consumer is a typescript module (.ts).

I have to require("CRMWebAPI") then "import CRMWebAPI = require("CRMWebAPI") to get webpack's script loader to activate and the 2nd to pull in the .d.ts. However, under the webpack bundle CRMWebAPI comes up null for some reason inside the consuming ts file.

@aappddeevv
Copy link
Author

I created a pure typescript webpack based build for CRMWebAPI that may be able to work. If you use compilation flags you can kick out UMD js and es6 modules. Also, there were some missing declares in the typescript .d.ts file. I think the issue is that the bundling options for a single isomorphic .js file probably won't work. Also, you can kick out a min version.

@paulbreuler
Copy link

I just ran into this issue using while setting up a new react project, though I'm not as proficient as aappddeevv at resolving the issue on my own.

Fails for the following snippet.

    let apiconfig = {
      APIUrl: "https://contoso.crm.dynamics.com/api/data/v9.0/",
      AccessToken: authContext.getCachedToken(authContext.config.clientId),
    };
    let crmAPI = new CRMWebAPI(apiconfig);
    
    var params = {
      Country: "US",
      Amount: 500
    };

    crmAPI.ExecuteAction("xt_CalculateDiscount", params).then(
      function(r) {
        console.log(r);
      },
      function(e) {
        console.log(e);
      }
    );
TypeError: Cannot read property 'parse' of undefined
    at CRMWebAPI._GetHttpRequestHTTPS (CRMWebAPI.js:460)
    at CRMWebAPI.js:342
    at new Promise (<anonymous>)
    at CRMWebAPI.ExecuteAction (CRMWebAPI.js:336)
    at App.render (App.js:22)
    at finishClassComponent (react-dom.development.js:13085)
    at updateClassComponent (react-dom.development.js:13047)
    at beginWork (react-dom.development.js:13715)
    at performUnitOfWork (react-dom.development.js:15741)
    at workLoop (react-dom.development.js:15780)
    at renderRoot (react-dom.development.js:15820)
    at performWorkOnRoot (react-dom.development.js:16437)
    at performWork (react-dom.development.js:16358)
    at performSyncWork (react-dom.development.js:16330)
    at requestWork (react-dom.development.js:16230)
    at scheduleWork$1 (react-dom.development.js:16096)
    at scheduleRootUpdate (react-dom.development.js:16663)
    at updateContainerAtExpirationTime (react-dom.development.js:16690)
    at updateContainer (react-dom.development.js:16717)
    at ReactRoot../node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render (react-dom.development.js:17000)
    at react-dom.development.js:17140
    at unbatchedUpdates (react-dom.development.js:16557)
    at legacyRenderSubtreeIntoContainer (react-dom.development.js:17136)
    at Object.render (react-dom.development.js:17195)
    at index.js:9
    at runWithAdal (react-adal.js:57)
    at Object../src/index.js (index.js:8)
    at __webpack_require__ (bootstrap 3180c7fd1cfef6d3ab5a:678)
    at fn (bootstrap 3180c7fd1cfef6d3ab5a:88)
    at Object.0 (logo.svg:1)
    at __webpack_require__ (bootstrap 3180c7fd1cfef6d3ab5a:678)
    at bootstrap 3180c7fd1cfef6d3ab5a:724
    at bootstrap 3180c7fd1cfef6d3ab5a:724

using create-react-app with the following package.json

{
  "name": "playground",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "CRMWebAPI": "^1.3.6",
    "adal-node": "^0.1.28",
    "react": "^16.4.0",
    "react-adal": "^0.4.18",
    "react-dom": "^16.4.0",
    "react-scripts": "1.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "precommit": "pretty-quick --staged"
  },
  "devDependencies": {
    "eslint-config-prettier": "^2.9.0",
    "eslint-plugin-prettier": "^2.6.0",
    "husky": "^0.14.3",
    "lint-staged": "^7.1.3",
    "prettier": "^1.13.4"
  }
}

@paulbreuler
Copy link

For now, I just hard-coded the required libraries since I'm just using this for testing at the moment.

let myUrl = require('url');
let myHttps = require('https');
...
if (typeof module !== 'undefined' && module.exports) {
                this.node = true;
                this.https = myHttps;
                this.urllib =  myUrl;

@jnaquin
Copy link

jnaquin commented Oct 19, 2018

For anyone who encounters this issue, below is the webpack configuration I use to work around the issue with the npm package not working in the browser.

var StringReplacePlugin = require("string-replace-webpack-plugin");

module.exports = {
    module: {
        rules: [
            {
                test: /CRMWebAPI.js/,
                loader: StringReplacePlugin.replace({
                    replacements: [
                        {
                            pattern: /typeof module !== 'undefined' && module.exports/,
                            replacement: function(match, offset, string) {
                                return "false";
                            }
                        }
                    ]
                })
            }
        ]
    },
}

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

No branches or pull requests

4 participants